summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Changelog91
-rw-r--r--dist/config/config.xml6
-rw-r--r--dist/packages/org.qtproject.ifw.binaries/meta/package.xml4
-rw-r--r--dist/packages/org.qtproject.ifw/meta/package.xml4
-rw-r--r--doc/config/ifw.qdocconf3
-rw-r--r--doc/installerfw.qdoc43
-rw-r--r--doc/operations.qdoc4
-rw-r--r--doc/scripting-api/gui.qdoc7
-rw-r--r--doc/scripting-api/packagemanagercore.qdoc26
-rw-r--r--doc/scripting.qdoc68
-rw-r--r--examples/dependencies/config/config.xml1
-rw-r--r--examples/dependencies/packages/componentG/meta/installscript.js39
-rw-r--r--examples/dependencies/packages/componentG/meta/package.xml6
-rw-r--r--examples/doc/hidecheckbox.qdoc59
-rw-r--r--examples/doc/images/qtifw-examples-hidecheckbox.pngbin0 -> 24807 bytes
-rw-r--r--examples/doc/images/qtifw-examples-stylesheet.pngbin0 -> 14796 bytes
-rw-r--r--examples/doc/stylesheet.qdoc51
-rw-r--r--examples/examples.pro3
-rw-r--r--examples/hidecheckbox/README6
-rw-r--r--examples/hidecheckbox/config/config.xml9
-rw-r--r--examples/hidecheckbox/hidecheckbox.pro13
-rw-r--r--examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/data/testF_sub1_sub1.txt1
-rw-r--r--examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/meta/package.xml7
-rw-r--r--examples/hidecheckbox/packages/componentF.subcomponent1/data/testF_sub1.txt1
-rw-r--r--examples/hidecheckbox/packages/componentF.subcomponent1/meta/package.xml9
-rw-r--r--examples/hidecheckbox/packages/componentF/data/testF.txt1
-rw-r--r--examples/hidecheckbox/packages/componentF/meta/package.xml9
-rw-r--r--examples/startmenu/packages/org.qtproject.ifw.example/meta/installscript.qs2
-rw-r--r--examples/stylesheet/README6
-rw-r--r--examples/stylesheet/config/config.xml12
-rw-r--r--examples/stylesheet/config/style.qss25
-rw-r--r--examples/stylesheet/packages/org.qtproject.ifw.example.stylesheet/meta/installscript.qs39
-rw-r--r--examples/stylesheet/packages/org.qtproject.ifw.example.stylesheet/meta/package.xml8
-rw-r--r--examples/stylesheet/stylesheet.pro13
-rw-r--r--examples/translations/README9
-rw-r--r--installerfw.pri12
-rw-r--r--installerfw.pro16
-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.cpp706
-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.cpp66
-rw-r--r--src/libs/installer/binarycontent.cpp10
-rw-r--r--src/libs/installer/binaryformat.cpp4
-rw-r--r--src/libs/installer/component.cpp149
-rw-r--r--src/libs/installer/component.h28
-rw-r--r--src/libs/installer/componentchecker.cpp12
-rw-r--r--src/libs/installer/componentmodel.cpp18
-rw-r--r--src/libs/installer/constants.h11
-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.cpp76
-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/globals.cpp5
-rw-r--r--src/libs/installer/globals.h1
-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.pro12
-rw-r--r--src/libs/installer/installercalculator.cpp78
-rw-r--r--src/libs/installer/installercalculator.h4
-rw-r--r--src/libs/installer/installiconsoperation.cpp48
-rw-r--r--src/libs/installer/installiconsoperation.h3
-rw-r--r--src/libs/installer/keepaliveobject.cpp4
-rw-r--r--src/libs/installer/lib7z_create.h77
-rw-r--r--src/libs/installer/lib7z_extract.h85
-rw-r--r--src/libs/installer/lib7z_facade.cpp1860
-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/localsocket.h68
-rw-r--r--src/libs/installer/messageboxhandler.cpp4
-rw-r--r--src/libs/installer/metadatajob.cpp275
-rw-r--r--src/libs/installer/metadatajob.h13
-rw-r--r--src/libs/installer/metadatajob_p.h15
-rw-r--r--src/libs/installer/minimumprogressoperation.cpp9
-rw-r--r--src/libs/installer/minimumprogressoperation.h3
-rw-r--r--src/libs/installer/packagemanagercore.cpp350
-rw-r--r--src/libs/installer/packagemanagercore.h20
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp446
-rw-r--r--src/libs/installer/packagemanagercore_p.h51
-rw-r--r--src/libs/installer/packagemanagercoredata.cpp108
-rw-r--r--src/libs/installer/packagemanagercoredata.h3
-rw-r--r--src/libs/installer/packagemanagergui.cpp507
-rw-r--r--src/libs/installer/packagemanagergui.h12
-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/productkeycheck.cpp5
-rw-r--r--src/libs/installer/productkeycheck.h1
-rw-r--r--src/libs/installer/progresscoordinator.cpp2
-rw-r--r--src/libs/installer/proxycredentialsdialog.h4
-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.cpp72
-rw-r--r--src/libs/installer/registerfiletypeoperation.h9
-rw-r--r--src/libs/installer/remoteclient.cpp19
-rw-r--r--src/libs/installer/remoteclient.h3
-rw-r--r--src/libs/installer/remoteclient_p.h25
-rw-r--r--src/libs/installer/remoteobject.cpp6
-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.cpp7
-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.cpp37
-rw-r--r--src/libs/installer/repository.h7
-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.cpp26
-rw-r--r--src/libs/installer/scriptengine_p.h6
-rw-r--r--src/libs/installer/selfrestartoperation.cpp24
-rw-r--r--src/libs/installer/selfrestartoperation.h3
-rw-r--r--src/libs/installer/settings.cpp82
-rw-r--r--src/libs/installer/settings.h5
-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.cpp166
-rw-r--r--src/libs/installer/testrepository.h52
-rw-r--r--src/libs/installer/unziptask.cpp50
-rw-r--r--src/libs/installer/utils.cpp56
-rw-r--r--src/libs/installer/utils.h16
-rw-r--r--src/libs/kdtools/environment.h6
-rw-r--r--src/libs/kdtools/filedownloader.cpp (renamed from src/libs/kdtools/kdupdaterfiledownloader.cpp)65
-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)88
-rw-r--r--src/libs/kdtools/job.h (renamed from src/libs/kdtools/kdjob.h)23
-rw-r--r--src/libs/kdtools/kdgenericfactory.cpp175
-rw-r--r--src/libs/kdtools/kdgenericfactory.h100
-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.cpp306
-rw-r--r--src/libs/kdtools/kdupdaterapplication.h100
-rw-r--r--src/libs/kdtools/kdupdaterupdatesourcesinfo.cpp475
-rw-r--r--src/libs/kdtools/kdupdaterupdatesourcesinfo.h112
-rw-r--r--src/libs/kdtools/localpackagehub.cpp (renamed from src/libs/kdtools/kdupdaterpackagesinfo.cpp)305
-rw-r--r--src/libs/kdtools/localpackagehub.h (renamed from src/libs/kdtools/kdupdaterpackagesinfo.h)74
-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)4
-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)149
-rw-r--r--src/libs/kdtools/updatefinder.h (renamed from src/libs/kdtools/kdupdaterupdatefinder.h)23
-rw-r--r--src/libs/kdtools/updateoperation.cpp (renamed from src/libs/kdtools/kdupdaterupdateoperation.cpp)126
-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/commandlineparser.cpp9
-rw-r--r--src/sdk/constants.h3
-rw-r--r--src/sdk/installerbase.cpp125
-rw-r--r--src/sdk/installerbase.qrc19
-rw-r--r--src/sdk/installerbasecommons.cpp28
-rw-r--r--src/sdk/installerbasecommons.h3
-rw-r--r--src/sdk/main.cpp33
-rw-r--r--src/sdk/sdk.pro96
-rw-r--r--src/sdk/settingsdialog.cpp67
-rw-r--r--src/sdk/settingsdialog.h2
-rw-r--r--src/sdk/tabcontroller.cpp20
-rw-r--r--src/sdk/tabcontroller.h1
-rw-r--r--src/sdk/translations/README23
-rw-r--r--src/sdk/translations/da.ts2450
-rw-r--r--src/sdk/translations/de.ts448
-rw-r--r--src/sdk/translations/en.ts2653
-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.ts309
-rw-r--r--src/sdk/translations/pl.ts242
-rw-r--r--src/sdk/translations/ru.ts1354
-rw-r--r--src/sdk/translations/zh_CN.ts (renamed from src/sdk/translations/zh_cn.ts)242
-rw-r--r--src/sdk/updatechecker.cpp14
-rw-r--r--src/src.pro10
-rw-r--r--sync.profile8
-rw-r--r--tests/auto/installer/binaryformat/tst_binaryformat.cpp8
-rw-r--r--tests/auto/installer/clientserver/tst_clientserver.cpp11
-rw-r--r--tests/auto/installer/componentmodel/data/updates.xml48
-rw-r--r--tests/auto/installer/componentmodel/tst_componentmodel.cpp128
-rw-r--r--tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp10
-rw-r--r--tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp21
-rw-r--r--tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp12
-rw-r--r--tests/auto/installer/factory/factory.pro5
-rw-r--r--tests/auto/installer/factory/tst_factory.cpp228
-rw-r--r--tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp16
-rw-r--r--tests/auto/installer/installer.pro9
-rw-r--r--tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp114
-rw-r--r--tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp17
-rw-r--r--tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp7
-rw-r--r--tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp27
-rw-r--r--tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro6
-rw-r--r--tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp126
-rw-r--r--tests/auto/installer/scriptengine/data/addOperation.qs52
-rw-r--r--tests/auto/installer/scriptengine/scriptengine.pro2
-rw-r--r--tests/auto/installer/scriptengine/scriptengine.qrc1
-rw-r--r--tests/auto/installer/scriptengine/tst_scriptengine.cpp166
-rw-r--r--tests/auto/installer/settings/data/full_config.xml3
-rw-r--r--tests/auto/installer/settings/data/length_units_invalid.xml7
-rw-r--r--tests/auto/installer/settings/data/length_units_valid_em.xml7
-rw-r--r--tests/auto/installer/settings/data/length_units_valid_ex.xml7
-rw-r--r--tests/auto/installer/settings/data/length_units_valid_px.xml7
-rw-r--r--tests/auto/installer/settings/settings.qrc4
-rw-r--r--tests/auto/installer/settings/tst_settings.cpp60
-rw-r--r--tests/auto/installer/settingsoperation/tst_settingsoperation.cpp34
-rw-r--r--tests/auto/installer/solver/tst_solver.cpp40
-rw-r--r--tests/auto/installer/unicodeexecutable/main.c54
-rw-r--r--tests/auto/installer/unicodeexecutable/stringdata.h41
-rw-r--r--tests/auto/installer/unicodeexecutable/unicodeexecutable.pro8
-rw-r--r--tests/downloadspeed/main.cpp20
-rw-r--r--tests/environmentvariable/environmentvariabletest.cpp8
-rw-r--r--tests/tests.pro1
-rw-r--r--tools/archivegen/archive.cpp169
-rw-r--r--tools/archivegen/archivegen.pro1
-rw-r--r--tools/binarycreator/binarycreator.cpp145
-rw-r--r--tools/binarycreator/binarycreator.qrc1
-rw-r--r--tools/binarycreator/rcc/rcc.cpp10
-rw-r--r--tools/binarycreator/resources/mkdmg.sh65
-rw-r--r--tools/common/repositorygen.cpp116
-rw-r--r--tools/common/repositorygen.h1
-rw-r--r--tools/devtool/binarydump.cpp20
-rw-r--r--tools/devtool/binaryreplace.cpp24
-rw-r--r--tools/devtool/main.cpp149
-rw-r--r--tools/devtool/operationrunner.cpp6
-rw-r--r--tools/repocompare/main.cpp2
-rw-r--r--tools/repocompare/mainwindow.cpp10
-rw-r--r--tools/repocompare/repositorymanager.cpp11
-rw-r--r--tools/repogen/repogen.cpp11
-rw-r--r--tools/tools.pro1
970 files changed, 62818 insertions, 48926 deletions
diff --git a/.gitignore b/.gitignore
index 2f83fcb16..cf1dfa3a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -88,3 +88,5 @@ doc-build
.rcc
.pch
.metadata
+
+/src/sdk/translations/untranslated.ts
diff --git a/Changelog b/Changelog
index 526533c98..d97dfc8e1 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,94 @@
+3.0.1
+- Fix install type if --online-only passed to binarycreator
+- Fix install fail if there are missing repositories
+- Fix Component Name visibility in maintenancetool
+- Adminauthorization freeze fixed under unix (QTIFW-934)
+- Enable high-DPI scaling (QTBUG-61122)
+- Fix maintenance tool update with silentUpdate (QTIFW-976)
+
+3.0.0
+- Change required Qt version, minimum version is now 5.6.2.
+- Clarify the add/remove components string to make it clearer
+- Fix crash at the very end of install if admin rights needed in Windows (QTIFW-943)
+- Make installer to check the dependency version (QTIFW-914)
+- Fix uninstallation on Windows when target path contains non-ascii characters
+- Fix installer crash when it contains replaced and replacement component (QTIFW-915)
+- Avoid warning messages when passing '--platform minimal'
+- New --silentUpdate command line option (QTIFW-906)
+- Allow installing compressed packages. (QTIFW-886)
+- Make support for modifying installations configurable. Introduces new setting 'SupportsModify' in the config.xml.
+- Allow the use of relative URLs to update repositories in Updates.xml.
+- Fix cancel button functionality in Settings->Repositories->Test. (QTIFW-832)
+- Introduced gui.setTextItems() method
+- Store lock files in temporary directory
+- Vertical layout for LicenseAgreement page. (QTIFW-815)
+- add NOMINMAX to fix compile with Qt5.7 in Windows (QTIFW-854)
+- Make usage of authorization fallback optional
+- Fix building with ICC on Windows. (QTIFW-851)
+- Add ApplicationsDirX86 and ApplicationsDirX64 predefined Variables.
+- Fixed (and greatly simplified) creating .dmg files
+- Add a logging category and debug print for http download
+- Make communication via installer.execute() Unicode safe - added two new optional arguments to installer.execute() to define the used codec.
+- Allow specifying the installer size in 'em' or 'ex' units
+- Fixed deleting files when uninstalling on OS X
+- Fix arguments in RegisterFileType
+- Add new '--sign' switch to binarycreator for signing OS X app bundles
+- Fix setValue saving in restart. (QTIFW-504)
+- Allow calling installer.setValue() with an empty string as the value.
+- Fixed writing log on Windows if target dir requires admin rights.
+- Fixed final 'Finish' message on OS X.
+- Resize banner image to fit default installer width.
+- Allow defining non-checkable items - introduces new element 'Checkable' for package. (QTIFW-773)
+- Added support for setting descriptions of Windows shortcuts.
+- Let mkdmg.sh script on OS X actually create random temporary file names. (QTIFW-780)
+- Fix timeout errors while building app bundles files on OS X.
+- Fix timezone issue in archive, simply keep the UTC time.
+- Optimized checking validity of target directory value on Windows. (QTIFW-673)
+- Remove implicit expanding vertical spacer from dynamic pages. (QTIFW-779)
+- Fixed compiling lib7z_facade.cpp with Visual Studio 2013.
+- Fixed several sudo problems eg. (QTIFW-771)
+- Fixed running binarycreator if the temporary directory name contains spaces. (QTIFW-787)
+- Fix violated assertion in error handling of binarycreator.
+- Automatically choose to perform uninstall if appropriate.
+- Implemented installer.readFile().
+- Implemented support for creating URL shortcuts on Windows.
+- Fixed occasional crash on Windows when terminating installer.
+- Fix broken daylight saving time check.
+- Fix crash when updating admin installation with user/temp repository. (QTIFW-740)
+- Read UrlQueryString from settings. (QTIFW-744)
+- Allow to use the stylesheet to customize UI.
+- Add Castilian Spanish translation.
+- Add possibility to run silently without a gui. (QTIFW-166)
+- Removed {kd} and {kdupdater} prefix.
+- Make the installation relocatable (with some limitations). (QTIFW-653)
+- Add factory auto test.
+- Fix canceling the download done by an external call.
+- Print Qt version in verbose output.
+- Fix missing filename conversion on UNIX systems. (QTIFW-643)
+- Remove superfluous clone() method from operations.
+- Implement generic factory using c++11 variadic template feature.
+- Follow description on MSDN to implement time utils. (QTIFW-445)
+- Fix compile for gcc 4.7.3.
+- Convert to Qt 5 connect syntax.
+- Remove signal finished() overload.
+- Use qmake .depends instead of CONFIG += ordered.
+- Update archivegen.
+ * Stop on file errors.
+ * Better verbose/ help output.
+ * Add support for compression level.
+ * Do not hide symbols in statically build lib7z to use e.g. CPercentPrinter symbol in dynamic IFW builds.
+- Update source tree with version 9.38.beta of LZMA SDK.
+- Store AutoDependOn inside components.xml.
+- Implemented xml:lang attribute support for DisplayName tag.
+- Added AllUsers constant.
+- Enable feature live preview of dependencies. Introduces new InstallActionColumnVisible property to config.xml.
+- Remove scRemoteVersion, it's the same as scVersion.
+- Introduce a new struct PackageInfo which replaces UpdateSourceInfo.
+- Use positional arguments instead of options in devtool.
+- Add a warning if component with data contains children.
+- Fix reading and checking arguments of CreateShortcutOperation
+- Introduc new isMaintainer() method
+
2.0.5
- Fix hang in Windows when admin rights needed. (QTIFW-902)
- Use deterministic sorting order for components. (QTIFW-833)
diff --git a/dist/config/config.xml b/dist/config/config.xml
index 022f3f738..f7d09e9d5 100644
--- a/dist/config/config.xml
+++ b/dist/config/config.xml
@@ -1,13 +1,13 @@
<?xml version="1.0"?>
<Installer>
<Name>Qt Installer Framework</Name>
- <Title>Qt Installer Framework 2.0.5</Title>
- <Version>1.0.0</Version>
+ <Title>Qt Installer Framework 3.0.1</Title>
+ <Version>3.0.1</Version>
<Publisher>Qt Project</Publisher>
<ProductUrl>http://qt-project.org</ProductUrl>
<Watermark>watermark.png</Watermark>
<MaintenanceToolName>Uninstaller</MaintenanceToolName>
<!-- Tweaked for windows in installscript.qs -->
- <TargetDir>@HomeDir@/Qt/QtIFW2.0.5</TargetDir>
+ <TargetDir>@HomeDir@/Qt/QtIFW-3.0.1</TargetDir>
</Installer>
diff --git a/dist/packages/org.qtproject.ifw.binaries/meta/package.xml b/dist/packages/org.qtproject.ifw.binaries/meta/package.xml
index 2391d7a51..71c32421c 100644
--- a/dist/packages/org.qtproject.ifw.binaries/meta/package.xml
+++ b/dist/packages/org.qtproject.ifw.binaries/meta/package.xml
@@ -2,7 +2,7 @@
<Package>
<DisplayName>Qt Installer Framework Binaries</DisplayName>
<Description>Installs the binaries, examples and help files.</Description>
- <Version>2.0.5</Version>
- <ReleaseDate>2017-01-13</ReleaseDate>
+ <Version>3.0.1</Version>
+ <ReleaseDate>2017-06-27</ReleaseDate>
<Default>True</Default>
</Package>
diff --git a/dist/packages/org.qtproject.ifw/meta/package.xml b/dist/packages/org.qtproject.ifw/meta/package.xml
index 01c2206e6..ef97d39f9 100644
--- a/dist/packages/org.qtproject.ifw/meta/package.xml
+++ b/dist/packages/org.qtproject.ifw/meta/package.xml
@@ -2,8 +2,8 @@
<Package>
<DisplayName>Qt Installer Framework</DisplayName>
<Description>Installs the Qt Installer Framework.</Description>
- <Version>2.0.5</Version>
- <ReleaseDate>2017-01-13</ReleaseDate>
+ <Version>3.0.1</Version>
+ <ReleaseDate>2017-06-27</ReleaseDate>
<Licenses>
<License name="The Qt Company GPL Exception 1.0" file="LICENSE.GPL3-EXCEPT" />
<License name="Third Party Code Licenses" file="3RDPARTY" />
diff --git a/doc/config/ifw.qdocconf b/doc/config/ifw.qdocconf
index 3d9b1d7d4..870245eb2 100644
--- a/doc/config/ifw.qdocconf
+++ b/doc/config/ifw.qdocconf
@@ -8,8 +8,7 @@ project = "Qt Installer Framework"
description = "Qt Installer Framework Manual"
url = http://qt-project.org/doc/qtinstallerframework/
-sourcedirs += includes
-sourcedirs += ../../src/libs/installer ../../src/libs/kdtools
+sourcedirs += ../../src/libs/installer ../../src/libs/kdtools ../includes
headerdirs += ../../src/libs/installer ../../src/libs/kdtools
imagedirs = $SRCDIR/images $SRCDIR/templates/images
diff --git a/doc/installerfw.qdoc b/doc/installerfw.qdoc
index 94659711a..cc15efb36 100644
--- a/doc/installerfw.qdoc
+++ b/doc/installerfw.qdoc
@@ -217,13 +217,18 @@
\li WizardStyle
\li Set the wizard style to be used ("Modern", "Mac", "Aero" or "Classic").
\row
+ \li StyleSheet
+ \li Set the stylesheet file.
+ \row
\li WizardDefaultWidth
\li Sets the default width of the wizard in pixels. Setting a banner image will
- override this.
+ override this. You can add the \c em or \c ex suffix to the specified value to
+ use the \e em or \e ex unit, as in a CSS file.
\row
\li WizardDefaultHeight
\li Sets the default height of the wizard in pixels. Setting a watermark image will
- override this.
+ override this. You can add the \c em or \c ex suffix to the specified value to
+ use the \e em or \e ex unit, as in a CSS file.
\row
\li TitleColor
\li Set the color of the titles and subtitles (takes an HTML color code,
@@ -277,6 +282,10 @@
\li Set to \c true if the installation path can contain non-ASCII
characters.
\row
+ \li DisableAuthorizationFallback
+ \li Set to \c true if the installation should not ask users to run the authorization
+ fallback in case of authorization errors. Instead abort the installation immediately.
+ \row
\li RepositorySettingsPageVisible
\li Set to \c false to hide the repository settings page inside the settings dialog.
\row
@@ -307,6 +316,14 @@
\li Set to \c true if you want to create a local repository inside the installation directory.
This option has no effect on online installers. The repository will be automatically added
to the list of default repositories.
+ \row
+ \li InstallActionColumnVisible
+ \li Set to \c true if you want to add an extra column into component tree showing install actions.
+ This extra column indicates whether a component is going to be installed or uninstalled,
+ or just stay installed or uninstalled.
+ \row
+ \li SupportsModify
+ \li Set to \c false if the product does not support modifying an existing installation.
\endtable
@@ -543,11 +560,12 @@
\row
\li DisplayName
\li Human-readable name of the component. Required.
+ Specify translations for the name of the component as values of additional
+ DisplayName tags, with the xml:lang attribute set to the correct locale.
\row
\li Description
\li Human-readable description of the component. Required.
- Specify translations for the description as values of additional
- Description tags, with the xml:lang attribute set to the correct locale.
+ Translations may be specified similarly to DisplayName tag.
If a localization that matches the locale is not found and an untranslated
version exists, that one will be used. Otherwise no Description will be
shown for that locale.
@@ -603,6 +621,8 @@
\li List of license agreements to be accepted by the installing
user. To add several licenses, add several \c <License> child
elements that each specify the license \c name and \c file.
+ ASCII and UTF8 file formats are supported for license files.
+
If there are translations listed for this component, the installer
will also look for translated licenses. These need to have the
same name as the original license file but with an added
@@ -667,6 +687,11 @@
\li RequiresAdminRights
\li Set to \c true if the package needs to be installed with elevated permissions.
Optional.
+ \row
+ \li Checkable
+ \li Set to \c false if you want to hide the checkbox for an item. This is useful
+ when only a few subcomponents should be selected instead of all. Optional.
+
\endtable
\section2 Component Dependencies
@@ -830,6 +855,11 @@
\row
\li -v or --verbose
\li Display debug output.
+
+ \row
+ \li -s or --sign identity
+ \li Only available on OS X. Allows specifying a code signing identity to be
+ used for signing the generated app bundle.
\endtable
These parameters are followed by the name of the target binary and a list
@@ -839,6 +869,11 @@
their dependencies and all packages that share the same prefix, unless you
specify the \c --nodeps parameter.
+ In the optional resource files specified via the \c --resources parameter, a
+ special \c fonts/ path can be used to ship custom fonts. These fonts will
+ be loaded automatically and thus become available in a stylesheet which can
+ be specified via the \c StyleSheet variable.
+
On Windows, the name of the target binary is automatically extended with
.exe, if you do not specify the extension. On Mac, the target is
created as an application bundle with the extension .app, which is automatically
diff --git a/doc/operations.qdoc b/doc/operations.qdoc
index 243ff7771..697502145 100644
--- a/doc/operations.qdoc
+++ b/doc/operations.qdoc
@@ -122,7 +122,9 @@
\li Creates a shortcut from the file specified by \c filename to
\c linkname.
On Windows, this creates a .lnk file which can have
- \c arguments. On Unix, this creates a symbolic link.
+ \c arguments. Furthermore, on Windows, \c filename can be
+ an HTTP or FTP URL in which case a URL shortcut is created.
+ On Unix, this creates a symbolic link.
\row
\li CreateDesktopEntry
\li "CreateDesktopEntry" \c {filename "key=value[ key2=value2[ key3=value3]]]"}
diff --git a/doc/scripting-api/gui.qdoc b/doc/scripting-api/gui.qdoc
index 9697c8b21..88f2b7bf8 100644
--- a/doc/scripting-api/gui.qdoc
+++ b/doc/scripting-api/gui.qdoc
@@ -168,3 +168,10 @@
/*!
\qmlmethod void gui::setModified(boolean value)
*/
+
+/*!
+ \qmlmethod void gui::setTextItems(object control, string[] items)
+
+ Updates the model of \a control (which must be a QComboBox or QAbstractItemView)
+ such that it contains the given \a items.
+*/
diff --git a/doc/scripting-api/packagemanagercore.qdoc b/doc/scripting-api/packagemanagercore.qdoc
index cbb7b477b..ed1972e13 100644
--- a/doc/scripting-api/packagemanagercore.qdoc
+++ b/doc/scripting-api/packagemanagercore.qdoc
@@ -35,9 +35,11 @@
/*!
\qmlmethod array installer::components()
- Returns an array of all available components.
+ Returns an array of all components currently available.
+ If the repository metadata have not been fetched yet,
+ the array will be empty.
- \sa component
+ \sa component, installer::finishAllComponentsReset(), installer::finishUpdaterComponentsReset()
*/
/*!
@@ -332,6 +334,17 @@
*/
/*!
+ \qmlmethod boolean installer::readFile(string filePath, string codecName)
+
+ 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.
+*/
+
+/*!
\qmlmethod boolean installer::fileExists(string filePath)
Returns \c true if the \a filePath exists; otherwise returns \c false.
@@ -492,13 +505,20 @@
/*!
\qmlmethod array installer::execute(string program, stringlist arguments = undefined,
- string stdin = "")
+ string stdin = "", string stdinCodec = "latin1",
+ string stdoutCodec = "latin1")
Starts the program \a program with the arguments \a arguments in a
new process and waits for it to finish.
\a stdin is sent as standard input to the application.
+ \a stdInCodec is the name of the codec to use for converting the input string
+ into bytes to write to the standard input of the application.
+
+ \a stdOutCodec is the name of the codec to use for converting data written by the
+ application to standard output into a string.
+
Returns an empty array if the program could not be executed, otherwise
the output of command as the first item, and the return code as the second.
diff --git a/doc/scripting.qdoc b/doc/scripting.qdoc
index b430c0464..708345c7d 100644
--- a/doc/scripting.qdoc
+++ b/doc/scripting.qdoc
@@ -138,7 +138,7 @@
methods that you must implement:
\code
- #include <KDUpdater/UpdateOperation>
+ #include <UpdateOperation>
class CustomOperation : public KDUpdater::UpdateOperation
{
@@ -205,7 +205,7 @@
Finally, you need to register your custom operation class, as follows:
\code
- #include <KDupdater/UpdateOperationFactory>
+ #include <UpdateOperationFactory>
KDUpdater::UpdateOperationFactory::instance().registerUpdateOperation< CustomOperation >( "CustomOperation" );
\endcode
@@ -266,6 +266,27 @@
For example, \c {C:\Program Files} on Windows,
\c {/opt} on Linux and \c {/Applications} on OS X.
+
+ See also the table that lists examples of \l {Applications-directory-on-Windows}
+ {applications directories on Windows}.
+ \row
+ \li ApplicationsDirX86
+ \li Applications Directory for 32 bit programs. This is useful on Windows,
+ on other platforms it is the same as \c ApplicationsDir.
+
+ For example, \c {C:\Program Files (x86)} on Windows.
+
+ See also the table that lists examples of \l {Applications-directory-on-Windows}
+ {applications directories on Windows}.
+ \row
+ \li ApplicationsDirX64
+ \li Applications Directory for 64 bit programs. This is useful on Windows,
+ on other platforms it is the same as \c ApplicationsDir.
+
+ For example, \c {C:\Program Files} on Windows.
+
+ See also the table that lists examples of \l {Applications-directory-on-Windows}
+ {applications directories on Windows}.
\row
\li InstallerDirPath
\li The directory that contains the installer application executable.
@@ -297,4 +318,47 @@
component.addOperation("CreateShortcut", "@TargetDir@/MyApp.exe", "@StartMenuDir@/MyApp.lnk");
}
\endcode
+
+
+ \target Applications-directory-on-Windows
+ For example, applications directory on Windows:
+ \table
+ \header
+ \li OS (Windows)
+ \li Qt Installer Framework
+ \li Variable
+ \li Example Path
+ \row
+ \li {1, 3} 32bit
+ \li {1, 3} 32bit
+ \li ApplicationsDir
+ \li \c {C:\Program Files}
+ \row
+ \li ApplicationsDirX86
+ \li \c {C:\Program Files}
+ \row
+ \li ApplicationsDirX64
+ \li \c {C:\Program Files}
+ \row
+ \li {1, 6} 64bit
+ \li {1, 3} 32bit
+ \li ApplicationsDir
+ \li \c {C:\Program Files (x86)}
+ \row
+ \li ApplicationsDirX86
+ \li \c {C:\Program Files (x86)}
+ \row
+ \li ApplicationsDirX64
+ \li \c {C:\Program Files}
+ \row
+ \li {1, 3} 64bit
+ \li ApplicationsDir
+ \li \c {C:\Program Files}
+ \row
+ \li ApplicationsDirX86
+ \li \c {C:\Program Files (x86)}
+ \row
+ \li ApplicationsDirX64
+ \li \c {C:\Program Files}
+ \endtable
*/
diff --git a/examples/dependencies/config/config.xml b/examples/dependencies/config/config.xml
index 72a127f19..d7a0723dd 100644
--- a/examples/dependencies/config/config.xml
+++ b/examples/dependencies/config/config.xml
@@ -7,4 +7,5 @@
<StartMenuDir>Qt IFW Examples</StartMenuDir>
<TargetDir>@HomeDir@/IfwExamples/dependencies</TargetDir>
<CreateLocalRepository>true</CreateLocalRepository>
+ <InstallActionColumnVisible>true</InstallActionColumnVisible>
</Installer>
diff --git a/examples/dependencies/packages/componentG/meta/installscript.js b/examples/dependencies/packages/componentG/meta/installscript.js
new file mode 100644
index 000000000..ea89a4162
--- /dev/null
+++ b/examples/dependencies/packages/componentG/meta/installscript.js
@@ -0,0 +1,39 @@
+/**************************************************************************
+**
+** 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$
+**
+**************************************************************************/
+
+function Component()
+{
+ component.addDependency("componentA");
+}
+
diff --git a/examples/dependencies/packages/componentG/meta/package.xml b/examples/dependencies/packages/componentG/meta/package.xml
index 3e14256b4..1cff56d48 100644
--- a/examples/dependencies/packages/componentG/meta/package.xml
+++ b/examples/dependencies/packages/componentG/meta/package.xml
@@ -1,10 +1,10 @@
<?xml version="1.0"?>
<Package>
- <DisplayName>Component G (default, depends on A)</DisplayName>
- <Description>By default, this component is selected for installation. It depends on component A.</Description>
+ <DisplayName>Component G (default, depends on A, dependency added dynamically)</DisplayName>
+ <Description>By default, this component is selected for installation. It depends on component A. Dependency is added from inside component script.</Description>
<Default>true</Default>
<Version>1.0.0</Version>
<ReleaseDate>2014-08-25</ReleaseDate>
- <Dependencies>componentA</Dependencies>
+ <Script>installscript.js</Script>
<SortingPriority>30</SortingPriority>
</Package>
diff --git a/examples/doc/hidecheckbox.qdoc b/examples/doc/hidecheckbox.qdoc
new file mode 100644
index 000000000..81f5a5a10
--- /dev/null
+++ b/examples/doc/hidecheckbox.qdoc
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** 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:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example hidecheckbox
+ \ingroup qtifwexamples
+ \title Hide Checkbox Example
+
+ \brief Using components' package.xml files to hide checkboxes for items.
+
+ \image qtifw-examples-hidecheckbox.png
+
+ \e{Hide Checkbox} illustrates how to hide the checkbox for an item.
+
+ \include installerfw-examples-configuring.qdocinc
+
+ \quotefile hidecheckbox/config/config.xml
+
+ \include installerfw-examples-packaging.qdocinc
+
+ \list
+ \li The \c <Checkable> element specifies whether a checkbox is displayed next to an item.
+ Set to \c false to hide the checkbox for the item.
+ \endlist
+
+ This example attempts to install three components, so we create a package.xml file in each
+ component directory: componentF, componentF.subcomponent1, and
+ componentF.subcomponent1.subcomponent1. We also specify the component name and description
+ in each of them. The top level item, componentF, has \c <Checkable> set to \c false,
+ so it cannot be selected.
+
+ \quotefile hidecheckbox/packages/componentF/meta/package.xml
+
+ \include installerfw-examples-generating.qdocinc
+*/
diff --git a/examples/doc/images/qtifw-examples-hidecheckbox.png b/examples/doc/images/qtifw-examples-hidecheckbox.png
new file mode 100644
index 000000000..58b0a1848
--- /dev/null
+++ b/examples/doc/images/qtifw-examples-hidecheckbox.png
Binary files differ
diff --git a/examples/doc/images/qtifw-examples-stylesheet.png b/examples/doc/images/qtifw-examples-stylesheet.png
new file mode 100644
index 000000000..eaa42b8b8
--- /dev/null
+++ b/examples/doc/images/qtifw-examples-stylesheet.png
Binary files differ
diff --git a/examples/doc/stylesheet.qdoc b/examples/doc/stylesheet.qdoc
new file mode 100644
index 000000000..cc408df33
--- /dev/null
+++ b/examples/doc/stylesheet.qdoc
@@ -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:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example stylesheet
+ \ingroup qtifwexamples
+ \title Stylesheet Example
+
+ \brief Using a stylesheet to customize a UI.
+
+ \image qtifw-examples-stylesheet.png
+
+ \e {Stylesheet} demonstrates how to use a stylesheet to customize
+ a wizard UI.
+
+ \include installerfw-examples-configuring.qdocinc
+
+ \list
+ \li The \c <WizardStyle> element sets the wizard style to be used.
+ \li The \c <StyleSheet> element sets the stylesheet file.
+ \li The \c <TitleColor> element sets the color of the titles and subtitles.
+ \endlist
+
+ \quotefile stylesheet/config/config.xml
+
+ \include installerfw-examples-generating.qdocinc
+*/
diff --git a/examples/examples.pro b/examples/examples.pro
index 92a976ff2..377632b9c 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -12,4 +12,5 @@ SUBDIRS += \
quitinstaller \
registerfileextension \
startmenu \
- systeminfo
+ systeminfo \
+ stylesheet
diff --git a/examples/hidecheckbox/README b/examples/hidecheckbox/README
new file mode 100644
index 000000000..bf6259aa2
--- /dev/null
+++ b/examples/hidecheckbox/README
@@ -0,0 +1,6 @@
+Shows how to hide top level item's checkbox.
+
+Generate installer with
+
+binarycreator --offline-only -c config/config.xml -p packages installer
+
diff --git a/examples/hidecheckbox/config/config.xml b/examples/hidecheckbox/config/config.xml
new file mode 100644
index 000000000..8d695ecdb
--- /dev/null
+++ b/examples/hidecheckbox/config/config.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+ <Name>Hide item checkbox</Name>
+ <Version>1.0.0</Version>
+ <Title>Hide checkbox</Title>
+ <Publisher>The Qt Company</Publisher>
+ <StartMenuDir>Qt IFW Examples</StartMenuDir>
+ <TargetDir>@HomeDir@/IfwExamples/hidecheckbox</TargetDir>
+</Installer>
diff --git a/examples/hidecheckbox/hidecheckbox.pro b/examples/hidecheckbox/hidecheckbox.pro
new file mode 100644
index 000000000..415df49d5
--- /dev/null
+++ b/examples/hidecheckbox/hidecheckbox.pro
@@ -0,0 +1,13 @@
+TEMPLATE = aux
+
+INSTALLER = installer
+
+INPUT = $$PWD/config/config.xml $$PWD/packages
+example.input = INPUT
+example.output = $$INSTALLER
+example.commands = ../../bin/binarycreator -c $$PWD/config/config.xml -p $$PWD/packages ${QMAKE_FILE_OUT}
+example.CONFIG += target_predeps no_link combine
+
+QMAKE_EXTRA_COMPILERS += example
+
+OTHER_FILES = README
diff --git a/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/data/testF_sub1_sub1.txt b/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/data/testF_sub1_sub1.txt
new file mode 100644
index 000000000..0478bd970
--- /dev/null
+++ b/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/data/testF_sub1_sub1.txt
@@ -0,0 +1 @@
+test sub sub versio3
diff --git a/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/meta/package.xml b/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/meta/package.xml
new file mode 100644
index 000000000..b613022a0
--- /dev/null
+++ b/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/meta/package.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<Package>
+ <DisplayName>Subsubcomponent 1</DisplayName>
+ <Description>This component does not depend on any other component.</Description>
+ <Version>1.0.2</Version>
+ <ReleaseDate>2015-12-01</ReleaseDate>
+</Package>
diff --git a/examples/hidecheckbox/packages/componentF.subcomponent1/data/testF_sub1.txt b/examples/hidecheckbox/packages/componentF.subcomponent1/data/testF_sub1.txt
new file mode 100644
index 000000000..c34214bb9
--- /dev/null
+++ b/examples/hidecheckbox/packages/componentF.subcomponent1/data/testF_sub1.txt
@@ -0,0 +1 @@
+test sub1 versio3
diff --git a/examples/hidecheckbox/packages/componentF.subcomponent1/meta/package.xml b/examples/hidecheckbox/packages/componentF.subcomponent1/meta/package.xml
new file mode 100644
index 000000000..58bbab370
--- /dev/null
+++ b/examples/hidecheckbox/packages/componentF.subcomponent1/meta/package.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<Package>
+ <DisplayName>Subcomponent 1</DisplayName>
+ <Description>This component contains sub component.</Description>
+ <Version>1.0.2</Version>
+ <ReleaseDate>2015-12-01</ReleaseDate>
+ <SortingPriority>100</SortingPriority>
+ <Checkable>true</Checkable>
+</Package>
diff --git a/examples/hidecheckbox/packages/componentF/data/testF.txt b/examples/hidecheckbox/packages/componentF/data/testF.txt
new file mode 100644
index 000000000..c34214bb9
--- /dev/null
+++ b/examples/hidecheckbox/packages/componentF/data/testF.txt
@@ -0,0 +1 @@
+test sub1 versio3
diff --git a/examples/hidecheckbox/packages/componentF/meta/package.xml b/examples/hidecheckbox/packages/componentF/meta/package.xml
new file mode 100644
index 000000000..96d7cbc21
--- /dev/null
+++ b/examples/hidecheckbox/packages/componentF/meta/package.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<Package>
+ <DisplayName>Uncheckable component</DisplayName>
+ <Description>This component is uncheckable.</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2015-12-01</ReleaseDate>
+ <SortingPriority>40</SortingPriority>
+ <Checkable>false</Checkable>
+</Package>
diff --git a/examples/startmenu/packages/org.qtproject.ifw.example/meta/installscript.qs b/examples/startmenu/packages/org.qtproject.ifw.example/meta/installscript.qs
index 9bcc350e9..de64b4441 100644
--- a/examples/startmenu/packages/org.qtproject.ifw.example/meta/installscript.qs
+++ b/examples/startmenu/packages/org.qtproject.ifw.example/meta/installscript.qs
@@ -39,6 +39,6 @@ Component.prototype.createOperations = function()
if (systemInfo.productType === "windows") {
component.addOperation("CreateShortcut", "@TargetDir@/README.txt", "@StartMenuDir@/README.lnk",
"workingDirectory=@TargetDir@", "iconPath=%SystemRoot%/system32/SHELL32.dll",
- "iconId=2");
+ "iconId=2", "description=Open README file");
}
}
diff --git a/examples/stylesheet/README b/examples/stylesheet/README
new file mode 100644
index 000000000..ee0d445db
--- /dev/null
+++ b/examples/stylesheet/README
@@ -0,0 +1,6 @@
+Shows how to customize a UI using stylesheet.
+
+Generate installer with
+
+binarycreator --offline-only -c config/config.xml -p packages installer
+
diff --git a/examples/stylesheet/config/config.xml b/examples/stylesheet/config/config.xml
new file mode 100644
index 000000000..3cd8e6060
--- /dev/null
+++ b/examples/stylesheet/config/config.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+ <Name>Stylesheet Example</Name>
+ <Version>1.0.0</Version>
+ <Title>Stylesheet Example</Title>
+ <Publisher>Qt-Project</Publisher>
+ <StartMenuDir>Qt IFW Examples</StartMenuDir>
+ <TargetDir>@HomeDir@/IfwExamples/stylesheet</TargetDir>
+ <WizardStyle>Classic</WizardStyle>
+ <StyleSheet>style.qss</StyleSheet>
+ <TitleColor>#FFFFFF</TitleColor>
+</Installer>
diff --git a/examples/stylesheet/config/style.qss b/examples/stylesheet/config/style.qss
new file mode 100644
index 000000000..8d4f75d65
--- /dev/null
+++ b/examples/stylesheet/config/style.qss
@@ -0,0 +1,25 @@
+QWidget
+{
+ color: white;
+ background-color: rgb(65, 65, 65);
+}
+
+QPushButton
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(150, 150, 150, 60%), stop:1 rgba(50, 50, 50, 60%));
+ border-color: rgb(60, 60, 60);
+ border-style: solid;
+ border-width: 2px;
+ border-radius: 9px;
+ min-height: 20px;
+ max-height: 20px;
+ min-width: 60px;
+ max-width: 60px;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+QPushButton:pressed, QPushButton:checked
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(50, 50, 50, 60%), stop:1 rgba(150, 150, 150, 60%));
+}
diff --git a/examples/stylesheet/packages/org.qtproject.ifw.example.stylesheet/meta/installscript.qs b/examples/stylesheet/packages/org.qtproject.ifw.example.stylesheet/meta/installscript.qs
new file mode 100644
index 000000000..e99733ff3
--- /dev/null
+++ b/examples/stylesheet/packages/org.qtproject.ifw.example.stylesheet/meta/installscript.qs
@@ -0,0 +1,39 @@
+/**************************************************************************
+**
+** 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$
+**
+**************************************************************************/
+
+function Component()
+{
+ // constructor
+ installer.setDefaultPageVisible(QInstaller.ComponentSelection, false);
+}
diff --git a/examples/stylesheet/packages/org.qtproject.ifw.example.stylesheet/meta/package.xml b/examples/stylesheet/packages/org.qtproject.ifw.example.stylesheet/meta/package.xml
new file mode 100644
index 000000000..c0698a4e4
--- /dev/null
+++ b/examples/stylesheet/packages/org.qtproject.ifw.example.stylesheet/meta/package.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Package>
+ <DisplayName>Dummy</DisplayName>
+ <ReleaseDate>2015-09-09</ReleaseDate>
+ <Version>1.0.1</Version>
+ <Default>true</Default>
+ <Script>installscript.qs</Script>
+</Package>
diff --git a/examples/stylesheet/stylesheet.pro b/examples/stylesheet/stylesheet.pro
new file mode 100644
index 000000000..415df49d5
--- /dev/null
+++ b/examples/stylesheet/stylesheet.pro
@@ -0,0 +1,13 @@
+TEMPLATE = aux
+
+INSTALLER = installer
+
+INPUT = $$PWD/config/config.xml $$PWD/packages
+example.input = INPUT
+example.output = $$INSTALLER
+example.commands = ../../bin/binarycreator -c $$PWD/config/config.xml -p $$PWD/packages ${QMAKE_FILE_OUT}
+example.CONFIG += target_predeps no_link combine
+
+QMAKE_EXTRA_COMPILERS += example
+
+OTHER_FILES = README
diff --git a/examples/translations/README b/examples/translations/README
index 13fb2b685..b3c20e3d7 100644
--- a/examples/translations/README
+++ b/examples/translations/README
@@ -10,11 +10,6 @@ You can now run the installer in German.
Linux:
-LANG=de ./installer
+LANGUAGE=de ./installer
-Windows:
-
-set LANG=de
-installer.exe
-
-On OS X you need to adapt the system settings to set German as preferred language, and then start the installer.
+On OS X and Windows you need to adapt the system settings to set German as preferred language, and then start the installer.
diff --git a/installerfw.pri b/installerfw.pri
index a0144c047..ca2bbaa24 100644
--- a/installerfw.pri
+++ b/installerfw.pri
@@ -3,8 +3,8 @@
}
IFW_PRI_INCLUDED = 1
-IFW_VERSION_STR = 2.0.5
-IFW_VERSION = 0x020005
+IFW_VERSION_STR = 3.0.1
+IFW_VERSION = 0x030001
IFW_REPOSITORY_FORMAT_VERSION = 1.0.0
IFW_NEWLINE = $$escape_expand(\\n\\t)
@@ -77,6 +77,7 @@ win32 {
QMAKE_BINARY = $${QMAKE_BINARY}.exe
}
win32-g++*:QMAKE_CXXFLAGS += -Wno-attributes
+macx:QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
INCLUDEPATH += \
$$IFW_SOURCE_TREE/src/libs/7zip \
@@ -120,8 +121,9 @@ isEmpty(GIT_SHA1) {
GIT_SHA1=\"$$cat(.tag)\"
}
-DEFINES += QT_NO_CAST_FROM_ASCII QT_USE_QSTRINGBUILDER "_GIT_SHA1_=$$GIT_SHA1" \
- IFW_VERSION_STR=$$IFW_VERSION_STR IFW_VERSION=$$IFW_VERSION
+DEFINES += NOMINMAX QT_NO_CAST_FROM_ASCII QT_STRICT_ITERATORS QT_USE_QSTRINGBUILDER \
+ "_GIT_SHA1_=$$GIT_SHA1" \
+ IFW_VERSION_STR=$$IFW_VERSION_STR IFW_VERSION=$$IFW_VERSION
DEFINES += IFW_REPOSITORY_FORMAT_VERSION=$$IFW_REPOSITORY_FORMAT_VERSION
static {
@@ -129,7 +131,7 @@ static {
win32-g++*: LIBS += -lmpr -luuid
equals(TEMPLATE, app) {
- win32-msvc*:POST_TARGETDEPS += $$IFW_LIB_PATH/installer.lib $$IFW_LIB_PATH/7z.lib
+ msvc:POST_TARGETDEPS += $$IFW_LIB_PATH/installer.lib $$IFW_LIB_PATH/7z.lib
win32-g++*:POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a $$IFW_LIB_PATH/lib7z.a
unix:POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a $$IFW_LIB_PATH/lib7z.a
}
diff --git a/installerfw.pro b/installerfw.pro
index c1e058830..1cec9c6a1 100644
--- a/installerfw.pro
+++ b/installerfw.pro
@@ -1,19 +1,25 @@
-CONFIG += ordered
TEMPLATE = subdirs
SUBDIRS += src tools
+tools.depends = src
include (installerfw.pri)
include (doc/doc.pri)
BUILD_TESTS = $$(BUILDTESTS)
isEmpty(BUILD_TESTS):BUILD_TESTS=$${BUILDTESTS}
-!isEmpty(BUILD_TESTS):SUBDIRS += tests
+!isEmpty(BUILD_TESTS) {
+ SUBDIRS += tests
+ tests.depends = src
+}
BUILD_EXAMPLES = $$(BUILDEXAMPLES)
isEmpty(BUILD_EXAMPLES):BUILD_EXAMPLES=$${BUILDEXAMPLES}
-!isEmpty(BUILD_EXAMPLES):SUBDIRS += examples
+!isEmpty(BUILD_EXAMPLES) {
+ SUBDIRS += examples
+ examples.depends = src
+}
-!minQtVersion(5, 5, 0) {
+!minQtVersion(5, 6, 2) {
message("Cannot build Qt Installer Framework with Qt version $${QT_VERSION}.")
- error("Use at least Qt 5.5.0.")
+ error("Use at least Qt 5.6.2.")
}
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 5e1424d44..17e64df8f 100644
--- a/src/libs/7zip/7zip.pro
+++ b/src/libs/7zip/7zip.pro
@@ -7,18 +7,8 @@ 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
target.path = $$[QT_INSTALL_LIBS]
INSTALLS += target
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 2a8466054..0c8deef18 100644
--- a/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
+++ b/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
@@ -26,108 +26,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 874e94e68..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
@@ -324,122 +400,107 @@ struct CSolidGroup
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 4b9c6abac..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, const_cast<LPSTR>(";"), (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 721c36de1..3ad193b5e 100644
--- a/src/libs/installer/adminauthorization_win.cpp
+++ b/src/libs/installer/adminauthorization_win.cpp
@@ -106,14 +106,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 1146519d2..7068bb2c6 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,25 +156,36 @@ 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];
char errBuf[1024];
+ int status;
+ bool statusValid = false;
while (bytes >= 0) {
- int state;
- if (::waitpid(child, &state, WNOHANG) == -1)
+ const pid_t waitResult = ::waitpid(child, &status, WNOHANG);
+ if (waitResult == -1) {
break;
+ }
+ if (waitResult == child) {
+ statusValid = true;
+ 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()) {
@@ -189,20 +205,28 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
if (bytes == 0)
::usleep(100000);
}
- if (!errData.isEmpty()) {
- printError(parent, QString::fromLocal8Bit(errData.constData()));
- return false;
+
+ while (true) {
+ errBytes = ::read(pipedData[0], errBuf, 1023);
+ if (errBytes == -1 && errno == EAGAIN) {
+ ::usleep(100000);
+ continue;
+ }
+
+ if (errBytes <= 0)
+ break;
+
+ errData.append(errBuf, errBytes);
}
- int status;
- child = ::wait(&status);
- const int exited = WIFEXITED(status);
- const int exitStatus = WEXITSTATUS(status);
- ::close(pipedData[1]);
- if (exited)
- return exitStatus == 0;
+ const bool success = statusValid && WIFEXITED(status) && WEXITSTATUS(status) == 0;
- return false;
+ if (!success && !errData.isEmpty()) {
+ printError(parent, QString::fromLocal8Bit(errData.constData()));
+ }
+
+ ::close(pipedData[0]);
+ return success;
}
// child process
@@ -229,7 +253,7 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
for (int i = 3; i < static_cast<int>(rlp.rlim_cur); ++i)
::close(i);
- char **argp = (char **) ::malloc(arguments.count() + 4 * sizeof(char *));
+ char **argp = (char **) ::malloc((arguments.count() + 4) * sizeof(char *));
QList<QByteArray> args;
args.push_back(SU_COMMAND);
args.push_back("-b");
@@ -245,8 +269,10 @@ bool AdminAuthorization::execute(QWidget *parent, const QString &program, const
::unsetenv("LANG");
::unsetenv("LC_ALL");
- ::execv(SU_COMMAND, argp);
- _exit(0);
+ int exitStatus = 0;
+ if (::execv(SU_COMMAND, argp) == -1)
+ exitStatus = -errno;
+ _exit(exitStatus);
return false;
}
}
diff --git a/src/libs/installer/binarycontent.cpp b/src/libs/installer/binarycontent.cpp
index d32be6238..6112704b0 100644
--- a/src/libs/installer/binarycontent.cpp
+++ b/src/libs/installer/binarycontent.cpp
@@ -113,7 +113,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
@@ -124,7 +124,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));
}
@@ -199,7 +199,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);
@@ -216,7 +216,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);
@@ -255,7 +255,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 d9ca133c0..42c94ab1d 100644
--- a/src/libs/installer/binaryformat.cpp
+++ b/src/libs/installer/binaryformat.cpp
@@ -164,7 +164,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;
@@ -392,7 +392,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 38e8cd844..da0230ade 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -38,8 +38,7 @@
#include "settings.h"
#include "utils.h"
-#include <kdupdaterupdatesourcesinfo.h>
-#include <kdupdaterupdateoperationfactory.h>
+#include "updateoperationfactory.h"
#include <productkeycheck.h>
@@ -51,18 +50,22 @@
#include <QtUiTools/QUiLoader>
+#include <private/qv8engine_p.h>
+#include <private/qv4scopedvalue_p.h>
+#include <private/qv4object_p.h>
+
#include <algorithm>
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
@@ -208,7 +211,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*>");
}
@@ -237,10 +240,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);
@@ -249,14 +251,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()) {
@@ -265,6 +261,7 @@ void Component::loadDataFromPackage(const LocalPackage &package)
}
setValue(scVirtual, package.virtualComp ? scTrue : scFalse);
setValue(scCurrentState, scInstalled);
+ setValue(scCheckable, package.checkable ? scTrue : scFalse);
}
/*!
@@ -282,7 +279,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());
@@ -297,6 +294,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())
@@ -307,7 +305,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())
@@ -388,6 +386,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);
@@ -570,8 +570,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;
@@ -579,8 +579,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);
@@ -624,7 +624,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);
@@ -698,11 +698,11 @@ void Component::createOperationsForPath(const QString &path)
if (fi.isFile()) {
static const QString copy = QString::fromLatin1("Copy");
- addOperation(copy, fi.filePath(), target);
+ addOperation(copy, QStringList() << fi.filePath() << target);
} else if (fi.isDir()) {
qApp->processEvents();
static const QString mkdir = QString::fromLatin1("Mkdir");
- addOperation(mkdir, target);
+ addOperation(mkdir, QStringList(target));
QDirIterator it(fi.filePath());
while (it.hasNext())
@@ -742,7 +742,7 @@ void Component::createOperationsForArchive(const QString &archive)
if (isZip) {
// archives get completely extracted per default (if the script isn't doing other stuff)
- addOperation(QLatin1String("Extract"), archive, QLatin1String("@TargetDir@"));
+ addOperation(QLatin1String("Extract"), QStringList() << archive << QLatin1String("@TargetDir@"));
} else {
createOperationsForPath(archive);
}
@@ -823,7 +823,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);
}
/*!
@@ -902,15 +902,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;
@@ -984,11 +983,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;
@@ -997,33 +997,50 @@ 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());
return operation;
}
-/*!
- Convenience method for calling the operation \a operation with up to ten parameters:
- \a parameter1, \a parameter2, \a parameter3, \a parameter4, \a parameter5, \a parameter6,
- \a parameter7, \a parameter8, \a parameter9, and \a parameter10.
-
- Returns \c true if the operation succeeds, otherwise returns \c false.
+namespace {
- \sa {component::addOperation}{component.addOperation}
-*/
-bool Component::addOperation(const QString &operation, const QString &parameter1, const QString &parameter2,
- const QString &parameter3, const QString &parameter4, const QString &parameter5, const QString &parameter6,
- const QString &parameter7, const QString &parameter8, const QString &parameter9, const QString &parameter10)
+inline bool convert(QQmlV4Function *func, QStringList *toArgs)
{
+ if (func->length() < 2)
+ return false;
- if (Operation *op = createOperation(operation, parameter1, parameter2, parameter3, parameter4, parameter5,
- parameter6, parameter7, parameter8, parameter9, parameter10)) {
- addOperation(op);
- return true;
+ QV4::Scope scope(func->v4engine());
+ QV4::ScopedValue val(scope);
+ val = (*func)[0];
+
+ *toArgs << val->toQString();
+ for (int i = 1; i < func->length(); i++) {
+ val = (*func)[i];
+ if (val->isObject() && val->as<QV4::Object>()->isArrayObject()) {
+ QV4::ScopedValue valtmp(scope);
+ QV4::Object *array = val->as<QV4::Object>();
+ uint length = array->getLength();
+ for (uint ii = 0; ii < length; ++ii) {
+ valtmp = array->getIndexed(ii);
+ *toArgs << valtmp->toQStringNoThrow();
+ }
+ } else {
+ *toArgs << val->toQString();
+ }
}
+ return true;
+}
+}
+/*!
+ \internal
+*/
+bool Component::addOperation(QQmlV4Function *func)
+{
+ QStringList args;
+ if (convert(func, &args))
+ return addOperation(args[0], args.mid(1));
return false;
}
@@ -1032,7 +1049,7 @@ bool Component::addOperation(const QString &operation, const QString &parameter1
The variables that the parameters contain, such as \c @TargetDir@, are replaced with their
values.
- Returns \c true if the operation succeeds, otherwise returns \c false.
+ \sa {component::addOperation}{component.addOperation}
*/
bool Component::addOperation(const QString &operation, const QStringList &parameters)
{
@@ -1045,25 +1062,13 @@ bool Component::addOperation(const QString &operation, const QStringList &parame
}
/*!
- Convenience method for calling the elevated operation \a operation with up to ten parameters:
- \a parameter1, \a parameter2, \a parameter3, \a parameter4, \a parameter5, \a parameter6,
- \a parameter7, \a parameter8, \a parameter9, and \a parameter10.
-
- \sa {component::addElevatedOperation}{component.addElevatedOperation}
-
- Returns \c true if the operation succeeds, otherwise returns \c false.
+ \internal
*/
-bool Component::addElevatedOperation(const QString &operation, const QString &parameter1,
- const QString &parameter2, const QString &parameter3, const QString &parameter4, const QString &parameter5,
- const QString &parameter6, const QString &parameter7, const QString &parameter8, const QString &parameter9,
- const QString &parameter10)
+bool Component::addElevatedOperation(QQmlV4Function *func)
{
- if (Operation *op = createOperation(operation, parameter1, parameter2, parameter3, parameter4, parameter5,
- parameter6, parameter7, parameter8, parameter9, parameter10)) {
- addElevatedOperation(op);
- return true;
- }
-
+ QStringList args;
+ if (convert(func, &args))
+ return addElevatedOperation(args[0], args.mid(1));
return false;
}
@@ -1072,8 +1077,7 @@ bool Component::addElevatedOperation(const QString &operation, const QString &pa
The variables that the parameters contain, such as \c @TargetDir@, are replaced with their
values. The operation is executed with elevated rights.
- Returns \c true if the operation succeeds, otherwise returns \c false.
-
+ \sa {component::addElevatedOperation}{component.addElevatedOperation}
*/
bool Component::addElevatedOperation(const QString &operation, const QStringList &parameters)
{
@@ -1086,9 +1090,8 @@ bool Component::addElevatedOperation(const QString &operation, const QStringList
}
/*!
- Returns whether operations should be automatically created when the
- installation starts and createOperations() is called. If you set this to
- \c false, it is completely up
+ Specifies whether operations should be automatically created when the installation starts. This
+ would be done by calling createOperations(). If you set this to \c false, it is completely up
to the component's script to create all operations.
\sa {component::autoCreateOperations}{component.autoCreateOperations}
@@ -1239,9 +1242,13 @@ bool Component::isDefault() const
return d->m_vars.value(scDefault).compare(scTrue, Qt::CaseInsensitive) == 0;
}
-bool Component::isInstalled() const
+bool Component::isInstalled(const QString version) const
{
- return scInstalled == d->m_vars.value(scCurrentState);
+ if (version.isEmpty()) {
+ return scInstalled == d->m_vars.value(scCurrentState);
+ } else {
+ return d->m_vars.value(scInstalledVersion) == version;
+ }
}
/*!
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index 4f4623aba..01622548f 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -39,11 +39,7 @@
#include <QtCore/QUrl>
QT_FORWARD_DECLARE_CLASS(QDebug)
-
-namespace KDUpdater {
- class Update;
- struct PackageInfo;
-}
+QT_FORWARD_DECLARE_CLASS(QQmlV4Function)
namespace QInstaller {
@@ -96,7 +92,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);
@@ -133,22 +129,12 @@ public:
OperationList operations() const;
void addOperation(Operation *operation);
- Q_INVOKABLE bool addOperation(const QString &operation, const QString &parameter1 = QString(),
- const QString &parameter2 = QString(), const QString &parameter3 = QString(),
- const QString &parameter4 = QString(), const QString &parameter5 = QString(),
- const QString &parameter6 = QString(), const QString &parameter7 = QString(),
- const QString &parameter8 = QString(), const QString &parameter9 = QString(),
- const QString &parameter10 = QString());
- Q_INVOKABLE bool addOperation(const QString &operation, const QStringList &parameters);
+ Q_INVOKABLE bool addOperation(QQmlV4Function *args);
+ bool addOperation(const QString &operation, const QStringList &parameters);
void addElevatedOperation(Operation *operation);
- Q_INVOKABLE bool addElevatedOperation(const QString &operation,
- const QString &parameter1 = QString(), const QString &parameter2 = QString(),
- const QString &parameter3 = QString(), const QString &parameter4 = QString(),
- const QString &parameter5 = QString(), const QString &parameter6 = QString(),
- const QString &parameter7 = QString(), const QString &parameter8 = QString(),
- const QString &parameter9 = QString(), const QString &parameter10 = QString());
- Q_INVOKABLE bool addElevatedOperation(const QString &operation, const QStringList &parameters);
+ Q_INVOKABLE bool addElevatedOperation(QQmlV4Function *args);
+ bool addElevatedOperation(const QString &operation, const QStringList &parameters);
QStringList downloadableArchives() const;
Q_INVOKABLE void addDownloadableArchive(const QString &path);
@@ -180,7 +166,7 @@ public:
Q_INVOKABLE bool isAutoDependOn(const QSet<QString> &componentsToInstall) const;
Q_INVOKABLE void setInstalled();
- Q_INVOKABLE bool isInstalled() const;
+ Q_INVOKABLE bool isInstalled(const QString version = QString()) const;
Q_INVOKABLE bool installationRequested() const;
bool isSelectedForInstallation() const;
diff --git a/src/libs/installer/componentchecker.cpp b/src/libs/installer/componentchecker.cpp
index d905786f3..e21bc6696 100644
--- a/src/libs/installer/componentchecker.cpp
+++ b/src/libs/installer/componentchecker.cpp
@@ -45,6 +45,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();
@@ -122,13 +128,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());
}
@@ -148,7 +154,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 ba4c2d238..e0cc3fcd8 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -77,6 +77,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 {
@@ -97,7 +101,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);
}
/*!
@@ -403,7 +407,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);
@@ -463,7 +467,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);
@@ -571,7 +575,13 @@ QSet<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compone
// we can start in descending order to check node and tri-state nodes properly
for (int i = sortedNodes.count(); i > 0; i--) {
Component * const node = sortedNodes.at(i - 1);
- if (!node->isCheckable() || !node->isEnabled() || !node->autoDependencies().isEmpty())
+
+ bool checkable = true;
+ if (node->value(scCheckable, scTrue).toLower() == scFalse) {
+ checkable = false;
+ }
+
+ if ((!node->isCheckable() && checkable) || !node->isEnabled() || !node->autoDependencies().isEmpty())
continue;
Qt::CheckState newState = state;
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index 6022b074b..f1eac9926 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -41,7 +41,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");
@@ -53,6 +52,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");
@@ -64,6 +64,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");
@@ -75,13 +76,21 @@ static const QLatin1String scRemoveTargetDir("RemoveTargetDir");
static const QLatin1String scRunProgramDescription("RunProgramDescription");
static const QLatin1String scTargetConfigurationFile("TargetConfigurationFile");
static const QLatin1String scAllowNonAsciiCharacters("AllowNonAsciiCharacters");
+static const QLatin1String scDisableAuthorizationFallback("DisableAuthorizationFallback");
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");
+static const QLatin1String scSupportsModify("SupportsModify");
+
+const char scRelocatable[] = "@RELOCATABLE_PATH@";
+
}
#endif // CONSTANTS_H
diff --git a/src/libs/installer/consumeoutputoperation.cpp b/src/libs/installer/consumeoutputoperation.cpp
index 8bd9d59f1..43c78193c 100644
--- a/src/libs/installer/consumeoutputoperation.cpp
+++ b/src/libs/installer/consumeoutputoperation.cpp
@@ -37,7 +37,8 @@
using namespace QInstaller;
-ConsumeOutputOperation::ConsumeOutputOperation()
+ConsumeOutputOperation::ConsumeOutputOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("ConsumeOutput"));
}
@@ -53,15 +54,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()));
@@ -71,8 +69,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;
}
@@ -85,7 +83,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;
}
@@ -106,7 +104,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;
}
@@ -124,8 +122,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;
@@ -140,9 +137,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 ff7629e6e..a1f8a09ff 100644
--- a/src/libs/installer/consumeoutputoperation.h
+++ b/src/libs/installer/consumeoutputoperation.h
@@ -37,13 +37,12 @@ class INSTALLER_EXPORT ConsumeOutputOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::ConsumeOutputOperation)
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 20358ca66..cdd6da6ab 100644
--- a/src/libs/installer/copydirectoryoperation.cpp
+++ b/src/libs/installer/copydirectoryoperation.cpp
@@ -46,7 +46,8 @@ public:
};
-CopyDirectoryOperation::CopyDirectoryOperation()
+CopyDirectoryOperation::CopyDirectoryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CopyDirectory"));
}
@@ -57,13 +58,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;
@@ -74,19 +72,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();
@@ -117,22 +118,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));
@@ -151,7 +154,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());
@@ -166,8 +169,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 57169e936..f934f8b91 100644
--- a/src/libs/installer/copydirectoryoperation.h
+++ b/src/libs/installer/copydirectoryoperation.h
@@ -40,13 +40,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 84287678a..b3cd61aa2 100644
--- a/src/libs/installer/copyfiletask.cpp
+++ b/src/libs/installer/copyfiletask.cpp
@@ -28,6 +28,7 @@
#include "copyfiletask.h"
#include "observer.h"
+#include <QDir>
#include <QFileInfo>
#include <QTemporaryFile>
@@ -63,8 +64,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());
@@ -79,8 +80,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
}
@@ -96,8 +97,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 a3bf045de..ed55cdbf2 100644
--- a/src/libs/installer/createdesktopentryoperation.cpp
+++ b/src/libs/installer/createdesktopentryoperation.cpp
@@ -91,7 +91,8 @@ QString CreateDesktopEntryOperation::absoluteFileName()
return QDir(directory).absoluteFilePath(filename);
}
-CreateDesktopEntryOperation::CreateDesktopEntryOperation()
+CreateDesktopEntryOperation::CreateDesktopEntryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateDesktopEntry"));
}
@@ -116,32 +117,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;
}
@@ -167,7 +163,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;
}
@@ -177,13 +173,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;
}
@@ -192,8 +188,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 6a7ab5c25..793d1db16 100644
--- a/src/libs/installer/createdesktopentryoperation.h
+++ b/src/libs/installer/createdesktopentryoperation.h
@@ -37,14 +37,13 @@ class INSTALLER_EXPORT CreateDesktopEntryOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::CreateDesktopEntryOperation)
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 1ca609237..851290ba8 100644
--- a/src/libs/installer/createlinkoperation.cpp
+++ b/src/libs/installer/createlinkoperation.cpp
@@ -29,11 +29,13 @@
#include "link.h"
+#include <QDir>
#include <QFileInfo>
using namespace QInstaller;
-CreateLinkOperation::CreateLinkOperation()
+CreateLinkOperation::CreateLinkOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateLink"));
}
@@ -44,22 +46,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;
}
@@ -79,7 +77,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;
}
@@ -90,8 +89,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 8b27014bd..2e4ece9aa 100644
--- a/src/libs/installer/createlinkoperation.h
+++ b/src/libs/installer/createlinkoperation.h
@@ -37,13 +37,12 @@ class INSTALLER_EXPORT CreateLinkOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::CreateLinkOperation)
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 6a78e68e3..8f6ab2eaa 100644
--- a/src/libs/installer/createlocalrepositoryoperation.cpp
+++ b/src/libs/installer/createlocalrepositoryoperation.cpp
@@ -34,11 +34,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>
@@ -82,8 +83,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())));
}
}
}
@@ -103,8 +104,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());
}
@@ -121,8 +122,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();
}
@@ -132,7 +134,8 @@ static QString createArchive(const QString repoPath, const QString &sourceDir, c
// -- CreateLocalRepositoryOperation
-CreateLocalRepositoryOperation::CreateLocalRepositoryOperation()
+CreateLocalRepositoryOperation::CreateLocalRepositoryOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("CreateLocalRepository"));
}
@@ -146,24 +149,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)));
}
@@ -185,9 +184,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();
@@ -206,13 +206,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;
@@ -242,8 +244,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
@@ -260,8 +263,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,
@@ -329,10 +332,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());
@@ -351,12 +354,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());
@@ -369,11 +372,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 c89fd2ca6..275d7a409 100644
--- a/src/libs/installer/createlocalrepositoryoperation.h
+++ b/src/libs/installer/createlocalrepositoryoperation.h
@@ -41,13 +41,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 754ba317e..2c2e96eff 100644
--- a/src/libs/installer/createshortcutoperation.cpp
+++ b/src/libs/installer/createshortcutoperation.cpp
@@ -41,6 +41,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;
@@ -93,39 +94,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))) {
@@ -137,7 +161,7 @@ static bool createLink(const QString &fileName, const QString &linkName, QString
CoTaskMemFree(pidl);
}
- return success;
+ return true;
#else
Q_UNUSED(arguments)
Q_UNUSED(workingDir)
@@ -152,13 +176,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;
@@ -171,25 +199,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);
@@ -199,11 +240,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;
@@ -213,15 +254,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;
}
@@ -230,6 +272,8 @@ bool CreateShortcutOperation::performOperation()
bool CreateShortcutOperation::undoOperation()
{
+ ensureOptionalArgumentsRead();
+
const QString &linkLocation = arguments().at(1);
if (!deleteFileNowOrLater(linkLocation) )
qDebug() << "Cannot delete:" << linkLocation;
@@ -271,8 +315,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 6cd5dc064..dc2ac6ddb 100644
--- a/src/libs/installer/createshortcutoperation.h
+++ b/src/libs/installer/createshortcutoperation.h
@@ -37,13 +37,21 @@ class INSTALLER_EXPORT CreateShortcutOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::CreateShortcutOperation)
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 4f153219e..8fd8a40a9 100644
--- a/src/libs/installer/downloadarchivesjob.cpp
+++ b/src/libs/installer/downloadarchivesjob.cpp
@@ -33,8 +33,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>
@@ -47,7 +47,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)
@@ -120,8 +120,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);
@@ -159,7 +159,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);
@@ -168,7 +168,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();
}
@@ -215,7 +216,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 {
@@ -235,7 +236,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)
@@ -245,7 +246,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)
@@ -257,7 +258,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
@@ -286,24 +287,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 35c62b3a2..8f2392064 100644
--- a/src/libs/installer/downloadarchivesjob.h
+++ b/src/libs/installer/downloadarchivesjob.h
@@ -29,7 +29,7 @@
#ifndef DOWNLOADARCHIVESJOB_H
#define DOWNLOADARCHIVESJOB_H
-#include <kdjob.h>
+#include "job.h"
#include <QtCore/QPair>
@@ -46,7 +46,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 b9b560383..2c99e04e1 100644
--- a/src/libs/installer/downloadfiletask.cpp
+++ b/src/libs/installer/downloadfiletask.cpp
@@ -31,12 +31,12 @@
#include "downloadfiletask_p.h"
#include <QCoreApplication>
+#include <QDir>
#include <QEventLoop>
#include <QFileInfo>
#include <QNetworkProxyFactory>
#include <QSslError>
#include <QTemporaryFile>
-#include <QTimer>
namespace QInstaller {
@@ -49,7 +49,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()
@@ -72,15 +73,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;
@@ -120,15 +123,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);
@@ -137,8 +142,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;
}
@@ -156,8 +162,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;
@@ -203,7 +210,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;
}
@@ -220,7 +227,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())));
}
}
@@ -262,7 +269,7 @@ void Downloader::onError(QNetworkReply::NetworkError error)
} 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)));
}
}
@@ -272,7 +279,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
}
@@ -319,6 +326,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()
@@ -337,7 +366,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;
}
@@ -346,14 +375,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;
}
@@ -400,7 +428,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 a682321f1..21908549d 100644
--- a/src/libs/installer/downloadfiletask.h
+++ b/src/libs/installer/downloadfiletask.h
@@ -30,7 +30,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 0e44e2aa3..3dfce27b4 100644
--- a/src/libs/installer/downloadfiletask_p.h
+++ b/src/libs/installer/downloadfiletask_p.h
@@ -36,6 +36,7 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
+#include <QTimer>
#include <memory>
#include <unordered_map>
@@ -90,7 +91,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();
@@ -99,6 +100,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 1241fc567..2cc988a4d 100644
--- a/src/libs/installer/elevatedexecuteoperation.cpp
+++ b/src/libs/installer/elevatedexecuteoperation.cpp
@@ -59,8 +59,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"));
@@ -75,12 +76,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"))
@@ -140,7 +138,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;
}
@@ -159,12 +157,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);
@@ -183,7 +181,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;
}
@@ -199,14 +197,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);
@@ -215,13 +213,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;
@@ -276,11 +275,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 fc9b42c66..5585e77a8 100644
--- a/src/libs/installer/elevatedexecuteoperation.h
+++ b/src/libs/installer/elevatedexecuteoperation.h
@@ -38,14 +38,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 00444f870..b80951d2b 100644
--- a/src/libs/installer/environmentvariablesoperation.cpp
+++ b/src/libs/installer/environmentvariablesoperation.cpp
@@ -40,7 +40,8 @@
using namespace QInstaller;
using namespace KDUpdater;
-EnvironmentVariableOperation::EnvironmentVariableOperation()
+EnvironmentVariableOperation::EnvironmentVariableOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("EnvironmentVariable"));
}
@@ -74,7 +75,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;
}
@@ -86,7 +87,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;
}
@@ -115,21 +116,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"
@@ -152,9 +148,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);
@@ -209,8 +204,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 bda0dd2cd..3c5252bc6 100644
--- a/src/libs/installer/environmentvariablesoperation.h
+++ b/src/libs/installer/environmentvariablesoperation.h
@@ -37,13 +37,12 @@ class INSTALLER_EXPORT EnvironmentVariableOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::EnvironmentVariableOperation)
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 7c66d09c2..117eb5119 100644
--- a/src/libs/installer/errors.h
+++ b/src/libs/installer/errors.h
@@ -39,13 +39,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 230d0f883..c41f029e3 100644
--- a/src/libs/installer/extractarchiveoperation.cpp
+++ b/src/libs/installer/extractarchiveoperation.cpp
@@ -26,17 +26,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"));
}
@@ -48,55 +46,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;
@@ -105,17 +94,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();
@@ -127,18 +115,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 ab22f4000..45c67a9cb 100644
--- a/src/libs/installer/extractarchiveoperation.h
+++ b/src/libs/installer/extractarchiveoperation.h
@@ -41,13 +41,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 03d45a6e3..f333da366 100644
--- a/src/libs/installer/extractarchiveoperation_p.h
+++ b/src/libs/installer/extractarchiveoperation_p.h
@@ -31,24 +31,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"));
@@ -56,26 +55,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);
@@ -84,44 +82,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));
}
@@ -136,94 +132,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 a1dc60057..69870fcab 100644
--- a/src/libs/installer/fakestopprocessforupdateoperation.cpp
+++ b/src/libs/installer/fakestopprocessforupdateoperation.cpp
@@ -34,7 +34,8 @@
using namespace KDUpdater;
using namespace QInstaller;
-FakeStopProcessForUpdateOperation::FakeStopProcessForUpdateOperation()
+FakeStopProcessForUpdateOperation::FakeStopProcessForUpdateOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("FakeStopProcessForUpdate"));
}
@@ -51,15 +52,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;
}
@@ -88,8 +86,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 ba5de745c..6fd5da44b 100644
--- a/src/libs/installer/fakestopprocessforupdateoperation.h
+++ b/src/libs/installer/fakestopprocessforupdateoperation.h
@@ -38,13 +38,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 60ebd1011..dac2e4c50 100644
--- a/src/libs/installer/fileio.cpp
+++ b/src/libs/installer/fileio.cpp
@@ -33,6 +33,7 @@
#include <QCoreApplication>
#include <QByteArray>
+#include <QDir>
#include <QFileDevice>
#include <QString>
@@ -102,7 +103,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()));
}
}
@@ -111,7 +113,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()));
}
}
@@ -120,7 +123,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()));
}
}
@@ -154,7 +158,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 60b912b6e..58744b3c2 100644
--- a/src/libs/installer/fileutils.cpp
+++ b/src/libs/installer/fileutils.cpp
@@ -176,10 +176,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;
}
}
}
@@ -217,10 +218,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;
}
}
}
@@ -264,7 +266,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())
@@ -287,8 +289,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()) {
@@ -301,8 +303,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()));
}
}
}
@@ -313,8 +317,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()) {
@@ -330,8 +334,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()));
}
}
}
@@ -341,8 +347,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)));
}
}
@@ -350,8 +356,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)));
}
}
@@ -361,7 +367,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();
}
@@ -380,7 +386,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();
@@ -481,14 +487,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;
}
@@ -574,3 +579,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 74436bef7..ae08f5ff3 100644
--- a/src/libs/installer/fileutils.h
+++ b/src/libs/installer/fileutils.h
@@ -94,6 +94,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/globals.cpp b/src/libs/installer/globals.cpp
index df97c11b0..5f3009905 100644
--- a/src/libs/installer/globals.cpp
+++ b/src/libs/installer/globals.cpp
@@ -30,6 +30,7 @@
const char IFW_COMPONENT_CHECKER[] = "ifw.componentChecker";
const char IFW_RESOURCES[] = "ifw.resources";
const char IFW_TRANSLATIONS[] = "ifw.translations";
+const char IFW_NETWORK[] = "ifw.network";
namespace QInstaller
{
@@ -37,13 +38,15 @@ namespace QInstaller
Q_LOGGING_CATEGORY(lcComponentChecker, IFW_COMPONENT_CHECKER)
Q_LOGGING_CATEGORY(lcResources, IFW_RESOURCES)
Q_LOGGING_CATEGORY(lcTranslations, IFW_TRANSLATIONS)
+Q_LOGGING_CATEGORY(lcNetwork, IFW_NETWORK)
QStringList loggingCategories()
{
static QStringList categories = QStringList()
<< QLatin1String(IFW_COMPONENT_CHECKER)
<< QLatin1String(IFW_RESOURCES)
- << QLatin1String(IFW_TRANSLATIONS);
+ << QLatin1String(IFW_TRANSLATIONS)
+ << QLatin1String(IFW_NETWORK);
return categories;
}
diff --git a/src/libs/installer/globals.h b/src/libs/installer/globals.h
index fd45b61f2..a5bd47ac8 100644
--- a/src/libs/installer/globals.h
+++ b/src/libs/installer/globals.h
@@ -38,6 +38,7 @@ namespace QInstaller {
INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcComponentChecker)
INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcResources)
INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcTranslations)
+INSTALLER_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcNetwork)
QStringList INSTALLER_EXPORT loggingCategories();
diff --git a/src/libs/installer/globalsettingsoperation.cpp b/src/libs/installer/globalsettingsoperation.cpp
index 12b57413b..f8f7c112d 100644
--- a/src/libs/installer/globalsettingsoperation.cpp
+++ b/src/libs/installer/globalsettingsoperation.cpp
@@ -31,7 +31,8 @@
using namespace QInstaller;
-GlobalSettingsOperation::GlobalSettingsOperation()
+GlobalSettingsOperation::GlobalSettingsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("GlobalConfig"));
}
@@ -49,7 +50,7 @@ bool GlobalSettingsOperation::performOperation()
if (!settings->isWritable()) {
setError(UserDefinedError);
- setErrorString(tr("Settings are not writable"));
+ setErrorString(tr("Settings are not writable."));
return false;
}
@@ -59,7 +60,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;
}
@@ -92,24 +93,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 be6e79c5d..fe5d14edb 100644
--- a/src/libs/installer/globalsettingsoperation.h
+++ b/src/libs/installer/globalsettingsoperation.h
@@ -38,13 +38,12 @@ class INSTALLER_EXPORT GlobalSettingsOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::GlobalSettingsOperation)
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 cf3ed918d..285c7ebc9 100644
--- a/src/libs/installer/init.cpp
+++ b/src/libs/installer/init.cpp
@@ -48,75 +48,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()
{
@@ -193,7 +138,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 53daf978d..d641ff1fc 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -34,7 +34,8 @@ QT += \
xml \
concurrent \
widgets \
- core-private
+ core-private \
+ qml-private
win32:QT += winextras
HEADERS += packagemanagercore.h \
@@ -124,7 +125,11 @@ HEADERS += packagemanagercore.h \
serverauthenticationdialog.h \
keepaliveobject.h \
systeminfo.h \
- localsocket.h
+ packagesource.h \
+ lib7z_guid.h \
+ lib7z_create.h \
+ lib7z_extract.h \
+ lib7z_list.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -198,7 +203,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 65713dc74..064dbafa5 100644
--- a/src/libs/installer/installercalculator.cpp
+++ b/src/libs/installer/installercalculator.cpp
@@ -71,7 +71,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:");
@@ -92,9 +92,9 @@ QString InstallerCalculator::componentsToInstallError() const
return m_componentsToInstallError;
}
-void InstallerCalculator::realAppendToInstallComponents(Component *component)
+void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version)
{
- if (!component->isInstalled() || component->updateRequested()) {
+ if (!component->isInstalled(version) || component->updateRequested()) {
m_orderedComponentsToInstall.append(component);
m_toInstallComponentIds.insert(component->name());
}
@@ -102,8 +102,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)
@@ -115,7 +115,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));
@@ -154,10 +154,10 @@ bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &co
return true;
}
-bool InstallerCalculator::appendComponentToInstall(Component *component)
+bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version)
{
QSet<QString> allDependencies = component->dependencies().toSet();
-
+ QString requiredDependencyVersion = version;
foreach (const QString &dependencyComponentName, allDependencies) {
// PackageManagerCore::componentByName returns 0 if dependencyComponentName contains a
// version which is not available
@@ -165,36 +165,56 @@ 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;
}
+ //Check if component requires higher version than what might be already installed
+ bool isUpdateRequired = false;
+ if (dependencyComponentName.contains(QChar::fromLatin1('-')) &&
+ !dependencyComponent->value(scInstalledVersion).isEmpty()) {
+ QRegExp compEx(QLatin1String("([<=>]+)(.*)"));
+ const QString installedVersion = compEx.exactMatch(dependencyComponent->value(scInstalledVersion)) ?
+ compEx.cap(2) : dependencyComponent->value(scInstalledVersion);
+
+ QString requiredVersion = dependencyComponentName.section(QLatin1Char('-'), 1);
+ requiredVersion = compEx.exactMatch(requiredVersion) ? compEx.cap(2) : requiredVersion;
+
+ if (KDUpdater::compareVersion(requiredVersion, installedVersion) >= 1 ) {
+ isUpdateRequired = true;
+ requiredDependencyVersion = requiredVersion;
+ }
+ }
+ //Check dependencies only if
+ //- Dependency is not installed or update requested, nor newer version of dependency component required
+ //- And dependency component is not already added for install
+ //- And component is not already added for install, then dependencies are already resolved
+ if (((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested())
+ || isUpdateRequired) && (!m_toInstallComponentIds.contains(dependencyComponent->name())
+ && !m_toInstallComponentIds.contains(component->name()))) {
+ if (m_visitedComponents.value(component).contains(dependencyComponent)) {
+ const QString errorMessage = recursionError(component);
+ qWarning().noquote() << errorMessage;
+ m_componentsToInstallError = errorMessage;
+ Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
+ Q_FUNC_INFO, qPrintable(errorMessage));
+ return false;
+ }
+ m_visitedComponents[component].insert(dependencyComponent);
+
+ // add needed dependency components to the next run
+ insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
+ component->name());
- if ((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested())
- && !m_toInstallComponentIds.contains(dependencyComponent->name())) {
- if (m_visitedComponents.value(component).contains(dependencyComponent)) {
- const QString errorMessage = recursionError(component);
- qWarning() << errorMessage;
- m_componentsToInstallError = errorMessage;
- Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
- Q_FUNC_INFO, qPrintable(errorMessage));
- return false;
- }
- m_visitedComponents[component].insert(dependencyComponent);
-
- // add needed dependency components to the next run
- insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
- component->name());
-
- if (!appendComponentToInstall(dependencyComponent))
- return false;
+ if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion))
+ return false;
}
}
if (!m_toInstallComponentIds.contains(component->name())) {
- realAppendToInstallComponents(component);
+ realAppendToInstallComponents(component, requiredDependencyVersion);
insertInstallReason(component, InstallerCalculator::Resolved);
}
return true;
diff --git a/src/libs/installer/installercalculator.h b/src/libs/installer/installercalculator.h
index 08dd47f78..b2d05bdbe 100644
--- a/src/libs/installer/installercalculator.h
+++ b/src/libs/installer/installercalculator.h
@@ -64,8 +64,8 @@ private:
void insertInstallReason(Component *component,
InstallReasonType installReasonType,
const QString &referencedComponentName = QString());
- void realAppendToInstallComponents(Component *component);
- bool appendComponentToInstall(Component *components);
+ void realAppendToInstallComponents(Component *component, const QString &version = QString());
+ bool appendComponentToInstall(Component *components, const QString &version = QString());
QString recursionError(Component *component);
QList<Component*> m_allComponents;
diff --git a/src/libs/installer/installiconsoperation.cpp b/src/libs/installer/installiconsoperation.cpp
index fe6127941..ecd21be86 100644
--- a/src/libs/installer/installiconsoperation.cpp
+++ b/src/libs/installer/installiconsoperation.cpp
@@ -86,7 +86,8 @@ QString InstallIconsOperation::targetDirectory()
return directory;
}
-InstallIconsOperation::InstallIconsOperation()
+InstallIconsOperation::InstallIconsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("InstallIcons"));
}
@@ -103,20 +104,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;
}
@@ -127,7 +124,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,
@@ -165,7 +162,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;
}
@@ -178,7 +176,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;
}
@@ -189,7 +188,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;
}
@@ -199,7 +199,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;
}
@@ -231,7 +232,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());
}
}
@@ -247,13 +248,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);
}
@@ -263,14 +264,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;
}
}
@@ -281,8 +282,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 d8170fef2..5f8dff514 100644
--- a/src/libs/installer/installiconsoperation.h
+++ b/src/libs/installer/installiconsoperation.h
@@ -39,14 +39,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/keepaliveobject.cpp b/src/libs/installer/keepaliveobject.cpp
index 148987280..6f56d7823 100644
--- a/src/libs/installer/keepaliveobject.cpp
+++ b/src/libs/installer/keepaliveobject.cpp
@@ -28,8 +28,8 @@
#include "keepaliveobject.h"
#include "remoteclient.h"
-#include "localsocket.h"
+#include <QLocalSocket>
#include <QTimer>
namespace QInstaller {
@@ -43,7 +43,7 @@ KeepAliveObject::KeepAliveObject()
void KeepAliveObject::start()
{
m_timer = new QTimer(this);
- m_socket = new LocalSocket(this);
+ m_socket = new QLocalSocket(this);
connect(m_timer, &QTimer::timeout, [this]() {
if (m_socket->state() != QLocalSocket::UnconnectedState)
diff --git a/src/libs/installer/lib7z_create.h b/src/libs/installer/lib7z_create.h
new file mode 100644
index 000000000..ad308ffd1
--- /dev/null
+++ b/src/libs/installer/lib7z_create.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $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 ebff609b4..f5561af2f 100644
--- a/src/libs/installer/lib7z_facade.cpp
+++ b/src/libs/installer/lib7z_facade.cpp
@@ -25,106 +25,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)
@@ -139,14 +232,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();
@@ -155,13 +249,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);
@@ -172,12 +265,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;
}
@@ -185,7 +279,6 @@ struct DirectoryGuard {
bool m_created;
bool m_released;
};
-}
static UString QString2UString(const QString &str)
{
@@ -197,32 +290,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;
@@ -233,193 +306,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)
@@ -427,29 +441,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;
@@ -459,1129 +472,652 @@ 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;
- }
+ bool hasPerm = false;
+ const QFile::Permissions permissions = getPermissions(arc->Archive, currentIndex, &hasPerm);
+ if (hasPerm)
+ QFile::setPermissions(absFilePath, permissions);
+ return S_OK;
+}
-private:
- ExtractCallback* const q;
- UInt32 currentIndex;
- const CArc* arc;
- UInt64 total;
- UInt64 completed;
- QPointer<QIODevice> device;
- QString targetDir;
-};
+/*!
+ \namespace Lib7z
+ \inmodule QtInstallerFramework
+ \brief The Lib7z namespace contains miscellaneous identifiers used throughout the Lib7z library.
+*/
+/*!
+ \fn virtual bool Lib7z::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 f0599b4ce..1c8811cfa 100644
--- a/src/libs/installer/lib7z_facade.h
+++ b/src/libs/installer/lib7z_facade.h
@@ -29,253 +29,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 25637b5a3..059798338 100644
--- a/src/libs/installer/licenseoperation.cpp
+++ b/src/libs/installer/licenseoperation.cpp
@@ -37,7 +37,8 @@
using namespace QInstaller;
-LicenseOperation::LicenseOperation()
+LicenseOperation::LicenseOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("License"));
}
@@ -55,26 +56,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;
}
@@ -87,7 +87,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."));
@@ -108,8 +108,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 37820fbe5..49b885565 100644
--- a/src/libs/installer/licenseoperation.h
+++ b/src/libs/installer/licenseoperation.h
@@ -37,13 +37,12 @@ class INSTALLER_EXPORT LicenseOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::LicenseOperation)
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 87e1f2bf7..e67335e55 100644
--- a/src/libs/installer/linereplaceoperation.cpp
+++ b/src/libs/installer/linereplaceoperation.cpp
@@ -34,7 +34,8 @@
using namespace QInstaller;
-LineReplaceOperation::LineReplaceOperation()
+LineReplaceOperation::LineReplaceOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("LineReplace"));
}
@@ -45,18 +46,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);
@@ -64,7 +61,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;
}
@@ -81,7 +79,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;
}
@@ -101,8 +100,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 6370a535c..d15e11fef 100644
--- a/src/libs/installer/linereplaceoperation.h
+++ b/src/libs/installer/linereplaceoperation.h
@@ -37,13 +37,12 @@ class INSTALLER_EXPORT LineReplaceOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::LineReplaceOperation)
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 ac4935a8b..ef91828ce 100644
--- a/src/libs/installer/link.cpp
+++ b/src/libs/installer/link.cpp
@@ -88,8 +88,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());
}
}
@@ -138,14 +137,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);
}
@@ -175,8 +172,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);
}
@@ -197,8 +194,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;
}
}
@@ -211,8 +207,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;
}
@@ -239,8 +234,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);
}
@@ -248,8 +242,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/localsocket.h b/src/libs/installer/localsocket.h
deleted file mode 100644
index 146547258..000000000
--- a/src/libs/installer/localsocket.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-**************************************************************************/
-
-#ifndef LOCALSOCKET_H
-#define LOCALSOCKET_H
-
-#include <QLocalSocket>
-
-#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK(5,5,0)
-
-// This is a crude hack to work around QLocalSocket::waitForReadyRead returning instantly
-// if there are still bytes left in the buffer. This has been fixed in Qt 5.5.0 ...
-class LocalSocket : public QLocalSocket
-{
-public:
- LocalSocket(QObject *parent = 0) : QLocalSocket(parent), inReadyRead(false)
- {
- }
-
- qint64 bytesAvailable() const {
- if (inReadyRead)
- return 0;
- return QLocalSocket::bytesAvailable();
- }
-
- bool waitForReadyRead(int msecs = 30000) {
- inReadyRead = true;
- bool result = QLocalSocket::waitForReadyRead(msecs);
- inReadyRead = false;
- return result;
- }
-
-private:
- bool inReadyRead;
-};
-
-#else
-
-typedef QLocalSocket LocalSocket;
-
-#endif
-
-#endif // LOCALSOCKET_H
diff --git a/src/libs/installer/messageboxhandler.cpp b/src/libs/installer/messageboxhandler.cpp
index f99a9ebd3..fcdee4a5f 100644
--- a/src/libs/installer/messageboxhandler.cpp
+++ b/src/libs/installer/messageboxhandler.cpp
@@ -401,8 +401,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 b88f71137..0c674e313 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -34,6 +34,7 @@
#include "proxycredentialsdialog.h"
#include "serverauthenticationdialog.h"
#include "settings.h"
+#include "testrepository.h"
#include <QTemporaryDir>
@@ -48,17 +49,19 @@ static QUrl resolveUrl(const FileTaskResult &result, const QString &url)
}
MetadataJob::MetadataJob(QObject *parent)
- : KDJob(parent)
+ : Job(parent)
, m_core(0)
+ , m_addCompressedPackages(false)
{
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()
{
+ resetCompressedFetch();
reset();
}
@@ -72,46 +75,183 @@ Repository MetadataJob::repositoryForDirectory(const QString &directory) const
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())) {
- QList<FileTaskItem> items;
- const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
- foreach (const Repository &repo, m_core->settings().repositories()) {
- if (repo.isEnabled() && productKeyCheck->isValidRepository(repo)) {
- QAuthenticator authenticator;
- authenticator.setUser(repo.username());
- 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('&');
-
- // also append a random string to avoid proxy caches
- FileTaskItem item(url.append(QString::number(qrand() * qrand())));
- item.insert(TaskRole::UserRole, QVariant::fromValue(repo));
- item.insert(TaskRole::Authenticator, QVariant::fromValue(authenticator));
- items.append(item);
+ const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
+ if (!m_addCompressedPackages) {
+ reset();
+ emit infoMessage(this, tr("Preparing meta information download..."));
+ const bool onlineInstaller = m_core->isInstaller() && !m_core->isOfflineOnly();
+
+ if (onlineInstaller || m_core->isMaintainer()) {
+ QList<FileTaskItem> items;
+ foreach (const Repository &repo, m_core->settings().repositories()) {
+ if (repo.isEnabled() &&
+ productKeyCheck->isValidRepository(repo)) {
+ QAuthenticator authenticator;
+ authenticator.setUser(repo.username());
+ authenticator.setPassword(repo.password());
+
+ if (!repo.isCompressed()) {
+ QString url = repo.url().toString() + QLatin1String("/Updates.xml?");
+ 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())));
+ item.insert(TaskRole::UserRole, QVariant::fromValue(repo));
+ item.insert(TaskRole::Authenticator, QVariant::fromValue(authenticator));
+ items.append(item);
+ }
+ else {
+ qDebug() << "Trying to parse compressed repo as normal repository."\
+ "Check repository syntax.";
+ }
+ }
}
+ if (items.count() > 0) {
+ startXMLTask(items);
+ } else {
+ emitFinished();
+ }
+ } else {
+ emitFinished();
}
- DownloadFileTask *const xmlTask = new DownloadFileTask(items);
- xmlTask->setProxyFactory(m_core->proxyFactory());
- m_xmlTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, xmlTask));
} else {
- emitFinished();
+ resetCompressedFetch();
+
+ bool repositoriesFound = false;
+ foreach (const Repository &repo, m_core->settings().temporaryRepositories()) {
+ if (repo.isCompressed() && repo.isEnabled() &&
+ productKeyCheck->isValidRepository(repo)) {
+ repositoriesFound = true;
+ startUnzipRepositoryTask(repo);
+
+ //Set the repository disabled so we don't handle it many times
+ Repository replacement = repo;
+ replacement.setEnabled(false);
+ Settings &s = m_core->settings();
+ QSet<Repository> temporaries = s.temporaryRepositories();
+ if (temporaries.contains(repo)) {
+ temporaries.remove(repo);
+ temporaries.insert(replacement);
+ s.setTemporaryRepositories(temporaries, true);
+ }
+ }
+ }
+ if (!repositoriesFound) {
+ emitFinished();
+ }
+ else {
+ setProgressTotalAmount(0);
+ emit infoMessage(this, tr("Unpacking compressed repositories. This may take a while..."));
+ }
}
}
+void MetadataJob::startXMLTask(const QList<FileTaskItem> items)
+{
+ DownloadFileTask *const xmlTask = new DownloadFileTask(items);
+ xmlTask->setProxyFactory(m_core->proxyFactory());
+ m_xmlTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, xmlTask));
+}
+
void MetadataJob::doCancel()
{
reset();
- emitFinishedWithError(KDJob::Canceled, tr("Meta data download canceled."));
+ emitFinishedWithError(Job::Canceled, tr("Meta data download canceled."));
+}
+
+void MetadataJob::startUnzipRepositoryTask(const Repository &repo)
+{
+ QTemporaryDir tempRepoDir(QDir::tempPath() + QLatin1String("/compressedRepo-XXXXXX"));
+ if (!tempRepoDir.isValid()) {
+ qDebug() << "Cannot create unique temporary directory.";
+ return;
+ }
+ tempRepoDir.setAutoRemove(false);
+ m_tempDirDeleter.add(tempRepoDir.path());
+ QString url = repo.url().toLocalFile();
+ UnzipArchiveTask *task = new UnzipArchiveTask(url, tempRepoDir.path());
+ QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
+ m_unzipRepositoryTasks.insert(watcher, qobject_cast<QObject*> (task));
+ connect(watcher, &QFutureWatcherBase::finished, this,
+ &MetadataJob::unzipRepositoryTaskFinished);
+ connect(watcher, &QFutureWatcherBase::progressValueChanged, this,
+ &MetadataJob::progressChanged);
+ watcher->setFuture(QtConcurrent::run(&UnzipArchiveTask::doTask, task));
+}
+
+void MetadataJob::unzipRepositoryTaskFinished()
+{
+ QFutureWatcher<void> *watcher = static_cast<QFutureWatcher<void> *>(sender());
+ int error = Job::NoError;
+ QString errorString;
+ try {
+ watcher->waitForFinished(); // trigger possible exceptions
+
+ QHashIterator<QFutureWatcher<void> *, QObject*> i(m_unzipRepositoryTasks);
+ while (i.hasNext()) {
+
+ i.next();
+ if (i.key() == watcher) {
+ UnzipArchiveTask *task = qobject_cast<UnzipArchiveTask*> (i.value());
+ QString url = task->target();
+
+ QUrl targetUrl = targetUrl.fromLocalFile(url);
+ Repository repo(targetUrl, false, true);
+ url = repo.url().toString() + QLatin1String("/Updates.xml");
+ TestRepository testJob(m_core);
+ testJob.setRepository(repo);
+ testJob.start();
+ testJob.waitForFinished();
+ error = testJob.error();
+ errorString = testJob.errorString();
+ if (error == Job::NoError) {
+ FileTaskItem item(url);
+ item.insert(TaskRole::UserRole, QVariant::fromValue(repo));
+ m_unzipRepositoryitems.append(item);
+ } else {
+ //Repository is not valid, remove it
+ Repository repository;
+ repository.setUrl(QUrl(task->archive()));
+ Settings &s = m_core->settings();
+ QSet<Repository> temporaries = s.temporaryRepositories();
+ foreach (Repository repository, temporaries) {
+ if (repository.url().toLocalFile() == task->archive()) {
+ temporaries.remove(repository);
+ }
+ }
+ s.setTemporaryRepositories(temporaries, false);
+ }
+ }
+ }
+ delete m_unzipRepositoryTasks.value(watcher);
+ m_unzipRepositoryTasks.remove(watcher);
+ delete watcher;
+
+ //One can specify many zipped repository items at once. As the repositories are
+ //unzipped one by one, we collect here all items before parsing xml files from those.
+ if (m_unzipRepositoryitems.count() > 0 && m_unzipRepositoryTasks.isEmpty()) {
+ startXMLTask(m_unzipRepositoryitems);
+ } else {
+ if (error != Job::NoError) {
+ emitFinishedWithError(QInstaller::DownloadError, errorString);
+ }
+ }
+
+ } catch (const UnzipArchiveException &e) {
+ reset();
+ emitFinishedWithError(QInstaller::ExtractionError, e.message());
+ } catch (const QUnhandledException &e) {
+ reset();
+ emitFinishedWithError(QInstaller::DownloadError, QLatin1String(e.what()));
+ } catch (...) {
+ reset();
+ emitFinishedWithError(QInstaller::DownloadError, tr("Unknown exception during extracting."));
+ }
}
void MetadataJob::xmlTaskFinished()
@@ -124,7 +264,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 ...";
@@ -139,7 +279,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)
@@ -160,7 +300,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();
}
}
@@ -181,7 +321,7 @@ void MetadataJob::xmlTaskFinished()
emitFinishedWithError(QInstaller::DownloadError, tr("Unknown exception during download."));
}
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return;
if (status == XmlDownloadSuccess) {
@@ -189,6 +329,7 @@ void MetadataJob::xmlTaskFinished()
DownloadFileTask *const metadataTask = new DownloadFileTask(m_packages);
metadataTask->setProxyFactory(m_core->proxyFactory());
m_metadataTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, metadataTask));
+ setProgressTotalAmount(100);
emit infoMessage(this, tr("Retrieving meta information from remote repository..."));
} else if (status == XmlDownloadRetry) {
QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
@@ -204,17 +345,14 @@ void MetadataJob::unzipTaskFinished()
try {
watcher->waitForFinished(); // trigger possible exceptions
} catch (const UnzipArchiveException &e) {
- reset();
emitFinishedWithError(QInstaller::ExtractionError, e.message());
} catch (const QUnhandledException &e) {
- reset();
emitFinishedWithError(QInstaller::DownloadError, QLatin1String(e.what()));
} catch (...) {
- reset();
emitFinishedWithError(QInstaller::DownloadError, tr("Unknown exception during extracting."));
}
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return;
delete m_unzipTasks.value(watcher);
@@ -232,6 +370,11 @@ void MetadataJob::progressChanged(int progress)
setProcessedAmount(progress);
}
+void MetadataJob::setProgressTotalAmount(int maximum)
+{
+ setTotalAmount(maximum);
+}
+
void MetadataJob::metadataTaskFinished()
{
try {
@@ -246,7 +389,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 {
@@ -272,13 +415,24 @@ void MetadataJob::reset()
m_packages.clear();
m_metadata.clear();
- setError(KDJob::NoError);
+ setError(Job::NoError);
setErrorString(QString());
setCapabilities(Cancelable);
try {
m_xmlTask.cancel();
m_metadataTask.cancel();
+ } catch (...) {}
+ m_tempDirDeleter.releaseAndDeleteAll();
+}
+
+void MetadataJob::resetCompressedFetch()
+{
+ setError(Job::NoError);
+ setErrorString(QString());
+ m_unzipRepositoryitems.clear();
+
+ try {
foreach (QFutureWatcher<void> *const watcher, m_unzipTasks.keys()) {
watcher->cancel();
watcher->deleteLater();
@@ -286,20 +440,32 @@ void MetadataJob::reset()
foreach (QObject *const object, m_unzipTasks)
object->deleteLater();
m_unzipTasks.clear();
+
+ foreach (QFutureWatcher<void> *const watcher, m_unzipRepositoryTasks.keys()) {
+ watcher->cancel();
+ watcher->deleteLater();
+ }
+ foreach (QObject *const object, m_unzipRepositoryTasks)
+ object->deleteLater();
+ m_unzipRepositoryTasks.clear();
} catch (...) {}
- m_tempDirDeleter.releaseAndDeleteAll();
}
MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &results)
{
foreach (const FileTaskResult &result, results) {
- if (error() != KDJob::NoError)
+ if (error() != Job::NoError)
return XmlDownloadFailure;
+ //If repository is not found, target might be empty. Do not continue parsing the
+ //repository and do not prevent further repositories usage.
+ if (result.target().isEmpty()) {
+ continue;
+ }
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;
}
@@ -309,21 +475,22 @@ 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);
- return XmlDownloadFailure;
+ qDebug().nospace() << "Cannot fetch a valid version of Updates.xml from repository "
+ << metadata.repository.displayname() << ": " << error;
+ //If there are other repositories, try to use those
+ continue;
}
file.close();
@@ -346,7 +513,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();
@@ -408,12 +575,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();
}
}
}
@@ -441,7 +608,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 bf1c8f54a..c6d5ad353 100644
--- a/src/libs/installer/metadatajob.h
+++ b/src/libs/installer/metadatajob.h
@@ -31,7 +31,7 @@
#include "downloadfiletask.h"
#include "fileutils.h"
-#include "kdjob.h"
+#include "job.h"
#include "repository.h"
#include <QFutureWatcher>
@@ -46,7 +46,7 @@ struct Metadata
Repository repository;
};
-class INSTALLER_EXPORT MetadataJob : public KDJob
+class INSTALLER_EXPORT MetadataJob : public Job
{
Q_OBJECT
Q_DISABLE_COPY(MetadataJob)
@@ -64,6 +64,7 @@ public:
QList<Metadata> metadata() const { return m_metadata.values(); }
Repository repositoryForDirectory(const QString &directory) const;
void setPackageManagerCore(PackageManagerCore *core) { m_core = core; }
+ void addCompressedPackages(bool addCompressPackage) { m_addCompressedPackages = addCompressPackage;}
private slots:
void doStart();
@@ -73,9 +74,14 @@ private slots:
void unzipTaskFinished();
void metadataTaskFinished();
void progressChanged(int progress);
+ void setProgressTotalAmount(int maximum);
+ void unzipRepositoryTaskFinished();
+ void startXMLTask(const QList<FileTaskItem> items);
private:
+ void startUnzipRepositoryTask(const Repository &repo);
void reset();
+ void resetCompressedFetch();
Status parseUpdatesXml(const QList<FileTaskResult> &results);
private:
@@ -87,6 +93,9 @@ private:
QFutureWatcher<FileTaskResult> m_xmlTask;
QFutureWatcher<FileTaskResult> m_metadataTask;
QHash<QFutureWatcher<void> *, QObject*> m_unzipTasks;
+ QHash<QFutureWatcher<void> *, QObject*> m_unzipRepositoryTasks;
+ bool m_addCompressedPackages;
+ QList<FileTaskItem> m_unzipRepositoryitems;
};
} // namespace QInstaller
diff --git a/src/libs/installer/metadatajob_p.h b/src/libs/installer/metadatajob_p.h
index 34e23cd78..9160f4cc9 100644
--- a/src/libs/installer/metadatajob_p.h
+++ b/src/libs/installer/metadatajob_p.h
@@ -29,9 +29,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
@@ -60,7 +64,8 @@ public:
UnzipArchiveTask(const QString &arcive, const QString &target)
: m_archive(arcive), m_targetDir(target)
{}
-
+ QString target() { return m_targetDir; }
+ QString archive() { return m_archive; }
void doTask(QFutureInterface<void> &fi)
{
fi.reportStarted();
@@ -77,14 +82,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 92762d3b1..5ae571a59 100644
--- a/src/libs/installer/minimumprogressoperation.cpp
+++ b/src/libs/installer/minimumprogressoperation.cpp
@@ -30,7 +30,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"));
@@ -56,9 +57,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 bfea8de72..4cdafca70 100644
--- a/src/libs/installer/minimumprogressoperation.h
+++ b/src/libs/installer/minimumprogressoperation.h
@@ -40,13 +40,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 8f492c06a..7b6842720 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -41,6 +41,7 @@
#include "qprocesswrapper.h"
#include "qsettingswrapper.h"
#include "remoteclient.h"
+#include "remotefileengine.h"
#include "settings.h"
#include "utils.h"
#include "installercalculator.h"
@@ -56,12 +57,16 @@
#include <QtCore/QRegExp>
#include <QtCore/QSettings>
#include <QtCore/QTemporaryFile>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextDecoder>
+#include <QtCore/QTextEncoder>
+#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"
@@ -423,7 +428,7 @@ void PackageManagerCore::writeMaintenanceTool()
gainAdminRights();
gainedAdminRights = true;
}
- d->m_updaterApplication.packagesInfo()->writeToDisk();
+ d->m_localPackageHub->writeToDisk();
if (gainedAdminRights)
dropAdminRights();
d->m_needToWriteMaintenanceTool = false;
@@ -634,11 +639,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);
@@ -646,13 +651,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."));
@@ -701,7 +706,6 @@ void PackageManagerCore::rollBackInstallation()
}
}
- KDUpdater::PackagesInfo &packages = *d->m_updaterApplication.packagesInfo();
while (!d->m_performedOperationsCurrentSession.isEmpty()) {
try {
Operation *const operation = d->m_performedOperationsCurrentSession.takeLast();
@@ -728,14 +732,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();
}
}
@@ -745,7 +749,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"),
@@ -781,6 +785,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
/*!
@@ -820,6 +850,8 @@ PackageManagerCore::PackageManagerCore(qint64 magicmaker, const QList<OperationB
d->initialize(QHash<QString, QString>());
+ RemoteClient::instance().setAuthorizationFallbackDisabled(settings().disableAuthorizationFallback());
+
//
// Sanity check to detect a broken installations with missing operations.
// Every installed package should have at least one MinimalProgress operation.
@@ -849,6 +881,40 @@ PackageManagerCore::PackageManagerCore(qint64 magicmaker, const QList<OperationB
}
}
+class VerboseWriterAdminOutput : public VerboseWriterOutput
+{
+public:
+ VerboseWriterAdminOutput(PackageManagerCore *core) : m_core(core) {}
+
+ virtual bool write(const QString &fileName, QIODevice::OpenMode openMode, const QByteArray &data)
+ {
+ bool gainedAdminRights = false;
+
+ if (!RemoteClient::instance().isActive()) {
+ m_core->gainAdminRights();
+ gainedAdminRights = true;
+ }
+
+ RemoteFileEngine file;
+ file.setFileName(fileName);
+ if (file.open(openMode)) {
+ file.write(data.constData(), data.size());
+ file.close();
+ if (gainedAdminRights)
+ m_core->dropAdminRights();
+ return true;
+ }
+
+ if (gainedAdminRights)
+ m_core->dropAdminRights();
+
+ return false;
+ }
+
+private:
+ PackageManagerCore *m_core;
+};
+
/*!
Destroys the instance.
*/
@@ -862,8 +928,19 @@ PackageManagerCore::~PackageManagerCore()
}
delete d;
+ try {
+ PlainVerboseWriterOutput plainOutput;
+ if (!VerboseWriter::instance()->flush(&plainOutput)) {
+ VerboseWriterAdminOutput adminOutput(this);
+ VerboseWriter::instance()->flush(&adminOutput);
+ }
+ } catch (...) {
+ // Intentionally left blank; don't permit exceptions from VerboseWriter
+ // to escape destructor.
+ }
+
RemoteClient::instance().setActive(false);
- RemoteClient::instance().shutdown();
+ RemoteClient::instance().destroy();
QMutexLocker _(globalVirtualComponentsFontMutex());
delete sVirtualComponentsFont;
@@ -962,7 +1039,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;
}
@@ -984,7 +1061,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;
}
@@ -1021,7 +1098,7 @@ 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()) {
@@ -1032,6 +1109,7 @@ void PackageManagerCore::networkSettingsChanged()
if (gainedAdminRights)
dropAdminRights();
}
+
KDUpdater::FileDownloaderFactory::instance().setProxyFactory(proxyFactory());
emit coreNetworkSettingsChanged();
@@ -1071,15 +1149,44 @@ PackagesList PackageManagerCore::remotePackages()
}
/*!
+ Checks for compressed packages to install. Returns \c true if newer versions exist
+ and they can be installed.
+*/
+bool PackageManagerCore::fetchCompressedPackagesTree()
+{
+ const LocalPackagesHash installedPackages = d->localInstalledPackages();
+ if (!isInstaller() && status() == Failure)
+ return false;
+
+ if (!d->fetchMetaInformationFromCompressedRepositories())
+ return false;
+
+ if (!d->addUpdateResourcesFromRepositories(true, true)) {
+ return false;
+ }
+
+ PackagesList packages;
+ const PackagesList &compPackages = d->compressedPackages();
+ if (compPackages.isEmpty())
+ return false;
+ packages.append(compPackages);
+ const PackagesList &rPackages = d->remotePackages();
+ packages.append(rPackages);
+
+ return fetchPackagesTree(packages, installedPackages);
+}
+
+
+/*!
Checks for packages to install. Returns \c true if newer versions exist
- and they can be installed and sets the status of the update to \c Success.
+ and they can be installed.
*/
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;
}
@@ -1095,6 +1202,9 @@ bool PackageManagerCore::fetchRemotePackagesTree()
if (!d->fetchMetaInformationFromRepositories())
return false;
+ if (!d->fetchMetaInformationFromCompressedRepositories())
+ return false;
+
if (!d->addUpdateResourcesFromRepositories(true))
return false;
@@ -1102,6 +1212,11 @@ bool PackageManagerCore::fetchRemotePackagesTree()
if (packages.isEmpty())
return false;
+ return fetchPackagesTree(packages, installedPackages);
+}
+
+bool PackageManagerCore::fetchPackagesTree(const PackagesList &packages, const LocalPackagesHash installedPackages) {
+
bool success = false;
if (!isUpdater()) {
success = fetchAllPackages(packages, installedPackages);
@@ -1115,7 +1230,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
@@ -1284,12 +1399,12 @@ void PackageManagerCore::addUserRepositories(const QStringList &repositories)
\sa {installer::setTemporaryRepositories}{installer.setTemporaryRepositories}
\sa addUserRepositories()
*/
-void PackageManagerCore::setTemporaryRepositories(const QStringList &repositories, bool replace)
+void PackageManagerCore::setTemporaryRepositories(const QStringList &repositories, bool replace,
+ bool compressed)
{
QSet<Repository> repositorySet;
foreach (const QString &repository, repositories)
- repositorySet.insert(Repository::fromUserInput(repository));
-
+ repositorySet.insert(Repository::fromUserInput(repository, compressed));
settings().setTemporaryRepositories(repositorySet, replace);
}
@@ -1513,6 +1628,52 @@ QList<Component*> PackageManagerCore::orderedComponentsToInstall() const
return d->installerCalculator()->orderedComponentsToInstall();
}
+bool PackageManagerCore::calculateComponents(QString *displayString)
+{
+ QString htmlOutput;
+ QString lastInstallReason;
+ if (!calculateComponentsToUninstall() ||
+ !calculateComponentsToInstall()) {
+ htmlOutput.append(QString::fromLatin1("<h2><font color=\"red\">%1</font></h2><ul>")
+ .arg(tr("Cannot resolve all dependencies.")));
+ //if we have a missing dependency or a recursion we can display it
+ if (!componentsToInstallError().isEmpty()) {
+ htmlOutput.append(QString::fromLatin1("<li> %1 </li>").arg(
+ componentsToInstallError()));
+ }
+ htmlOutput.append(QLatin1String("</ul>"));
+ if (displayString)
+ *displayString = htmlOutput;
+ return false;
+ }
+
+ // In case of updater mode we don't uninstall components.
+ if (!isUpdater()) {
+ QList<Component*> componentsToRemove = componentsToUninstall();
+ if (!componentsToRemove.isEmpty()) {
+ htmlOutput.append(QString::fromLatin1("<h3>%1</h3><ul>").arg(tr("Components about to "
+ "be removed.")));
+ foreach (Component *component, componentsToRemove)
+ htmlOutput.append(QString::fromLatin1("<li> %1 </li>").arg(component->name()));
+ htmlOutput.append(QLatin1String("</ul>"));
+ }
+ }
+
+ foreach (Component *component, orderedComponentsToInstall()) {
+ const QString reason = installReason(component);
+ if (lastInstallReason != reason) {
+ if (!lastInstallReason.isEmpty()) // means we had to close the previous list
+ htmlOutput.append(QLatin1String("</ul>"));
+ htmlOutput.append(QString::fromLatin1("<h3>%1</h3><ul>").arg(reason));
+ lastInstallReason = reason;
+ }
+ htmlOutput.append(QString::fromLatin1("<li> %1 </li>").arg(component->name()));
+ }
+ if (displayString)
+ *displayString = htmlOutput;
+ return true;
+}
+
/*!
Calculates a list of components to uninstall based on the current run mode.
The aboutCalculateComponentsToUninstall() signal is emitted
@@ -1616,8 +1777,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;
}
@@ -1631,11 +1792,70 @@ 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;
}
+void PackageManagerCore::updateComponentsSilently()
+{
+ //Check if there are processes running in the install
+ QStringList excludeFiles;
+ excludeFiles.append(maintenanceToolName());
+
+ QStringList runningProcesses = d->runningInstallerProcesses(excludeFiles);
+ if (!runningProcesses.isEmpty()) {
+ qDebug() << "Unable to update components. Please stop these processes: "
+ << runningProcesses << " and try again.";
+ return;
+ }
+
+ autoAcceptMessageBoxes();
+
+ //Prevent infinite loop if installation for some reason fails.
+ setMessageBoxAutomaticAnswer(QLatin1String("installationErrorWithRetry"), QMessageBox::Cancel);
+
+ fetchRemotePackagesTree();
+
+ const QList<QInstaller::Component*> componentList = components(
+ ComponentType::Root | ComponentType::Descendants);
+
+ if (componentList.count() == 0) {
+ qDebug() << "No updates available.";
+ } else {
+ // Check if essential components are available (essential components are disabled).
+ // If essential components are found, update first essential updates,
+ // restart installer and install rest of the updates.
+ bool essentialUpdatesFound = false;
+ foreach (Component *component, componentList) {
+ if (component->value(scEssential, scFalse).toLower() == scTrue)
+ essentialUpdatesFound = true;
+ }
+ if (!essentialUpdatesFound) {
+ //Mark all components to be updated
+ foreach (Component *comp, componentList) {
+ comp->setCheckState(Qt::Checked);
+ }
+ }
+ QString htmlOutput;
+ bool componentsOk = calculateComponents(&htmlOutput);
+ if (componentsOk) {
+ if (runPackageUpdater()) {
+ writeMaintenanceTool();
+ if (essentialUpdatesFound) {
+ qDebug() << "Essential components updated successfully.";
+ }
+ else {
+ qDebug() << "Components updated successfully.";
+ }
+ }
+ }
+ else {
+ qDebug() << htmlOutput;
+ }
+ }
+}
+
/*!
Returns the settings for the package manager.
*/
@@ -1700,20 +1920,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();
}
}
@@ -1757,6 +1978,12 @@ bool PackageManagerCore::localInstallerBinaryUsed()
\a stdIn is sent as standard input to the application.
+ \a stdInCodec is the name of the codec to use for converting the input string
+ into bytes to write to the standard input of the application.
+
+ \a stdOutCodec is the name of the codec to use for converting data written by the
+ application to standard output into a string.
+
Returns an empty array if the program could not be executed, otherwise
the output of command as the first item, and the return code as the second.
@@ -1766,7 +1993,7 @@ bool PackageManagerCore::localInstallerBinaryUsed()
\sa executeDetached()
*/
QList<QVariant> PackageManagerCore::execute(const QString &program, const QStringList &arguments,
- const QString &stdIn) const
+ const QString &stdIn, const QString &stdInCodec, const QString &stdOutCodec) const
{
QProcessWrapper process;
@@ -1783,13 +2010,23 @@ QList<QVariant> PackageManagerCore::execute(const QString &program, const QStrin
return QList< QVariant >();
if (!adjustedStdIn.isNull()) {
- process.write(adjustedStdIn.toLatin1());
+ QTextCodec *codec = QTextCodec::codecForName(qPrintable(stdInCodec));
+ if (!codec)
+ return QList<QVariant>();
+
+ QTextEncoder encoder(codec);
+ process.write(encoder.fromUnicode(adjustedStdIn));
process.closeWriteChannel();
}
process.waitForFinished(-1);
- return QList<QVariant>() << QString::fromLatin1(process.readAllStandardOutput()) << process.exitCode();
+ QTextCodec *codec = QTextCodec::codecForName(qPrintable(stdOutCodec));
+ if (!codec)
+ return QList<QVariant>();
+ return QList<QVariant>()
+ << QTextDecoder(codec).toUnicode(process.readAllStandardOutput())
+ << process.exitCode();
}
/*!
@@ -1864,14 +2101,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);
}
/*!
@@ -1883,7 +2113,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;
@@ -2260,6 +2490,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}
@@ -2308,7 +2546,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;
}
@@ -2327,7 +2565,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;
}
@@ -2413,7 +2651,7 @@ void PackageManagerCore::storeReplacedComponents(QHash<QString, Component *> &co
// installer binary or the installed component list, just ignore it. This
// can happen when in installer mode and probably package manager mode too.
if (isUpdater())
- qWarning() << componentName << "- Does not exist in the repositories anymore.";
+ qDebug() << componentName << "- Does not exist in the repositories anymore.";
continue;
}
if (!componentToReplace && !d->componentsToReplace().contains(componentName)) {
@@ -2529,7 +2767,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 +2888,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 +2936,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 dc24bb46c..2a235bd44 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -122,6 +122,7 @@ public:
PackagesList remotePackages();
bool fetchRemotePackagesTree();
+ bool fetchCompressedPackagesTree();
bool run();
void reset(const QHash<QString, QString> &params);
@@ -133,7 +134,9 @@ public:
Q_INVOKABLE bool localInstallerBinaryUsed();
Q_INVOKABLE QList<QVariant> execute(const QString &program,
- const QStringList &arguments = QStringList(), const QString &stdIn = QString()) const;
+ const QStringList &arguments = QStringList(), const QString &stdIn = QString(),
+ const QString &stdInCodec = QLatin1String("latin1"),
+ const QString &stdOutCodec = QLatin1String("latin1")) const;
Q_INVOKABLE bool executeDetached(const QString &program,
const QStringList &arguments = QStringList(),
const QString &workingDirectory = QString()) const;
@@ -174,8 +177,8 @@ public:
void setTestChecksum(bool test);
Q_INVOKABLE void addUserRepositories(const QStringList &repositories);
- Q_INVOKABLE void setTemporaryRepositories(const QStringList &repositories, bool replace = false);
-
+ Q_INVOKABLE void setTemporaryRepositories(const QStringList &repositories,
+ bool replace = false, bool compressed = false);
Q_INVOKABLE void autoAcceptMessageBoxes();
Q_INVOKABLE void autoRejectMessageBoxes();
Q_INVOKABLE void setMessageBoxAutomaticAnswer(const QString &identifier, int button);
@@ -184,6 +187,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;
@@ -199,6 +203,7 @@ public:
Q_INVOKABLE bool calculateComponentsToInstall() const;
QList<Component*> orderedComponentsToInstall() const;
+ bool calculateComponents(QString *displayString);
Q_INVOKABLE bool calculateComponentsToUninstall() const;
QList<Component*> componentsToUninstall() const;
@@ -210,6 +215,7 @@ public:
ComponentModel *defaultComponentModel() const;
ComponentModel *updaterComponentModel() const;
+ void updateComponentsSilently();
// convenience
Q_INVOKABLE bool isInstaller() const;
@@ -224,6 +230,8 @@ public:
Q_INVOKABLE void setPackageManager();
Q_INVOKABLE bool isPackageManager() const;
+ bool isMaintainer() const;
+
bool isVerbose() const;
void setVerbose(bool on);
@@ -254,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();
@@ -279,6 +290,7 @@ Q_SIGNALS:
void finishButtonClicked();
void metaJobProgress(int progress);
+ void metaJobTotalProgress(int progress);
void metaJobInfoMessage(const QString &message);
void startAllComponentsReset();
@@ -327,6 +339,8 @@ private:
ComponentModel *componentModel(PackageManagerCore *core, const QString &objectName) const;
QList<Component *> componentsMarkedForInstallation() const;
+ bool fetchPackagesTree(const PackagesList &packages, const LocalPackagesHash installedPackages);
+
private:
PackageManagerCorePrivate *const d;
friend class PackageManagerCorePrivate;
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index c0723d72c..fb802ef8b 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -49,13 +49,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>
@@ -92,9 +92,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() {
@@ -151,6 +151,7 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
.fileName()));
QTextStream batch(&f);
+ batch.setCodec("UTF-16");
batch << "Set fso = WScript.CreateObject(\"Scripting.FileSystemObject\")\n";
batch << "Set tmp = WScript.CreateObject(\"WScript.Shell\")\n";
batch << QString::fromLatin1("file = \"%1\"\n").arg(arguments[2]);
@@ -161,8 +162,16 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
batch << " WScript.Sleep(1000)\n";
batch << "wend\n";
batch << QString::fromLatin1("fso.MoveFile \"%1\", file\n").arg(arguments[1]);
- if (restart)
- batch << QString::fromLatin1("tmp.exec \"%1 --updater\"\n").arg(arguments[2]);
+ if (restart) {
+ //Restart with same command line arguments as first executable
+ QStringList commandLineArguments = QCoreApplication::arguments();
+ batch << QString::fromLatin1("tmp.exec \"%1 --updater").arg(arguments[2]);
+ //Skip the first argument as that is executable itself
+ for (int i = 1; i < commandLineArguments.count(); i++) {
+ batch << QString::fromLatin1(" %1").arg(commandLineArguments.at(i));
+ }
+ batch << QString::fromLatin1("\"\n");
+ }
batch << "fso.DeleteFile(WScript.ScriptFullName)\n";
}
@@ -171,7 +180,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
}
@@ -180,7 +189,8 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
: m_updateFinder(0)
- , m_updaterApplication(new DummyConfigurationInterface)
+ , m_compressedFinder(0)
+ , m_localPackageHub(std::make_shared<LocalPackageHub>())
, m_core(core)
, m_updates(false)
, m_repoFetched(false)
@@ -201,7 +211,8 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, qint64 magicInstallerMaker,
const QList<OperationBlob> &performedOperations)
: m_updateFinder(0)
- , m_updaterApplication(new DummyConfigurationInterface)
+ , m_compressedFinder(0)
+ , m_localPackageHub(std::make_shared<LocalPackageHub>())
, m_status(PackageManagerCore::Unfinished)
, m_needsHardRestart(false)
, m_testChecksum(false)
@@ -227,24 +238,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()
@@ -306,7 +320,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())
@@ -338,7 +353,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) {
@@ -390,7 +405,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();
@@ -408,7 +423,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,
@@ -543,45 +558,38 @@ 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);
+ connect(&m_metadataJob, &Job::totalProgress, this, &PackageManagerCorePrivate::totalProgress);
KDUpdater::FileDownloaderFactory::instance().setProxyFactory(m_core->proxyFactory());
}
@@ -651,7 +659,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();
}
@@ -732,24 +740,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"));
@@ -794,17 +808,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;
@@ -1003,13 +1022,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);
@@ -1028,13 +1047,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()));
}
@@ -1066,8 +1085,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);
}
}
@@ -1080,9 +1098,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());
@@ -1258,17 +1273,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;
@@ -1278,9 +1293,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();
}
@@ -1329,12 +1344,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);
@@ -1394,7 +1409,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\\")
@@ -1486,14 +1501,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
@@ -1521,7 +1535,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"));
@@ -1862,7 +1875,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 =
@@ -1900,7 +1913,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);
@@ -1908,12 +1921,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();
@@ -2018,7 +2037,13 @@ void PackageManagerCorePrivate::registerMaintenanceTool()
const quint64 limit = std::numeric_limits<quint32>::max(); // maximum 32 bit value
if (estimatedSizeKB <= limit)
settings.setValue(QLatin1String("EstimatedSize"), static_cast<quint32>(estimatedSizeKB));
- settings.setValue(QLatin1String("NoModify"), 0);
+
+ const bool supportsModify = m_core->value(scSupportsModify, scTrue) == scTrue;
+ if (supportsModify)
+ settings.setValue(QLatin1String("NoModify"), 0);
+ else
+ settings.setValue(QLatin1String("NoModify"), 1);
+
settings.setValue(QLatin1String("NoRepair"), 1);
#endif
}
@@ -2034,7 +2059,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())
@@ -2070,7 +2094,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());
}
}
@@ -2081,13 +2105,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()
@@ -2098,12 +2122,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();
}
@@ -2112,6 +2138,29 @@ PackagesList PackageManagerCorePrivate::remotePackages()
return m_updateFinder->updates();
}
+PackagesList PackageManagerCorePrivate::compressedPackages()
+{
+ if (m_compressedUpdates && m_compressedFinder)
+ return m_compressedFinder->updates();
+ m_compressedUpdates = false;
+ delete m_compressedFinder;
+
+ m_compressedFinder = new KDUpdater::UpdateFinder;
+ m_compressedFinder->setAutoDelete(false);
+ m_compressedFinder->addCompressedPackage(true);
+ m_compressedFinder->setPackageSources(m_compressedPackageSources);
+
+ m_compressedFinder->setLocalPackageHub(m_localPackageHub);
+ m_compressedFinder->run();
+ if (m_compressedFinder->updates().isEmpty()) {
+ setStatus(PackageManagerCore::Failure, tr("Cannot retrieve remote tree %1.")
+ .arg(m_compressedFinder->errorString()));
+ return PackagesList();
+ }
+ m_compressedUpdates = true;
+ return m_compressedFinder->updates();
+}
+
/*!
Returns a hash containing the installed package name and it's associated package information. If
the application is running in installer mode or the local components file could not be parsed, the
@@ -2119,27 +2168,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;
}
@@ -2157,12 +2211,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
@@ -2176,9 +2230,46 @@ bool PackageManagerCorePrivate::fetchMetaInformationFromRepositories()
return m_repoFetched;
}
-bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChecksum)
+bool PackageManagerCorePrivate::fetchMetaInformationFromCompressedRepositories()
+{
+ bool compressedRepoFetched = false;
+
+ m_compressedUpdates = false;
+ m_updateSourcesAdded = false;
+
+ try {
+ //Tell MetadataJob that only compressed packages needed to be fetched and not all.
+ //We cannot do this in general fetch meta method as the compressed packages might be
+ //installed after components tree is generated
+ m_metadataJob.addCompressedPackages(true);
+ m_metadataJob.start();
+ m_metadataJob.waitForFinished();
+ m_metadataJob.addCompressedPackages(false);
+ } catch (Error &error) {
+ setStatus(PackageManagerCore::Failure, tr("Cannot retrieve meta information: %1")
+ .arg(error.message()));
+ return compressedRepoFetched;
+ }
+
+ 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
+ default:
+ //Do not change core status here, we can recover if there is invalid
+ //compressed repository
+ setStatus(m_core->status(), m_metadataJob.errorString());
+ return compressedRepoFetched;
+ }
+ }
+
+ compressedRepoFetched = true;
+ return compressedRepoFetched;
+}
+
+bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChecksum, bool compressedRepository)
{
- if (m_updateSourcesAdded)
+ if (!compressedRepository && m_updateSourcesAdded)
return m_updateSourcesAdded;
const QList<Metadata> metadata = m_metadataJob.metadata();
@@ -2186,21 +2277,21 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
m_updateSourcesAdded = true;
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);
+ if (compressedRepository) {
+ m_compressedPackageSources.clear();
+ }
+ else {
+ m_packageSources.clear();
+ m_updates = false;
+ m_updateSourcesAdded = false;
+ 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 (compressedRepository && !data.repository.isCompressed()) {
+ continue;
+ }
if (statusCanceledOrFailed())
return false;
@@ -2214,7 +2305,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;
}
@@ -2223,9 +2314,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;
}
@@ -2233,14 +2324,16 @@ 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);
+ if (compressedRepository)
+ m_compressedPackageSources.insert(PackageSource(QUrl::fromLocalFile(data.directory), 1));
+ else
+ 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 ((compressedRepository && m_compressedPackageSources.count() == 0 ) ||
+ (!compressedRepository && m_packageSources.count() == 0)) {
+ setStatus(PackageManagerCore::Failure, tr("Cannot find any update source information."));
return false;
}
@@ -2292,25 +2385,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)
@@ -2326,4 +2414,44 @@ 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
+ }
+ }
+}
+
+void PackageManagerCorePrivate::findExecutablesRecursive(const QString &path, const QStringList &excludeFiles, QStringList *result)
+{
+ QString executable;
+ QDirIterator it(path, QDir::NoDotAndDotDot | QDir::Executable | QDir::Files | QDir::System, QDirIterator::Subdirectories );
+
+ while (it.hasNext()) {
+ executable = it.next();
+ foreach (QString exclude, excludeFiles) {
+ if (QDir::toNativeSeparators(executable.toLower())
+ != QDir::toNativeSeparators(exclude.toLower())) {
+ result->append(executable);
+ }
+ }
+ }
+}
+
+QStringList PackageManagerCorePrivate::runningInstallerProcesses(const QStringList &excludeFiles)
+{
+ QStringList resultFiles;
+ findExecutablesRecursive(QCoreApplication::applicationDirPath(), excludeFiles, &resultFiles);
+ return checkRunningProcessesFromList(resultFiles);
+}
+
+
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index 663bb19bd..21ab3fc40 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -33,15 +33,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)
@@ -60,27 +60,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
@@ -191,7 +170,11 @@ signals:
public:
UpdateFinder *m_updateFinder;
- Application m_updaterApplication;
+ UpdateFinder *m_compressedFinder;
+ QSet<PackageSource> m_packageSources;
+ QSet<PackageSource> m_compressedPackageSources;
+ std::shared_ptr<LocalPackageHub> m_localPackageHub;
+ QStringList m_filesForDelayedDeletion;
int m_status;
QString m_error;
@@ -219,13 +202,17 @@ 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);
}
+ void totalProgress(quint64 total) {
+ emit m_core->metaJobTotalProgress(total);
+ }
+
void handleMethodInvocationRequest(const QString &invokableMethodName);
private:
@@ -241,15 +228,21 @@ private:
bool adminRightsGained, bool deleteOperation);
PackagesList remotePackages();
+ PackagesList compressedPackages();
LocalPackagesHash localInstalledPackages();
bool fetchMetaInformationFromRepositories();
- bool addUpdateResourcesFromRepositories(bool parseChecksum);
+ bool fetchMetaInformationFromCompressedRepositories();
+ bool addUpdateResourcesFromRepositories(bool parseChecksum, bool compressedRepository = false);
+ void processFilesForDelayedDeletion();
+ void findExecutablesRecursive(const QString &path, const QStringList &excludeFiles, QStringList *result);
+ QStringList runningInstallerProcesses(const QStringList &exludeFiles);
private:
PackageManagerCore *m_core;
MetadataJob m_metadataJob;
bool m_updates;
+ bool m_compressedUpdates;
bool m_repoFetched;
bool m_updateSourcesAdded;
qint64 m_magicBinaryMarker;
diff --git a/src/libs/installer/packagemanagercoredata.cpp b/src/libs/installer/packagemanagercoredata.cpp
index 2a92a468e..3b35794cf 100644
--- a/src/libs/installer/packagemanagercoredata.cpp
+++ b/src/libs/installer/packagemanagercoredata.cpp
@@ -47,27 +47,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)
@@ -78,26 +65,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);
@@ -127,12 +94,81 @@ 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);
+
+ QString dirX86 = dir;
+ QString dirX64 = dir;
+#ifdef Q_OS_WIN
+ QSettingsWrapper current(QLatin1String("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion")
+ , QSettingsWrapper::NativeFormat);
+ BOOL onWow64Or64bit = TRUE;
+#ifndef Q_OS_WIN64
+ IsWow64Process(GetCurrentProcess(), &onWow64Or64bit);
+#endif
+ QString programfilesX86;
+ QString programfilesX64;
+ if (onWow64Or64bit == TRUE) {
+ programfilesX86 = current.value(QLatin1String("ProgramFilesDir (x86)"), QString()).toString();
+ programfilesX64 = current.value(QLatin1String("ProgramW6432Dir"), QString()).toString();
+ } else {
+ programfilesX86 = current.value(QLatin1String("ProgramFilesDir"), QString()).toString();
+ programfilesX64 = programfilesX86;
+ }
+ dirX86 = replaceWindowsEnvironmentVariables(programfilesX86);
+ dirX64 = replaceWindowsEnvironmentVariables(programfilesX64);
+#endif
+ m_variables.insert(QLatin1String("ApplicationsDirX86"), dirX86);
+ m_variables.insert(QLatin1String("ApplicationsDirX64"), dirX64);
+
+#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();
}
@@ -144,7 +180,7 @@ bool PackageManagerCoreData::contains(const QString &key) const
bool PackageManagerCoreData::setValue(const QString &key, const QString &normalizedValue)
{
- if (m_variables.value(key) == normalizedValue)
+ if (m_variables.contains(key) && m_variables.value(key) == normalizedValue)
return false;
m_variables.insert(key, normalizedValue);
return true;
diff --git a/src/libs/installer/packagemanagercoredata.h b/src/libs/installer/packagemanagercoredata.h
index 59b0c9808..ec0d4c302 100644
--- a/src/libs/installer/packagemanagercoredata.h
+++ b/src/libs/installer/packagemanagercoredata.h
@@ -40,9 +40,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 31d733599..5ee3d14fc 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -40,7 +40,7 @@
#include "scriptengine.h"
#include "productkeycheck.h"
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include <QApplication>
@@ -49,7 +49,9 @@
#include <QtCore/QProcess>
#include <QtCore/QTimer>
+#include <QAbstractItemView>
#include <QCheckBox>
+#include <QComboBox>
#include <QDesktopServices>
#include <QFileDialog>
#include <QGridLayout>
@@ -63,10 +65,12 @@
#include <QProgressBar>
#include <QPushButton>
#include <QRadioButton>
+#include <QStringListModel>
#include <QTextBrowser>
#include <QTreeView>
#include <QVBoxLayout>
#include <QShowEvent>
+#include <QFileDialog>
#ifdef Q_OS_WIN
# include <qt_windows.h>
@@ -105,7 +109,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());
@@ -202,6 +205,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"));
@@ -225,6 +229,7 @@ public:
bool m_modified;
bool m_autoSwitchPage;
bool m_showSettingsButton;
+ bool m_silent;
QHash<int, QWizardPage*> m_defaultPages;
QHash<int, QString> m_defaultButtonText;
@@ -310,48 +315,66 @@ 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()) {
+ QFile sheet(styleSheetFile);
+ if (sheet.exists()) {
+ 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)));
@@ -395,6 +418,43 @@ 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;
+}
+
+/*!
+ Updates the model of \a object (which must be a QComboBox or
+ QAbstractItemView) such that it contains the given \a items.
+*/
+void PackageManagerGui::setTextItems(QObject *object, const QStringList &items)
+{
+ if (QComboBox *comboBox = qobject_cast<QComboBox*>(object)) {
+ comboBox->setModel(new QStringListModel(items));
+ return;
+ }
+
+ if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(object)) {
+ view->setModel(new QStringListModel(items));
+ return;
+ }
+
+ qDebug() << "Cannot set text items on object of type"
+ << object->metaObject()->className() << ".";
+}
+
+/*!
Enables automatic page switching when \a request is \c true.
*/
void PackageManagerGui::setAutomatedPageSwitchEnabled(bool request)
@@ -445,7 +505,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!";
}
@@ -738,13 +798,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) {
@@ -784,7 +844,6 @@ void PackageManagerGui::setModified(bool value)
*/
void PackageManagerGui::showFinishedPage()
{
- qDebug() << "SHOW FINISHED PAGE";
if (d->m_autoSwitchPage)
next();
else
@@ -1023,7 +1082,17 @@ QPixmap PackageManagerPage::watermarkPixmap() const
*/
QPixmap PackageManagerPage::bannerPixmap() const
{
- return QPixmap(m_core->value(QLatin1String("BannerPixmap")));
+ QPixmap banner(m_core->value(QLatin1String("BannerPixmap")));
+
+ if (!banner.isNull()) {
+ int width;
+ if (m_core->settings().containsValue(QLatin1String("WizardDefaultWidth")) )
+ width = m_core->settings().wizardDefaultWidth();
+ else
+ width = size().width();
+ banner = banner.scaledToWidth(width, Qt::SmoothTransformation);
+ }
+ return banner;
}
/*!
@@ -1149,7 +1218,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
@@ -1210,20 +1279,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));
@@ -1251,16 +1322,19 @@ 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::metaJobTotalProgress, this, &IntroductionPage::setTotalProgress);
+ 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;
}
@@ -1276,7 +1350,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();
@@ -1301,8 +1375,7 @@ bool IntroductionPage::validatePage()
}
gui()->setSettingsButtonEnabled(false);
- const bool maintenance = core->isUpdater() || core->isPackageManager();
- if (maintenance) {
+ if (core->isMaintainer()) {
showAll();
setMaintenanceToolsEnabled(false);
} else {
@@ -1363,7 +1436,7 @@ bool IntroductionPage::validatePage()
setComplete(true);
}
- if (maintenance) {
+ if (core->isMaintainer()) {
showMaintenanceTools();
setMaintenanceToolsEnabled(true);
} else {
@@ -1440,11 +1513,19 @@ void IntroductionPage::setMessage(const QString &msg)
*/
void IntroductionPage::onProgressChanged(int progress)
{
- m_progressBar->setRange(0, 100);
m_progressBar->setValue(progress);
}
/*!
+ Sets total \a progress value to progress bar.
+*/
+void IntroductionPage::setTotalProgress(int totalProgress)
+{
+ if (m_progressBar)
+ m_progressBar->setRange(0, totalProgress);
+}
+
+/*!
Displays the error message \a error on the page.
*/
void IntroductionPage::setErrorMessage(const QString &error)
@@ -1545,7 +1626,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);
}
@@ -1635,19 +1716,19 @@ 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*)));
+ m_licenseListWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ connect(m_licenseListWidget, &QListWidget::currentItemChanged,
+ this, &LicenseAgreementPage::currentItemChanged);
m_textBrowser = new QTextBrowser(this);
m_textBrowser->setReadOnly(true);
m_textBrowser->setOpenLinks(false);
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)));
+ m_textBrowser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ connect(m_textBrowser, &QTextBrowser::anchorClicked, this, &LicenseAgreementPage::openLicenseUrl);
- QHBoxLayout *licenseBoxLayout = new QHBoxLayout();
+ QVBoxLayout *licenseBoxLayout = new QVBoxLayout();
licenseBoxLayout->addWidget(m_licenseListWidget);
licenseBoxLayout->addWidget(m_textBrowser);
@@ -1684,8 +1765,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);
}
@@ -1758,7 +1839,7 @@ void LicenseAgreementPage::updateUi()
acceptButtonText = tr("I accept the licenses.");
rejectButtonText = tr("I do not accept the licenses.");
}
-
+ m_licenseListWidget->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
setColoredSubTitle(subTitleText);
m_acceptLabel->setText(acceptButtonText);
@@ -1781,6 +1862,7 @@ public:
, m_allModel(m_core->defaultComponentModel())
, m_updaterModel(m_core->updaterComponentModel())
, m_currentModel(m_allModel)
+ , m_compressedButtonVisible(false)
{
m_treeView->setObjectName(QLatin1String("ComponentsTreeView"));
@@ -1796,23 +1878,28 @@ public:
m_descriptionLabel->setWordWrap(true);
m_descriptionLabel->setObjectName(QLatin1String("ComponentDescriptionLabel"));
- QVBoxLayout *vlayout = new QVBoxLayout;
- vlayout->addWidget(m_descriptionLabel);
+ m_vlayout = new QVBoxLayout;
+ m_vlayout->setObjectName(QLatin1String("VerticalLayout"));
+ m_vlayout->addWidget(m_descriptionLabel);
m_sizeLabel = new QLabel(q);
m_sizeLabel->setWordWrap(true);
- vlayout->addWidget(m_sizeLabel);
+ m_vlayout->addWidget(m_sizeLabel);
m_sizeLabel->setObjectName(QLatin1String("ComponentSizeLabel"));
- vlayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
+#ifdef INSTALLCOMPRESSED
+ allowCompressedRepositoryInstall();
+#endif
+ m_vlayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding));
- hlayout->addLayout(vlayout, 2);
+ hlayout->addLayout(m_vlayout, 2);
QVBoxLayout *layout = new QVBoxLayout(q);
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",
@@ -1830,7 +1917,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")));
@@ -1838,7 +1926,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")));
@@ -1849,22 +1938,56 @@ public:
layout->addLayout(hlayout);
}
+ void allowCompressedRepositoryInstall()
+ {
+ if (m_compressedButtonVisible) {
+ return;
+ }
+
+ connect(m_core, SIGNAL(metaJobProgress(int)), this, SLOT(onProgressChanged(int)));
+ connect(m_core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
+
+ m_bspLabel = new QLabel(ComponentSelectionPage::tr("To install new "\
+ "compressed repository, browse the repositories from your computer"),q);
+ m_bspLabel->setWordWrap(true);
+ m_bspLabel->setObjectName(QLatin1String("CompressedButtonLabel"));
+
+ m_vlayout->addSpacing(50);
+ m_vlayout->addWidget(m_bspLabel);
+
+ m_progressBar = new QProgressBar();
+ m_progressBar->setRange(0, 0);
+ m_progressBar->hide();
+ m_vlayout->addWidget(m_progressBar);
+ m_progressBar->setObjectName(QLatin1String("CompressedInstallProgressBar"));
+
+ m_installCompressButton = new QPushButton;
+ connect(m_installCompressButton, &QAbstractButton::clicked,
+ this, &ComponentSelectionPage::Private::selectCompressedPackage);
+ m_installCompressButton->setObjectName(QLatin1String("InstallCompressedPackageButton"));
+ m_installCompressButton->setText(ComponentSelectionPage::tr("&Browse QBSP files"));
+ m_vlayout->addWidget(m_installCompressButton);
+ m_compressedButtonVisible = true;
+ }
+
void updateTreeView()
{
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);
+ m_treeView->header()->setSectionResizeMode(
+ ComponentModelHelper::NameColumn, QHeaderView::ResizeToContents);
if (m_core->isInstaller()) {
m_treeView->setHeaderHidden(true);
for (int i = ComponentModelHelper::InstalledVersionColumn; i < m_currentModel->columnCount(); ++i)
@@ -1895,8 +2018,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));
}
@@ -1932,6 +2055,59 @@ public slots:
m_currentModel->setCheckedState(ComponentModel::AllUnchecked);
}
+ void selectCompressedPackage()
+ {
+ QString defaultDownloadDirectory =
+ QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
+ QStringList fileNames = QFileDialog::getOpenFileNames(NULL,
+ ComponentSelectionPage::tr("Open File"),defaultDownloadDirectory,
+ QLatin1String("QBSP or 7z Files (*.qbsp *.7z)"));
+
+ QSet<Repository> set;
+ foreach (QString fileName, fileNames) {
+ Repository repository = Repository::fromUserInput(fileName, true);
+ repository.setEnabled(true);
+ set.insert(repository);
+ }
+ if (set.count() > 0) {
+ m_progressBar->show();
+ m_installCompressButton->hide();
+ QPushButton *const b = qobject_cast<QPushButton *>(q->gui()->button(QWizard::NextButton));
+ b->setEnabled(false);
+ m_core->settings().addTemporaryRepositories(set, false);
+ if (!m_core->fetchCompressedPackagesTree()) {
+ setMessage(m_core->error());
+ }
+ else {
+ updateTreeView();
+ setMessage(ComponentSelectionPage::tr("To install new "\
+ "compressed repository, browse the repositories from your computer"));
+ }
+
+ m_progressBar->hide();
+ m_installCompressButton->show();
+ b->setEnabled(true);
+ }
+ }
+
+ /*!
+ Updates the value of \a progress on the progress bar.
+ */
+ void onProgressChanged(int progress)
+ {
+ m_progressBar->setValue(progress);
+ }
+
+ /*!
+ Displays the message \a msg on the page.
+ */
+ void setMessage(const QString &msg)
+ {
+ QWizardPage *page = q->gui()->currentPage();
+ if (m_bspLabel && page && page->objectName() == QLatin1String("ComponentSelectionPage"))
+ m_bspLabel->setText(msg);
+ }
+
void selectDefault()
{
m_currentModel->setCheckedState(ComponentModel::DefaultChecked);
@@ -1969,6 +2145,11 @@ public:
QPushButton *m_checkAll;
QPushButton *m_uncheckAll;
QPushButton *m_checkDefault;
+ QPushButton *m_installCompressButton;
+ QLabel *m_bspLabel;
+ QProgressBar *m_progressBar;
+ QVBoxLayout *m_vlayout;
+ bool m_compressedButtonVisible;
};
@@ -2012,7 +2193,7 @@ void ComponentSelectionPage::entering()
QT_TR_NOOP("Please select the components you want to update."),
QT_TR_NOOP("Please select the components you want to install."),
QT_TR_NOOP("Please select the components you want to uninstall."),
- QT_TR_NOOP("Select the components to install. Deselect installed components to uninstall them.")
+ QT_TR_NOOP("Select the components to install. Deselect installed components to uninstall them. Any components already installed will not be updated.")
};
int index = 0;
@@ -2087,6 +2268,11 @@ void ComponentSelectionPage::deselectComponent(const QString &id)
d->m_currentModel->setData(idx, Qt::Unchecked, Qt::CheckStateRole);
}
+void ComponentSelectionPage::allowCompressedRepositoryInstall()
+{
+ d->allowCompressedRepositoryInstall();
+}
+
void ComponentSelectionPage::setModified(bool modified)
{
setComplete(modified);
@@ -2143,19 +2329,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);
@@ -2226,6 +2417,11 @@ void TargetDirectoryPage::initializePage()
*/
bool TargetDirectoryPage::validatePage()
{
+ m_textChangeTimer.stop();
+
+ if (!isComplete())
+ return false;
+
if (!isVisible())
return true;
@@ -2251,14 +2447,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."));
@@ -2313,7 +2509,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())
@@ -2376,7 +2572,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)(\\\\|$)");
@@ -2391,8 +2587,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();
@@ -2437,7 +2633,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()));
@@ -2445,7 +2641,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);
}
@@ -2461,8 +2657,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);
}
/*!
@@ -2568,7 +2764,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."));
@@ -2581,7 +2777,7 @@ void ReadyForInstallationPage::entering()
}
QString htmlOutput;
- bool componentsOk = calculateComponents(&htmlOutput);
+ bool componentsOk = packageManagerCore()->calculateComponents(&htmlOutput);
m_taskDetailsBrowser->setHtml(htmlOutput);
m_taskDetailsBrowser->setVisible(!componentsOk || isVerbose());
setComplete(componentsOk);
@@ -2594,19 +2790,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:"
@@ -2638,7 +2834,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);
@@ -2646,16 +2842,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;
@@ -2678,51 +2874,7 @@ void ReadyForInstallationPage::entering()
.arg(humanReadableSize(packageManagerCore()->requiredDiskSpace()))));
}
-bool ReadyForInstallationPage::calculateComponents(QString *displayString)
-{
- QString htmlOutput;
- QString lastInstallReason;
- if (!packageManagerCore()->calculateComponentsToUninstall() ||
- !packageManagerCore()->calculateComponentsToInstall()) {
- htmlOutput.append(QString::fromLatin1("<h2><font color=\"red\">%1</font></h2><ul>")
- .arg(tr("Cannot resolve all dependencies.")));
- //if we have a missing dependency or a recursion we can display it
- if (!packageManagerCore()->componentsToInstallError().isEmpty()) {
- htmlOutput.append(QString::fromLatin1("<li> %1 </li>").arg(
- packageManagerCore()->componentsToInstallError()));
- }
- htmlOutput.append(QLatin1String("</ul>"));
- if (displayString)
- *displayString = htmlOutput;
- return false;
- }
- // In case of updater mode we don't uninstall components.
- if (!packageManagerCore()->isUpdater()) {
- QList<Component*> componentsToRemove = packageManagerCore()->componentsToUninstall();
- if (!componentsToRemove.isEmpty()) {
- htmlOutput.append(QString::fromLatin1("<h3>%1</h3><ul>").arg(tr("Components about to "
- "be removed.")));
- foreach (Component *component, componentsToRemove)
- htmlOutput.append(QString::fromLatin1("<li> %1 </li>").arg(component->name()));
- htmlOutput.append(QLatin1String("</ul>"));
- }
- }
-
- foreach (Component *component, packageManagerCore()->orderedComponentsToInstall()) {
- const QString installReason = packageManagerCore()->installReason(component);
- if (lastInstallReason != installReason) {
- if (!lastInstallReason.isEmpty()) // means we had to close the previous list
- htmlOutput.append(QLatin1String("</ul>"));
- htmlOutput.append(QString::fromLatin1("<h3>%1</h3><ul>").arg(installReason));
- lastInstallReason = installReason;
- }
- htmlOutput.append(QString::fromLatin1("<li> %1 </li>").arg(component->name()));
- }
- if (displayString)
- *displayString = htmlOutput;
- return true;
-}
/*!
Called when end users leave the page and the PackageManagerGui:currentPageChanged()
@@ -2769,22 +2921,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);
@@ -2823,7 +2980,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()));
@@ -2924,12 +3081,6 @@ FinishedPage::FinishedPage(PackageManagerCore *core)
m_msgLabel->setWordWrap(true);
m_msgLabel->setObjectName(QLatin1String("MessageLabel"));
-#ifdef Q_OS_OSX
- m_msgLabel->setText(tr("Click Done to exit the %1 Wizard.").arg(productName()));
-#else
- m_msgLabel->setText(tr("Click Finish to exit the %1 Wizard.").arg(productName()));
-#endif
-
m_runItCheckBox = new QCheckBox(this);
m_runItCheckBox->setObjectName(QLatin1String("RunItCheckBox"));
m_runItCheckBox->setChecked(true);
@@ -2948,12 +3099,16 @@ FinishedPage::FinishedPage(PackageManagerCore *core)
*/
void FinishedPage::entering()
{
+ m_msgLabel->setText(tr("Click %1 to exit the %2 Wizard.")
+ .arg(gui()->defaultButtonText(QWizard::FinishButton).remove(QLatin1Char('&')))
+ .arg(productName()));
+
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
@@ -2962,13 +3117,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));
@@ -2987,8 +3142,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) {
@@ -3055,12 +3210,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 94dd0a9d4..238e22a62 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -33,6 +33,7 @@
#include <QtCore/QEvent>
#include <QtCore/QMetaType>
+#include <QtCore/QTimer>
#include <QWizard>
#include <QWizardPage>
@@ -87,6 +88,11 @@ public:
void updateButtonLayout();
static QWizard::WizardStyle getStyle(const QString &name);
+ void setSilent(bool silent);
+ bool isSilent() const;
+
+ void setTextItems(QObject *object, const QStringList &items);
+
Q_SIGNALS:
void interrupted();
void languageChanged();
@@ -218,6 +224,7 @@ public Q_SLOTS:
void onCoreNetworkSettingsChanged();
void setMessage(const QString &msg);
void onProgressChanged(int progress);
+ void setTotalProgress(int totalProgress);
void setErrorMessage(const QString &error);
Q_SIGNALS:
@@ -303,6 +310,7 @@ public:
Q_INVOKABLE void selectDefault();
Q_INVOKABLE void selectComponent(const QString &id);
Q_INVOKABLE void deselectComponent(const QString &id);
+ Q_INVOKABLE void allowCompressedRepositoryInstall();
protected:
void entering();
@@ -347,6 +355,7 @@ private:
private:
QLineEdit *m_lineEdit;
QLabel *m_warningLabel;
+ QTimer m_textChangeTimer;
};
@@ -389,9 +398,6 @@ protected:
void leaving();
private:
- bool calculateComponents(QString *displayString);
-
-private:
QLabel *m_msgLabel;
QTextBrowser* m_taskDetailsBrowser;
};
diff --git a/src/libs/installer/packagemanagerpagefactory.cpp b/src/libs/installer/packagemanagerpagefactory.cpp
index f891bfbb3..808dec263 100644
--- a/src/libs/installer/packagemanagerpagefactory.cpp
+++ b/src/libs/installer/packagemanagerpagefactory.cpp
@@ -36,9 +36,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 87a08fd34..4cb7cf5d4 100644
--- a/src/libs/installer/packagemanagerpagefactory.h
+++ b/src/libs/installer/packagemanagerpagefactory.h
@@ -29,16 +29,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)
@@ -46,12 +46,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 734e1ba34..98aef7d9a 100644
--- a/src/libs/installer/packagemanagerproxyfactory.cpp
+++ b/src/libs/installer/packagemanagerproxyfactory.cpp
@@ -115,7 +115,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 f2d64ae96..31f1ffeba 100644
--- a/src/libs/installer/packagemanagerproxyfactory.h
+++ b/src/libs/installer/packagemanagerproxyfactory.h
@@ -29,7 +29,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 bf5a74985..b66cbb5bd 100644
--- a/src/libs/installer/performinstallationform.cpp
+++ b/src/libs/installer/performinstallationform.cpp
@@ -117,13 +117,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();
@@ -142,7 +142,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);
@@ -176,7 +177,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/productkeycheck.cpp b/src/libs/installer/productkeycheck.cpp
index 4a8ce4677..c1dfe83d6 100644
--- a/src/libs/installer/productkeycheck.cpp
+++ b/src/libs/installer/productkeycheck.cpp
@@ -101,3 +101,8 @@ QList<int> ProductKeyCheck::registeredPages() const
{
return QList<int>();
}
+
+bool ProductKeyCheck::hasValidLicense() const
+{
+ return true;
+}
diff --git a/src/libs/installer/productkeycheck.h b/src/libs/installer/productkeycheck.h
index 221fdc7ef..b7e8c6d52 100644
--- a/src/libs/installer/productkeycheck.h
+++ b/src/libs/installer/productkeycheck.h
@@ -66,6 +66,7 @@ public:
bool isValidPackage(const QString &packageName) const;
QList<int> registeredPages() const;
+ bool hasValidLicense() const;
private:
ProductKeyCheck();
diff --git a/src/libs/installer/progresscoordinator.cpp b/src/libs/installer/progresscoordinator.cpp
index f94142de6..1a3f4e33f 100644
--- a/src/libs/installer/progresscoordinator.cpp
+++ b/src/libs/installer/progresscoordinator.cpp
@@ -101,7 +101,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 eaac3cacf..99dfd942c 100644
--- a/src/libs/installer/proxycredentialsdialog.h
+++ b/src/libs/installer/proxycredentialsdialog.h
@@ -30,9 +30,7 @@
#include <QDialog>
-QT_BEGIN_NAMESPACE
-class QNetworkProxy;
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QNetworkProxy)
namespace QInstaller {
diff --git a/src/libs/installer/qinstallerglobal.h b/src/libs/installer/qinstallerglobal.h
index 2dc1f92b3..884044db9 100644
--- a/src/libs/installer/qinstallerglobal.h
+++ b/src/libs/installer/qinstallerglobal.h
@@ -31,9 +31,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 {
@@ -55,8 +55,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 9396a3b56..1bf60ead2 100644
--- a/src/libs/installer/qprocesswrapper.cpp
+++ b/src/libs/installer/qprocesswrapper.cpp
@@ -43,20 +43,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()
@@ -97,7 +94,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 95c7fadb7..e76217eda 100644
--- a/src/libs/installer/qprocesswrapper.h
+++ b/src/libs/installer/qprocesswrapper.h
@@ -117,7 +117,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 6bd8ab853..23ac372fd 100644
--- a/src/libs/installer/qtpatch.cpp
+++ b/src/libs/installer/qtpatch.cpp
@@ -85,8 +85,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);
@@ -120,7 +120,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;
}
@@ -168,8 +168,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;
}
@@ -183,7 +182,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;
}
@@ -203,7 +202,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 a1f55a4b5..2cfd8f9c4 100644
--- a/src/libs/installer/registerfiletypeoperation.cpp
+++ b/src/libs/installer/registerfiletypeoperation.cpp
@@ -28,6 +28,7 @@
#include "registerfiletypeoperation.h"
+#include "constants.h"
#include "packagemanagercore.h"
#include "qsettingswrapper.h"
@@ -73,7 +74,9 @@ static QVariantHash readHive(QSettingsWrapper *const settings, const QString &hi
// -- RegisterFileTypeOperation
-RegisterFileTypeOperation::RegisterFileTypeOperation()
+RegisterFileTypeOperation::RegisterFileTypeOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
+ , m_optionalArgumentsRead(false)
{
setName(QLatin1String("RegisterFileType"));
}
@@ -85,37 +88,29 @@ void RegisterFileTypeOperation::backup()
bool RegisterFileTypeOperation::performOperation()
{
#ifdef Q_OS_WIN
- 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("")));
+ ensureOptionalArgumentsRead();
+ if (!checkArgumentCount(2, 5, tr("<extension> <command> [description [contentType [icon]]]")))
return false;
- }
+ QStringList args = arguments();
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")
, QSettingsWrapper::NativeFormat);
- const QString extension = args.at(0);
- if (progId.isEmpty())
- progId = QString::fromLatin1("%1_auto_file").arg(extension);
- const QString classesProgId = QString::fromLatin1("Software/Classes/") + progId;
- const QString classesFileType = QString::fromLatin1("Software/Classes/.%2").arg(extension);
- const QString classesApplications = QString::fromLatin1("Software/Classes/Applications/") + progId;
+ const QString classesProgId = QString::fromLatin1("Software/Classes/") + m_progId;
+ const QString classesFileType = QString::fromLatin1("Software/Classes/.%2").arg(args.at(0));
+ const QString classesApplications = QString::fromLatin1("Software/Classes/Applications/") + m_progId;
// backup old value
setValue(QLatin1String("oldType"), readHive(&settings, classesFileType));
// register new values
- settings.setValue(QString::fromLatin1("%1/Default").arg(classesFileType), progId);
- settings.setValue(QString::fromLatin1("%1/OpenWithProgIds/%2").arg(classesFileType, progId), QString());
+ settings.setValue(QString::fromLatin1("%1/Default").arg(classesFileType), m_progId);
+ settings.setValue(QString::fromLatin1("%1/OpenWithProgIds/%2").arg(classesFileType, m_progId), QString());
settings.setValue(QString::fromLatin1("%1/shell/Open/Command/Default").arg(classesProgId), args.at(1));
settings.setValue(QString::fromLatin1("%1/shell/Open/Command/Default").arg(classesApplications), args.at(1));
@@ -151,28 +146,23 @@ bool RegisterFileTypeOperation::performOperation()
bool RegisterFileTypeOperation::undoOperation()
{
#ifdef Q_OS_WIN
+ ensureOptionalArgumentsRead();
QStringList args = arguments();
- QString progId = takeProgIdArgument(args);
- if (args.count() < 2 || args.count() > 5) {
- setErrorString(tr("Register File Type: Invalid arguments"));
+ if (!checkArgumentCount(2, 5, tr("Register File Type: Invalid arguments")))
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")
, QSettingsWrapper::NativeFormat);
- const QString extension = args.at(0);
- if (progId.isEmpty())
- progId = QString::fromLatin1("%1_auto_file").arg(extension);
- const QString classesProgId = QString::fromLatin1("Software/Classes/") + progId;
- const QString classesFileType = QString::fromLatin1("Software/Classes/.%2").arg(extension);
- const QString classesApplications = QString::fromLatin1("Software/Classes/Applications/") + progId;
+ const QString classesProgId = QString::fromLatin1("Software/Classes/") + m_progId;
+ const QString classesFileType = QString::fromLatin1("Software/Classes/.%2").arg(args.at(0));
+ const QString classesApplications = QString::fromLatin1("Software/Classes/Applications/") + m_progId;
// Quoting MSDN here: When uninstalling an application, the ProgIDs and most other registry information
// associated with that application should be deleted as part of the uninstallation.However, applications
@@ -194,7 +184,7 @@ bool RegisterFileTypeOperation::undoOperation()
settings.endGroup();
} else {
// some changes happened, remove the only save value we know about
- settings.remove(QString::fromLatin1("%1/OpenWithProgIds/%2").arg(classesFileType, progId));
+ settings.remove(QString::fromLatin1("%1/OpenWithProgIds/%2").arg(classesFileType, m_progId));
}
// remove ProgId and Applications entry
@@ -216,7 +206,21 @@ bool RegisterFileTypeOperation::testOperation()
return true;
}
-Operation *RegisterFileTypeOperation::clone() const
+void RegisterFileTypeOperation::ensureOptionalArgumentsRead()
{
- return new RegisterFileTypeOperation();
+#ifdef Q_OS_WIN
+ if (m_optionalArgumentsRead)
+ return;
+
+ m_optionalArgumentsRead = true;
+
+ QStringList args = arguments();
+
+ m_progId = takeProgIdArgument(args);
+
+ if (m_progId.isEmpty() && args.count() > 0)
+ m_progId = QString::fromLatin1("%1_auto_file").arg(args.at(0));
+
+ setArguments(args);
+#endif
}
diff --git a/src/libs/installer/registerfiletypeoperation.h b/src/libs/installer/registerfiletypeoperation.h
index de82dedd5..8850ab44b 100644
--- a/src/libs/installer/registerfiletypeoperation.h
+++ b/src/libs/installer/registerfiletypeoperation.h
@@ -38,13 +38,18 @@ 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;
+
+private:
+ void ensureOptionalArgumentsRead();
+
+ bool m_optionalArgumentsRead;
+ QString m_progId;
};
}
diff --git a/src/libs/installer/remoteclient.cpp b/src/libs/installer/remoteclient.cpp
index 666cd813a..c6f5e535f 100644
--- a/src/libs/installer/remoteclient.cpp
+++ b/src/libs/installer/remoteclient.cpp
@@ -31,6 +31,8 @@
namespace QInstaller {
+RemoteClient *RemoteClient::s_instance = 0;
+
RemoteClient::RemoteClient()
: d_ptr(new RemoteClientPrivate(this))
{
@@ -42,8 +44,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
@@ -69,6 +72,12 @@ void RemoteClient::init(const QString &socketName, const QString &key, Protocol:
d->init(socketName, key, mode, startAs);
}
+void RemoteClient::setAuthorizationFallbackDisabled(bool disabled)
+{
+ Q_D(RemoteClient);
+ d->setAuthorizationFallbackDisabled(disabled);
+}
+
void RemoteClient::shutdown()
{
Q_D(RemoteClient);
@@ -76,6 +85,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 4d435098c..c2090bf98 100644
--- a/src/libs/installer/remoteclient.h
+++ b/src/libs/installer/remoteclient.h
@@ -47,8 +47,10 @@ public:
static RemoteClient &instance();
void init(const QString &socketName, const QString &key, Protocol::Mode mode,
Protocol::StartAs startAs);
+ void setAuthorizationFallbackDisabled(bool disabled);
void shutdown();
+ void destroy();
QString socketName() const;
QString authorizationKey() const;
@@ -61,6 +63,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 0afd9dc16..d1e873d43 100644
--- a/src/libs/installer/remoteclient_p.h
+++ b/src/libs/installer/remoteclient_p.h
@@ -59,6 +59,7 @@ public:
, m_active(false)
, m_key(QLatin1String(Protocol::DefaultAuthorizationKey))
, m_mode(Protocol::Mode::Debug)
+ , m_authorizationFallbackDisabled(false)
{
m_thread.setObjectName(QLatin1String("KeepAlive"));
}
@@ -101,6 +102,11 @@ public:
}
}
+ void setAuthorizationFallbackDisabled(bool disabled)
+ {
+ m_authorizationFallbackDisabled = disabled;
+ }
+
void maybeStartServer() {
if (m_mode == Protocol::Mode::Debug)
m_serverStarted = true; // we expect the server to be started by the developer
@@ -118,6 +124,16 @@ public:
started = AdminAuthorization::execute(0, m_serverCommand, m_serverArguments);
if (!started) {
+ if (m_authorizationFallbackDisabled) {
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
+ QLatin1String("AuthorizationError"),
+ QCoreApplication::translate("RemoteClient", "Cannot get authorization."),
+ QCoreApplication::translate("RemoteClient",
+ "Cannot get authorization that is needed for continuing the installation.\n\n"
+ "Please start the setup program as a user with the appropriate rights.\n"
+ "Or accept the elevation of access rights if being asked."));
+ return;
+ }
// something went wrong with authorizing, either user pressed cancel or entered
// wrong password
const QString fallback = m_serverCommand + QLatin1String(" ") + m_serverArguments
@@ -126,11 +142,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)
@@ -179,6 +195,7 @@ private:
QString m_key;
QThread m_thread;
Protocol::Mode m_mode;
+ bool m_authorizationFallbackDisabled;
};
} // namespace QInstaller
diff --git a/src/libs/installer/remoteobject.cpp b/src/libs/installer/remoteobject.cpp
index 69cc66e65..49c111610 100644
--- a/src/libs/installer/remoteobject.cpp
+++ b/src/libs/installer/remoteobject.cpp
@@ -30,7 +30,6 @@
#include "protocol.h"
#include "remoteclient.h"
-#include "localsocket.h"
#include <QCoreApplication>
#include <QElapsedTimer>
@@ -52,7 +51,8 @@ RemoteObject::~RemoteObject()
{
if (m_socket) {
if (QThread::currentThread() == m_socket->thread()) {
- writeData(QLatin1String(Protocol::Destroy), m_type, dummy, dummy);
+ if (m_type != QLatin1String("RemoteClientPrivate"))
+ writeData(QLatin1String(Protocol::Destroy), m_type, dummy, dummy);
} else {
Q_ASSERT_X(false, Q_FUNC_INFO, "Socket running in a different Thread than this object.");
}
@@ -68,7 +68,7 @@ bool RemoteObject::authorize()
if (m_socket)
delete m_socket;
- m_socket = new LocalSocket;
+ m_socket = new QLocalSocket;
m_socket->connectToServer(RemoteClient::instance().socketName());
if (m_socket->waitForConnected()) {
diff --git a/src/libs/installer/remoteobject.h b/src/libs/installer/remoteobject.h
index 832e3ccf3..ecd86c984 100644
--- a/src/libs/installer/remoteobject.h
+++ b/src/libs/installer/remoteobject.h
@@ -93,7 +93,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 3cd3d0248..9d178ca06 100644
--- a/src/libs/installer/remoteserver.cpp
+++ b/src/libs/installer/remoteserver.cpp
@@ -75,13 +75,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 2660f1219..e39350f2f 100644
--- a/src/libs/installer/remoteserver_p.h
+++ b/src/libs/installer/remoteserver_p.h
@@ -79,9 +79,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.cpp b/src/libs/installer/remoteserverconnection.cpp
index 5236657e2..61bacc0c5 100644
--- a/src/libs/installer/remoteserverconnection.cpp
+++ b/src/libs/installer/remoteserverconnection.cpp
@@ -33,7 +33,6 @@
#include "remoteserverconnection_p.h"
#include "utils.h"
#include "permissionsettings.h"
-#include "localsocket.h"
#include <QCoreApplication>
#include <QDataStream>
@@ -66,7 +65,7 @@ private:
void RemoteServerConnection::run()
{
- LocalSocket socket;
+ QLocalSocket socket;
socket.setSocketDescriptor(m_socketDescriptor);
QScopedPointer<PermissionSettings> settings;
@@ -144,11 +143,11 @@ void RemoteServerConnection::run()
stream >> type;
if (type == QLatin1String(Protocol::QSettings)) {
settings.reset();
- } else if (command == QLatin1String(Protocol::QProcess)) {
+ } else if (type == QLatin1String(Protocol::QProcess)) {
m_signalReceiver->m_receivedSignals.clear();
m_process->deleteLater();
m_process = 0;
- } else if (command == QLatin1String(Protocol::QAbstractFileEngine)) {
+ } else if (type == QLatin1String(Protocol::QAbstractFileEngine)) {
delete m_engine;
m_engine = 0;
}
diff --git a/src/libs/installer/remoteserverconnection_p.h b/src/libs/installer/remoteserverconnection_p.h
index d8334d566..dad5f4133 100644
--- a/src/libs/installer/remoteserverconnection_p.h
+++ b/src/libs/installer/remoteserverconnection_p.h
@@ -46,19 +46,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 946711feb..8cc1e0315 100644
--- a/src/libs/installer/replaceoperation.cpp
+++ b/src/libs/installer/replaceoperation.cpp
@@ -34,7 +34,8 @@
using namespace QInstaller;
-ReplaceOperation::ReplaceOperation()
+ReplaceOperation::ReplaceOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Replace"));
}
@@ -45,18 +46,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);
@@ -64,7 +61,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;
}
@@ -74,7 +72,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;
}
@@ -95,8 +94,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 0ad614697..0d2783ab6 100644
--- a/src/libs/installer/replaceoperation.h
+++ b/src/libs/installer/replaceoperation.h
@@ -37,13 +37,12 @@ class INSTALLER_EXPORT ReplaceOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::ReplaceOperation)
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 0bfa23a96..eb45573a9 100644
--- a/src/libs/installer/repository.cpp
+++ b/src/libs/installer/repository.cpp
@@ -27,7 +27,7 @@
**************************************************************************/
#include "repository.h"
-#include "kdupdaterfiledownloaderfactory.h"
+#include "filedownloaderfactory.h"
#include <QDataStream>
#include <QFileInfo>
@@ -41,6 +41,7 @@ namespace QInstaller {
Repository::Repository()
: m_default(false)
, m_enabled(false)
+ , m_compressed(false)
{
registerMetaType();
}
@@ -55,28 +56,31 @@ Repository::Repository(const Repository &other)
, m_username(other.m_username)
, m_password(other.m_password)
, m_displayname(other.m_displayname)
+ , m_compressed(other.m_compressed)
{
registerMetaType();
}
/*!
- Constructs a new repository by setting its address to \a url and its default state.
+ Constructs a new repository by setting its address to \a url
+ and its default and \a compressed states.
*/
-Repository::Repository(const QUrl &url, bool isDefault)
+Repository::Repository(const QUrl &url, bool isDefault, bool compressed)
: m_url(url)
, m_default(isDefault)
, m_enabled(true)
+ , m_compressed(compressed)
{
registerMetaType();
}
/*!
- Constructs a new repository by setting its address to \a repositoryUrl as string and its
- default state.
+ Constructs a new repository by setting its address to \a repositoryUrl as
+ string and its \a compressed state.
Note: user and password can be inside the \a repositoryUrl string: http://user:password@repository.url
*/
-Repository Repository::fromUserInput(const QString &repositoryUrl)
+Repository Repository::fromUserInput(const QString &repositoryUrl, bool compressed)
{
QUrl url = QUrl::fromUserInput(repositoryUrl);
const QStringList supportedSchemes = KDUpdater::FileDownloaderFactory::supportedSchemes();
@@ -88,7 +92,7 @@ Repository Repository::fromUserInput(const QString &repositoryUrl)
url.setUserName(QString());
url.setPassword(QString());
- Repository repository(url, false);
+ Repository repository(url, false, compressed);
repository.setUsername(userName);
repository.setPassword(password);
return repository;
@@ -195,6 +199,22 @@ void Repository::setDisplayName(const QString &displayname)
}
/*!
+ Returns true if repository is compressed
+*/
+bool Repository::isCompressed() const
+{
+ return m_compressed;
+}
+
+/*!
+ Sets this repository to \a compressed state to know weather the repository
+ needs to be uncompressed before use.
+*/
+void Repository::setCompressed(bool compressed)
+{
+ m_compressed = compressed;
+}
+/*!
Compares the values of this repository to \a other and returns true if they are equal (same server,
default state, enabled state as well as username and password). \sa operator!=()
*/
@@ -227,6 +247,7 @@ const Repository &Repository::operator=(const Repository &other)
m_username = other.m_username;
m_password = other.m_password;
m_displayname = other.m_displayname;
+ m_compressed = other.m_compressed;
return *this;
}
@@ -239,7 +260,7 @@ void Repository::registerMetaType()
QDataStream &operator>>(QDataStream &istream, Repository &repository)
{
- QByteArray url, username, password, displayname;
+ QByteArray url, username, password, displayname, compressed;
istream >> url >> repository.m_default >> repository.m_enabled >> username >> password >> displayname;
repository.setUrl(QUrl::fromEncoded(QByteArray::fromBase64(url)));
repository.setUsername(QString::fromUtf8(QByteArray::fromBase64(username)));
diff --git a/src/libs/installer/repository.h b/src/libs/installer/repository.h
index 89b18f612..b73e7bd4c 100644
--- a/src/libs/installer/repository.h
+++ b/src/libs/installer/repository.h
@@ -41,10 +41,10 @@ class INSTALLER_EXPORT Repository
public:
explicit Repository();
Repository(const Repository &other);
- explicit Repository(const QUrl &url, bool isDefault);
+ explicit Repository(const QUrl &url, bool isDefault, bool compressed = false);
static void registerMetaType();
- static Repository fromUserInput(const QString &repositoryUrl);
+ static Repository fromUserInput(const QString &repositoryUrl, bool compressed = false);
bool isValid() const;
bool isDefault() const;
@@ -64,6 +64,8 @@ public:
QString displayname() const;
void setDisplayName(const QString &displayname);
+ bool isCompressed() const;
+ void setCompressed(bool compressed);
bool operator==(const Repository &other) const;
bool operator!=(const Repository &other) const;
@@ -80,6 +82,7 @@ private:
QString m_username;
QString m_password;
QString m_displayname;
+ bool m_compressed;
};
inline uint qHash(const Repository &repository)
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 d099ba218..59f71a52c 100644
--- a/src/libs/installer/scriptengine.cpp
+++ b/src/libs/installer/scriptengine.cpp
@@ -198,6 +198,21 @@ 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::setTextItems(QObject *object, const QStringList &items)
+{
+ if (m_gui)
+ m_gui->setTextItems(object, items);
+}
+
void GuiProxy::cancelButtonClicked()
{
if (m_gui)
@@ -260,7 +275,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));
}
@@ -366,7 +381,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()));
}
@@ -384,9 +399,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 2d76912d4..7af5cbab8 100644
--- a/src/libs/installer/scriptengine_p.h
+++ b/src/libs/installer/scriptengine_p.h
@@ -49,7 +49,7 @@ public:
ConsoleProxy() {}
public slots :
- void log(const QString &log) { qDebug() << log; }
+ void log(const QString &log) { qDebug().noquote() << log; }
};
class InstallerProxy : public QObject
@@ -153,6 +153,10 @@ 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);
+
+ Q_INVOKABLE void setTextItems(QObject *object, const QStringList &items);
+
signals:
void interrupted();
void languageChanged();
diff --git a/src/libs/installer/selfrestartoperation.cpp b/src/libs/installer/selfrestartoperation.cpp
index 1d7c16f23..586e5bb0b 100644
--- a/src/libs/installer/selfrestartoperation.cpp
+++ b/src/libs/installer/selfrestartoperation.cpp
@@ -29,30 +29,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;
@@ -63,13 +64,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;
}
@@ -77,8 +78,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 54a05f3d1..7adccd183 100644
--- a/src/libs/installer/selfrestartoperation.h
+++ b/src/libs/installer/selfrestartoperation.h
@@ -37,13 +37,12 @@ class INSTALLER_EXPORT SelfRestartOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::SelfRestartOperation)
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 95f32afbf..79d4bcddc 100644
--- a/src/libs/installer/settings.cpp
+++ b/src/libs/installer/settings.cpp
@@ -33,6 +33,8 @@
#include <QtCore/QFileInfo>
#include <QtCore/QStringList>
+#include <QtGui/QFontMetrics>
+#include <QtWidgets/QApplication>
#include <QRegularExpression>
#include <QXmlStreamReader>
@@ -56,6 +58,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");
@@ -79,9 +82,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));
}
@@ -97,7 +101,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 {
@@ -105,7 +109,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;
}
@@ -147,23 +151,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);
}
}
@@ -230,12 +234,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()));
}
}
@@ -247,26 +251,27 @@ Settings Settings::fromFileAndPrefix(const QString &path, const QString &prefix,
<< scStartMenuDir << scMaintenanceToolName << scMaintenanceToolIniFile << scRemoveTargetDir
<< scRunProgram << scRunProgramArguments << scRunProgramDescription
<< scDependsOnLocalInstallerBinary
- << scAllowSpaceInPath << scAllowNonAsciiCharacters << scWizardStyle << scTitleColor
+ << scAllowSpaceInPath << scAllowNonAsciiCharacters << scDisableAuthorizationFallback
+ << scWizardStyle << scStyleSheet << scTitleColor
<< scWizardDefaultWidth << scWizardDefaultHeight
<< scRepositorySettingsPageVisible << scTargetConfigurationFile
- << scRemoteRepositories << scTranslations << QLatin1String(scControlScript)
- << scCreateLocalRepository;
+ << scRemoteRepositories << scTranslations << scUrlQueryString << QLatin1String(scControlScript)
+ << scCreateLocalRepository << scInstallActionColumnVisible << scSupportsModify;
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));
@@ -318,6 +323,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;
}
@@ -372,19 +379,41 @@ 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();
}
+static int lengthToInt(const QVariant &variant)
+{
+ QString length = variant.toString().trimmed();
+ if (length.endsWith(QLatin1String("em"), Qt::CaseInsensitive)) {
+ length.chop(2);
+ return qRound(length.toDouble() * QApplication::fontMetrics().height());
+ }
+ if (length.endsWith(QLatin1String("ex"), Qt::CaseInsensitive)) {
+ length.chop(2);
+ return qRound(length.toDouble() * QApplication::fontMetrics().xHeight());
+ }
+ if (length.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) {
+ length.chop(2);
+ }
+ return length.toInt();
+}
+
int Settings::wizardDefaultWidth() const
{
- return d->m_data.value(scWizardDefaultWidth).toInt();
+ return lengthToInt(d->m_data.value(scWizardDefaultWidth));
}
int Settings::wizardDefaultHeight() const
{
- return d->m_data.value(scWizardDefaultHeight).toInt();
+ return lengthToInt(d->m_data.value(scWizardDefaultHeight));
}
QString Settings::installerApplicationIcon() const
@@ -472,6 +501,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();
@@ -482,6 +516,11 @@ bool Settings::allowNonAsciiCharacters() const
return d->m_data.value(scAllowNonAsciiCharacters, false).toBool();
}
+bool Settings::disableAuthorizationFallback() const
+{
+ return d->m_data.value(scDisableAuthorizationFallback, false).toBool();
+}
+
bool Settings::dependsOnLocalInstallerBinary() const
{
return d->m_data.value(scDependsOnLocalInstallerBinary).toBool();
@@ -699,3 +738,8 @@ QString Settings::controlScript() const
{
return d->m_data.value(QLatin1String(scControlScript)).toString();
}
+
+bool Settings::supportsModify() const
+{
+ return d->m_data.value(scSupportsModify, true).toBool();
+}
diff --git a/src/libs/installer/settings.h b/src/libs/installer/settings.h
index 0fa938167..3dc1c99c3 100644
--- a/src/libs/installer/settings.h
+++ b/src/libs/installer/settings.h
@@ -83,6 +83,7 @@ public:
QString installerWindowIcon() const;
QString systemIconSuffix() const;
QString wizardStyle() const;
+ QString styleSheet() const;
QString titleColor() const;
int wizardDefaultWidth() const;
int wizardDefaultHeight() const;
@@ -106,6 +107,7 @@ public:
QString configurationFileName() const;
bool createLocalRepository() const;
+ bool installActionColumnVisible() const;
bool dependsOnLocalInstallerBinary() const;
bool hasReplacementRepos() const;
@@ -127,6 +129,7 @@ public:
bool allowSpaceInPath() const;
bool allowNonAsciiCharacters() const;
+ bool disableAuthorizationFallback() const;
bool containsValue(const QString &key) const;
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
@@ -149,6 +152,8 @@ public:
QString controlScript() const;
+ bool supportsModify() const;
+
private:
class Private;
QSharedDataPointer<Private> d;
diff --git a/src/libs/installer/settingsoperation.cpp b/src/libs/installer/settingsoperation.cpp
index 53a5e8c8a..e6d88b71e 100644
--- a/src/libs/installer/settingsoperation.cpp
+++ b/src/libs/installer/settingsoperation.cpp
@@ -27,7 +27,7 @@
**************************************************************************/
#include "settingsoperation.h"
#include "packagemanagercore.h"
-#include "kdupdaterupdateoperations.h"
+#include "updateoperations.h"
#include "qsettingswrapper.h"
#include <QDir>
@@ -35,7 +35,8 @@
using namespace QInstaller;
-SettingsOperation::SettingsOperation()
+SettingsOperation::SettingsOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Settings"));
}
@@ -63,7 +64,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;
}
@@ -73,7 +74,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;
@@ -177,14 +178,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();
}
}
}
@@ -195,9 +196,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 14b0eb169..0b94ea015 100644
--- a/src/libs/installer/settingsoperation.h
+++ b/src/libs/installer/settingsoperation.h
@@ -37,13 +37,12 @@ class INSTALLER_EXPORT SettingsOperation : public Operation
{
Q_DECLARE_TR_FUNCTIONS(QInstaller::SettingsOperation)
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 5f6ea4ff3..d5cbde2ee 100644
--- a/src/libs/installer/simplemovefileoperation.cpp
+++ b/src/libs/installer/simplemovefileoperation.cpp
@@ -28,11 +28,13 @@
#include "simplemovefileoperation.h"
+#include <QDir>
#include <QtCore/QFileInfo>
namespace QInstaller {
-SimpleMoveFileOperation::SimpleMoveFileOperation()
+SimpleMoveFileOperation::SimpleMoveFileOperation(PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("SimpleMoveFile"));
}
@@ -43,21 +45,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;
}
@@ -67,8 +65,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;
}
}
@@ -76,12 +74,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;
}
@@ -91,7 +91,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;
}
@@ -101,9 +102,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 9b2ea2603..26cb5c462 100644
--- a/src/libs/installer/simplemovefileoperation.h
+++ b/src/libs/installer/simplemovefileoperation.h
@@ -40,13 +40,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 de1318295..69c1744ca 100644
--- a/src/libs/installer/sysinfo_win.cpp
+++ b/src/libs/installer/sysinfo_win.cpp
@@ -26,7 +26,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 a3e8ce9c3..4ee2d41ae 100644
--- a/src/libs/installer/testrepository.cpp
+++ b/src/libs/installer/testrepository.cpp
@@ -27,26 +27,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
@@ -56,100 +59,127 @@ 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;
- if (m_downloader->isDownloaded()) {
- QFile file(m_downloader->downloadedFileName());
- if (file.exists() && file.open(QIODevice::ReadOnly)) {
+ try {
+ m_xmlTask.waitForFinished();
+
+ 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);
+ } else {
+ QMetaObject::invokeMethod(this, "doCancel", 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 43165560d..80d964692 100644
--- a/src/libs/installer/testrepository.h
+++ b/src/libs/installer/testrepository.h
@@ -28,55 +28,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 4b78b6d6e..f1f0dd0a1 100644
--- a/src/libs/installer/unziptask.cpp
+++ b/src/libs/installer/unziptask.cpp
@@ -25,7 +25,9 @@
** $QT_END_LICENSE$
**
**************************************************************************/
+
#include "unziptask.h"
+#include "lib7z_facade.h"
#ifdef Q_OS_UNIX
# include "StdAfx.h"
@@ -34,21 +36,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
@@ -99,11 +95,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)
@@ -149,7 +145,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;
@@ -157,7 +153,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);
@@ -234,13 +230,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)
@@ -251,19 +241,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)
@@ -272,7 +272,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/installer/utils.cpp b/src/libs/installer/utils.cpp
index d76eab696..a11ac774e 100644
--- a/src/libs/installer/utils.cpp
+++ b/src/libs/installer/utils.cpp
@@ -214,24 +214,40 @@ QInstaller::VerboseWriter::VerboseWriter()
QInstaller::VerboseWriter::~VerboseWriter()
{
+ if (preFileBuffer.isOpen()) {
+ PlainVerboseWriterOutput output;
+ (void)flush(&output);
+ }
+}
+
+bool QInstaller::VerboseWriter::flush(VerboseWriterOutput *output)
+{
stream.flush();
if (logFileName.isEmpty()) // binarycreator
- return;
+ return true;
+ if (!preFileBuffer.isOpen())
+ return true;
//if the installer installed nothing - there is no target directory - where the logfile can be saved
if (!QFileInfo(logFileName).absoluteDir().exists())
- return;
-
- QFile output(logFileName);
- if (output.open(QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text)) {
- QString logInfo;
- logInfo += QLatin1String("************************************* Invoked: ");
- logInfo += currentDateTimeAsString;
- logInfo += QLatin1String("\n");
- output.write(logInfo.toLocal8Bit());
- output.write(preFileBuffer.data());
- output.close();
+ return true;
+
+ QString logInfo;
+ logInfo += QLatin1String("************************************* Invoked: ");
+ logInfo += currentDateTimeAsString;
+ logInfo += QLatin1String("\n");
+
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ buffer.write(logInfo.toLocal8Bit());
+ buffer.write(preFileBuffer.data());
+ buffer.close();
+
+ if (output->write(logFileName, QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text, buffer.data())) {
+ preFileBuffer.close();
+ stream.setDevice(0);
+ return true;
}
- stream.setDevice(0);
+ return false;
}
void QInstaller::VerboseWriter::setFileName(const QString &fileName)
@@ -252,6 +268,20 @@ void QInstaller::VerboseWriter::appendLine(const QString &msg)
stream << msg << endl;
}
+QInstaller::VerboseWriterOutput::~VerboseWriterOutput()
+{
+}
+
+bool QInstaller::PlainVerboseWriterOutput::write(const QString &fileName, QIODevice::OpenMode openMode, const QByteArray &data)
+{
+ QFile output(fileName);
+ if (output.open(openMode)) {
+ output.write(data);
+ return true;
+ }
+ return false;
+}
+
#ifdef Q_OS_WIN
// taken from qcoreapplication_p.h
template<typename Char>
diff --git a/src/libs/installer/utils.h b/src/libs/installer/utils.h
index cfaeaa67d..7cd237dcc 100644
--- a/src/libs/installer/utils.h
+++ b/src/libs/installer/utils.h
@@ -67,6 +67,20 @@ namespace QInstaller {
INSTALLER_EXPORT std::ostream& operator<<(std::ostream &os, const QString &string);
+ class INSTALLER_EXPORT VerboseWriterOutput
+ {
+ public:
+ virtual bool write(const QString &fileName, QIODevice::OpenMode openMode, const QByteArray &data) = 0;
+
+ protected:
+ ~VerboseWriterOutput();
+ };
+
+ class INSTALLER_EXPORT PlainVerboseWriterOutput : public VerboseWriterOutput
+ {
+ public:
+ virtual bool write(const QString &fileName, QIODevice::OpenMode openMode, const QByteArray &data);
+ };
class INSTALLER_EXPORT VerboseWriter
{
@@ -76,6 +90,8 @@ namespace QInstaller {
static VerboseWriter *instance();
+ bool flush(VerboseWriterOutput *output);
+
void appendLine(const QString &msg);
void setFileName(const QString &fileName);
diff --git a/src/libs/kdtools/environment.h b/src/libs/kdtools/environment.h
index 37412e483..13802df64 100644
--- a/src/libs/kdtools/environment.h
+++ b/src/libs/kdtools/environment.h
@@ -26,8 +26,8 @@
**
****************************************************************************/
-#ifndef LIBINSTALLER_ENVIRONMENT_H
-#define LIBINSTALLER_ENVIRONMENT_H
+#ifndef ENVIRONMENT_H
+#define ENVIRONMENT_H
#include "kdtoolsglobal.h"
@@ -64,4 +64,4 @@ private:
} // namespace KDUpdater
-#endif
+#endif // ENVIRONMENT_H
diff --git a/src/libs/kdtools/kdupdaterfiledownloader.cpp b/src/libs/kdtools/filedownloader.cpp
index 28ef4b4bb..1a0a8f1c2 100644
--- a/src/libs/kdtools/kdupdaterfiledownloader.cpp
+++ b/src/libs/kdtools/filedownloader.cpp
@@ -26,13 +26,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>
@@ -45,6 +46,9 @@
#include <QSslError>
#include <QBasicTimer>
#include <QTimerEvent>
+#include <QLoggingCategory>
+#include <globals.h>
+#include <QHostInfo>
using namespace KDUpdater;
using namespace QInstaller;
@@ -690,8 +694,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;
}
@@ -706,8 +710,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;
}
@@ -779,8 +783,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;
@@ -969,7 +974,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;
}
@@ -1053,7 +1058,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();
@@ -1071,11 +1076,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);
}
/*!
@@ -1157,7 +1162,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;
}
@@ -1247,7 +1252,19 @@ void KDUpdater::HttpDownloader::httpReqFinished()
} else {
if (d->http == 0)
return;
-
+ const QUrl url = d->http->url();
+ if (url.isValid() && QInstaller::lcNetwork().isDebugEnabled()){
+ const QFileInfo fi(d->http->url().toString());
+ if (fi.suffix() != QLatin1String("sha1")){
+ const QString hostName = url.host();
+ QHostInfo info = QHostInfo::fromName(hostName);
+ QStringList hostAddresses;
+ foreach (const QHostAddress &address, info.addresses())
+ hostAddresses << address.toString();
+ qCDebug(QInstaller::lcNetwork) << "Using host:" << hostName
+ << "for" << url.fileName() << "\nIP:" << hostAddresses;
+ }
+ }
httpReadyRead();
d->destination->flush();
setDownloadCompleted();
@@ -1287,12 +1304,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);
@@ -1307,7 +1324,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 c815d977b..8c73cbeb0 100644
--- a/src/libs/kdtools/kdupdaterfiledownloader.h
+++ b/src/libs/kdtools/filedownloader.h
@@ -26,8 +26,8 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_FILE_DOWNLOADER_H
-#define KD_UPDATER_FILE_DOWNLOADER_H
+#ifndef FILEDOWNLOADER_H
+#define FILEDOWNLOADER_H
#include "kdtoolsglobal.h"
@@ -104,10 +104,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);
@@ -142,4 +138,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 522d93fd6..f5a80c432 100644
--- a/src/libs/kdtools/kdupdaterfiledownloader_p.h
+++ b/src/libs/kdtools/filedownloader_p.h
@@ -26,10 +26,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>
@@ -141,4 +141,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 76f196fad..7350df6e3 100644
--- a/src/libs/kdtools/kdupdaterfiledownloaderfactory.cpp
+++ b/src/libs/kdtools/filedownloaderfactory.cpp
@@ -26,8 +26,8 @@
**
****************************************************************************/
-#include "kdupdaterfiledownloaderfactory.h"
-#include "kdupdaterfiledownloader_p.h"
+#include "filedownloaderfactory.h"
+#include "filedownloader_p.h"
#include <QtNetwork/QSslSocket>
@@ -68,7 +68,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;
@@ -149,10 +149,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 236ad3b67..d20e7d213 100644
--- a/src/libs/kdtools/kdupdaterfiledownloaderfactory.h
+++ b/src/libs/kdtools/filedownloaderfactory.h
@@ -26,11 +26,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>
@@ -52,7 +52,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 {
@@ -97,4 +98,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 5c5ef446a..426aa1198 100644
--- a/src/libs/kdtools/kdjob.cpp
+++ b/src/libs/kdtools/job.cpp
@@ -26,30 +26,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()
@@ -78,7 +78,7 @@ public:
int error;
QString errorString;
- KDJob::Capabilities caps;
+ Job::Capabilities caps;
bool autoDelete;
quint64 totalAmount;
quint64 processedAmount;
@@ -87,93 +87,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();
@@ -187,44 +187,42 @@ 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;
d->totalAmount = amount;
- emit progress(this, d->processedAmount, d->totalAmount);
+ emit totalProgress(d->totalAmount);
}
/*!
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;
@@ -232,11 +230,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 3afb5b570..200650259 100644
--- a/src/libs/kdtools/kdjob.h
+++ b/src/libs/kdtools/job.h
@@ -26,14 +26,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;
@@ -42,8 +42,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,
@@ -81,11 +81,12 @@ 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);
+ void totalProgress(quint64 total);
protected:
virtual void doStart() = 0;
@@ -110,6 +111,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 105cca66a..000000000
--- a/src/libs/kdtools/kdgenericfactory.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $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 f1ecf5845..000000000
--- a/src/libs/kdtools/kdgenericfactory.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $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 ad845497b..0aa7e7aa3 100644
--- a/src/libs/kdtools/kdsysinfo_win.cpp
+++ b/src/libs/kdtools/kdsysinfo_win.cpp
@@ -26,7 +26,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 bbfc9afbf..fc30de1cb 100644
--- a/src/libs/kdtools/kdtoolsglobal.h
+++ b/src/libs/kdtools/kdtoolsglobal.h
@@ -26,8 +26,8 @@
**
****************************************************************************/
-#ifndef KDTOOLS_KDTOOLSGLOBAL_H
-#define KDTOOLS_KDTOOLSGLOBAL_H
+#ifndef KDTOOLSGLOBAL_H
+#define KDTOOLSGLOBAL_H
#include <QtCore/QtGlobal>
@@ -41,5 +41,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 f3c20b7cc..000000000
--- a/src/libs/kdtools/kdupdaterapplication.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $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 7d60fb801..000000000
--- a/src/libs/kdtools/kdupdaterapplication.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $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 f6a9d509d..000000000
--- a/src/libs/kdtools/kdupdaterupdatesourcesinfo.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $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 baf9c7cf2..000000000
--- a/src/libs/kdtools/kdupdaterupdatesourcesinfo.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Installer Framework.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $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 7b8e830d2..6ac3da803 100644
--- a/src/libs/kdtools/kdupdaterpackagesinfo.cpp
+++ b/src/libs/kdtools/localpackagehub.cpp
@@ -1,7 +1,8 @@
/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
**
@@ -26,20 +27,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()
@@ -50,14 +52,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.
@@ -71,64 +69,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
{
- if (!d->fileName.isEmpty())
- return d->error <= NotYetReadError;
- return d->error == NoError;
+ return d->error <= NotYetReadError;
+}
+
+/*!
+ Returns a list of all local installed packages.
+*/
+QStringList LocalPackageHub::packageNames() const
+{
+ 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;
}
@@ -137,7 +142,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;
}
@@ -145,10 +150,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;
@@ -160,7 +163,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;
}
@@ -169,7 +172,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;
}
@@ -177,7 +180,7 @@ void PackagesInfo::setApplicationName(const QString &name)
/*!
Returns the application name.
*/
-QString PackagesInfo::applicationName() const
+QString LocalPackageHub::applicationName() const
{
return d->applicationName;
}
@@ -186,7 +189,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;
}
@@ -194,51 +197,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
+LocalPackage LocalPackageHub::packageInfo(const QString &pkgName) 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
-{
- 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();
}
/*!
@@ -246,12 +232,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);
@@ -260,15 +246,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;
}
@@ -284,7 +268,6 @@ void PackagesInfo::refresh()
QString::number(parseErrorLine),
QString::number(parseErrorColumn),
parseErrorMessage);
- emit reset();
return;
}
file.close();
@@ -292,8 +275,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;
}
@@ -314,74 +297,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)
-{
- 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)
+ \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)
{
- 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;
}
@@ -404,9 +378,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);
@@ -414,11 +388,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())
@@ -426,20 +399,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);
}
@@ -455,7 +431,7 @@ void PackagesInfo::writeToDisk()
}
}
-void PackagesInfo::PackagesInfoData::addPackageFrom(const QDomElement &packageE)
+void LocalPackageHub::PackagesInfoData::addPackageFrom(const QDomElement &packageE)
{
if (packageE.isNull())
return;
@@ -464,9 +440,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();
@@ -475,8 +452,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"))
@@ -492,38 +467,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>
@@ -531,30 +502,26 @@ void PackagesInfo::clearPackageInfoList()
*/
/*!
- \variable PackageInfo::name
+ \variable LocalPackage::name
\brief The name of the package.
*/
/*!
- \variable PackageInfo::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 91e078510..f5c7b7623 100644
--- a/src/libs/kdtools/kdupdaterpackagesinfo.h
+++ b/src/libs/kdtools/localpackagehub.h
@@ -1,7 +1,8 @@
/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
**
@@ -26,42 +27,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
{
@@ -73,42 +74,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;
@@ -117,4 +117,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 667d3cbc2..a1a2c82a9 100644
--- a/src/libs/kdtools/kdlockfile.cpp
+++ b/src/libs/kdtools/lockfile.cpp
@@ -27,30 +27,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 3957a90c2..b3ca0afef 100644
--- a/src/libs/kdtools/kdlockfile.h
+++ b/src/libs/kdtools/lockfile.h
@@ -27,18 +27,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;
@@ -50,4 +52,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 6c2d3894e..de02ccf7a 100644
--- a/src/libs/kdtools/kdlockfile_p.h
+++ b/src/libs/kdtools/lockfile_p.h
@@ -27,10 +27,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>
@@ -38,7 +38,9 @@
# include <qt_windows.h>
#endif
-class KDLockFile::Private
+namespace KDUpdater {
+
+class LockFile::Private
{
public:
explicit Private(const QString& name)
@@ -62,4 +64,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 28eb20ae7..bb978c40f 100644
--- a/src/libs/kdtools/kdlockfile_unix.cpp
+++ b/src/libs/kdtools/lockfile_unix.cpp
@@ -27,15 +27,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;
@@ -44,8 +47,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());
@@ -55,8 +58,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;
@@ -64,13 +67,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)
@@ -79,10 +82,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 6ff9eec9a..20961cc4e 100644
--- a/src/libs/kdtools/kdlockfile_win.cpp
+++ b/src/libs/kdtools/lockfile_win.cpp
@@ -27,15 +27,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;
@@ -46,41 +49,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 d5712091e..91161ba8e 100644
--- a/src/libs/kdtools/kdrunoncechecker.cpp
+++ b/src/libs/kdtools/runoncechecker.cpp
@@ -27,9 +27,9 @@
**
****************************************************************************/
-#include "kdrunoncechecker.h"
-#include "kdlockfile.h"
-#include "kdsysinfo.h"
+#include "runoncechecker.h"
+#include "lockfile.h"
+#include "sysinfo.h"
#include <QCoreApplication>
#include <QDebug>
@@ -41,15 +41,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
@@ -85,7 +85,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();
@@ -97,7 +97,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 b282f15dd..abd4f7114 100644
--- a/src/libs/kdtools/kdrunoncechecker.h
+++ b/src/libs/kdtools/runoncechecker.h
@@ -27,16 +27,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 {
@@ -45,13 +45,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 af138dffc..e94d0fea7 100644
--- a/src/libs/kdtools/kdselfrestarter.cpp
+++ b/src/libs/kdtools/selfrestarter.cpp
@@ -26,13 +26,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[])
@@ -61,33 +61,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 789b68385..d6fde2f32 100644
--- a/src/libs/kdtools/kdselfrestarter.h
+++ b/src/libs/kdtools/selfrestarter.h
@@ -26,24 +26,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 3d8b006ec..871596c7c 100644
--- a/src/libs/kdtools/kdsysinfo.cpp
+++ b/src/libs/kdtools/sysinfo.cpp
@@ -26,7 +26,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 11901b14f..127791fef 100644
--- a/src/libs/kdtools/kdsysinfo.h
+++ b/src/libs/kdtools/sysinfo.h
@@ -26,10 +26,10 @@
**
****************************************************************************/
-#ifndef KDSYSINFO_H
-#define KDSYSINFO_H
+#ifndef SYSINFO_H
+#define SYSINFO_H
-#include <kdtoolsglobal.h>
+#include "kdtoolsglobal.h"
#include <QtCore/QString>
@@ -88,4 +88,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 04afc1138..6bdb16ac5 100644
--- a/src/libs/kdtools/kdsysinfo_mac.cpp
+++ b/src/libs/kdtools/sysinfo_mac.cpp
@@ -26,7 +26,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 a08b6f093..3099a369a 100644
--- a/src/libs/kdtools/kdsysinfo_x11.cpp
+++ b/src/libs/kdtools/sysinfo_x11.cpp
@@ -26,7 +26,7 @@
**
****************************************************************************/
-#include "kdsysinfo.h"
+#include "sysinfo.h"
#include <sys/utsname.h>
#include <sys/statvfs.h>
@@ -80,7 +80,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 b6db999dc..80bbcbd52 100644
--- a/src/libs/kdtools/kdupdatertask.cpp
+++ b/src/libs/kdtools/task.cpp
@@ -26,7 +26,7 @@
**
****************************************************************************/
-#include "kdupdatertask.h"
+#include "task.h"
using namespace KDUpdater;
@@ -178,7 +178,7 @@ void Task::run()
return;
}
- if (m_finished || m_stopped) {
+ if (m_stopped) {
qDebug("Trying to start a finished or canceled task");
return;
}
diff --git a/src/libs/kdtools/kdupdatertask.h b/src/libs/kdtools/task.h
index 92a9898f1..ca492ce9f 100644
--- a/src/libs/kdtools/kdupdatertask.h
+++ b/src/libs/kdtools/task.h
@@ -26,10 +26,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>
@@ -111,4 +111,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 6b8b52c9b..63c515276 100644
--- a/src/libs/kdtools/kdupdaterupdate.cpp
+++ b/src/libs/kdtools/update.cpp
@@ -26,7 +26,7 @@
**
****************************************************************************/
-#include "kdupdaterupdate.h"
+#include "update.h"
using namespace KDUpdater;
@@ -46,10 +46,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)
{
}
@@ -59,22 +58,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 e17773ce4..639f46ba6 100644
--- a/src/libs/kdtools/kdupdaterupdate.h
+++ b/src/libs/kdtools/update.h
@@ -26,11 +26,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 {
@@ -40,19 +40,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 e8bafcac5..ec1be8a4e 100644
--- a/src/libs/kdtools/kdupdaterupdatefinder.cpp
+++ b/src/libs/kdtools/updatefinder.cpp
@@ -1,7 +1,8 @@
/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
**
@@ -26,14 +27,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"
@@ -43,16 +42,17 @@
#include <QRegExp>
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.
*/
//
@@ -69,7 +69,6 @@ public:
Private(UpdateFinder *qq)
: q(qq)
- , application(0)
, downloadCompleteCount(0)
, m_downloadsToComplete(0)
{}
@@ -82,14 +81,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.
@@ -105,9 +103,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;
};
@@ -147,7 +148,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
@@ -155,7 +156,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.
@@ -168,28 +169,25 @@ void UpdateFinder::Private::computeUpdates()
// 1. Downloading Update XML files from all the update sources
// 2. Matching updates with Package XML and figuring out available updates
- clear();
+ if (!q->isCompressedPackage())
+ clear();
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;
}
@@ -242,18 +240,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);
@@ -301,8 +290,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());
}
@@ -347,7 +336,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
@@ -371,7 +360,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;
@@ -386,17 +375,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;
@@ -405,7 +396,8 @@ 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));
+ if (!q->isCompressedPackage() || value == Resolution::AddPackage)
+ updates.insert(name, new Update(source, info));
}
}
@@ -415,7 +407,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)) {
@@ -426,23 +418,27 @@ 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;
+ }
+ if (q->isCompressedPackage() && match == 0 && source.priority == existingPackage->packageSource().priority) {
+ //Same package with the same priority and version already exists
return Resolution::RemoveExisting;
}
return Resolution::KeepExisting; // otherwise keep existing
@@ -455,14 +451,13 @@ 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),
+ m_compressedPackage(false),
d(new Private(this))
{
- d->application = application;
}
/*!
@@ -474,14 +469,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
@@ -632,4 +639,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 8aa992d36..47fa42c9a 100644
--- a/src/libs/kdtools/kdupdaterupdatefinder.h
+++ b/src/libs/kdtools/updatefinder.h
@@ -1,7 +1,8 @@
/****************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
-** Contact: https://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
**
@@ -26,14 +27,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
@@ -42,11 +46,15 @@ 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);
+ void addCompressedPackage(bool add) { m_compressedPackage = add; }
+ bool isCompressedPackage() { return m_compressedPackage; }
private:
void doRun();
bool doStop();
@@ -54,10 +62,11 @@ private:
bool doResume();
private:
+ bool m_compressedPackage;
Private *d;
Q_PRIVATE_SLOT(d, void slotDownloadDone())
};
} // 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 3c7a16fac..dc40b0e1b 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.cpp
+++ b/src/libs/kdtools/updateoperation.cpp
@@ -26,9 +26,11 @@
**
****************************************************************************/
-#include "kdupdaterupdateoperation.h"
+#include "updateoperation.h"
-#include "kdupdaterapplication.h"
+#include "constants.h"
+#include "fileutils.h"
+#include "packagemanagercore.h"
#include <QDataStream>
#include <QDebug>
@@ -83,17 +85,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());
}
/*!
@@ -175,6 +181,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)
@@ -206,9 +248,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;
}
@@ -271,6 +313,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.
*/
@@ -297,7 +347,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));
@@ -335,12 +386,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
@@ -352,10 +397,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);
@@ -364,18 +412,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;
@@ -389,18 +450,25 @@ 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();
+ // Does not change target on non OSX platforms.
+ if (QInstaller::isInBundle(target, &target))
+ target = QDir::cleanPath(target + QLatin1String("/.."));
+
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);
@@ -420,6 +488,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 94d7e7515..45120ab95 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.h
+++ b/src/libs/kdtools/updateoperation.h
@@ -26,16 +26,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
@@ -49,7 +53,7 @@ public:
UserDefinedError = 128
};
- UpdateOperation();
+ explicit UpdateOperation(QInstaller::PackageManagerCore *core);
virtual ~UpdateOperation();
QString name() const;
@@ -68,11 +72,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);
@@ -84,6 +89,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;
@@ -92,8 +99,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 f64c0ca4b..b0261f87d 100644
--- a/src/libs/kdtools/kdupdaterupdateoperationfactory.cpp
+++ b/src/libs/kdtools/updateoperationfactory.cpp
@@ -26,10 +26,10 @@
**
****************************************************************************/
-#include "kdupdaterupdateoperationfactory.h"
-#include "kdupdaterupdateoperations.h"
+#include "updateoperationfactory.h"
-#include <QHash>
+#include "packagemanagercore.h"
+#include "updateoperations.h"
using namespace KDUpdater;
@@ -57,10 +57,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 1bc2f0f01..97643beb4 100644
--- a/src/libs/kdtools/kdupdaterupdateoperationfactory.h
+++ b/src/libs/kdtools/updateoperationfactory.h
@@ -26,18 +26,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)
@@ -50,10 +55,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 c3536cbf6..1620a36c4 100644
--- a/src/libs/kdtools/kdupdaterupdateoperations.cpp
+++ b/src/libs/kdtools/updateoperations.cpp
@@ -26,7 +26,7 @@
**
****************************************************************************/
-#include "kdupdaterupdateoperations.h"
+#include "updateoperations.h"
#include "errors.h"
#include "fileutils.h"
@@ -93,7 +93,8 @@ static QString backupFileName(const QString &templateName)
// KDUpdater::CopyOperation
////////////////////////////////////////////////////////////////////////////
-CopyOperation::CopyOperation()
+CopyOperation::CopyOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Copy"));
}
@@ -133,18 +134,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();
@@ -152,7 +150,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
@@ -161,7 +159,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;
}
}
@@ -169,7 +168,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;
}
@@ -186,7 +187,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;
}
@@ -199,7 +201,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;
}
@@ -227,17 +230,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"));
}
@@ -260,37 +259,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());
@@ -303,13 +301,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;
}
@@ -322,7 +321,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;
}
@@ -333,17 +333,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"));
}
@@ -360,19 +356,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()
@@ -384,7 +378,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;
}
@@ -394,11 +389,6 @@ bool DeleteOperation::testOperation()
return true;
}
-DeleteOperation *DeleteOperation::clone() const
-{
- return new DeleteOperation;
-}
-
/*!
\reimp
*/
@@ -421,7 +411,8 @@ QDomDocument DeleteOperation::toXml() const
// KDUpdater::MkdirOperation
////////////////////////////////////////////////////////////////////////////
-MkdirOperation::MkdirOperation()
+MkdirOperation::MkdirOperation(QInstaller::PackageManagerCore *core)
+ : UpdateOperation(core)
{
setName(QLatin1String("Mkdir"));
}
@@ -453,18 +444,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;
}
@@ -496,9 +484,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;
}
@@ -509,16 +499,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);
@@ -532,26 +519,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;
}
@@ -565,7 +551,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;
}
@@ -576,17 +563,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"));
}
@@ -601,7 +584,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"));
}
}
@@ -610,15 +594,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
@@ -640,14 +620,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;
@@ -659,13 +640,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;
}
@@ -676,7 +659,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;
}
@@ -686,17 +670,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"));
}
@@ -711,7 +691,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"));
}
}
@@ -721,19 +702,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;
}
@@ -742,7 +721,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)) {
@@ -751,7 +730,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);
@@ -769,12 +749,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;
}
@@ -785,7 +767,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;
}
@@ -795,8 +778,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 5314dc81e..b13a42559 100644
--- a/src/libs/kdtools/kdupdaterupdateoperations.h
+++ b/src/libs/kdtools/updateoperations.h
@@ -26,10 +26,10 @@
**
****************************************************************************/
-#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 {
@@ -37,14 +37,13 @@ class KDTOOLS_EXPORT CopyOperation : public UpdateOperation
{
Q_DECLARE_TR_FUNCTIONS(KDUpdater::CopyOperation)
public:
- CopyOperation();
+ explicit CopyOperation(QInstaller::PackageManagerCore *core = 0);
~CopyOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- CopyOperation *clone() const;
QDomDocument toXml() const;
private:
@@ -56,28 +55,26 @@ class KDTOOLS_EXPORT MoveOperation : public UpdateOperation
{
Q_DECLARE_TR_FUNCTIONS(KDUpdater::MoveOperation)
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
{
Q_DECLARE_TR_FUNCTIONS(KDUpdater::DeleteOperation)
public:
- DeleteOperation();
+ explicit DeleteOperation(QInstaller::PackageManagerCore *core = 0);
~DeleteOperation();
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- DeleteOperation *clone() const;
QDomDocument toXml() const;
};
@@ -86,54 +83,50 @@ class KDTOOLS_EXPORT MkdirOperation : public UpdateOperation
{
Q_DECLARE_TR_FUNCTIONS(KDUpdater::MkdirOperation)
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
{
Q_DECLARE_TR_FUNCTIONS(KDUpdater::RmdirOperation)
public:
- RmdirOperation();
+ RmdirOperation(QInstaller::PackageManagerCore *core = 0);
void backup();
bool performOperation();
bool undoOperation();
bool testOperation();
- RmdirOperation *clone() const;
};
class KDTOOLS_EXPORT AppendFileOperation : public UpdateOperation
{
Q_DECLARE_TR_FUNCTIONS(KDUpdater::AppendFileOperation)
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
{
Q_DECLARE_TR_FUNCTIONS(KDUpdater::PrependFileOperation)
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 9d8859e51..4a10b3207 100644
--- a/src/libs/kdtools/kdupdater.h
+++ b/src/libs/kdtools/updater.h
@@ -26,8 +26,8 @@
**
****************************************************************************/
-#ifndef KD_UPDATER_H
-#define KD_UPDATER_H
+#ifndef UPDATER_H
+#define UPDATER_H
#include "kdtoolsglobal.h"
@@ -45,4 +45,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 eec1aed81..f01e60eb6 100644
--- a/src/libs/kdtools/kdupdaterupdatesinfo.cpp
+++ b/src/libs/kdtools/updatesinfo.cpp
@@ -26,9 +26,10 @@
**
****************************************************************************/
-#include "kdupdaterupdatesinfo_p.h"
+#include "updatesinfo_p.h"
#include "utils.h"
+#include <QDomDocument>
#include <QFile>
#include <QLocale>
#include <QPair>
@@ -57,7 +58,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;
}
@@ -138,6 +139,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();
@@ -178,6 +181,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 1e833ed4a..93e2fe8c6 100644
--- a/src/libs/kdtools/kdupdaterupdatesinfo_p.h
+++ b/src/libs/kdtools/updatesinfo_p.h
@@ -26,11 +26,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>
@@ -82,4 +82,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 8e84cb82b..69b004bc3 100644
--- a/src/libs/kdtools/kdupdaterupdatesinfodata_p.h
+++ b/src/libs/kdtools/updatesinfodata_p.h
@@ -26,13 +26,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;
@@ -56,8 +57,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/commandlineparser.cpp b/src/sdk/commandlineparser.cpp
index 1a1847538..fbaa91328 100644
--- a/src/sdk/commandlineparser.cpp
+++ b/src/sdk/commandlineparser.cpp
@@ -109,7 +109,14 @@ CommandLineParser::CommandLineParser()
"a value is omitted, the client will use a default instead. Note: The server process is "
"not started by the client application in that case, you need to start it on your own."),
QLatin1String("socketname,key")));
-
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::InstallCompressedRepository),
+ QLatin1String("Installs QBSP or 7z file. The QBSP (Board Support Package) file must be a .7z "
+ "file which contains a valid repository."),
+ QLatin1String("URI,...")));
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::SilentUpdate),
+ QLatin1String("Updates all packages silently.")));
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::Platform),
+ QLatin1String("Use the specified platform plugin."), QLatin1String("plugin")));
m_parser.addPositionalArgument(QLatin1String(CommandLineOptions::KeyValue),
QLatin1String("Key Value pair to be set."));
}
diff --git a/src/sdk/constants.h b/src/sdk/constants.h
index d82f2d4bc..ce447ac4b 100644
--- a/src/sdk/constants.h
+++ b/src/sdk/constants.h
@@ -51,6 +51,9 @@ const char AddTmpRepository[] = "addTempRepository";
const char SetTmpRepository[] = "setTempRepository";
const char StartServer[] = "startserver";
const char StartClient[] = "startclient";
+const char InstallCompressedRepository[] = "installCompressedRepository";
+const char SilentUpdate[] = "silentUpdate";
+const char Platform[] = "platform";
} // namespace CommandLineOptions
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index 423ef942b..043d7beca 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -36,7 +36,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>
@@ -47,10 +47,12 @@
#include <utils.h>
#include <globals.h>
-#include <kdrunoncechecker.h>
-#include <kdupdaterfiledownloaderfactory.h>
+#include <runoncechecker.h>
+#include <filedownloaderfactory.h>
+#include <QDir>
#include <QDirIterator>
+#include <QFontDatabase>
#include <QTemporaryFile>
#include <QTranslator>
#include <QUuid>
@@ -70,13 +72,17 @@ InstallerBase::~InstallerBase()
int InstallerBase::run()
{
- KDRunOnceChecker runCheck(qApp->applicationDirPath() + QLatin1String("/lockmyApp1234865.lock"));
- if (runCheck.isRunning(KDRunOnceChecker::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)) {
+ RunOnceChecker runCheck(QDir::tempPath()
+ + QLatin1Char('/')
+ + qApp->applicationName()
+ + QLatin1String("1234865.lock"));
+ if (runCheck.isRunning(RunOnceChecker::ConditionFlag::Lockfile)) {
+ // It is possible that two installers with the same name get executed
+ // concurrently and thus try to access the same lock file. This causes
+ // a warning to be shown (when verbose output is enabled) but let's
+ // just silently ignore the fact that we could not create the lock file
+ // and check the running processes.
+ if (runCheck.isRunning(RunOnceChecker::ConditionFlag::ProcessList)) {
QInstaller::MessageBoxHandler::information(0, QLatin1String("AlreadyRunning"),
tr("Waiting for %1").arg(qAppName()),
tr("Another %1 instance is already running. Wait "
@@ -123,7 +129,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))) {
@@ -206,6 +212,20 @@ int InstallerBase::run()
m_core->setTemporaryRepositories(repoList, true);
}
+ if (parser.isSet(QLatin1String(CommandLineOptions::InstallCompressedRepository))) {
+ const QStringList repoList = repositories(parser
+ .value(QLatin1String(CommandLineOptions::InstallCompressedRepository)));
+ if (repoList.isEmpty())
+ throw QInstaller::Error(QLatin1String("Empty repository list for option 'installCompressedRepository'."));
+ foreach (QString repository, repoList) {
+ if (!QFileInfo::exists(repository)) {
+ qDebug() << "The file " << repository << "does not exist.";
+ return EXIT_FAILURE;
+ }
+ }
+ m_core->setTemporaryRepositories(repoList, false, true);
+ }
+
QInstaller::PackageManagerCore::setNoForceInstallation(parser
.isSet(QLatin1String(CommandLineOptions::NoForceInstallation)));
QInstaller::PackageManagerCore::setCreateLocalRepositoryFromBinary(parser
@@ -253,41 +273,68 @@ int InstallerBase::run()
}
}
- //create the wizard GUI
- TabController controller(0);
- controller.setManager(m_core);
- controller.setManagerParams(params);
- controller.setControlScript(controlScript);
+ {
+ QDirIterator fontIt(QStringLiteral(":/fonts"));
+ while (fontIt.hasNext()) {
+ const QString path = fontIt.next();
+ qCDebug(QInstaller::lcResources) << "Registering custom font" << path;
+ if (QFontDatabase::addApplicationFont(path) == -1)
+ qWarning() << "Failed to register font!";
+ }
+ }
- if (m_core->isInstaller())
- controller.setGui(new InstallerGui(m_core));
- else
- controller.setGui(new MaintenanceGui(m_core));
+ //Do not show gui with --silentUpdate, instead update components silently
+ if (parser.isSet(QLatin1String(CommandLineOptions::SilentUpdate))) {
+ if (m_core->isInstaller())
+ throw QInstaller::Error(QLatin1String("Cannot start installer binary as updater."));
+ const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
+ if (!productKeyCheck->hasValidLicense())
+ throw QInstaller::Error(QLatin1String("Silent update not allowed."));
+ m_core->setUpdater();
+ m_core->updateComponentsSilently();
+ }
+ else {
+ //create the wizard GUI
+ TabController controller(0);
+ controller.setManager(m_core);
+ controller.setManagerParams(params);
+ controller.setControlScript(controlScript);
+ if (m_core->isInstaller()) {
+ controller.setGui(new InstallerGui(m_core));
+ }
+ else {
+ controller.setGui(new MaintenanceGui(m_core));
+ //Start listening to setValue changes that newly installed components might have
+ connect(m_core, &QInstaller::PackageManagerCore::valueChanged, &controller,
+ &TabController::updateManagerParams);
+ }
- QInstaller::PackageManagerCore::Status status =
- QInstaller::PackageManagerCore::Status(controller.init());
- if (status != QInstaller::PackageManagerCore::Success)
- return status;
+ QInstaller::PackageManagerCore::Status status =
+ QInstaller::PackageManagerCore::Status(controller.init());
+ if (status != QInstaller::PackageManagerCore::Success)
+ return status;
- const int result = QCoreApplication::instance()->exec();
- if (result != 0)
- return result;
+ const int result = QCoreApplication::instance()->exec();
+ if (result != 0)
+ return result;
- if (m_core->finishedWithSuccess())
- return QInstaller::PackageManagerCore::Success;
+ if (m_core->finishedWithSuccess())
+ return QInstaller::PackageManagerCore::Success;
- status = m_core->status();
- switch (status) {
- case QInstaller::PackageManagerCore::Success:
- return status;
+ status = m_core->status();
+ switch (status) {
+ case QInstaller::PackageManagerCore::Success:
+ return status;
- case QInstaller::PackageManagerCore::Canceled:
- return status;
+ case QInstaller::PackageManagerCore::Canceled:
+ return status;
- default:
- break;
+ default:
+ break;
+ }
+ return QInstaller::PackageManagerCore::Failure;
}
- return QInstaller::PackageManagerCore::Failure;
+ return QInstaller::PackageManagerCore::Success;
}
@@ -309,6 +356,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
deleted file mode 100644
index 3358e87c3..000000000
--- a/src/sdk/installerbase.qrc
+++ /dev/null
@@ -1,19 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>translations/de.qm</file>
- <file>translations/en.qm</file>
- <file>translations/fr.qm</file>
- <file>translations/it.qm</file>
- <file>translations/ja.qm</file>
- <file>translations/ru.qm</file>
- <file>translations/pl.qm</file>
- <file alias="translations/zh_CN.qm">translations/zh_cn.qm</file>
- <file>translations/qt_fr.qm</file>
- <file alias="translations/qt_de.qm">translations/qtbase_de.qm</file>
- <file alias="translations/qt_ja.qm">translations/qtbase_ja.qm</file>
- <file>translations/qt_pl.qm</file>
- <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>
- </qresource>
-</RCC>
diff --git a/src/sdk/installerbasecommons.cpp b/src/sdk/installerbasecommons.cpp
index a2a8fcfda..1a335f660 100644
--- a/src/sdk/installerbasecommons.cpp
+++ b/src/sdk/installerbasecommons.cpp
@@ -31,6 +31,7 @@
#include <scriptengine.h>
#include <packagemanagerpagefactory.h>
#include <productkeycheck.h>
+#include <settings.h>
using namespace QInstaller;
@@ -81,17 +82,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())
@@ -109,3 +117,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 ec88c724e..1a2f27f45 100644
--- a/src/sdk/installerbasecommons.h
+++ b/src/sdk/installerbasecommons.h
@@ -56,6 +56,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 732ea9703..70c675f91 100644
--- a/src/sdk/main.cpp
+++ b/src/sdk/main.cpp
@@ -34,7 +34,7 @@
#include "updatechecker.h"
#include <errors.h>
-#include <kdselfrestarter.h>
+#include <selfrestarter.h>
#include <remoteserver.h>
#include <utils.h>
@@ -44,20 +44,21 @@
#include <iostream>
-#if defined(Q_OS_OSX)
+#if defined(Q_OS_OSX) or defined(Q_OS_UNIX)
# include <unistd.h>
# include <sys/types.h>
#endif
#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[])
{
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
// increase maximum numbers of file descriptors
#if defined (Q_OS_OSX)
QCoreApplication::setSetuidAllowed(true);
@@ -132,8 +133,24 @@ int main(int argc, char *argv[])
const bool production = (mode.compare(QLatin1String(QInstaller::Protocol::ModeProduction),
Qt::CaseInsensitive) == 0);
- if (production)
+ if (production) {
argumentsValid = (!key.isEmpty()) && (!socketName.isEmpty());
+#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
+ /* In production mode detach child so that sudo waiting on us will terminate. */
+ pid_t child = fork();
+ if (child <= -1) {
+ std::cerr << "Fatal cannot fork and detach server." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (child != 0) {
+ return EXIT_SUCCESS;
+ }
+
+ ::setsid();
+#endif
+ }
+
SDKApp<QCoreApplication> app(argc, argv);
if (!argumentsValid) {
@@ -152,7 +169,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));
@@ -195,7 +212,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 4993ad38d..6af36feb2 100644
--- a/src/sdk/sdk.pro
+++ b/src/sdk/sdk.pro
@@ -6,7 +6,7 @@ include(../../installerfw.pri)
QT += network qml xml widgets
# add the minimal plugin in static build to be able to start the installer headless with:
-# installer-binary -platform minimal
+# installer-binary --platform minimal
# using QT += qpa_minimal_plugin would result in a minimal only compiled version
!win32:CONFIG(static, static|shared) {
QTPLUGIN += qminimal
@@ -22,95 +22,93 @@ 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
- defineReplace(prependAll) {
- for(a,$$1):result += $$2$${a}$$3
- return($$result)
- }
-
- defineTest(testFiles) {
- for(file, $$1) {
- !exists($$file):return(false)
- }
- return(true)
- }
-
- SUCCESS = false
- IB_TRANSLATIONS = $$prependAll(IB_LANGUAGES, $$PWD/translations/,.ts)
- QT_TRANSLATIONS = $$prependAll(QT_LANGUAGES, $$[QT_INSTALL_TRANSLATIONS]/,.ts)
+ IB_TRANSLATIONS = $$files($$PWD/translations/??.ts) $$files($$PWD/translations/??_??.ts)
+ IB_TRANSLATIONS -= $$PWD/translations/en.ts
wd = $$toNativeSeparators($$IFW_SOURCE_TREE)
sources = src
lupdate_opts = -locations relative -no-ui-lines -no-sort
- for(file, IB_TRANSLATIONS) {
+ IB_ALL_TRANSLATIONS = $$IB_TRANSLATIONS $$PWD/translations/untranslated.ts
+ for(file, IB_ALL_TRANSLATIONS) {
lang = $$replace(file, .*/([^/]*)\\.ts, \\1)
v = ts-$${lang}.commands
$$v = cd $$wd && $$LUPDATE $$lupdate_opts $$sources -ts $$file
QMAKE_EXTRA_TARGETS += ts-$$lang
}
- ts-all.commands = cd $$wd && $$LUPDATE $$lupdate_opts $$sources -ts $$IB_TRANSLATIONS
+ ts-all.commands = cd $$wd && $$LUPDATE $$lupdate_opts $$sources -ts $$IB_ALL_TRANSLATIONS
QMAKE_EXTRA_TARGETS += ts-all
isEqual(QMAKE_DIR_SEP, /) {
commit-ts.commands = \
cd $$wd; \
- git add -N src/sdk/translations/*_??.ts && \
- for f in `git diff-files --name-only src/sdk/translations/*_??.ts`; do \
+ git add -N src/sdk/translations/??.ts src/sdk/translations/??_??.ts && \
+ for f in `git diff-files --name-only src/sdk/translations/??.ts src/sdk/translations/??_??.ts`; do \
$$LCONVERT -locations none -i \$\$f -o \$\$f; \
done; \
- git add src/sdk/translations/*_??.ts && git commit
+ git add src/sdk/translations/??.ts src/sdk/translations/??_??.ts && git commit
} else {
commit-ts.commands = \
cd $$wd && \
- git add -N src/sdk/translations/*_??.ts && \
- for /f usebackq %%f in (`git diff-files --name-only src/sdk/translations/*_??.ts`) do \
+ git add -N src/sdk/translations/??.ts src/sdk/translations/??_??.ts && \
+ for /f usebackq %%f in (`git diff-files --name-only src/sdk/translations/??.ts src/sdk/translations/??_??.ts`) do \
$$LCONVERT -locations none -i %%f -o %%f $$escape_expand(\\n\\t) \
- cd $$wd && git add src/sdk/translations/*_??.ts && git commit
+ cd $$wd && git add src/sdk/translations/??.ts src/sdk/translations/??_??.ts && git commit
}
QMAKE_EXTRA_TARGETS += commit-ts
- if (!testFiles(QT_TRANSLATIONS)) {
- QT_COMPILED_TRANSLATIONS = $$prependAll(QT_LANGUAGES, $$[QT_INSTALL_TRANSLATIONS]/,.qm)
- if (testFiles(QT_COMPILED_TRANSLATIONS)) {
- SUCCESS = true
- copyqm.input = QT_COMPILED_TRANSLATIONS
- copyqm.output = $$PWD/translations/${QMAKE_FILE_BASE}.qm
- unix:copyqm.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
- win32:copyqm.commands = $$QMAKE_COPY \"${QMAKE_FILE_IN}\" \"${QMAKE_FILE_OUT}\"
- copyqm.name = COPY ${QMAKE_FILE_IN}
- copyqm.CONFIG += no_link target_predeps
- QMAKE_EXTRA_COMPILERS += copyqm
+ empty_ts = "<TS></TS>"
+ write_file($$OUT_PWD/translations/en.ts, empty_ts)|error("Aborting.")
+ IB_TRANSLATIONS += $$OUT_PWD/translations/en.ts
+ QMAKE_DISTCLEAN += translations/en.ts
+
+ qrc_cont = \
+ "<RCC>" \
+ " <qresource prefix=\"/\">"
+ for (file, IB_TRANSLATIONS) {
+ lang = $$replace(file, .*/([^/]*)\\.ts, \\1)
+ qfile = $$[QT_INSTALL_TRANSLATIONS]/qtbase_$${lang}.qm
+ !exists($$qfile) {
+ qfile = $$[QT_INSTALL_TRANSLATIONS]/qt_$${lang}.qm
+ !exists($$qfile) {
+ warning("No Qt translation for '$$lang'; skipping.")
+ next()
+ }
}
- } else {
- SUCCESS = true
- IB_TRANSLATIONS += $$QT_TRANSLATIONS
+ qrc_cont += \
+ " <file>translations/$${lang}.qm</file>" \
+ " <file alias=\"translations/qt_$${lang}.qm\">$$qfile</file>"
+ ACTIVE_IB_TRANSLATIONS += $$file
+ RESOURCE_DEPS += $$qfile translations/$${lang}.qm
}
-
- if (contains(SUCCESS, true)) {
- updateqm.input = IB_TRANSLATIONS
- updateqm.output = $$PWD/translations/${QMAKE_FILE_BASE}.qm
+ qrc_cont += \
+ " </qresource>" \
+ "</RCC>"
+ RESOURCE = $$OUT_PWD/installerbase.qrc
+ write_file($$RESOURCE, qrc_cont)|error("Aborting.")
+ QMAKE_DISTCLEAN += $$RESOURCE
+
+ !isEmpty(ACTIVE_IB_TRANSLATIONS) {
+ updateqm.input = ACTIVE_IB_TRANSLATIONS
+ updateqm.output = translations/${QMAKE_FILE_BASE}.qm
updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT}
updateqm.name = LRELEASE ${QMAKE_FILE_IN}
updateqm.CONFIG += no_link target_predeps
QMAKE_EXTRA_COMPILERS += updateqm
exists($$RCC) {
- RESOURCE_IB_TRANSLATIONS = $$prependAll(IB_LANGUAGES, $$PWD/translations/,.qm)
- RESOURCE_QT_TRANSLATIONS = $$prependAll(QT_LANGUAGES, $$PWD/translations/,.qm)
- RESOURCE = $$PWD/installerbase.qrc
runrcc.input = RESOURCE
- runrcc.output = $$PWD/qrc_installerbase.cpp
+ runrcc.output = qrc_${QMAKE_FILE_BASE}.cpp
runrcc.commands = $$RCC -name ${QMAKE_FILE_BASE} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
runrcc.name = RCC ${QMAKE_FILE_IN}
runrcc.CONFIG += no_link explicit_dependencies
- runrcc.depends = $$RESOURCE_IB_TRANSLATIONS $$RESOURCE_QT_TRANSLATIONS
+ runrcc.depends = $$RESOURCE_DEPS
runrcc.variable_out = SOURCES
QMAKE_EXTRA_COMPILERS += runrcc
}
}
}
+
FORMS += settingsdialog.ui
HEADERS += \
diff --git a/src/sdk/settingsdialog.cpp b/src/sdk/settingsdialog.cpp
index 83883f54f..c4c2c65c3 100644
--- a/src/sdk/settingsdialog.cpp
+++ b/src/sdk/settingsdialog.cpp
@@ -31,6 +31,7 @@
#include <packagemanagercore.h>
#include <productkeycheck.h>
+#include <testrepository.h>
#include <QtCore/QFile>
@@ -221,13 +222,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());
@@ -319,25 +325,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 a5bfff38f..eb25a2e87 100644
--- a/src/sdk/settingsdialog.h
+++ b/src/sdk/settingsdialog.h
@@ -30,7 +30,6 @@
#include <repository.h>
#include <settings.h>
-#include <testrepository.h>
#include <QDialog>
#include <QStyledItemDelegate>
@@ -129,7 +128,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 32accb50f..1ebdbdbeb 100644
--- a/src/sdk/tabcontroller.cpp
+++ b/src/sdk/tabcontroller.cpp
@@ -89,7 +89,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)
@@ -119,8 +119,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 =
@@ -132,7 +133,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;
@@ -163,14 +164,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) {
@@ -198,3 +199,8 @@ void TabController::onNetworkSettingsChanged(const QInstaller::Settings &setting
d->m_settings = settings;
d->m_networkSettingsChanged = true;
}
+
+void TabController::updateManagerParams(const QString &key, const QString &value)
+{
+ d->m_params.insert(key, value);
+}
diff --git a/src/sdk/tabcontroller.h b/src/sdk/tabcontroller.h
index 41c78f82e..a314cb15b 100644
--- a/src/sdk/tabcontroller.h
+++ b/src/sdk/tabcontroller.h
@@ -57,6 +57,7 @@ public:
public Q_SLOTS:
int init();
+ void updateManagerParams(const QString &key, const QString &value);
private Q_SLOTS:
void restartWizard();
diff --git a/src/sdk/translations/README b/src/sdk/translations/README
index 35da60d6a..2bade2c54 100644
--- a/src/sdk/translations/README
+++ b/src/sdk/translations/README
@@ -2,16 +2,17 @@ You need to have a Qt translation for your new language,
otherwise your language won't be loaded at runtime.
To add a new language:
-1) Inside src/sdk/sdk.pro:
- add your language into IB_LANGUAGES and QT_LANGUAGES.
- QT_LANGUAGES contains base name of the Qt translation file.
-2) Add Installer Framework translation filename into:
- src/src.pro
-3) Add Installer Framework and Qt messages (.qm) filenames into:
- src/sdk/installerbase.qrc
+1) Run 'cd src/sdk' (change to the parent directory of this file)
+2) Run 'make ts-untranslated'
+3) Rename translations/untranslated.ts to translations/<lang>.ts
+4) Run 'make qmake'
+5) Do your translation. Just run 'make' whenever you want to test it.
+6) Run 'make commit-ts'
+7) Submit the translation for review
-In order to provide an update to translations, according to changes done in sources, run:
+To update an existing translation, just run 'make ts-<lang>' instead
+of steps 2) to 4).
-lupdate installerfw.pro
-
-in a root directory.
+More information is available at https://wiki.qt.io/Qt_Localization -
+these instructions apply here equally, except for the different
+directory names.
diff --git a/src/sdk/translations/da.ts b/src/sdk/translations/da.ts
new file mode 100644
index 000000000..42a742217
--- /dev/null
+++ b/src/sdk/translations/da.ts
@@ -0,0 +1,2450 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="da">
+<context>
+ <name>AuthenticationRequiredException</name>
+ <message>
+ <source>%1 at %2</source>
+ <translation>%1 hos %2</translation>
+ </message>
+ <message>
+ <source>Proxy requires authentication.</source>
+ <translation>Proxyen kræver autentifikation.</translation>
+ </message>
+</context>
+<context>
+ <name>BinaryContent</name>
+ <message>
+ <source>Cannot seek to %1 to read the operation data.</source>
+ <translation>Kan ikke søge til %1 for at læse handlingsdataene.</translation>
+ </message>
+ <message>
+ <source>Cannot seek to %1 to read the resource collection block.</source>
+ <translation>Kan ikke søge til %1 for at læse ressourcesamlingsblokken.</translation>
+ </message>
+ <message>
+ <source>Cannot open meta resource %1.</source>
+ <translation>Kan ikke åbne meta-ressourcen %1.</translation>
+ </message>
+</context>
+<context>
+ <name>BinaryLayout</name>
+ <message>
+ <source>Cannot seek to %1 to read the embedded meta data count.</source>
+ <translation>Kan ikke søge til %1 for at læse antallet af indlejret meta-data.</translation>
+ </message>
+ <message>
+ <source>Cannot seek to %1 to read the resource collection segment.</source>
+ <translation>Kan ikke søge til %1 for at læse ressourcesamlingssegmentet.</translation>
+ </message>
+ <message>
+ <source>Unexpected mismatch of meta resources. Read %1, expected: %2.</source>
+ <translation>Uventet uoverensstemmelse af meta-ressourcer. Læste %1, ventede: %2.</translation>
+ </message>
+</context>
+<context>
+ <name>Dialog</name>
+ <message>
+ <source>Http authentication required</source>
+ <translation>Http-autentifikation krævet</translation>
+ </message>
+ <message>
+ <source>You need to supply a Username and Password to access this site.</source>
+ <translation>Du skal angive brugernavn og adgangskode for at tilgå dette sted.</translation>
+ </message>
+ <message>
+ <source>Username:</source>
+ <translation>Brugernavn:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Adgangskode:</translation>
+ </message>
+ <message>
+ <source>%1 at %2</source>
+ <translation>%1 hos %2</translation>
+ </message>
+</context>
+<context>
+ <name>DirectoryGuard</name>
+ <message>
+ <source>Path &quot;%1&quot; exists but is not a directory.</source>
+ <translation>Stien &quot;%1&quot; findes men er ikke en mappe.</translation>
+ </message>
+ <message>
+ <source>Cannot create directory &quot;%1&quot;.</source>
+ <translation>Kan ikke oprette mappen &quot;%1&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>ExtractCallbackImpl</name>
+ <message>
+ <source>Cannot retrieve path of archive item %1.</source>
+ <translation>Kan ikke hente stien af arkivposten %1.</translation>
+ </message>
+ <message>
+ <source>Cannot remove already existing symlink %1.</source>
+ <translation>Kan ikke fjerne allerede eksisterende symlink %1.</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create symlink at &quot;%1&quot;. Another one is already existing.</source>
+ <translation>Kan ikke oprette symlink ved &quot;%1&quot;. Et andet findes allerede.</translation>
+ </message>
+ <message>
+ <source>Cannot read symlink target from file &quot;%1&quot;.</source>
+ <translation>Kan ikke læse symlink-mål fra filen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot create symlink at %1: %2</source>
+ <translation>Kan ikke oprette symlink ved %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>InstallerBase</name>
+ <message>
+ <source>Waiting for %1</source>
+ <translation>Venter på %1</translation>
+ </message>
+ <message>
+ <source>Another %1 instance is already running. Wait until it finishes, close it, or restart your system.</source>
+ <translation>En anden %1-instans kører allerede. Vent til den er færdig, luk den eller genstart dit system.</translation>
+ </message>
+</context>
+<context>
+ <name>InstallerCalculator</name>
+ <message>
+ <source>Components added as automatic dependencies:</source>
+ <translation>Komponenter tilføjet som automatiske afhængigheder:</translation>
+ </message>
+ <message>
+ <source>Components added as dependency for &quot;%1&quot;:</source>
+ <translation>Komponenter tilføjet som afhængighed til &quot;%1&quot;:</translation>
+ </message>
+ <message>
+ <source>Components that have resolved dependencies:</source>
+ <translation>Komponenter som har løste afhængigheder:</translation>
+ </message>
+ <message>
+ <source>Selected components without dependencies:</source>
+ <translation>Valgte komponenter uden afhængigheder:</translation>
+ </message>
+ <message>
+ <source>Recursion detected, component &quot;%1&quot; already added with reason: &quot;%2&quot;</source>
+ <translation>Rekursion registreret, komponenten &quot;%1&quot; allerede tilføjet med begrundelsen: &quot;%2&quot;</translation>
+ </message>
+ <message>
+ <source>Cannot find missing dependency &quot;%1&quot; for &quot;%2&quot;.</source>
+ <translation>Kan ikke finde manglende afhængighed &quot;%1&quot; til &quot;%2&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>Job</name>
+ <message>
+ <source>Canceled</source>
+ <translation>Annulleret</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::AppendFileOperation</name>
+ <message>
+ <source>Cannot backup file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke sikkerhedskopiere filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot find backup file for &quot;%1&quot;.</source>
+ <translation>Kan ikke finde sikkerhedskopieret fil for &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for &quot;%1&quot;.</source>
+ <translation>Kan ikke genskabe sikkerhedskopieret fil for &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
+ <translation>Kan ikke genskabe sikkerhedskopieret fil for &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::CopyOperation</name>
+ <message>
+ <source>Cannot backup file &quot;%1&quot;.</source>
+ <translation>Kan ikke sikkerhedskopiere filen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot copy a non-existent file: %1</source>
+ <translation>Kan ikke kopiere en ikke-eksisterende fil: %1</translation>
+ </message>
+ <message>
+ <source>Cannot remove file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Kan ikke kopiere filen &quot;%1&quot; til &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>Cannot delete file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke slette filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file into &quot;%1&quot;: %2</source>
+ <translation>Kan ikke genskabe sikkerhedskopieret fil ind i &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::DeleteOperation</name>
+ <message>
+ <source>Cannot create backup of file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke oprette sikkerhedskopi af filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
+ <translation>Kan ikke genskabe sikkerhedskopieret fil for &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::FileDownloader</name>
+ <message>
+ <source>Download finished.</source>
+ <translation>Download færdig.</translation>
+ </message>
+ <message>
+ <source>Cryptographic hashes do not match.</source>
+ <translation>Kryptografiske hashes matcher ikke.</translation>
+ </message>
+ <message>
+ <source>Download canceled.</source>
+ <translation>Download annulleret.</translation>
+ </message>
+ <message>
+ <source>%1 of %2</source>
+ <translation>%1 af %2</translation>
+ </message>
+ <message>
+ <source>%1 downloaded.</source>
+ <translation>%1 downloadet.</translation>
+ </message>
+ <message>
+ <source>(%1/sec)</source>
+ <translation>(%1/sek.)</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s), </source>
+ <translation>
+ <numerusform>%n dag, </numerusform>
+ <numerusform>%n dage, </numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s), </source>
+ <translation>
+ <numerusform>%n time, </numerusform>
+ <numerusform>%n timer, </numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n minute(s)</source>
+ <translation>
+ <numerusform>%n minut</numerusform>
+ <numerusform>%n minutter</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n second(s)</source>
+ <translation>
+ <numerusform>%n sekund</numerusform>
+ <numerusform>%n sekunder</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source> - %1%2%3%4 remaining.</source>
+ <translation> - %1%2%3%4 tilbage.</translation>
+ </message>
+ <message>
+ <source> - unknown time remaining.</source>
+ <translation> - ukendt tid tilbage.</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::HttpDownloader</name>
+ <message>
+ <source>Cannot download %1. Writing to file &quot;%2&quot; failed: %3</source>
+ <translation>Kan ikke downloade %1. Skrivning til filen &quot;%2&quot; fejlede: %3</translation>
+ </message>
+ <message>
+ <source>Cannot download %1. Cannot create file &quot;%2&quot;: %3</source>
+ <translation>Kan ikke downloade %1. Kan ikke oprette filen &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>%1 at %2</source>
+ <translation>%1 hos %2</translation>
+ </message>
+ <message>
+ <source>Authentication request canceled.</source>
+ <translation>Autentifikationsanmodning annulleret.</translation>
+ </message>
+ <message>
+ <source>Secure Connection Failed</source>
+ <translation>Sikker forbindelse fejlede</translation>
+ </message>
+ <message>
+ <source>There was an error during connection to: %1.</source>
+ <translation>Der opstod en fejl under forbindelse til: %1.</translation>
+ </message>
+ <message>
+ <source>This could be a problem with the server&apos;s configuration, or it could be someone trying to impersonate the server.</source>
+ <translation>Der kan være et problem med serverens konfiguration eller det kan være nogen som prøve at udgive sig for at være serveren. </translation>
+ </message>
+ <message>
+ <source>If you have connected to this server successfully in the past or trust this server, the error may be temporary and you can try again.</source>
+ <translation>Hvis du førhen har oprettet forbindelse til denne server eller har tillid til denne server, kan fejlen være midlertidig og du kan prøve igen.</translation>
+ </message>
+ <message>
+ <source>Try again</source>
+ <translation>Prøv igen</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::LocalFileDownloader</name>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+ <message>
+ <source>Writing to file &quot;%1&quot; failed: %2</source>
+ <translation>Skrivning til filen &quot;%1&quot; fejlede: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::MkdirOperation</name>
+ <message>
+ <source>Cannot create directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke oprette mappen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Unknown error.</source>
+ <translation>Ukendt fejl.</translation>
+ </message>
+ <message>
+ <source>Cannot remove directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne mappen &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::MoveOperation</name>
+ <message>
+ <source>Cannot backup file &quot;%1&quot;.</source>
+ <translation>Kan ikke sikkerhedskopiere filen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot remove file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Kan ikke kopiere filen &quot;%1&quot; til &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>Cannot remove file &quot;%1&quot;.</source>
+ <translation>Kan ikke fjerne filen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
+ <translation>Kan ikke genskabe sikkerhedskopieret fil for &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::PrependFileOperation</name>
+ <message>
+ <source>Cannot backup file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke sikkerhedskopiere filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot find backup file for &quot;%1&quot;.</source>
+ <translation>Kan ikke finde sikkerhedskopieret fil for &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for &quot;%1&quot;.</source>
+ <translation>Kan ikke genskabe sikkerhedskopieret fil for &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
+ <translation>Kan ikke genskabe sikkerhedskopieret fil for &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::ResourceFileDownloader</name>
+ <message>
+ <source>Cannot read resource file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke læse ressourcefilen &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::RmdirOperation</name>
+ <message>
+ <source>Cannot remove directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne mappen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>The directory does not exist.</source>
+ <translation>Mappen findes ikke.</translation>
+ </message>
+ <message>
+ <source>Cannot recreate directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke genoprette mappen &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::Task</name>
+ <message>
+ <source>%1 started</source>
+ <translation>%1 startet</translation>
+ </message>
+ <message>
+ <source>%1 cannot be stopped</source>
+ <translation>%1 kan ikke stoppes</translation>
+ </message>
+ <message>
+ <source>Cannot stop task %1</source>
+ <translation>Kan ikke stoppe opgaven %1</translation>
+ </message>
+ <message>
+ <source>%1 cannot be paused</source>
+ <translation>%1 kan ikke sættes på pause</translation>
+ </message>
+ <message>
+ <source>Cannot pause task %1</source>
+ <translation>Kan ikke sætte opgaven %1 på pause</translation>
+ </message>
+ <message>
+ <source>Cannot resume task %1</source>
+ <translation>Kan ikke genoptage opgaven %1</translation>
+ </message>
+ <message>
+ <source>%1 done</source>
+ <translation>%1 færdig</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::UpdateFinder</name>
+ <message>
+ <source>Cannot access the package information of this application.</source>
+ <translation>Kan ikke tilgå pakkeinformationen til dette program.</translation>
+ </message>
+ <message>
+ <source>No package sources set for this application.</source>
+ <translation>Ingen pakkekilder sat til dette program.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n update(s) found.</source>
+ <translation>
+ <numerusform>%n opdatering fundet.</numerusform>
+ <numerusform>%n opdateringer fundet.</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Downloading Updates.xml from update sources.</source>
+ <translation>Downloader Updates.xml fra opdateringskilder.</translation>
+ </message>
+ <message>
+ <source>Cannot download package source %1 from &quot;%2&quot;.</source>
+ <translation>Kan ikke downloade pakkekilden %1 fra &quot;%2&quot;.</translation>
+ </message>
+ <message>
+ <source>Updates.xml file(s) downloaded from update sources.</source>
+ <translation>Updates.xml fil(er) downloadet fra opdateringskilder.</translation>
+ </message>
+ <message>
+ <source>Computing applicable updates.</source>
+ <translation>Udregner anvendelige opdateringer.</translation>
+ </message>
+ <message>
+ <source>Application updates computed.</source>
+ <translation>Programopdateringer udregnet.</translation>
+ </message>
+</context>
+<context>
+ <name>KDUpdater::UpdatesInfoData</name>
+ <message>
+ <source>Updates.xml contains invalid content: %1</source>
+ <translation>Updates.xml indeholder ugyldigt indhold: %1</translation>
+ </message>
+ <message>
+ <source>Cannot read &quot;%1&quot;</source>
+ <translation>Kan ikke læse &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>Parse error in %1 at %2, %3: %4</source>
+ <translation>Parse-fejl i %1 ved %2, %3: %4</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &quot;Updates&quot;.</source>
+ <translation>Rod-elementet %1 uventet, skulle være &quot;Updates&quot;.</translation>
+ </message>
+ <message>
+ <source>ApplicationName element is missing.</source>
+ <translation>ApplicationName-element mangler.</translation>
+ </message>
+ <message>
+ <source>ApplicationVersion element is missing.</source>
+ <translation>ApplicationVersion-element mangler.</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without Name</source>
+ <translation>PackageUpdate-element uden Name</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without Version</source>
+ <translation>PackageUpdate-element uden Version</translation>
+ </message>
+ <message>
+ <source>PackageUpdate element without ReleaseDate</source>
+ <translation>PackageUpdate-element uden ReleaseDate</translation>
+ </message>
+</context>
+<context>
+ <name>Lib7z</name>
+ <message>
+ <source>internal code: %1</source>
+ <translation>intern kode: %1</translation>
+ </message>
+ <message>
+ <source>not enough memory</source>
+ <translation>ikke nok hukommelse</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Fejl: %1</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve property %1 for item %2.</source>
+ <translation>Kan ikke hente egenskaben %1 for posten %2.</translation>
+ </message>
+ <message>
+ <source>Property %1 for item %2 not of type VT_FILETIME but %3.</source>
+ <translation>Egenskaben %1 for posten %2 ikke af typen VT_FILETIME men %3.</translation>
+ </message>
+ <message>
+ <source>Cannot convert UTC file time to system time.</source>
+ <translation>Kan ikke konvertere UTC-filtid til systemets tid.</translation>
+ </message>
+ <message>
+ <source>Cannot load codecs.</source>
+ <translation>Kan ikke indlæse codecs.</translation>
+ </message>
+ <message>
+ <source>Cannot open archive &quot;%1&quot;.</source>
+ <translation>Kan ikke åbne arkivet &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve number of items in archive.</source>
+ <translation>Kan ikke hente antal poster i arkiv.</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve path of archive item &quot;%1&quot;.</source>
+ <translation>Kan ikke hente stien af arkivposten &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught (%1).</source>
+ <translation>Ukendt undtagelse fanget (%1).</translation>
+ </message>
+ <message>
+ <source>Cannot create temporary file: %1</source>
+ <translation>Kan ikke oprette midlertidig fil: %1</translation>
+ </message>
+ <message>
+ <source>Unsupported archive type.</source>
+ <translation>Ikke-understøttet arkivtype.</translation>
+ </message>
+ <message>
+ <source>Cannot create archive &quot;%1&quot;</source>
+ <translation>Kan ikke oprette arkivet &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>Cannot create archive &quot;%1&quot;: %2</source>
+ <translation>Kan ikke oprette arkivet &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot remove old archive &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne gamle arkiv &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot rename temporary archive &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Kan ikke omdøbe midlertidigt arkiv &quot;%1&quot; til &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught (%1)</source>
+ <translation>Ukendt undtagelse fanget (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>LocalPackageHub</name>
+ <message>
+ <source>%1 contains invalid content: %2</source>
+ <translation>%1 indeholder ugyldigt indhold: %2</translation>
+ </message>
+ <message>
+ <source>The file %1 does not exist.</source>
+ <translation>Filen %1 findes ikke.</translation>
+ </message>
+ <message>
+ <source>Cannot open %1.</source>
+ <translation>Kan ikke åbne %1.</translation>
+ </message>
+ <message>
+ <source>Parse error in %1 at %2, %3: %4</source>
+ <translation>Parse-fejl i %1 ved %2, %3: %4</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &apos;Packages&apos;.</source>
+ <translation>Rod-elementet %1 uventet, skulle være &apos;Packages&apos;.</translation>
+ </message>
+</context>
+<context>
+ <name>LockFile</name>
+ <message>
+ <source>Cannot create lock file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke oprette låsfilen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot write PID to lock file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke skrive PID til låsfilen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot obtain the lock for file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke få låsfilen for filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot release the lock for file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke frigive låsfilen for filen &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller</name>
+ <message>
+ <source>No marker found, stopped after %1.</source>
+ <translation>Ingen markør fundet, stoppet efter %1.</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+ <message>
+ <source>Read failed after %1 bytes: %2</source>
+ <translation>Læsning fejlede efter %1 byte: %2</translation>
+ </message>
+ <message>
+ <source>Copy failed: %1</source>
+ <translation>Kopiering fejlede: %1</translation>
+ </message>
+ <message>
+ <source>Write failed after %1 bytes: %2</source>
+ <translation>Skrivning fejlede efter %1 byte: %2</translation>
+ </message>
+ <message>
+ <source>bytes</source>
+ <translation>byte</translation>
+ </message>
+ <message>
+ <source>KiB</source>
+ <translation>KiB</translation>
+ </message>
+ <message>
+ <source>MiB</source>
+ <translation>MiB</translation>
+ </message>
+ <message>
+ <source>GiB</source>
+ <translation>GiB</translation>
+ </message>
+ <message>
+ <source>TiB</source>
+ <translation>TiB</translation>
+ </message>
+ <message>
+ <source>PiB</source>
+ <translation>PiB</translation>
+ </message>
+ <message>
+ <source>EiB</source>
+ <translation>EiB</translation>
+ </message>
+ <message>
+ <source>ZiB</source>
+ <translation>ZiB</translation>
+ </message>
+ <message>
+ <source>YiB</source>
+ <translation>YiB</translation>
+ </message>
+ <message>
+ <source>Cannot remove file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot remove directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne mappen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create directory &quot;%1&quot;.</source>
+ <translation>Kan ikke oprette mappen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot copy file from &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Kan ikke kopiere filen fra &quot;%1&quot; til &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>Cannot move file from &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Kan ikke flytte filen fra &quot;%1&quot; til &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>Cannot create directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke oprette mappen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open temporary file: %1</source>
+ <translation>Kan ikke åbne midlertidig fil: %1</translation>
+ </message>
+ <message>
+ <source>Cannot open temporary file for template %1: %2</source>
+ <translation>Kan ikke åbne midlertidig fil til skabelonen %1: %2</translation>
+ </message>
+ <message>
+ <source>Corrupt installation</source>
+ <translation>Ødelagt installation</translation>
+ </message>
+ <message>
+ <source>Your installation seems to be corrupted. Please consider re-installing from scratch.</source>
+ <translation>Din installation ser ud til at være ødelagt. Overvej venligst at geninstallere from bunden.</translation>
+ </message>
+ <message>
+ <source>The specified module could not be found.</source>
+ <translation>Det specificerede modul blev ikke fundet.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::Component</name>
+ <message>
+ <source>Components cannot have children in updater mode.</source>
+ <translation>Komponenter må ikke have børn i opdateringstilstand.</translation>
+ </message>
+ <message>
+ <source>Cannot open the requested UI file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke åbne den anmodede UI-fil &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot load the requested UI file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke indlæse den anmodede UI-fil &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open the requested license file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke åbne den anmodede licensfil &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+ <message>
+ <source>Error: Operation %1 does not exist.</source>
+ <translation>Fejl: handlingen %1 findes ikke.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve isDefault in %1</source>
+ <translation>Kan ikke løse isDefault i %1</translation>
+ </message>
+ <message>
+ <source>Update Info: </source>
+ <translation>Opdateringsinfo:</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ComponentModel</name>
+ <message>
+ <source>Component is marked for installation.</source>
+ <translation>Komponenten er mærket til installation.</translation>
+ </message>
+ <message>
+ <source>Component is marked for uninstallation.</source>
+ <translation>Komponenten er mærket til afinstallation.</translation>
+ </message>
+ <message>
+ <source>Component is installed.</source>
+ <translation>Komponenten er installeret.</translation>
+ </message>
+ <message>
+ <source>Component is not installed.</source>
+ <translation>Komponenten er ikke installeret.</translation>
+ </message>
+ <message>
+ <source>Component Name</source>
+ <translation>Komponentnavn</translation>
+ </message>
+ <message>
+ <source>Action</source>
+ <translation>Handling</translation>
+ </message>
+ <message>
+ <source>Installed Version</source>
+ <translation>Installeret version</translation>
+ </message>
+ <message>
+ <source>New Version</source>
+ <translation>Ny version</translation>
+ </message>
+ <message>
+ <source>Release Date</source>
+ <translation>Udgivelsesdato</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>Størrelse</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ComponentSelectionPage</name>
+ <message>
+ <source>Alt+A</source>
+ <comment>select default components</comment>
+ <translation>Alt+S</translation>
+ </message>
+ <message>
+ <source>Def&amp;ault</source>
+ <translation>&amp;Standard</translation>
+ </message>
+ <message>
+ <source>Alt+R</source>
+ <comment>reset to already installed components</comment>
+ <translation>Alt+N</translation>
+ </message>
+ <message>
+ <source>&amp;Reset</source>
+ <translation>&amp;Nulstil</translation>
+ </message>
+ <message>
+ <source>Alt+S</source>
+ <comment>select all components</comment>
+ <translation>Alt+V</translation>
+ </message>
+ <message>
+ <source>&amp;Select All</source>
+ <translation>&amp;Vælg alle</translation>
+ </message>
+ <message>
+ <source>Alt+D</source>
+ <comment>deselect all components</comment>
+ <translation>Alt+F</translation>
+ </message>
+ <message>
+ <source>&amp;Deselect All</source>
+ <translation>&amp;Fravælg alle</translation>
+ </message>
+ <message>
+ <source>To install new compressed repository, browse the repositories from your computer</source>
+ <translation>Gennemse repositorierne fra din computer, for at installere nyt komprimeret repository</translation>
+ </message>
+ <message>
+ <source>&amp;Browse QBSP files</source>
+ <translation>&amp;Gennemse QBSP-filer</translation>
+ </message>
+ <message>
+ <source>Select the components to install. Deselect installed components to uninstall them. Any components already installed will not be updated.</source>
+ <translation>Vælg de komponenter du vil installere. Fravælg installeret komponenter for at afinstallere dem. Komponenter som allerede er installeret vil ikke blive opdateret.</translation>
+ </message>
+ <message>
+ <source>This component will occupy approximately %1 on your hard disk drive.</source>
+ <translation>Denne komponent vil optage cirka %1 på dit harddisk-drev.</translation>
+ </message>
+ <message>
+ <source>Open File</source>
+ <translation>Ã…bn fil</translation>
+ </message>
+ <message>
+ <source>Select Components</source>
+ <translation>Vælg komponenter</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to update.</source>
+ <translation>Vælg venligst de komponenter du vil opdatere.</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to install.</source>
+ <translation>Vælg venligst de komponenter du vil installere.</translation>
+ </message>
+ <message>
+ <source>Please select the components you want to uninstall.</source>
+ <translation>Vælg venligst de komponenter du vil afinstallere.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ConsumeOutputOperation</name>
+ <message>
+ <source>&lt;to be saved installer key name&gt; &lt;executable&gt; [argument1] [argument2] [...]</source>
+ <translation>&lt;installer-nøglenavn som skal gammes&gt; &lt;eksekverbar&gt; [argument1] [argument2] [...]</translation>
+ </message>
+ <message>
+ <source>Needed installer object in %1 operation is empty.</source>
+ <translation>Nødvendigt installer-objekt i %1-handling er tomt.</translation>
+ </message>
+ <message>
+ <source>Cannot save the output of &quot;%1&quot; to an empty installer key value.</source>
+ <translation>Kan ikke gemme outputtet fra &quot;%1&quot; til en tom installer-nøgleværdi.</translation>
+ </message>
+ <message>
+ <source>File &quot;%1&quot; does not exist or is not an executable binary.</source>
+ <translation>Filen &quot;%1&quot; findes ikke eller er ikke en eksekverbar binær.</translation>
+ </message>
+ <message>
+ <source>Running &quot;%1&quot; resulted in a crash.</source>
+ <translation>Kørsel af &quot;%1&quot; resulterede i at det holdt op med at virke.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CopyDirectoryOperation</name>
+ <message>
+ <source>&lt;source&gt; &lt;target&gt; [&quot;forceOverwrite&quot;]</source>
+ <translation>&lt;kilde&gt; &lt;mål&gt; [&quot;forceOverwrite&quot;]</translation>
+ </message>
+ <message>
+ <source>Invalid argument in %1: Third argument needs to be forceOverwrite, if specified.</source>
+ <translation>Ugyldigt argument i %1: tredje argument skal være forceOverwrite, hvis specificeret.</translation>
+ </message>
+ <message>
+ <source>Invalid argument in %1: Directory &quot;%2&quot; is invalid.</source>
+ <translation>Ugyldigt argument i %1: mappen &quot;%2&quot; er ugyldig.</translation>
+ </message>
+ <message>
+ <source>Cannot create directory &quot;%1&quot;.</source>
+ <translation>Kan ikke oprette mappen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite &quot;%1&quot;.</source>
+ <translation>Kunne ikke overskrive &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Kan ikke kopiere filen &quot;%1&quot; til &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>Cannot remove file &quot;%1&quot;.</source>
+ <translation>Kan ikke fjerne filen &quot;%1&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CopyFileTask</name>
+ <message>
+ <source>Invalid task item count.</source>
+ <translation>Ugyldigt antal poster i opgave.</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+ <message>
+ <source>Writing to file &quot;%1&quot; failed: %2</source>
+ <translation>Skrivning til filen &quot;%1&quot; fejlede: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateDesktopEntryOperation</name>
+ <message>
+ <source>Cannot backup file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke sikkerhedskopiere filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite file &quot;%1&quot;.</source>
+ <translation>Kunne ikke overskrive filen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot write desktop entry to &quot;%1&quot;.</source>
+ <translation>Kan ikke skrive skrivebordspost til &quot;%1&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateLinkOperation</name>
+ <message>
+ <source>Cannot create link from &quot;%1&quot; to &quot;%2&quot;.</source>
+ <translation>Kan ikke oprette link fra &quot;%1&quot; til &quot;%2&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot remove link from &quot;%1&quot; to &quot;%2&quot;.</source>
+ <translation>Kan ikke fjerne link fra &quot;%1&quot; til &quot;%2&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateLocalRepositoryOperation</name>
+ <message>
+ <source>Cannot set permissions for file &quot;%1&quot;.</source>
+ <translation>Kan ikke sætte tilladelser for filen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot remove file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot move file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Kan ikke flytte filen &quot;%1&quot; til &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>Installer at &quot;%1&quot; needs to be an offline one.</source>
+ <translation>Installeren ved &quot;%1&quot; skal være af typen offline.</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading.</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning.</translation>
+ </message>
+ <message>
+ <source>Cannot read file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke læse filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create target directory: &quot;%1&quot;.</source>
+ <translation>Kan ikke oprette mål-mappen: &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught: %1.</source>
+ <translation>Ukendt undtagelse fanget: %1.</translation>
+ </message>
+ <message>
+ <source>Removing file &quot;%1&quot;.</source>
+ <translation>Fjerner filen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot remove file &quot;%1&quot;.</source>
+ <translation>Kan ikke fjerne filen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot remove directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne mappen &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::CreateShortcutOperation</name>
+ <message>
+ <source>&lt;target&gt; &lt;link location&gt; [target arguments] [&quot;workingDirectory=...&quot;] [&quot;iconPath=...&quot;] [&quot;iconId=...&quot;] [&quot;description=...&quot;]</source>
+ <translation>&lt;mål&gt; &lt;linkplacering&gt; [mål-argumenter] [&quot;workingDirectory=...&quot;] [&quot;iconPath=...&quot;] [&quot;iconId=...&quot;] [&quot;description=...&quot;]</translation>
+ </message>
+ <message>
+ <source>Cannot create directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke oprette mappen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite &quot;%1&quot;: %2</source>
+ <translation>Kunne ikke overskrive &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create link &quot;%1&quot;: %2</source>
+ <translation>Kan ikke oprette linket &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::DownloadArchivesJob</name>
+ <message>
+ <source>Canceled</source>
+ <translation>Annulleret</translation>
+ </message>
+ <message>
+ <source>Downloading hash signature failed.</source>
+ <translation>Download af hash-signatur fejlede.</translation>
+ </message>
+ <message>
+ <source>Download Error</source>
+ <translation>Download-fejl</translation>
+ </message>
+ <message>
+ <source>Hash verification while downloading failed. This is a temporary error, please retry.</source>
+ <translation>Hash-verifikation under download fejlede. Dette er en midlertidig fejl, prøv venligst igen.</translation>
+ </message>
+ <message>
+ <source>Cannot verify Hash</source>
+ <translation>Kan ikke verificere hash</translation>
+ </message>
+ <message>
+ <source>Cannot download archive %1: %2</source>
+ <translation>Kan ikke downloade arkivet %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot fetch archives: %1
+Error while loading %2</source>
+ <translation>Kan ikke hente arkiver: %1
+Fejl under indlæsning af %2</translation>
+ </message>
+ <message>
+ <source>Downloading archive &quot;%1&quot; for component %2.</source>
+ <translation>Downloader arkivet &quot;%1&quot; til komponenten %2.</translation>
+ </message>
+ <message>
+ <source>Scheme %1 not supported (URL: %2).</source>
+ <translation>Skemaet %1 understøttes ikke (URL: %2).</translation>
+ </message>
+ <message>
+ <source>Cannot find component for %1.</source>
+ <translation>Kan ikke finde komponent til %1.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::Downloader</name>
+ <message>
+ <source>Target file &quot;%1&quot; already exists but is not a file.</source>
+ <translation>MÃ¥l-filen &quot;%1&quot; findes allerede men er ikke en fil.</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <extracomment>%2 is a sentence describing the error</extracomment>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+ <message>
+ <source>File &quot;%1&quot; not open for writing: %2</source>
+ <extracomment>%2 is a sentence describing the error.</extracomment>
+ <translation>Filen &quot;%1&quot; er ikke åben til skrivning: %2</translation>
+ </message>
+ <message>
+ <source>Writing to file &quot;%1&quot; failed: %2</source>
+ <extracomment>%2 is a sentence describing the error.</extracomment>
+ <translation>Skrivning til filen &quot;%1&quot; fejlede: %2</translation>
+ </message>
+ <message>
+ <source>Redirect loop detected for &quot;%1&quot;.</source>
+ <translation>Omdirigeringsløkke registreret for &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Checksum mismatch detected for &quot;%1&quot;.</source>
+ <translation>Tjeksum uoverensstemmelse registreret for &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Network error while downloading &apos;%1&apos;: %2.</source>
+ <translation>Netværksfejl under download af &apos;%1&apos;: %2.</translation>
+ </message>
+ <message>
+ <source>Unknown network error while downloading &quot;%1&quot;.</source>
+ <extracomment>%1 is a sentence describing the error</extracomment>
+ <translation>Ukendt netværksfejl under download af &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Network transfers canceled.</source>
+ <translation>Netværksoverførsler annulleret.</translation>
+ </message>
+ <message>
+ <source>Pause and resume not supported by network transfers.</source>
+ <translation>Pause og genoptag understøttes ikke af netværksoverførsler.</translation>
+ </message>
+ <message>
+ <source>Invalid source URL &quot;%1&quot;: %2</source>
+ <extracomment>%2 is a sentence describing the error</extracomment>
+ <translation>Ugyldig kilde-URL &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ElevatedExecuteOperation</name>
+ <message>
+ <source>Cannot start detached: &quot;%1&quot;</source>
+ <translation>Kan ikke starte afkoblet: &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>Cannot start: &quot;%1&quot;: %2</source>
+ <translation>Kan ikke starte: &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Program crashed: &quot;%1&quot;</source>
+ <translation>Programmet holdt op med at virke: &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <source>Execution failed (Unexpected exit code: %1): &quot;%2&quot;</source>
+ <translation>Eksekvering fejlede (uventet afslutningskode: %1): &quot;%2&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ExtractArchiveOperation::Runnable</name>
+ <message>
+ <source>Cannot open archive &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne arkivet &quot;%1&quot; til læsning: %2</translation>
+ </message>
+ <message>
+ <source>Error while extracting archive &quot;%1&quot;: %2</source>
+ <translation>Fejl under udtrækning af arkivet &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught while extracting &quot;%1&quot;.</source>
+ <translation>Ukendt undtagelse fanget under udtrækning af &quot;%1&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::FakeStopProcessForUpdateOperation</name>
+ <message>
+ <source>Cannot get package manager core.</source>
+ <translation>Kan ikke få pakkehåndterings-kerne.</translation>
+ </message>
+ <message>
+ <source>This process should be stopped before continuing: %1</source>
+ <translation>Denne proces bør stoppes inden der fortsættes: %1</translation>
+ </message>
+ <message>
+ <source>These processes should be stopped before continuing: %1</source>
+ <translation>Disse processer bør stoppes inden der fortsættes: %1</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::FileTaskObserver</name>
+ <message>
+ <source>%1 of %2</source>
+ <translation>%1 af %2</translation>
+ </message>
+ <message>
+ <source>%1 received.</source>
+ <translation>%1 modtaget.</translation>
+ </message>
+ <message>
+ <source>(%1/sec)</source>
+ <translation>(%1/sek.)</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s), </source>
+ <translation>
+ <numerusform>%n dag, </numerusform>
+ <numerusform>%n dage, </numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s), </source>
+ <translation>
+ <numerusform>%n time, </numerusform>
+ <numerusform>%n timer, </numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n minute(s)</source>
+ <translation>
+ <numerusform>%n minut</numerusform>
+ <numerusform>%n minutter</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n second(s)</source>
+ <translation>
+ <numerusform>%n sekund</numerusform>
+ <numerusform>%n sekunder</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source> - %1%2%3%4 remaining.</source>
+ <translation> - %1%2%3%4 tilbage.</translation>
+ </message>
+ <message>
+ <source> - unknown time remaining.</source>
+ <translation> - ukendt tid tilbage.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::FinishedPage</name>
+ <message>
+ <source>Completing the %1 Wizard</source>
+ <translation>Fuldfører %1 assistenten</translation>
+ </message>
+ <message>
+ <source>Click %1 to exit the %2 Wizard.</source>
+ <translation>Klik på %1 for at afslutte %2 assistenten.</translation>
+ </message>
+ <message>
+ <source>Restart</source>
+ <translation>Genstart</translation>
+ </message>
+ <message>
+ <source>Run %1 now.</source>
+ <translation>Kør %1 nu.</translation>
+ </message>
+ <message>
+ <source>The %1 Wizard failed.</source>
+ <translation>%1 assistenten fejlede.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::GlobalSettingsOperation</name>
+ <message>
+ <source>Settings are not writable.</source>
+ <translation>Indstillinger er ikke skrivbare.</translation>
+ </message>
+ <message>
+ <source>Failed to write settings.</source>
+ <translation>Kunne ikke skrive indstillinger.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::InstallIconsOperation</name>
+ <message>
+ <source>&lt;source path&gt; [vendor prefix]</source>
+ <translation>&lt;kildesti&gt; [producent præfiks]</translation>
+ </message>
+ <message>
+ <source>Invalid Argument: source directory must not be empty.</source>
+ <translation>Ugyldigt argument: kildemappen må ikke være tom.</translation>
+ </message>
+ <message>
+ <source>Cannot backup file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke sikkerhedskopiere filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Failed to overwrite &quot;%1&quot;: %2</source>
+ <translation>Kunne ikke overskrive &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Failed to copy file &quot;%1&quot;: %2</source>
+ <translation>Kunne ikke kopiere filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot create directory &quot;%1&quot;: %2</source>
+ <translation>Kan ikke oprette mappen &quot;%1&quot;: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::IntroductionPage</name>
+ <message>
+ <source>Setup - %1</source>
+ <translation>Opsætning - %1</translation>
+ </message>
+ <message>
+ <source>Welcome to the %1 Setup Wizard.</source>
+ <translation>Velkommen til opsætningsassistenten for %1.</translation>
+ </message>
+ <message>
+ <source>Add or remove components</source>
+ <translation>Tilføj eller fjern komponenter</translation>
+ </message>
+ <message>
+ <source>Update components</source>
+ <translation>Opdater komponenter</translation>
+ </message>
+ <message>
+ <source>Remove all components</source>
+ <translation>Fjern alle komponenter</translation>
+ </message>
+ <message>
+ <source>Retrieving information from remote installation sources...</source>
+ <translation>Henter information fra fjern-installationskilder...</translation>
+ </message>
+ <message>
+ <source>At least one valid and enabled repository required for this action to succeed.</source>
+ <translation>Mindst ét gyldigt og aktiveret repository krævet for at denne handling skal lykkedes.</translation>
+ </message>
+ <message>
+ <source>No updates available.</source>
+ <translation>Ingen tilgængelige opdateringer.</translation>
+ </message>
+ <message>
+ <source> Only local package management available.</source>
+ <translation> Kun lokal pakkehåndtering tilgængeligt.</translation>
+ </message>
+ <message>
+ <source>Quit</source>
+ <translation>Afslut</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LicenseAgreementPage</name>
+ <message>
+ <source>License Agreement</source>
+ <translation>Licensaftale</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <comment>agree license</comment>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Alt+D</source>
+ <comment>do not agree license</comment>
+ <translation>Alt+I</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>Læs venligst følgende licensaftale. Du skal acceptere vilkårene i denne aftale for at fortsætte installationen.</translation>
+ </message>
+ <message>
+ <source>I accept the license.</source>
+ <translation>Jeg accepterer licensen.</translation>
+ </message>
+ <message>
+ <source>I do not accept the license.</source>
+ <translation>Jeg accepterer ikke licensen.</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>Læs venligst følgende licensaftaler. Du skal acceptere vilkårene i disse aftaler for at fortsætte installationen.</translation>
+ </message>
+ <message>
+ <source>I accept the licenses.</source>
+ <translation>Jeg accepterer licenserne.</translation>
+ </message>
+ <message>
+ <source>I do not accept the licenses.</source>
+ <translation>Jeg accepterer ikke licenserne.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LicenseOperation</name>
+ <message>
+ <source>No license files found to copy.</source>
+ <translation>Ingen licensfil fundet til kopiering.</translation>
+ </message>
+ <message>
+ <source>Needed installer object in %1 operation is empty.</source>
+ <translation>Nødvendigt installer-objekt i %1-handling er tomt.</translation>
+ </message>
+ <message>
+ <source>Can not write license file &quot;%1&quot;.</source>
+ <translation>Kan ikke skrive licensfilen &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>No license files found to delete.</source>
+ <translation>Ingen licensfil fundet til sletning.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::LineReplaceOperation</name>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::MetadataJob</name>
+ <message>
+ <source>Missing package manager core engine.</source>
+ <translation>Manglende pakkehåndterings-kernemotor.</translation>
+ </message>
+ <message>
+ <source>Preparing meta information download...</source>
+ <translation>Forbedreder download af meta-information...</translation>
+ </message>
+ <message>
+ <source>Unpacking compressed repositories...</source>
+ <translation>Udpakker komprimerede repositories...</translation>
+ </message>
+ <message>
+ <source>Meta data download canceled.</source>
+ <translation>Download af meta-data annulleret.</translation>
+ </message>
+ <message>
+ <source>Unknown exception during extracting.</source>
+ <translation>Ukendt undtagelse under udtrækning.</translation>
+ </message>
+ <message>
+ <source>Missing proxy credentials.</source>
+ <translation>Manglende proxy-loginoplysninger.</translation>
+ </message>
+ <message>
+ <source>Authentication failed.</source>
+ <translation>Autentifikation fejlede.</translation>
+ </message>
+ <message>
+ <source>Unknown exception during download.</source>
+ <translation>Ukendt undtagelse under download.</translation>
+ </message>
+ <message>
+ <source>Retrieving meta information from remote repository...</source>
+ <translation>Henter meta-information fra fjern-repository...</translation>
+ </message>
+ <message>
+ <source>Failure to fetch repositories.</source>
+ <translation>Kunne ikke hente repositories.</translation>
+ </message>
+ <message>
+ <source>Extracting meta information...</source>
+ <translation>Udtrækker meta-information...</translation>
+ </message>
+ <message>
+ <source>Error while extracting archive &quot;%1&quot;: %2</source>
+ <translation>Fejl under udtrækning af arkivet &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Unknown exception caught while extracting archive &quot;%1&quot;.</source>
+ <translation>Ukendt undtagelse fanget under udtrækning af arkivet &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerCore</name>
+ <message>
+ <source>Error writing Maintenance Tool</source>
+ <translation>Fejl ved skrivning af vedligeholdelsesværktøj</translation>
+ </message>
+ <message>
+ <source>
+Downloading packages...</source>
+ <translation>
+Downloader pakker...</translation>
+ </message>
+ <message>
+ <source>Installation canceled by user.</source>
+ <translation>Installation annulleret af bruger.</translation>
+ </message>
+ <message>
+ <source>All downloads finished.</source>
+ <translation>Alle downloads færdige.</translation>
+ </message>
+ <message>
+ <source>Cancelling the Installer</source>
+ <translation>Annullerer installeren</translation>
+ </message>
+ <message>
+ <source>Authentication Error</source>
+ <translation>Autentifikationsfejl</translation>
+ </message>
+ <message>
+ <source>Some components could not be removed completely because administrative rights could not be acquired: %1.</source>
+ <translation>Nogle komponenter kunne ikke fjernes fuldstændigt da administrative rettigheder ikke kunne anskaffes: %1.</translation>
+ </message>
+ <message>
+ <source>Unknown error.</source>
+ <translation>Ukendt fejl.</translation>
+ </message>
+ <message>
+ <source>Some components could not be removed completely because an unknown error happened.</source>
+ <translation>Nogle komponenter kunne ikke fjernes fuldstændigt da der opstod en ukendt fejl.</translation>
+ </message>
+ <message>
+ <source>Application not running in Package Manager mode.</source>
+ <translation>Program kører ikke i pakkehåndteringstilstand.</translation>
+ </message>
+ <message>
+ <source>No installed packages found.</source>
+ <translation>Ingen installeret pakker fundet.</translation>
+ </message>
+ <message>
+ <source>Application running in Uninstaller mode.</source>
+ <translation>Program kører i afinstallationstilstand.</translation>
+ </message>
+ <message>
+ <source>There is an important update available, please run the updater first.</source>
+ <translation>Der er en vigtig opdatering tilgængelig, kør venligst opdateringen først.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve all dependencies.</source>
+ <translation>Kan ikke løse alle afhængigheder.</translation>
+ </message>
+ <message>
+ <source>Components about to be removed.</source>
+ <translation>Komponenter som er ved at blive fjernet.</translation>
+ </message>
+ <message>
+ <source>Error while elevating access rights.</source>
+ <translation>Fejl under ophøjelse af adgangsrettigheder.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+ <message>
+ <source>invalid</source>
+ <translation>ugyldig</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerCorePrivate</name>
+ <message>
+ <source>Unresolved dependencies</source>
+ <translation>Uløste afhængigheder</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+ <message>
+ <source>Access error</source>
+ <translation>Adgangsfejl</translation>
+ </message>
+ <message>
+ <source>Format error</source>
+ <translation>Format-fejl</translation>
+ </message>
+ <message>
+ <source>Cannot write installer configuration to %1: %2</source>
+ <translation>Kan ikke skrive installerens konfiguration til %1: %2</translation>
+ </message>
+ <message>
+ <source>Stop Processes</source>
+ <translation>Stop processer</translation>
+ </message>
+ <message>
+ <source>These processes should be stopped to continue:
+
+%1</source>
+ <translation>Disse processer bør stoppes inden der fortsættes:
+
+%1</translation>
+ </message>
+ <message>
+ <source>Installation canceled by user</source>
+ <translation>Installation annulleret af bruger</translation>
+ </message>
+ <message>
+ <source>Writing maintenance tool.</source>
+ <translation>Skriver vedligeholdelsesværktøj.</translation>
+ </message>
+ <message>
+ <source>Failed to seek in file %1: %2</source>
+ <translation>Kunne ikke søge i filen %1: %2</translation>
+ </message>
+ <message>
+ <source>Maintenance tool is not a bundle</source>
+ <translation>Vedligeholdelsesværktøjet er ikke et bundt</translation>
+ </message>
+ <message>
+ <source>Cannot remove data file &quot;%1&quot;: %2</source>
+ <translation>Kan ikke fjerne data-filen &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot write maintenance tool data to %1: %2</source>
+ <translation>Kan ikke skrive vedligeholdelsesværktøjets data til %1: %2</translation>
+ </message>
+ <message>
+ <source>Cannot write maintenance tool to &quot;%1&quot;: %2</source>
+ <translation>Kan ikke skrive vedligeholdelsesværktøjet til &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
+ <translation>Kan ikke skrive vedligeholdelsesværktøjets binære data til %1: %2</translation>
+ </message>
+ <message>
+ <source>Variable &apos;TargetDir&apos; not set.</source>
+ <translation>Variablen &apos;TargetDir&apos; ikke sat.</translation>
+ </message>
+ <message>
+ <source>Preparing the installation...</source>
+ <translation>Klargør installationen...</translation>
+ </message>
+ <message>
+ <source>It is not possible to install from network location</source>
+ <translation>Det er ikke muligt at installere fra netværksplacering</translation>
+ </message>
+ <message>
+ <source>Creating local repository</source>
+ <translation>Opretter lokal repository</translation>
+ </message>
+ <message>
+ <source>Creating Maintenance Tool</source>
+ <translation>Opretter vedligeholdelsesværktøj</translation>
+ </message>
+ <message>
+ <source>
+Installation finished!</source>
+ <translation>
+Installation færdig!</translation>
+ </message>
+ <message>
+ <source>
+Installation aborted!</source>
+ <translation>
+Installation afbrudt!</translation>
+ </message>
+ <message>
+ <source>It is not possible to run that operation from a network location</source>
+ <translation>Det er ikke muligt at køre handlingen fra en netværksplacering</translation>
+ </message>
+ <message>
+ <source>Removing deselected components...</source>
+ <translation>Fjerner fravalgte komponenter...</translation>
+ </message>
+ <message>
+ <source>
+Update finished!</source>
+ <translation>
+Opdatering færdig!</translation>
+ </message>
+ <message>
+ <source>
+Update aborted!</source>
+ <translation>
+Opdatering afbrudt!</translation>
+ </message>
+ <message>
+ <source>Uninstallation completed successfully.</source>
+ <translation>Afinstallation fuldført med succes.</translation>
+ </message>
+ <message>
+ <source>Uninstallation aborted.</source>
+ <translation>Afinstallation afbrudt.</translation>
+ </message>
+ <message>
+ <source>
+Installing component %1</source>
+ <translation>
+Installerer komponenten %1</translation>
+ </message>
+ <message>
+ <source>Installer Error</source>
+ <translation>Installer-fejl</translation>
+ </message>
+ <message>
+ <source>Error during installation process (%1):
+%2</source>
+ <translation>Fejl under installationsprocessen (%1):
+%2</translation>
+ </message>
+ <message>
+ <source>Cannot prepare uninstall</source>
+ <translation>Kan ikke klargøre afinstallation</translation>
+ </message>
+ <message>
+ <source>Cannot start uninstall</source>
+ <translation>Kan ikke starte afinstallation</translation>
+ </message>
+ <message>
+ <source>Error during uninstallation process:
+%1</source>
+ <translation>Fejl under afinstallationsprocessen:
+%1</translation>
+ </message>
+ <message>
+ <source>Unknown error</source>
+ <translation>Ukendt fejl</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve remote tree %1.</source>
+ <translation>Kan ikke hente fjern-træet %1.</translation>
+ </message>
+ <message>
+ <source>Failure to read packages from %1.</source>
+ <translation>Kunne ikke læse pakker fra %1.</translation>
+ </message>
+ <message>
+ <source>Cannot retrieve meta information: %1</source>
+ <translation>Kan ikke hente meta-information: %1</translation>
+ </message>
+ <message>
+ <source>Cannot add temporary update source information.</source>
+ <translation>Kan ikke tilføje kildeinformation for midlertidig opdatering.</translation>
+ </message>
+ <message>
+ <source>Cannot find any update source information.</source>
+ <translation>Kan ikke finde nogen kildeinformation for opdatering.</translation>
+ </message>
+ <message>
+ <source>Dependency cycle between components &quot;%1&quot; and &quot;%2&quot; detected.</source>
+ <translation>Afhængighedscyklus registreret mellem komponenterne &quot;%1&quot; og &quot;%2&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PackageManagerGui</name>
+ <message>
+ <source>%1 Setup</source>
+ <translation>%1 opsætning</translation>
+ </message>
+ <message>
+ <source>Maintain %1</source>
+ <translation>Vedligehold %1</translation>
+ </message>
+ <message>
+ <source>Do you want to cancel the installation process?</source>
+ <translation>Vil du annullere installationsprocessen?</translation>
+ </message>
+ <message>
+ <source>Do you want to cancel the uninstallation process?</source>
+ <translation>Vil du annullere afinstallationsprocessen?</translation>
+ </message>
+ <message>
+ <source>Do you want to quit the installer application?</source>
+ <translation>Vil du afslutte installationsprogrammet?</translation>
+ </message>
+ <message>
+ <source>Do you want to quit the uninstaller application?</source>
+ <translation>Vil du afslutte afinstallationsprogrammet?</translation>
+ </message>
+ <message>
+ <source>Do you want to quit the maintenance application?</source>
+ <translation>Vil du afslutte vedligeholdelsesprogrammet?</translation>
+ </message>
+ <message>
+ <source>%1 Question</source>
+ <translation>%1 spørgsmål</translation>
+ </message>
+ <message>
+ <source>Settings</source>
+ <translation>Indstillinger</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+ <message>
+ <source>It is not possible to install from network location.
+Please copy the installer to a local drive</source>
+ <translation>Det er ikke muligt at installere fra netværksplacering.
+Kopiér venligst installeren til et lokalt drev</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PerformInstallationForm</name>
+ <message>
+ <source>&amp;Show Details</source>
+ <translation>&amp;Vis detaljer</translation>
+ </message>
+ <message>
+ <source>&amp;Hide Details</source>
+ <translation>&amp;Skjul detaljer</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::PerformInstallationPage</name>
+ <message>
+ <source>U&amp;ninstall</source>
+ <translation>&amp;Afinstaller</translation>
+ </message>
+ <message>
+ <source>Uninstalling %1</source>
+ <translation>Afinstallerer %1</translation>
+ </message>
+ <message>
+ <source>&amp;Update</source>
+ <translation>&amp;Opdater</translation>
+ </message>
+ <message>
+ <source>Updating components of %1</source>
+ <translation>Opdaterer komponenter af %1</translation>
+ </message>
+ <message>
+ <source>&amp;Install</source>
+ <translation>&amp;Installer</translation>
+ </message>
+ <message>
+ <source>Installing %1</source>
+ <translation>Installerer %1</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ProxyCredentialsDialog</name>
+ <message>
+ <source>Dialog</source>
+ <translation>Dialog</translation>
+ </message>
+ <message>
+ <source>The proxy %1 requires a username and password.</source>
+ <translation>Proxyen %1 kræver brugernavn og adgangskode.</translation>
+ </message>
+ <message>
+ <source>Username:</source>
+ <translation>Brugernavn:</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Brugernavn</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Adgangskode:</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Adgangskode</translation>
+ </message>
+ <message>
+ <source>Proxy Credentials</source>
+ <translation>Proxy-loginoplysninger</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ReadyForInstallationPage</name>
+ <message>
+ <source>U&amp;ninstall</source>
+ <translation>&amp;Afinstaller</translation>
+ </message>
+ <message>
+ <source>Ready to Uninstall</source>
+ <translation>Klar til afinstallation</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>Opsætningen er nu klar til at begynde fjernelsen af %1 fra din computer.&lt;br&gt;&lt;font color=&quot;red&quot;&gt;Programmappen %2 slettes fuldstændigt&lt;/font&gt;, inklusiv alt indhold i mappen!</translation>
+ </message>
+ <message>
+ <source>U&amp;pdate</source>
+ <translation>&amp;Opdater</translation>
+ </message>
+ <message>
+ <source>Ready to Update Packages</source>
+ <translation>Klar til opdateringspakker</translation>
+ </message>
+ <message>
+ <source>Setup is now ready to begin updating your installation.</source>
+ <translation>Opsætningen er nu klar til at begynde opdateringen af din installation.</translation>
+ </message>
+ <message>
+ <source>&amp;Install</source>
+ <translation>&amp;Installer</translation>
+ </message>
+ <message>
+ <source>Ready to Install</source>
+ <translation>Klar til installation</translation>
+ </message>
+ <message>
+ <source>Setup is now ready to begin installing %1 on your computer.</source>
+ <translation>Opsætningen er nu klar til at begynde installationen af %1 på din computer.</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store temporary files and the installation. %1 are available, while %2 are at least required.</source>
+ <translation>Ikke nok displads til at lagre midlertidige filer og installationen. %1 er tilgængelige, mens mindst %2 kræves.</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store all selected components! %1 are available while %2 are at least required.</source>
+ <translation>Ikke nok displads til at lagre alle valgte komponenter! %1 er tilgængelige, mens mindst %2 kræves.</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store temporary files! %1 are available while %2 are at least required.</source>
+ <translation>Ikke nok displads til at lagre midlertidige filer! %1 er tilgængelige, mens mindst %2 kræves.</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>Det bind du har valg til installation ser ud til at have tilstrækkelig plads til installationen, men der vil efterfølgende være mindre end 1% af bindets plads tilgængeligt. %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>Det bind du har valg til installation ser ud til at have tilstrækkelig plads til installationen, men der vil efterfølgende være mindre end 100 MB tilgængeligt. %1</translation>
+ </message>
+ <message>
+ <source>Installation will use %1 of disk space.</source>
+ <translation>Installationen vil bruge %1 diskplads.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RegisterFileTypeOperation</name>
+ <message>
+ <source>&lt;extension&gt; &lt;command&gt; [description [contentType [icon]]]</source>
+ <translation>&lt;udvidelse&gt; &lt;kommando&gt; [beskrivelse [indholdsType [ikon]]]</translation>
+ </message>
+ <message>
+ <source>Registering file types is only supported on Windows.</source>
+ <translation>Tilknytning af filtyper understøttes kun i Windows.</translation>
+ </message>
+ <message>
+ <source>Register File Type: Invalid arguments</source>
+ <translation>Tilknytning af filtype: ugyldige argumenter</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RemoteObject</name>
+ <message>
+ <source>Cannot read all data after sending command: %1. Bytes expected: %2, Bytes received: %3. Error: %4</source>
+ <translation>Kan ikke læse alle data efter afsendelse af kommando: %1. Byte ventet: %2, byte modtaget: %3. Fejl: %4</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ReplaceOperation</name>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til læsning: %2</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Kan ikke åbne filen &quot;%1&quot; til skrivning: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::Resource</name>
+ <message>
+ <source>Cannot open resource %1 for reading.</source>
+ <translation>Kan ikke åbne ressourcen %1 til læsning.</translation>
+ </message>
+ <message>
+ <source>Read failed after %1 bytes: %2</source>
+ <translation>Læsning fejlede efter %1 byte: %2</translation>
+ </message>
+ <message>
+ <source>Write failed after %1 bytes: %2</source>
+ <translation>Skrivning fejlede efter %1 byte: %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::RestartPage</name>
+ <message>
+ <source>Completing the %1 Setup Wizard</source>
+ <translation>Fuldfører opsætningsassistenten for %1</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ScriptEngine</name>
+ <message>
+ <source>Cannot open script file at %1: %2</source>
+ <translation>Kan ikke åbne script-filen ved %1: %2</translation>
+ </message>
+ <message>
+ <source>Exception while loading the component script &quot;%1&quot;: %2</source>
+ <translation>Undtagelse under indlæsning af komponent-scriptet &quot;%1&quot;: %2</translation>
+ </message>
+ <message>
+ <source>Unknown error.</source>
+ <translation>Ukendt fejl.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SelfRestartOperation</name>
+ <message>
+ <source>Installer object needed in operation %1 is empty.</source>
+ <translation>Nødvendigt installer-objekt i %1-handling er tomt.</translation>
+ </message>
+ <message>
+ <source>Self Restart: Only valid within updater or packagemanager mode.</source>
+ <translation>Selv-genstart: kun gyldigt i opdaterings- eller pakkehåndteringstilstand.</translation>
+ </message>
+ <message>
+ <source>Self Restart: Invalid arguments</source>
+ <translation>Selv-genstart: ugyldige argumenter</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ServerAuthenticationDialog</name>
+ <message>
+ <source>Server Requires Authentication</source>
+ <translation>Serveren kræver autentifikation</translation>
+ </message>
+ <message>
+ <source>You need to supply a username and password to access this site.</source>
+ <translation>Du skal angive brugernavn og adgangskode for at tilgå dette sted.</translation>
+ </message>
+ <message>
+ <source>Username:</source>
+ <translation>Brugernavn:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Adgangskode:</translation>
+ </message>
+ <message>
+ <source>%1 at %2</source>
+ <translation>%1 hos %2</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SettingsOperation</name>
+ <message>
+ <source>Missing argument(s) &quot;%1&quot; calling %2 with arguments &quot;%3&quot;.</source>
+ <translation>Manglende argument(er) &quot;%1&quot; kalder %2 med argumenterne &quot;%3&quot;.</translation>
+ </message>
+ <message>
+ <source>Current method argument calling &quot;%1&quot; with arguments &quot;%2&quot; is not supported. Please use set, remove, add_array_value or remove_array_value.</source>
+ <translation>Aktuelle metode-argument som kalder &quot;%1&quot; med argumenterne &quot;%2&quot; understøttes ikke. Brug venligst set, remove, add_array_value eller remove_array_value.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::SimpleMoveFileOperation</name>
+ <message>
+ <source>None of the arguments can be empty: source &quot;%1&quot;, target &quot;%2&quot;.</source>
+ <translation>Ingen af argumenterne må være tomme: kilde &quot;%1&quot;, mål &quot;%2&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot move file from &quot;%1&quot; to &quot;%2&quot;, because the target path exists and is not removable.</source>
+ <translation>Kan ikke flytte filen fra &quot;%1&quot; to &quot;%2&quot;, da mål-stien findes og ikke er flytbar.</translation>
+ </message>
+ <message>
+ <source>Cannot move file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Kan ikke flytte filen &quot;%1&quot; til &quot;%2&quot;: %3</translation>
+ </message>
+ <message>
+ <source>Moving file &quot;%1&quot; to &quot;%2&quot;.</source>
+ <translation>Flytter filen &quot;%1&quot; til &quot;%2&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::StartMenuDirectoryPage</name>
+ <message>
+ <source>Start Menu shortcuts</source>
+ <translation>Genveje i menuen Start</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 directory.</source>
+ <translation>Vælg hvor i menuen Start du ønsker programmernes genveje oprettet. Du kan også indtaste et navn for at oprette en ny mappe.</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::TargetDirectoryPage</name>
+ <message>
+ <source>Installation Folder</source>
+ <translation>Installationsmappe</translation>
+ </message>
+ <message>
+ <source>Please specify the directory where %1 will be installed.</source>
+ <translation>Specificer venligst mappen hvor %1 skal installeres.</translation>
+ </message>
+ <message>
+ <source>Alt+R</source>
+ <comment>browse file system to choose a file</comment>
+ <translation>Alt+G</translation>
+ </message>
+ <message>
+ <source>B&amp;rowse...</source>
+ <translation>&amp;Gennemse...</translation>
+ </message>
+ <message>
+ <source>The directory you selected already exists and contains an installation. Choose a different target for installation.</source>
+ <translation>Mappen du har valgt findes allerede og indeholder en installation. Vælg et andet mål til installationen.</translation>
+ </message>
+ <message>
+ <source>You have selected an existing, non-empty directory for installation.
+Note that it will be completely wiped on uninstallation of this application.
+It is not advisable to install into this directory as installation might fail.
+Do you want to continue?</source>
+ <translation>Du har valgt en eksisterende, ikke-tom mappe til installation.
+Bemærk at den vil blive fuldstændigt ryddet ved afinstallation af dette program.
+Det anbefales ikke at installere i denne mappe eftersom installationen kan fejle.
+Vil du fortsætte?</translation>
+ </message>
+ <message>
+ <source>You have selected an existing file or symlink, please choose a different target for installation.</source>
+ <translation>Du har valgt en eksisterende fil eller symlink, vælg venligst et andet mål for installationen.</translation>
+ </message>
+ <message>
+ <source>Select Installation Folder</source>
+ <translation>Vælg installationsmappe</translation>
+ </message>
+ <message>
+ <source>The installation path cannot be empty, please specify a valid directory.</source>
+ <translation>Installationsstien må ikke være tom, specificer venligst en gyldig mappe.</translation>
+ </message>
+ <message>
+ <source>The installation path cannot be relative, please specify an absolute path.</source>
+ <translation>Installationsstien må ikke være relativ, specificer venligst en absolut sti.</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>Stien eller installationsmappen indeholder ikke-ASCII-tegn. Det understøttes ikke i øjeblikket! Vælg venligst en anden sti eller installationsmappe.</translation>
+ </message>
+ <message>
+ <source>As the install directory is completely deleted, installing in %1 is forbidden.</source>
+ <translation>Da installationsmappen er fuldstændigt slettet, er installation i %1 forbudt.</translation>
+ </message>
+ <message>
+ <source>The path you have entered is too long, please make sure to specify a valid path.</source>
+ <translation>Stien du har indtastet er for lang, sørg venligst for at specificere en gyldig sti.</translation>
+ </message>
+ <message>
+ <source>The path you have entered is not valid, please make sure to specify a valid target.</source>
+ <translation>Stien du har indtastet er ikke gyldig, sørg venligst for at specificere et gyldigt mål.</translation>
+ </message>
+ <message>
+ <source>The path you have entered is not valid, please make sure to specify a valid drive.</source>
+ <translation>Stien du har indtastet er ikke gyldig, sørg venligst for at specificere et gyldigt drev.</translation>
+ </message>
+ <message>
+ <source>The installation path must not end with &apos;.&apos;, please specify a valid directory.</source>
+ <translation>Installationsstien må ikke slutte med &apos;.&apos;, specificer venligst en gyldig mappe.</translation>
+ </message>
+ <message>
+ <source>The installation path must not contain &quot;%1&quot;, please specify a valid directory.</source>
+ <translation>Installationsstien må ikke indholde &quot;%1&quot;, specificer venligst en gyldig mappe.</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Advarsel</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::TestRepository</name>
+ <message>
+ <source>Missing package manager core engine.</source>
+ <translation>Manglende pakkehåndterings-kernemotor.</translation>
+ </message>
+ <message>
+ <source>Empty repository URL.</source>
+ <translation>Tom repository-URL.</translation>
+ </message>
+ <message>
+ <source>Download canceled.</source>
+ <translation>Download annulleret.</translation>
+ </message>
+ <message>
+ <source>Timeout while testing repository &quot;%1&quot;.</source>
+ <translation>Timeout ved test af repository&apos;et &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <source>Cannot parse Updates.xml: %1</source>
+ <translation>Kan ikke parse Updates.xml: %1</translation>
+ </message>
+ <message>
+ <source>Cannot open Updates.xml for reading: %1</source>
+ <translation>Kan ikke åbne Updates.xml til læsning: %1</translation>
+ </message>
+ <message>
+ <source>Authentication failed.</source>
+ <translation>Autentifikation fejlede.</translation>
+ </message>
+ <message>
+ <source>Unknown error while testing repository &quot;%1&quot;.</source>
+ <translation>Ukendt fejl ved test af repository&apos;et &quot;%1&quot;.</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Authorization required</source>
+ <translation>Godkendelse kræves</translation>
+ </message>
+ <message>
+ <source>Enter your password to authorize for sudo:</source>
+ <translation>Indtast din adgangskode til godkendelse for sudo:</translation>
+ </message>
+ <message>
+ <source>Error acquiring admin rights</source>
+ <translation>Fejl ved anskaffelse af administrator rettigheder</translation>
+ </message>
+</context>
+<context>
+ <name>RemoteClient</name>
+ <message>
+ <source>Cannot get authorization.</source>
+ <translation>Kan ikke få godkendelse.</translation>
+ </message>
+ <message>
+ <source>Cannot get authorization that is needed for continuing the installation.
+
+Please start the setup program as a user with the appropriate rights.
+Or accept the elevation of access rights if being asked.</source>
+ <translation>Kan ikke få godkendelse som er nødvendigt for at fortsætte installationen.
+
+Start venligst opsætningsprogrammet som en bruger med de fornødne rettigheder.
+Eller acceptér ophøjelsen af adgangsrettigheder hvis du bliver spurgt.</translation>
+ </message>
+ <message>
+ <source>Cannot get authorization that is needed for continuing the installation.
+ Either abort the installation or use the fallback solution by running
+
+%1
+
+as a user with the appropriate rights and then clicking OK.</source>
+ <translation>Kan ikke få godkendelse som er nødvendigt for at fortsætte installationen.
+ Abryd enten installationen eller brug tilbagefaldsløsningen ved at køre
+
+%1
+
+som en bruger med de fornødne rettigheder og klik så på OK.</translation>
+ </message>
+</context>
+<context>
+ <name>ResourceCollectionManager</name>
+ <message>
+ <source>Cannot open resource %1: %2</source>
+ <translation>Kan ikke åbne ressourcen %1: %2</translation>
+ </message>
+</context>
+<context>
+ <name>Settings</name>
+ <message>
+ <source>Cannot open settings file %1 for reading: %2</source>
+ <translation>Kan ikke åbne indstillingsfilen %1 til læsning: %2</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsDialog</name>
+ <message>
+ <source>Settings</source>
+ <translation>Indstillinger</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netværk</translation>
+ </message>
+ <message>
+ <source>No proxy</source>
+ <translation>Ingen proxy</translation>
+ </message>
+ <message>
+ <source>System proxy settings</source>
+ <translation>Systemets proxy-indstillinger</translation>
+ </message>
+ <message>
+ <source>Manual proxy configuration</source>
+ <translation>Manuel proxy-konfiguration</translation>
+ </message>
+ <message>
+ <source>HTTP proxy:</source>
+ <translation>HTTP-proxy:</translation>
+ </message>
+ <message>
+ <source>Port:</source>
+ <translation>Port:</translation>
+ </message>
+ <message>
+ <source>FTP proxy:</source>
+ <translation>FTP-proxy:</translation>
+ </message>
+ <message>
+ <source>Repositories</source>
+ <translation>Repositories</translation>
+ </message>
+ <message>
+ <source>Add Username and Password for authentication if needed.</source>
+ <translation>Tilføj brugernavn og adgangskode til autentifikation hvis det er nødvendigt.</translation>
+ </message>
+ <message>
+ <source>Use temporary repositories only</source>
+ <translation>Brug kun midlertidige repositories</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>Tilføj</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Fjern</translation>
+ </message>
+ <message>
+ <source>Test</source>
+ <translation>Test</translation>
+ </message>
+ <message>
+ <source>Show Passwords</source>
+ <translation>Vis adgangskoder</translation>
+ </message>
+ <message>
+ <source>Check this to use repository during fetch.</source>
+ <translation>Tilvælg denne for at bruge repository under hentning.</translation>
+ </message>
+ <message>
+ <source>Add the username to authenticate on the server.</source>
+ <translation>Tilføj brugernavnet til at autentificere på serveren.</translation>
+ </message>
+ <message>
+ <source>Add the password to authenticate on the server.</source>
+ <translation>Tilføj adgangskoden til at autentificere på serveren.</translation>
+ </message>
+ <message>
+ <source>The servers URL that contains a valid repository.</source>
+ <translation>Serverens URL som indeholder et gyldigt repository.</translation>
+ </message>
+ <message>
+ <source>An error occurred while testing this repository.</source>
+ <translation>Der opstod en fejl under test af dette repository.</translation>
+ </message>
+ <message>
+ <source>The repository was tested successfully.</source>
+ <translation>Repository&apos;et blev testet med succes.</translation>
+ </message>
+ <message>
+ <source>Do you want to disable the repository?</source>
+ <translation>Vil du deaktivere repository&apos;et? </translation>
+ </message>
+ <message>
+ <source>Do you want to enable the repository?</source>
+ <translation>Vil du aktivere repository&apos;et?</translation>
+ </message>
+ <message>
+ <source>Hide Passwords</source>
+ <translation>Skjul adgangskoder</translation>
+ </message>
+ <message>
+ <source>Use</source>
+ <translation>Brug</translation>
+ </message>
+ <message>
+ <source>Username</source>
+ <translation>Brugernavn</translation>
+ </message>
+ <message>
+ <source>Password</source>
+ <translation>Adgangskode</translation>
+ </message>
+ <message>
+ <source>Repository</source>
+ <translation>Repository</translation>
+ </message>
+ <message>
+ <source>Default repositories</source>
+ <translation>Standard repositories</translation>
+ </message>
+ <message>
+ <source>Temporary repositories</source>
+ <translation>Midlertidige repositories</translation>
+ </message>
+ <message>
+ <source>User defined repositories</source>
+ <translation>Brugerdefinerede repositories</translation>
+ </message>
+</context>
+<context>
+ <name>UpdateOperation</name>
+ <message>
+ <source>Registry path %1 is not writable.</source>
+ <translation>Registreringsdatabasestien %1 er ikke skrivbar.</translation>
+ </message>
+ <message>
+ <source>Cannot write to registry path %1.</source>
+ <translation>Kan ikke skrive til registreringsdatabasestien %1.</translation>
+ </message>
+ <message>
+ <source>exactly %1</source>
+ <translation>præcist %1</translation>
+ </message>
+ <message>
+ <source>at least %1</source>
+ <translation>mindst %1</translation>
+ </message>
+ <message>
+ <source>not more than %1</source>
+ <translation>ikke flere end %1</translation>
+ </message>
+ <message>
+ <source>%1 or %2</source>
+ <translation>%1 eller %2</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 til %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>Invalid arguments in %1: %n arguments given, %2 arguments expected.</source>
+ <translation>
+ <numerusform>Ugyldigt argument i %1: %n argument givet, %2 argument ventet.</numerusform>
+ <numerusform>Ugyldige argumenter i %1: %n argumenter givet, %2 argumenter ventet.</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>Invalid arguments in %1: %n arguments given, %2 arguments expected in the form: %3.</source>
+ <translation>
+ <numerusform>Ugyldigt argument i %1: %n argument givet, %2 argument ventet i udformningen: %3.</numerusform>
+ <numerusform>Ugyldige argumenter i %1: %n argumenter givet, %2 argumenter ventet i udformningen: %3.</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Renaming file &quot;%1&quot; to &quot;%2&quot; failed: %3</source>
+ <translation>Omdøbning af filen &quot;%1&quot; til &quot;%2&quot; fejlede: %3</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/sdk/translations/de.ts b/src/sdk/translations/de.ts
index 20d510564..23aa045b1 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>
@@ -46,11 +46,11 @@
<name>Dialog</name>
<message>
<source>Http authentication required</source>
- <translation>HTTP Authentifizierung erforderlich</translation>
+ <translation>HTTP-Authentifizierung erforderlich</translation>
</message>
<message>
<source>You need to supply a Username and Password to access this site.</source>
- <translation>Nutzername und Passwort für die Authentifizierung benötigt.</translation>
+ <translation>Benutzername und Passwort für die Authentifizierung benötigt.</translation>
</message>
<message>
<source>Username:</source>
@@ -72,46 +72,46 @@
<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>
- <translation>Konnte keine Dateisystemverknüpfung (Symlink) %1 anlegen. Fehlermeldung: %2</translation>
+ <source>Cannot create symlink at %1. %2</source>
+ <translation>Konnte Verknüpfung (Symlink) %1 nicht anlegen. Fehlermeldung: %2</translation>
</message>
</context>
<context>
<name>InstallerCalculator</name>
<message>
<source>Components added as automatic dependencies:</source>
- <translation>Komponenten, die als automatische Abhängigkeiten zugefügt wurden:</translation>
+ <translation>Komponenten, die als automatische Abhängigkeiten hinzugefügt wurden:</translation>
</message>
<message>
<source>Components added as dependency for &apos;%1&apos;:</source>
- <translation>Komponenten, die als Abhängigkeiten für &apos;%1&apos; zugefügt wurden:</translation>
+ <translation>Komponenten, die als Abhängigkeiten für &apos;%1&apos; hinzugefügt wurden:</translation>
</message>
<message>
<source>Components that have resolved dependencies:</source>
@@ -123,7 +123,7 @@
</message>
<message>
<source>Recursion detected, component &apos;%1&apos; already added with reason: &apos;%2&apos;</source>
- <translation>Rekursion entdeckt, Komponente &apos;%1&apos; wurde bereits zugefügt aufgrund von: &apos;%2&apos;</translation>
+ <translation>Rekursion entdeckt, Komponente &apos;%1&apos; wurde bereits aufgrund von &apos;%2&apos; hinzugefügt</translation>
</message>
<message>
<source>Cannot find missing dependency &apos;%1&apos; for &apos;%2&apos;.</source>
@@ -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">
@@ -526,10 +526,10 @@
</message>
<message>
<source>Downloading Updates.xml from update sources.</source>
- <translation>Lade Updates.xml von der Aktualisierungsquelle herunter.</translation>
+ <translation>Datei Updates.xml wird von der Aktualisierungsquelle heruntergeladen.</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>
@@ -538,11 +538,11 @@
</message>
<message>
<source>Computing applicable updates.</source>
- <translation>Berechne anwendbare Aktualisierungen.</translation>
+ <translation>Anwendbare Aktualisierungen werden ermittelt.</translation>
</message>
<message>
<source>Application updates computed.</source>
- <translation>Anwendbare Aktualisierungen berechnet.</translation>
+ <translation>Anwendbare Aktualisierungen ermittelt.</translation>
</message>
</context>
<context>
@@ -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>
@@ -806,18 +806,18 @@
</message>
<message>
<source>Copy failed. Error: %1</source>
- <translation>Kopieren schlug fehl. Fehlermeldung: %1</translation>
+ <translation>Kopieren ist fehlgeschlagen. Fehlermeldung: %1</translation>
</message>
<message>
<source>Write failed after %1 bytes: %2</source>
<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>
@@ -849,22 +849,22 @@
<name>QInstaller::Component</name>
<message>
<source>Components cannot have children in updater mode.</source>
- <translation>Komponenten können im Updater Modus keine Kinder haben.</translation>
+ <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>
@@ -908,7 +908,7 @@
</message>
<message>
<source>Size</source>
- <translation>Grösse</translation>
+ <translation>Größe</translation>
</message>
<message>
<source>Component is marked for installation.</source>
@@ -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>
- <translation>Konnte Dateirechte auf Datei %1 nicht setzen!</translation>
+ <source>Cannot set file permissions %1!</source>
+ <translation>Konnte Dateiberechtigungen 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>
@@ -1141,22 +1141,22 @@
</message>
<message>
<source>Installer needs to be an offline version: %1.</source>
- <translation>Installer muss eine offline Version sein: %1.</translation>
+ <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>
@@ -1165,11 +1165,11 @@
</message>
<message>
<source>Removing file: %0</source>
- <translation>Entferne Datei %0</translation>
+ <translation>Datei %0 wird entfernt</translation>
</message>
<message>
- <source>Could not remove %0.</source>
- <translation>Konnte Datei %0. nicht löschen.</translation>
+ <source>Cannot remove %0.</source>
+ <translation>Konnte Datei %0 nicht löschen.</translation>
</message>
<message>
<source>Cannot remove directory %1: %2</source>
@@ -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>
@@ -1266,7 +1266,7 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Checksum mismatch detected &apos;%1&apos;.</source>
- <translation>Checksumme stimmt nicht überein &apos;%1&apos;.</translation>
+ <translation>Checksummen stimmen nicht überein &apos;%1&apos;.</translation>
</message>
<message>
<source>Network error while downloading &apos;%1&apos;: %2.</source>
@@ -1280,7 +1280,7 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Pause and resume not supported by network transfers.</source>
- <translation>Pause und Fortsetzen werden bei Netzwerkübertragungen nicht unterstützt.</translation>
+ <translation>Pausieren und Fortsetzen werden bei Netzwerkübertragungen nicht unterstützt.</translation>
</message>
<message>
<source>Invalid source &apos;%1&apos;. Error: %2.</source>
@@ -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>
- <translation>Ausführung fehlgeschlagen: Konnte %1 nicht detached starten.</translation>
+ <source>Execution failed: Cannot start detached: &quot;%1&quot;</source>
+ <translation>Ausführung fehlgeschlagen: Konnte %1 nicht losgelöst 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>
@@ -1358,7 +1358,7 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Unknown exception caught while extracting %1.</source>
- <translation>Beim Auspacken von %1 trat eine unbekannte Ausnahmebedingung auf.</translation>
+ <translation>Beim Auspacken von %1 ist eine unbekannte Ausnahmebedingung aufgetreten.</translation>
</message>
</context>
<context>
@@ -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>
@@ -1435,7 +1435,7 @@ Fehler beim Laden von %2</translation>
<name>QInstaller::FinishedPage</name>
<message>
<source>Completing the %1 Wizard</source>
- <translation>Beende den %1 Assistenten.</translation>
+ <translation>Den %1-Assistent abschließen.</translation>
</message>
<message>
<source>Click Done to exit the %1 Wizard.</source>
@@ -1455,7 +1455,7 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>The %1 Wizard failed.</source>
- <translation>Der %1 Assistent ist fehlgeschlagen.</translation>
+ <translation>Der %1-Assistent ist fehlgeschlagen.</translation>
</message>
</context>
<context>
@@ -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>
@@ -1520,7 +1520,7 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Welcome to the %1 Setup Wizard.</source>
- <translation>Willkommen zum %1 Einrichtungsassistenten.</translation>
+ <translation>Willkommen zum %1-Einrichtungsassistenten.</translation>
</message>
<message>
<source>Add or remove components</source>
@@ -1536,11 +1536,11 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Retrieving information from remote installation sources...</source>
- <translation>Empfange Daten vom Installationsserver...</translation>
+ <translation>Daten werden vom Installationsserver empfangen ...</translation>
</message>
<message>
<source>At least one valid and enabled repository required for this action to succeed.</source>
- <translation>Mindestens ein gültiges und aktiviertes Repository wird benötigt, um diese Aktion erfolgreich abzuschliessen.</translation>
+ <translation>Mindestens ein gültiges und aktiviertes Repository wird benötigt, um diese Aktion erfolgreich abzuschließen.</translation>
</message>
<message>
<source>No updates available.</source>
@@ -1606,7 +1606,7 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Needed installer object in %1 operation is empty.</source>
- <translation>Das für die Anweisung %1 benötigte Installerobjekt ist leer.</translation>
+ <translation>Das für die Anweisung %1 benötigte Installer-Objekt ist leer.</translation>
</message>
<message>
<source>Can not write license file: %1.</source>
@@ -1640,11 +1640,11 @@ Fehler beim Laden von %2</translation>
<name>QInstaller::MetadataJob</name>
<message>
<source>Missing package manager core engine.</source>
- <translation>Fehlende Paketmanager Kernkomponente.</translation>
+ <translation>Fehlende Paketmanager-Kernkomponente.</translation>
</message>
<message>
<source>Preparing meta information download...</source>
- <translation>Bereite Herunterladen der Metainformationen vor...</translation>
+ <translation>Herunterladen der Metainformationen wird vorbereitet ...</translation>
</message>
<message>
<source>Meta data download canceled.</source>
@@ -1652,7 +1652,7 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Missing proxy credentials.</source>
- <translation>Fehlende Proxy Zugangsdaten.</translation>
+ <translation>Fehlende Proxy-Zugangsdaten.</translation>
</message>
<message>
<source>Authentication failed.</source>
@@ -1660,11 +1660,11 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Unknown exception during download.</source>
- <translation>Beim Herunterladen trat eine unbekannte Ausnahmebedingung auf.</translation>
+ <translation>Beim Herunterladen ist eine unbekannte Ausnahmebedingung aufgetreten.</translation>
</message>
<message>
<source>Retrieving meta information from remote repository...</source>
- <translation>Empfange Metainformationen vom Installationsserver...</translation>
+ <translation>Metainformationen werden vom Installationsserver empfangen ...</translation>
</message>
<message>
<source>Failure to fetch repositories.</source>
@@ -1672,11 +1672,11 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Unknown exception during extracting.</source>
- <translation>Beim Auspacken trat eine unbekannte Ausnahmebedingung auf.</translation>
+ <translation>Beim Auspacken ist eine unbekannte Ausnahmebedingung aufgetreten.</translation>
</message>
<message>
<source>Extracting meta information...</source>
- <translation>Packe Metainformationen aus...</translation>
+ <translation>Metainformationen werden ausgepackt ...</translation>
</message>
<message>
<source>Error while extracting &apos;%1&apos;: %2</source>
@@ -1684,10 +1684,10 @@ Fehler beim Laden von %2</translation>
</message>
<message>
<source>Unknown exception caught while extracting %1.</source>
- <translation>Beim Auspacken von %1 trat eine unbekannte Ausnahmebedingung auf.</translation>
+ <translation>Beim Auspacken von %1 ist eine unbekannte Ausnahmebedingung aufgetreten.</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>
@@ -1697,11 +1697,11 @@ Fehler beim Laden von %2</translation>
<source>
Downloading packages...</source>
<translation>
-Lade Pakete herunter...</translation>
+Pakete werden heruntergeladen ...</translation>
</message>
<message>
<source>Installation canceled by user</source>
- <translation>Installation durch den Nutzer abgebrochen</translation>
+ <translation>Installation durch den Benutzer abgebrochen</translation>
</message>
<message>
<source>All downloads finished.</source>
@@ -1713,7 +1713,7 @@ Lade Pakete herunter...</translation>
</message>
<message>
<source>Cancelling the Installer</source>
- <translation>Breche den Installationsvorgang ab</translation>
+ <translation>Der Installationsvorgang wird abgebrochen</translation>
</message>
<message>
<source>Error writing Maintenance Tool</source>
@@ -1725,7 +1725,7 @@ Lade Pakete herunter...</translation>
</message>
<message>
<source>Some components could not be removed completely because admin rights could not be acquired: %1.</source>
- <translation>Einige Komponenten konnten nicht vollständig entfernt werden, weil die nötigen Systemverwalterrechte nicht erlangt werden konnten. Fehlermeldung: %1</translation>
+ <translation>Einige Komponenten konnten nicht vollständig entfernt werden, weil die nötigen Administratorrechte nicht erlangt werden konnten. Fehlermeldung: %1</translation>
</message>
<message>
<source>Unknown error.</source>
@@ -1733,11 +1733,11 @@ Lade Pakete herunter...</translation>
</message>
<message>
<source>Some components could not be removed completely because an unknown error happened.</source>
- <translation>Einige Komponenten konnten nicht vollständig entfernt werden, weil ein unbekannter Fehler auftrat.</translation>
+ <translation>Einige Komponenten konnten nicht vollständig entfernt werden, weil ein unbekannter Fehler aufgetreten ist.</translation>
</message>
<message>
<source>Application not running in Package Manager mode!</source>
- <translation>Die Anwendung ist nicht im Paketverwaltermodus!</translation>
+ <translation>Die Anwendung läuft nicht im Paketverwaltungsmodus.</translation>
</message>
<message>
<source>No installed packages found.</source>
@@ -1745,7 +1745,7 @@ Lade Pakete herunter...</translation>
</message>
<message>
<source>Application running in Uninstaller mode!</source>
- <translation>Die Anwendung befindet sich im Deinstallierermodus!</translation>
+ <translation>Die Anwendung läuft im Deinstallationsmodus.</translation>
</message>
<message>
<source>There is an important update available, please run the updater first.</source>
@@ -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>
@@ -1792,7 +1792,7 @@ Lade Pakete herunter...</translation>
</message>
<message>
<source>Installation canceled by user</source>
- <translation>Installation durch den Nutzer abgebrochen</translation>
+ <translation>Installation durch den Benutzer abgebrochen</translation>
</message>
<message>
<source>Variable &apos;TargetDir&apos; not set.</source>
@@ -1800,15 +1800,15 @@ Lade Pakete herunter...</translation>
</message>
<message>
<source>Preparing the installation...</source>
- <translation>Bereite Installation vor...</translation>
+ <translation>Installation wird vorbereitet ...</translation>
</message>
<message>
<source>It is not possible to install from network location</source>
- <translation>Es ist nicht möglich, von einem Netzwerkort aus zu installieren</translation>
+ <translation>Es ist nicht möglich, von einem Netzwerk-Speicherort aus zu installieren</translation>
</message>
<message>
<source>Creating local repository</source>
- <translation>Erstelle lokale Quelle</translation>
+ <translation>Lokale Quelle wird erstellt</translation>
</message>
<message>
<source>
@@ -1824,11 +1824,11 @@ Installation abgebrochen!</translation>
</message>
<message>
<source>It is not possible to run that operation from a network location</source>
- <translation>Es ist nicht möglich, diese Oparation von einem Netzwerkort aus zu starten</translation>
+ <translation>Es ist nicht möglich, diese Oparation von einem Netzwerk-Speicherort aus zu starten</translation>
</message>
<message>
<source>Removing deselected components...</source>
- <translation>Entferne abgewählte Komponenten...</translation>
+ <translation>Abgewählte Komponenten werden entfernt ...</translation>
</message>
<message>
<source>
@@ -1859,24 +1859,24 @@ 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>
- <translation>Konnte Binäre Datei des Verwaltungswerkzeugs nicht nach %1 schreiben: %2</translation>
+ <source>Cannot write maintenance tool binary data to %1: %2</source>
+ <translation>Konnte Binärdaten des Verwaltungswerkzeugs nicht nach %1 schreiben: %2</translation>
</message>
<message>
<source>Creating Maintenance Tool</source>
- <translation>Erstelle Verwaltungswerkzeug</translation>
+ <translation>Verwaltungswerkzeug wird erstellt</translation>
</message>
<message>
<source>Uninstallation completed successfully.</source>
@@ -1890,7 +1890,7 @@ Aktualisierung abgebrochen!</translation>
<source>
Installing component %1</source>
<translation>
-Installiere Komponente %1</translation>
+Komponente %1 wird installiert</translation>
</message>
<message>
<source>Installer Error</source>
@@ -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>
- <translation>Konnte Informationen zu temporären Aktualisierungsquellen nicht hinzufügen.</translation>
+ <source>Cannot add temporary update source information.</source>
+ <translation>Konnte Informationen nicht zu temporären Aktualisierungsquellen 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>
@@ -1973,7 +1973,7 @@ Installiere Komponente %1</translation>
</message>
<message>
<source>Do you want to quit the maintenance application?</source>
- <translation>Möchten Sie die Wartungsanwendung beenden?</translation>
+ <translation>Möchten Sie das Verwaltungswerkzeug beenden?</translation>
</message>
<message>
<source>Question</source>
@@ -1990,7 +1990,7 @@ Installiere Komponente %1</translation>
<message>
<source>It is not possible to install from network location.
Please copy the installer to a local drive</source>
- <translation>Es ist nicht möglich, von einem Netzwerkort aus zu installieren.
+ <translation>Es ist nicht möglich, von einem Netzwerk-Speicherort aus zu installieren.
Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
</context>
@@ -1998,11 +1998,11 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
<name>QInstaller::PerformInstallationForm</name>
<message>
<source>&amp;Show Details</source>
- <translation>&amp;Zeige Details</translation>
+ <translation>Details &amp;anzeigen</translation>
</message>
<message>
<source>&amp;Hide Details</source>
- <translation>&amp;Verstecke Details</translation>
+ <translation>Details aus&amp;blenden</translation>
</message>
</context>
<context>
@@ -2013,7 +2013,7 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>Uninstalling %1</source>
- <translation>Deinstalliere %1</translation>
+ <translation>%1 wird deinstalliert</translation>
</message>
<message>
<source>&amp;Update</source>
@@ -2021,7 +2021,7 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>Updating components of %1</source>
- <translation>Aktualisiere Komponenten des %1</translation>
+ <translation>Komponenten von %1 werden aktualisiert</translation>
</message>
<message>
<source>&amp;Install</source>
@@ -2029,7 +2029,7 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>Installing %1</source>
- <translation>Installiere %1</translation>
+ <translation>%1 wird installiert</translation>
</message>
</context>
<context>
@@ -2040,15 +2040,15 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>The proxy %1 requires a username and password.</source>
- <translation>Der Proxy %1 benötigt einen Nutzernamen und Passwort.</translation>
+ <translation>Der Proxy %1 verlangt einen Benutzernamen und Passwort.</translation>
</message>
<message>
<source>Username:</source>
- <translation>Nutzername:</translation>
+ <translation>Benutzername:</translation>
</message>
<message>
<source>Username</source>
- <translation>Nutzername</translation>
+ <translation>Benutzername</translation>
</message>
<message>
<source>Password:</source>
@@ -2095,19 +2095,19 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>Setup is now ready to begin installing %1 on your computer.</source>
- <translation>Das Einrichtungsprogramm ist jetzt bereit, %1 auf Ihrem Computer einzurichten.</translation>
+ <translation>Das Einrichtungsprogramm ist jetzt bereit, %1 auf Ihrem Computer zu installieren.</translation>
</message>
<message>
<source>Not enough disk space to store temporary files and the installation! Available space: %1, at least required %2.</source>
- <translation>Nicht genügend Plattenplatz für temporäre Dateien und die Installation! Verfügbarer Platz: %1, mindestens benötigt: %2.</translation>
+ <translation>Nicht genügend Festplattenplatz für temporäre Dateien und die Installation! Verfügbarer Platz: %1, mindestens benötigt: %2.</translation>
</message>
<message>
<source>Not enough disk space to store all selected components! Available space: %1, at least required: %2.</source>
- <translation>Nicht genügend Plattenplatz für alle ausgewählten Komponenten! Verfügbarer Platz: %1, mindestens benötigt: %2.</translation>
+ <translation>Nicht genügend Festplattenplatz für alle ausgewählten Komponenten! Verfügbarer Platz: %1, mindestens benötigt: %2.</translation>
</message>
<message>
<source>Not enough disk space to store temporary files! Available space: %1, at least required: %2.</source>
- <translation>Nicht genügend Plattenplatz für temporäre Dateien! Verfügbarer Platz: %1, mindestens benötigt: %2.</translation>
+ <translation>Nicht genügend Festplattenplatz für temporäre Dateien! Verfügbarer Platz: %1, mindestens benötigt: %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>
@@ -2115,11 +2115,11 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</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>Die für die Installation ausgewählte Partition scheint genügend Platz zu bieten, aber es werden anschließend weniger als 100 MiB verfügbar sein. %1</translation>
+ <translation>Die für die Installation ausgewählte Partition scheint genügend Platz zu bieten, aber es werden anschließend weniger als 100 MB verfügbar sein. %1</translation>
</message>
<message>
<source>Installation will use %1 of disk space.</source>
- <translation>Installation wird %1 Plattenplatz verwenden.</translation>
+ <translation>Die Installation wird %1 Festplattenplatz verwenden.</translation>
</message>
<message>
<source>Cannot resolve all dependencies.</source>
@@ -2146,21 +2146,21 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>Register File Type: Invalid arguments</source>
- <translation>Register File Type: Ungültige Argumente</translation>
+ <translation>Dateitypenregistrierung: Ungültige Argumente</translation>
</message>
</context>
<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>
- <translation>Konnte nicht alle Daten nach dem Senden des Kommandos &apos;%1&apos; lesen. Bytes erwartet: %2, Bytes erhalten: %3. Fehler: %4</translation>
+ <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 Befehls &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>
- <translation>Konnte nicht alle Daten nach dem Senden des Kommandos &apos;%1&apos; lesen. Bytes erwartet: %2, Bytes erhalten: %3. Fehler: %4</translation>
+ <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 Befehls &apos;%1&apos; lesen. Bytes erwartet: %2, Bytes erhalten: %3. Fehler: %4</translation>
</message>
</context>
<context>
@@ -2185,8 +2185,8 @@ 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>
- <translation>Konnte Ressourcendatei &apos;%1&apos; nicht zum Nur-Lesen öffnen.</translation>
+ <source>Cannot open Resource &apos;%1&apos; read-only.</source>
+ <translation>Konnte Ressourcendatei &apos;%1&apos; nicht schreibgeschützt öffnen.</translation>
</message>
<message>
<source>Read failed after %1 bytes: %2</source>
@@ -2201,13 +2201,13 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
<name>QInstaller::RestartPage</name>
<message>
<source>Completing the %1 Setup Wizard</source>
- <translation>Vervollständige den %1 Assistenten</translation>
+ <translation>Der %1-Assistent wird abgeschlossen</translation>
</message>
</context>
<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>
@@ -2219,15 +2219,15 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
<name>QInstaller::SelfRestartOperation</name>
<message>
<source>Installer object needed in &apos;%1&apos; operation is empty.</source>
- <translation>Das für die Anweisung &apos;%1&apos; benötigte Installerobjekt ist leer.</translation>
+ <translation>Das für die Anweisung &apos;%1&apos; benötigte Installer-Objekt ist leer.</translation>
</message>
<message>
<source>Self Restart: Only valid within updater or packagemanager mode.</source>
- <translation>Self Restart: Nur im updater oder packagemanager Modus erlaubt.</translation>
+ <translation>Automatischer Neustart: Nur im Aktualisierungs- und Pakatverwaltungs-Modus erlaubt.</translation>
</message>
<message>
<source>Self Restart: Invalid arguments</source>
- <translation>Self Restart: Ungültige Argumente</translation>
+ <translation>Automatischer Neustart: Ungültige Argumente</translation>
</message>
</context>
<context>
@@ -2238,11 +2238,11 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>You need to supply a username and password to access this site.</source>
- <translation>Nutzername und Passwort für den Zugriff benötigt.</translation>
+ <translation>Benutzername und Passwort für den Zugriff benötigt.</translation>
</message>
<message>
<source>Username:</source>
- <translation>Nutzername:</translation>
+ <translation>Benutzername:</translation>
</message>
<message>
<source>Password:</source>
@@ -2288,7 +2288,7 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>Move &apos;%1&apos; to &apos;%2&apos;.</source>
- <translation>Verschiebe &apos;%1&apos; nach &apos;%2&apos;.</translation>
+ <translation>&apos;%1&apos; nach &apos;%2&apos; verschieben.</translation>
</message>
</context>
<context>
@@ -2306,7 +2306,7 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
<name>QInstaller::TargetDirectoryPage</name>
<message>
<source>Installation Folder</source>
- <translation>Installationsverzeichnis</translation>
+ <translation>Installationsordner</translation>
</message>
<message>
<source>Please specify the folder where %1 will be installed.</source>
@@ -2320,11 +2320,11 @@ Bitte kopieren Sie den Installer auf ein lokales Laufwerk</translation>
</message>
<message>
<source>B&amp;rowse...</source>
- <translation>&amp;Durchsuchen...</translation>
+ <translation>&amp;Durchsuchen ...</translation>
</message>
<message>
<source>The folder you selected already exists and contains an installation. Choose a different target for installation.</source>
- <translation>Der ausgewählte Ordner existiert bereits und enthält eine Installation. Bitte ein anderes Zielverzeichnis auswählen.</translation>
+ <translation>Der ausgewählte Ordner existiert bereits und enthält eine Installation. Bitte wählen Sie einen anderen Zielordner aus.</translation>
</message>
<message>
<source>You have selected an existing, non-empty folder for installation.
@@ -2350,27 +2350,27 @@ Möchten Sie trotzdem fortsetzen?</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>Der Pfad zum Installationsverzeichnis enthält Zeichen ausserhalb des ASCII Zeichensatzes. Dies ist zur Zeit nicht unterstützt. Bitte wählen Sie einen anderen Pfad für das Installationsverzeichnis.</translation>
+ <translation>Der Pfad zum Installationsverzeichnis enthält Zeichen ausserhalb des ASCII-Zeichensatzes. Dies ist zur Zeit nicht unterstützt. Bitte wählen Sie einen anderen Pfad oder Installationsordner.</translation>
</message>
<message>
<source>The path you have entered is too long, please make sure to specify a valid path.</source>
- <translation>Der von ihnen eingegebene Pfad ist zu lang, bitte geben sie einen gültigen Pfad ein.</translation>
+ <translation>Der von Ihnen eingegebene Pfad ist zu lang, bitte geben Sie einen gültigen Pfad ein.</translation>
</message>
<message>
<source>The path you have entered is not valid, please make sure to specify a valid target.</source>
- <translation>Der eingegebene Pfad ist ungültig, bitte ein gültiges Ziel angeben.</translation>
+ <translation>Der von Ihnen eingegebene Pfad ist ungültig, bitte geben Sie ein gültiges Ziel ein.</translation>
</message>
<message>
<source>The path you have entered is not valid, please make sure to specify a valid drive.</source>
- <translation>Der von ihnen eingegebene Pfad ist ungültig, bitte geben sie ein gültiges Laufwerk an.</translation>
+ <translation>Der von Ihnen eingegebene Pfad ist ungültig, bitte geben Sie ein gültiges Laufwerk an.</translation>
</message>
<message>
<source>The installation path must not end with &apos;.&apos;, please specify a valid folder.</source>
- <translation>Der Installationspfad darf nicht auf &apos;.&apos; enden, bitte einen gültigen Ordner angeben.</translation>
+ <translation>Der Installationspfad darf nicht auf &apos;.&apos; enden, bitte geben Sie einen gültigen Ordner ein.</translation>
</message>
<message>
<source>The installation path must not contain &apos;%1&apos;, please specify a valid folder.</source>
- <translation>Der Installationspfad darf nicht %1 enthalten, bitte einen gültigen Ordner angeben.</translation>
+ <translation>Der Installationspfad darf nicht %1 enthalten, bitte geben Sie einen gültigen Ordner ein.</translation>
</message>
<message>
<source>Error</source>
@@ -2382,11 +2382,11 @@ Möchten Sie trotzdem fortsetzen?</translation>
</message>
<message>
<source>Warning</source>
- <translation>Warnung</translation>
+ <translation>Achtung</translation>
</message>
<message>
<source>Select Installation Folder</source>
- <translation>Installationsverzeichnis auswählen.</translation>
+ <translation>Installationsordner auswählen.</translation>
</message>
</context>
<context>
@@ -2401,10 +2401,10 @@ Möchten Sie trotzdem fortsetzen?</translation>
</message>
<message>
<source>Got a timeout while testing: &apos;%1&apos;</source>
- <translation>Erhielt Timeout beim Testen von: &apos;%1&apos;</translation>
+ <translation>Zeitüberschreitung 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,18 +2434,18 @@ 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
as root and then clicking OK.</source>
<translation>Konnte die Autorisierung, die zum Fortsetzen der Installation nötig ist, nicht erhalten.
-Brechen sie entweder die Installation ab, oder verwenden sie die Fallback Lösung, indem sie
+Brechen Sie entweder die Installation ab, oder verwenden Sie die Fallback-Lösung, indem Sie
%1
als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
</message>
@@ -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>
@@ -2488,7 +2488,7 @@ als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
</message>
<message>
<source>HTTP proxy:</source>
- <translation>HTTP Proxy:</translation>
+ <translation>HTTP-Proxy:</translation>
</message>
<message>
<source>Port:</source>
@@ -2496,7 +2496,7 @@ als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
</message>
<message>
<source>FTP proxy:</source>
- <translation>FTP Proxy:</translation>
+ <translation>FTP-Proxy:</translation>
</message>
<message>
<source>Repositories</source>
@@ -2504,11 +2504,11 @@ als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
</message>
<message>
<source>Add Username and Password for authentication if needed.</source>
- <translation>Nutzername und Passwort für die Autentifizierung hinzufügen, falls benötigt.</translation>
+ <translation>Benutzername und Passwort für die Autentifizierung hinzufügen, falls benötigt.</translation>
</message>
<message>
<source>Use temporary repositories only</source>
- <translation>Verwende ausschließlich temporäre Quellen</translation>
+ <translation>Ausschließlich temporäre Quellen verwenden</translation>
</message>
<message>
<source>Add</source>
@@ -2524,7 +2524,7 @@ als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
</message>
<message>
<source>Show Passwords</source>
- <translation>Zeige Passwörter</translation>
+ <translation>Passwörter anzeigen</translation>
</message>
<message>
<source>Check this to use repository during fetch.</source>
@@ -2532,7 +2532,7 @@ als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
</message>
<message>
<source>Add the username to authenticate on the server.</source>
- <translation>Nutzernamen eintragen, um sich gegenüber der Quelle zu authentifizieren.</translation>
+ <translation>Benutzernamen eintragen, um sich gegenüber der Quelle zu authentifizieren.</translation>
</message>
<message>
<source>Add the password to authenticate on the server.</source>
@@ -2544,23 +2544,23 @@ als root aufrufen und dann &quot;Ok&quot; auswählen. </translation>
</message>
<message>
<source>There was an error testing this repository.</source>
- <translation>Beim testen des Repositories ist ein Fehler aufgetreten.</translation>
+ <translation>Beim Testen der Quelle ist ein Fehler aufgetreten.</translation>
</message>
<message>
<source>Do you want to disable the tested repository?</source>
- <translation>Soll das getestete Repository ausgeschaltet werden?</translation>
+ <translation>Soll die getestete Quelle deaktiviert werden?</translation>
</message>
<message>
<source>Hide Passwords</source>
- <translation>Verstecke Passwörter</translation>
+ <translation>Passwörter ausblenden</translation>
</message>
<message>
<source>Use</source>
- <translation>Nutze</translation>
+ <translation>Verwende</translation>
</message>
<message>
<source>Username</source>
- <translation>Nutzername</translation>
+ <translation>Benutzername</translation>
</message>
<message>
<source>Password</source>
@@ -2590,12 +2590,12 @@ 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>
<source>Renaming %1 into %2 failed with %3.</source>
- <translation>Umbenennung von %1 nach %2 schlug mit Meldung %3 fehl.</translation>
+ <translation>Umbenennung von %1 nach %2 ist mit Meldung %3 fehlgeschlagen.</translation>
</message>
</context>
</TS>
diff --git a/src/sdk/translations/en.ts b/src/sdk/translations/en.ts
deleted file mode 100644
index e14431ab0..000000000
--- a/src/sdk/translations/en.ts
+++ /dev/null
@@ -1,2653 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1" language="en_US">
-<context>
- <name>Component</name>
- <message>
- <source>Could not open archive %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>Dialog</name>
- <message>
- <source>Http authentication required</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You need to supply a Username and Password to access this site.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Username:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Password:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 at %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>IntroductionPageImpl</name>
- <message>
- <source>Package manager</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Update components</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Remove all components</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Retrieving information from remote installation sources...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>At least one valid and enabled repository required for this action to succeed.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No updates available.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> Only local package management available.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Quit</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDJob</name>
- <message>
- <source>Canceled</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDSaveFile</name>
- <message>
- <source>Append mode not supported.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Read-only access not supported.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not backup existing file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TODO</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::AppendFileOperation</name>
- <message>
- <source>Cannot backup file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, 2 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open file %1 for writing: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot find backup file for %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not restore backup file for %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, 2 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove destination file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not copy %1 to %2: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not delete file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not restore backup file into %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::DeleteOperation</name>
- <message>
- <source>Cannot create backup of %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, 1 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot restore backup file for %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::FileDownloader</name>
- <message>
- <source>Download canceled.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cryptographic hashes do not match.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Download finished.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> of </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> downloaded.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>/sec</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> day</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> days</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> hour</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> hours</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> minute</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> minutes</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> second</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> seconds</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> - </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> remaining.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> - unknown time remaining.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::HttpDownloader</name>
- <message>
- <source>Cannot download %1: Writing to file &apos;%2&apos; failed: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot download %1: Could not create %2: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 at %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Authentication request canceled.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::LocalFileDownloader</name>
- <message>
- <source>Cannot open source file &apos;%1&apos; for reading.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot open destination file &apos;%1&apos; for writing.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Writing to %1 failed: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::MkdirOperation</name>
- <message>
- <source>Invalid arguments: %1 arguments given, 1 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create folder %1: Unknown error.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot remove directory %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::MoveOperation</name>
- <message>
- <source>Could not backup file %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, 2 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove destination file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not copy %1 to %2: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot copy %1 to %2: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot remove file %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot restore backup file for %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::PackagesInfo</name>
- <message>
- <source>%1 contains invalid content: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The file %1 does not exist.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Parse error in %1 at %2, %3: %4</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Root element %1 unexpected, should be &apos;Packages&apos;.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::PrependFileOperation</name>
- <message>
- <source>Cannot backup file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, 2 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open file %1 for reading: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open file %1 for writing: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot find backup file for %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot restore backup file for %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot restore backup file for %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::ResourceFileDownloader</name>
- <message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::RmdirOperation</name>
- <message>
- <source>Invalid arguments: %1 arguments given, 1 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove folder %1: The folder does not exist.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove folder %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot recreate directory %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::Task</name>
- <message>
- <source>%1 started</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 cannot be stopped</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot stop task %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 cannot be paused</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot pause task %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot resume task %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 done</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::UpdateFinder</name>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>%1 updates found.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Downloading Updates.xml from update sources.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not download updates from %1 (&apos;%2&apos;)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Updates.xml file(s) downloaded from update sources.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Computing applicable updates.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Application updates computed.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>KDUpdater::UpdateSourcesInfo</name>
- <message>
- <source>%1 contains invalid content: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not read &quot;%1&quot;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>XML Parse error in %1 at %2, %3: %4</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Root element %1 unexpected, should be &quot;UpdateSources&quot;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Parse error in %1 at %2, %3: %4</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Updates.xml contains invalid content: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Root element %1 unexpected, should be &quot;Updates&quot;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>ApplicationName element is missing.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>ApplicationVersion element is missing.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>PackageUpdate element without Name</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>PackageUpdate element without Version</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>PackageUpdate element without ReleaseDate</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>Lib7z::ExtractItemJob</name>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::AddQtCreatorArrayValueOperation</name>
- <message>
- <source>exactly 4</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> (group, arrayname, key, value)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in %1 operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There is no value set for %1 on the installer object.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::Component</name>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>An error has occurred while reading the UI file.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error: Operation %1 does not exist</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Can&apos;t resolve isAutoDependOn in %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Can&apos;t resolve isDefault in %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Update Info: </source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ComponentModel</name>
- <message>
- <source>Component Name</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Installed Version</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>New Version</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Size</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ComponentSelectionPage</name>
- <message>
- <source>Alt+A</source>
- <comment>select default components</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Def&amp;ault</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Alt+R</source>
- <comment>reset to already installed components</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>&amp;Reset</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Alt+S</source>
- <comment>select all components</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>&amp;Select All</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Alt+D</source>
- <comment>deselect all components</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>&amp;Deselect All</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>This component will occupy approximately %1 on your hard disk drive.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Select Components</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Please select the components you want to update.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Please select the components you want to install.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Please select the components you want to uninstall.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Select the components to install. Deselect installed components to uninstall them.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ConsumeOutputOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at least 2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in %1 operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Can not save the output of %1 to an empty installer key value.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>File &apos;%1&apos; does not exist or is not an executable binary.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Running &apos;%1&apos; resulted in a crash.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CopyDirectoryOperation</name>
- <message>
- <source>2 or 3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> (&lt;source&gt; &lt;target&gt; [forceOverwrite])</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid argument in %0: Third argument needs to be forceOverwrite, if specified</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: Directories are invalid: %1 %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create %0</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to overwrite %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not copy %0 to %1, error was: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove %0</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CreateDesktopEntryOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to overwrite %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not write Desktop Entry at %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CreateLinkOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CreateLocalRepositoryOperation</name>
- <message>
- <source>Could not set file permissions %1!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not move file %1 to %2. Error: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Installer needs to be an offline version: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open file: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not read: %1. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open file: %1. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create target dir: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Unknown exception caught: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Removing file: %0</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove %0.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot remove directory %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::CreateShortcutOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>2 or 3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> (optional: &apos;workingDirectory=...&apos;)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create folder %1: %2.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create link %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::DownloadArchivesJob</name>
- <message>
- <source>Canceled</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Downloading hash signature failed.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Download Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hash verification while downloading failed. This is a temporary error, please retry.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not verify Hash</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not download archive: %1 : %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not fetch archives: %1
-Error while loading %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Downloading archive hash for component: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Downloading archive for component: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Scheme not supported: %1 (%2)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not find component for: %1.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ElevatedExecuteOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at least 1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Execution failed(Crash): &quot;%1&quot;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Execution failed(Unexpected exit code: %1): &quot;%2&quot;</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::EnvironmentVariableOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>2 or 3</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ExtractArchiveOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ExtractArchiveOperation::Runnable</name>
- <message>
- <source>Could not open %1 for reading: %2.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error while extracting &apos;%1&apos;: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Unknown exception caught while extracting %1.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::FinishedPage</name>
- <message>
- <source>Completing the %1 Wizard</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Click Done to exit the %1 Wizard.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Click Finish to exit the %1 Wizard.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Restart</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Run %1 now.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The %1 Wizard failed.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::GetRepositoryMetaInfoJob</name>
- <message>
- <source>Empty repository URL.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Retrieving component meta information...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid repository URL: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>URL scheme not supported: %1 (%2)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not fetch a valid version of Updates.xml from repository: %1. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Download Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Parsing component meta information...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Repository updates received.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Finished updating component meta information.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not fetch Updates.xml from repository: %1. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Retrieving component information from remote repository...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open meta info archive: %1. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The hash of one component does not match the expected one.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Bad hash.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not download meta information for component: %1. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::GetRepositoryMetaInfoJob::ZipRunnable</name>
- <message>
- <source>Error while extracting &apos;%1&apos;: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Unknown exception caught while extracting %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open %1 for reading. Error: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::GlobalSettingsOperation</name>
- <message>
- <source>Settings are not writable</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to write settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>3 or 4</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::InstallIconsOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>1 or 2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> (Sourcepath, [Vendorprefix])</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::IntroductionPage</name>
- <message>
- <source>Setup - %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Welcome to the %1 Setup Wizard.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::LicenseAgreementPage</name>
- <message>
- <source>License Agreement</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Alt+A</source>
- <comment>agree license</comment>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>I accept the license.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>I do not accept the license.</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>I accept the licenses.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>I do not accept the licenses.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Alt+D</source>
- <comment>do not agree license</comment>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::LicenseOperation</name>
- <message>
- <source>No license files found to copy.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in %1 operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Can not write license file: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No license files found to delete.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::LineReplaceOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 3</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::MacReplaceInstallNamesOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at least 3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>One of the given arguments is empty. Argument1=%1; Argument2=%2, Argument3=%3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Can&apos;t invoke otool. Is Xcode installed?</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Can&apos;t start process %0.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::PackageManagerCore</name>
- <message>
- <source>Error writing Uninstaller</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>
-Downloading packages...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Installation canceled by user</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>All downloads finished.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cancelling the Installer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Authentication Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some components could not be removed completely because admin rights could not be acquired: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Unknown error.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some components could not be removed completely because an unknown error happened.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Application not running in Package Manager mode!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No installed packages found.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Application running in Uninstaller mode!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>invalid</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::PackageManagerCorePrivate</name>
- <message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Component(s) added as automatic dependencies</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Added as dependency for %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Component(s) that have resolved Dependencies</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Selected Component(s) without Dependencies</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Access error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Format error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not write installer configuration to %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Stop Processes</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>These processes should be stopped to continue:
-
-%1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Installation canceled by user</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Writing uninstaller.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Uninstaller is not a bundle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not write uninstaller data to %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not write uninstaller to %1: %2</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>Could not write uninstaller binary data to %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>ProductName should be set</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Variable &apos;TargetDir&apos; not set.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Preparing the installation...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>It is not possible to install from network location</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Creating local repository</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Creating Uninstaller</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>
-Installation finished!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>
-Installation aborted!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>It is not possible to run that operation from a network location</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Removing deselected components...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>
-Update finished!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>
-Update aborted!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>
-Uninstallation completed successfully!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>
-Uninstallation aborted!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>
-Installing component %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Installer Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during installation process (%1):
-%2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot prepare uninstall</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot start uninstall</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during uninstallation process:
-%1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Unknown error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not retrieve remote tree: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failure to read packages from: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not retrieve meta information: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not add temporary update source information.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not find any update source information.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::PackageManagerGui</name>
- <message>
- <source>%1 Setup</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Maintain %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Question</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Do you want to abort the %1 process?</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>uninstallation</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>installation</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>installer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>uninstaller</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>maintenance</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Do you want to quit the %1 application?</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>It is not possible to install from network location.
-Please copy the installer to a local drive</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::PerformInstallationForm</name>
- <message>
- <source>&amp;Show Details</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>&amp;Hide Details</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::PerformInstallationPage</name>
- <message>
- <source>U&amp;ninstall</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Uninstalling %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>&amp;Update</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Updating components of %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>&amp;Install</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Installing %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::QtPatchOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
- <translation type="unfinished"></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 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>
- <translation type="unfinished"></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 type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>Qt patch error: new Qt dir(%1)
-needs to be less than 255 characters.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Qt patch error: Can not open %1.(%2)</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ReadyForInstallationPage</name>
- <message>
- <source>&amp;Show Details</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>U&amp;ninstall</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Ready to Uninstall</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>U&amp;pdate</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Ready to Update Packages</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Setup is now ready to begin updating your installation.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>&amp;Install</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Ready to Install</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Setup is now ready to begin installing %1 on your computer.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Not enough disk space to store temporary files and the installation! Available space: %1, at least required %2.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Not enough disk space to store all selected components! Available space: %1, at least required: %2.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Not enough disk space to store temporary files! Available space: %1, at least required: %2.</source>
- <translation type="unfinished"></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 type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>Can not resolve all dependencies!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Components about to be removed.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>&amp;Hide Details</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::RegisterDefaultDebuggerOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, 2 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There is no value set for %1 on the installer object.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Can&apos;t read from tool chains xml file(%1) correctly.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::RegisterFileTypeOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>2 to 5</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Register File Type: Invalid arguments</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::RegisterQtInCreatorQNXOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>at least 5</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There is no value set for %1 on the installer object.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, minimum 4 expected.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::RegisterToolChainOperation</name>
- <message>
- <source>at least 4</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in &apos;%1&apos; operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There is no value set for &apos;%1&apos; on the installer object.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, minimum 4 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Can&apos;t read from tool chains xml file(%1) correctly.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some arguments are not right in %1 operation.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ReplaceOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 3</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::RestartPage</name>
- <message>
- <source>Completing the %1 Setup Wizard</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ScriptEngine</name>
- <message>
- <source>Could not open the requested script file at %1: %2.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Exception while loading the component script: &apos;%1&apos;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not load the component script inside a script context: &apos;%1&apos;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Fatal error while evaluating a script.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SelfRestartOperation</name>
- <message>
- <source>Installer object needed in &apos;%1&apos; operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Self Restart: Only valid within updater or packagemanager mode.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Self Restart: Invalid arguments</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SetDemosPathOnQtOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>Qt patch error: new Qt demo path &apos;%1&apos;
-needs to be less than 255 characters.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SetExamplesPathOnQtOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>Qt patch error: new Qt example path &apos;%1&apos;
-needs to be less than 255 characters.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SetImportsPathOnQtCoreOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Qt patch error: new Qt imports path &apos;%1&apos;
-needs to be less than 255 characters.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SetPathOnQtCoreOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The second type/value needs to be one of: %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SetPluginPathOnQtCoreOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Qt patch error: new Qt plugin path &apos;%1&apos;
-needs to be less than 255 characters.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SetQtCreatorValueOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 4</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source> (rootInstallPath, group, key, value)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There is no value set for &apos;%1&apos; on the installer object.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Needed installer object in &apos;%1&apos; operation is empty.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::SimpleMoveFileOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>None of the arguments can be empty: source &apos;%1&apos;, target &apos;%2&apos;.</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>Can not move source &apos;%1&apos; to target &apos;%2&apos;: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Move &apos;%1&apos; to &apos;%2&apos;.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::StartMenuDirectoryPage</name>
- <message>
- <source>Start Menu shortcuts</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstaller::TargetDirectoryPage</name>
- <message>
- <source>Installation Folder</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Please specify the folder where %1 will be installed.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Alt+R</source>
- <comment>browse file system to choose a file</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>B&amp;rowse...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The install directory cannot be empty, please specify a valid folder.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>As the install directory is completely deleted on uninstall, installing in %1 is forbidden.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Warning</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>Select Installation Folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QInstallerCreator::Archive</name>
- <message>
- <source>Could not create %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open archive file %1 for reading.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create archive from %1: Not a file.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error while packing directory at %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QObject</name>
- <message>
- <source>Searched whole file, no marker found</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not seek to %1 in file %2: %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No marker found, stopped after %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No marker found, unknown exception caught.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot create zipped file for path %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not seek to in-binary resource. (offset: %1, length: %2)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not register in-binary resource.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open binary %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not seek to binary layout section.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not seek to metadata index.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not seek to operation list.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not seek to component index information.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not seek to component index.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot open file %1 for reading: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Cannot open file %1 for writing: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Write failed after %1 bytes: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Read failed after %1 bytes: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove folder %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create folder %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create folder %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open temporary file: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create lock file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not write PID to lock file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not lock lock file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not unlock lock file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Path exists but is not a folder: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create folder: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create temporary file</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not retrieve property %1 for item %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Property %1 for item %2 not of type VT_FILETIME but %3</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not convert file time to local time</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not convert local file time to system time</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No device set for output stream</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not load codecs</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not retrieve default format</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not open archive</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No CArc found</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not retrieve number of items in archive</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not retrieve path of archive item %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Unknown exception caught (%1)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove already existing symlink. %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not 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>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not read symlink target from file &apos;%1&apos;.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create symlink at %1. %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>internal code: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>not enough memory</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create archive %1. %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error while extracting &apos;%1&apos;: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>CArc index %1 out of bounds [0, %2]</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Item index %1 out of bounds [0, %2]</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create output file for writing: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Authorization required</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enter your password to authorize for sudo:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error acquiring admin rights</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not backup file %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not delete file %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not restore backup file into %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to overwrite %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Registry path %1 is not writable</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not write to registry path %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid Argument: source folder must not be empty.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not backup file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to copy file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create folder at %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, %2 to %3 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, %2 expected.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error while elevating access rights.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to seek in file %1: %2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to open %1 for reading</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to open %1 for writing</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to seek in file %1. Reason: %2.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not create link from %1 to %2.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not remove link from %1 to %2.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Authorization Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Couldn&apos;t get authorization.</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>Registering file types is only supported on Windows.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to open &apos;%1&apos; for reading.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Failed to open &apos;%1&apos; for writing.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Number of arguments does not match: one is required</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not get package manager core.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>This process should be stopped before continuing: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>These processes should be stopped before continuing: %1</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>Settings</name>
- <message>
- <source>Could not open settings file %1 for reading: %2</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>SettingsDialog</name>
- <message>
- <source>Settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Network</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No proxy</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>System proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Manual proxy configuration</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>HTTP proxy:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Port:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>HTTP proxy requires authentication</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Username:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Password:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>FTP proxy:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>FTP proxy requires authentication</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Repositories</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Add Username and Password for authentication if needed.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Use temporary repositories only</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Add</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Remove</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Test</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Show Passwords</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Check this to use repository during fetch.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Add the username to authenticate on the server.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Add the password to authenticate on the server.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The servers URL that contains a valid repository.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There was an error testing this repository.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Do you want to disable the tested repository?</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hide Passwords</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Use</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Username</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Password</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Repository</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Default repositories</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Temporary repositories</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>User defined repositories</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>TargetDirectoryPageImpl</name>
- <message>
- <source>The installation path cannot be empty, please specify a valid folder.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The installation path cannot be relative, please specify an absolute path.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Warning</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>The path you have entered is too long, please make sure to specify a valid path.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The path you have entered is not valid, please make sure to specify a valid drive.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The installation path must not contain %1, please specify a valid folder.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>As the install directory is completely deleted installing in %1 is forbidden.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The folder you selected exists already and contains an installation.
-Do you want to overwrite it?</source>
- <translation type="unfinished"></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 type="unfinished"></translation>
- </message>
- <message>
- <source>You have selected an existing file or symlink, please choose a different target for installation.</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>TestRepository</name>
- <message>
- <source>Empty repository URL.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>URL scheme not supported: %1 (%2).</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Could not parse Updates.xml! Error: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Updates.xml could not be opened for reading!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Updates.xml could not be found on server!</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-</TS>
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 5fdd0605c..d994bcd72 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,15 +641,19 @@
<context>
<name>QInstaller::Component</name>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
+ <source>Cannot open the requested translation file &apos;%1&apos;.</source>
+ <translation>è¦æ±‚ã•ã‚ŒãŸç¿»è¨³ãƒ•ã‚¡ã‚¤ãƒ« &apos;%1&apos; ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
+ </message>
+ <message>
+ <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>
@@ -829,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>
@@ -837,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>
@@ -860,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>
@@ -879,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>
@@ -910,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>
@@ -934,7 +938,7 @@
<translation>ファイルを削除ã—ã¦ã„ã¾ã™: %0</translation>
</message>
<message>
- <source>Could not remove %0.</source>
+ <source>Cannot remove %0.</source>
<translation>%0 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
@@ -942,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>
@@ -961,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>
@@ -992,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>
@@ -1010,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>
@@ -1029,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>
@@ -1070,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>
@@ -1147,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>
@@ -1159,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>
@@ -1369,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>
@@ -1469,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>
@@ -1477,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>
@@ -1505,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>
@@ -1743,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>
@@ -1916,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>
@@ -1946,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 +2130,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 +2145,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 +2175,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 +2186,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 +2242,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 +2265,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 +2280,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 +2326,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 +2340,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 +2359,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 +2383,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,7 +2403,7 @@ 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>
<message>
@@ -2410,27 +2414,27 @@ Do you want to continue?</source>
<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>
@@ -2485,7 +2489,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>
@@ -2537,13 +2541,73 @@ Do you want to continue?</source>
</message>
</context>
<context>
+ <name>QtPatchOperation</name>
+ <message>
+ <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
+ <translation>%0 ã«ç„¡åŠ¹ãªå¼•æ•°: %1個ã®å¼•æ•°ãŒæ¸¡ã•ã‚Œã¾ã—ãŸãŒã€å¿…è¦ãªã®ã¯%2ã§ã™%3。</translation>
+ </message>
+ <message>
+ <source>3 or 4</source>
+ <translation>3ã‚ã‚‹ã„ã¯4個</translation>
+ </message>
+ <message>
+ <source>Needed installer object in &quot;%1&quot; operation is empty.</source>
+ <translation>&quot;%1&quot; ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ©ä½œæˆã«å¿…è¦ãªæ“作ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。</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>最åˆã®å¼•æ•°ã¯ &apos;linux&apos;, &apos;mac&apos;, &apos;windows&apos; ã®ã„ãšã‚Œã‹ã‚’指定ã—ã¦ãã ã•ã„。ãれ以外ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。</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>インストーラã«å¿…è¦ãª QmakeOutputInstallerKey(%1) ã®å€¤ã‚’見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚é©åˆ‡ãª qmake 㧠ConsumeOutput æ“作を最åˆã«å®Ÿè¡Œã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</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>ç¾åœ¨ã® Qt ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³(%1)ã® QMake ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。ã“ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‹ã‚‰ 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>以下ã®å‡ºåŠ›ãŒãƒ‘ースã§ãã¾ã›ã‚“。
+%1 -query
+ã“ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‹ã‚‰ https://bugreports.qt-project.org ã¸ãƒã‚°å ±å‘Šã‚’ã—ã¦ãã ã•ã„。
+出力: &quot;%2&quot;</translation>
+ </message>
+ <message>
+ <source>Qt patch error: new Qt dir(%1)
+needs to be less than 255 characters.</source>
+ <translation>Qt パッãƒã‚¨ãƒ©ãƒ¼: æ–°ã—ã„ Qt ã®ãƒ‘ス(%1)
+ã¯255文字以下ã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</translation>
+ </message>
+ <message>
+ <source>Qt patch error: Can not open %1.(%2)</source>
+ <translation>Qt パッãƒã‚¨ãƒ©ãƒ¼: %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>インストーラã¯ãƒ‘ッãƒæœªé©ç”¨æ™‚ã®ãƒ‘スを %1 ã‹ã‚‰å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+(ãŠãらãファイルãŒå£Šã‚Œã¦ã„ã‚‹ã‹å‰Šé™¤ã•ã‚Œã¦ã„ã¾ã™)
+Qt ã®ãƒã‚¤ãƒŠãƒªã«ãƒ‘ッãƒã‚’é©ç”¨ã—よã†ã¨ã—ã¾ã—ãŸãŒã€Qt ã®ä»–ã®ã™ã¹ã¦ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«å¯¾ã—ã¦ãƒ‘ッãƒã¯é©ç”¨ã•ã‚Œã¦ã„ã¾ã›ã‚“。
+ã“ã®ãŸã‚ã€ã“ã® Qt ã¯æ­£å¸¸ãªçŠ¶æ…‹ã«ç„¡ã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚
+アンãƒã‚¦ã‚£ãƒ«ã‚¹ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã‚’オフã«ã—ã¦ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ©ã‚’å†èµ·å‹•ã™ã‚‹ã“ã¨ã«ã‚ˆã£ã¦æ”¹å–„ã•ã‚Œã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。</translation>
+ </message>
+</context>
+<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
@@ -2558,26 +2622,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>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 7e021ea6d..d23095583 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>
- <translation>Ðе удалоÑÑŒ открыть метареÑурÑÑ‹. Ошибка: %1</translation>
+ <source>Cannot open meta resource %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>
@@ -68,39 +68,39 @@
<context>
<name>DirectoryGuard</name>
<message>
- <source>Path exists but is not a folder: %1</source>
- <translation>Путь ÑущеÑтвует, но не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼: %1</translation>
+ <source>Path &quot;%1&quot; exists but is not a directory.</source>
+ <translation>Путь «%1» ÑущеÑтвует, но не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼.</translation>
</message>
<message>
- <source>Could not create folder: %1</source>
- <translation>Ðе удалоÑÑŒ Ñоздать каталог: %1</translation>
+ <source>Cannot create directory &quot;%1&quot;.</source>
+ <translation>Ðевозможно Ñоздать каталог «%1».</translation>
</message>
</context>
<context>
<name>ExtractCallbackImpl</name>
<message>
- <source>Could not retrieve path of archive item %1</source>
- <translation>Ðе удалоÑÑŒ определить путь файла %1 в архиве</translation>
+ <source>Cannot retrieve path of archive item %1.</source>
+ <translation>Ðе удалоÑÑŒ определить путь Ñлемента архива %1.</translation>
</message>
<message>
- <source>Could not remove already existing symlink. %1</source>
- <translation>Ðе удалоÑÑŒ удалить ÑущеÑтвующую Ñимвольную ÑÑылку. %1</translation>
+ <source>Cannot remove already existing symlink %1.</source>
+ <translation>Ðе удалоÑÑŒ удалить ÑущеÑтвующую Ñимвольную ÑÑылку %1.</translation>
</message>
<message>
- <source>Could not open file: %1 (%2)</source>
- <translation>Ðе удалоÑÑŒ открыть файл: %1 (%2)</translation>
+ <source>Cannot open file &quot;%1&quot; for writing: %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 &quot;%1&quot;. 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 &quot;%1&quot;.</source>
<translation>Ðе удалоÑÑŒ прочитать цель Ñимвольной ÑÑылки из файла «%1».</translation>
</message>
<message>
- <source>Could not create symlink at %1. %2</source>
- <translation>Ðе удалоÑÑŒ Ñоздать Ñимвольную ÑÑылку %1. %2</translation>
+ <source>Cannot create symlink at %1: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать Ñимвольную ÑÑылку %1: %2</translation>
</message>
</context>
<context>
@@ -111,7 +111,7 @@
</message>
<message>
<source>Another %1 instance is already running. Wait until it finishes, close it, or restart your system.</source>
- <translation>Другой ÑкземплÑÑ€ %1 уже работает. ДождитеÑÑŒ его завершениÑ, закройте его или перезагрузите ÑиÑтему. </translation>
+ <translation>Другой ÑкземплÑÑ€ %1 уже работает. ДождитеÑÑŒ его завершениÑ, закройте его или перезагрузите ÑиÑтему.</translation>
</message>
</context>
<context>
@@ -121,10 +121,6 @@
<translation>Компоненты, добавленные как автоматичеÑкие завиÑимоÑти:</translation>
</message>
<message>
- <source>Components added as dependency for &apos;%1&apos;:</source>
- <translation>Компоненты, добавленные как завиÑимоÑÑ‚ÑŒ Ð´Ð»Ñ %1:</translation>
- </message>
- <message>
<source>Components that have resolved dependencies:</source>
<translation>Компоненты Ñ Ñ€Ð°Ð·Ñ€ÐµÑˆÑ‘Ð½Ð½Ñ‹Ð¼Ð¸ завиÑимоÑÑ‚Ñми:</translation>
</message>
@@ -133,115 +129,84 @@
<translation>Выбранные компоненты без завиÑимоÑтей:</translation>
</message>
<message>
- <source>Recursion detected, component &apos;%1&apos; already added with reason: &apos;%2&apos;</source>
+ <source>Components added as dependency for &quot;%1&quot;:</source>
+ <translation>Компоненты, добавленные как завиÑимоÑти Ð´Ð»Ñ Â«%1»:</translation>
+ </message>
+ <message>
+ <source>Recursion detected, component &quot;%1&quot; already added with reason: &quot;%2&quot;</source>
<translation>Обнаружена рекурÑиÑ: компонент «%1» уже добавлен по причине: «%2»</translation>
</message>
<message>
- <source>Cannot find missing dependency &apos;%1&apos; for &apos;%2&apos;.</source>
+ <source>Cannot find missing dependency &quot;%1&quot; for &quot;%2&quot;.</source>
<translation>Ðе удалоÑÑŒ найти компонент «%1», необходимый Ð´Ð»Ñ Â«%2».</translation>
</message>
</context>
<context>
- <name>KDJob</name>
+ <name>Job</name>
<message>
<source>Canceled</source>
<translation>Отменено</translation>
</message>
</context>
<context>
- <name>KDLockFile</name>
- <message>
- <source>Could not 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>
- <translation>Ðе удалоÑÑŒ запиÑать PID в файл блокировки «%1»: %2</translation>
- </message>
- <message>
- <source>Could not 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>
- <translation>Ðе удалоÑÑŒ разблокировать файл «%1»: %2</translation>
- </message>
-</context>
-<context>
<name>KDUpdater::AppendFileOperation</name>
<message>
- <source>Cannot backup file %1: %2</source>
- <translation>Ðевозможно Ñоздать резервную копию файла %1: %2</translation>
+ <source>Cannot backup file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла «%1»: %2</translation>
</message>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
<message>
- <source>exactly 2</source>
- <translation>ровно 2</translation>
+ <source>Cannot find backup file for &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ найти резервную копию «%1».</translation>
</message>
<message>
- <source>Could not open file &apos;%1&apos; for writing: %2</source>
- <translation>Ðевозможно открыть файл «%1» на запиÑÑŒ: %2</translation>
+ <source>Cannot restore backup file for &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ воÑÑтановить резервную копию «%1».</translation>
</message>
<message>
- <source>Cannot find backup file for %1.</source>
- <translation>Ðевозможно найти резервную копию %1.</translation>
- </message>
- <message>
- <source>Could not restore backup file for %1.</source>
- <translation>Ðевозможно воÑÑтановить резервную копию %1.</translation>
- </message>
- <message>
- <source>Could not restore backup file for %1: %2</source>
- <translation>Ðевозможно воÑÑтановить резервную копию %1: %2</translation>
+ <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ воÑÑтановить резервную копию «%1»: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::CopyOperation</name>
<message>
- <source>Could not backup file %1.</source>
- <translation>Ðевозможно Ñоздать резервную копию файла %1.</translation>
+ <source>Cannot copy a non-existent file: %1</source>
+ <translation>Ðе удалоÑÑŒ Ñкопировать отÑутÑтвующий файл: %1</translation>
</message>
<message>
- <source>Invalid arguments: %1 arguments given, 2 expected.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 2.</translation>
+ <source>Cannot backup file &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла «%1».</translation>
</message>
<message>
- <source>Could not copy a non-existent file: %1</source>
- <translation>Ðе удалоÑÑŒ Ñкопировать отÑутÑтвующий файл: %1</translation>
+ <source>Cannot remove file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить файл «%1»: %2</translation>
</message>
<message>
- <source>Could not remove destination file %1: %2</source>
- <translation>Ðевозможно удалить файл %1: %2</translation>
+ <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Ðе удалоÑÑŒ Ñкопировать файл из «%1» в «%2»: %3</translation>
</message>
<message>
- <source>Could not copy %1 to %2: %3</source>
- <translation>Ðевозможно Ñкопировать %1 в %2: %3</translation>
+ <source>Cannot delete file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить файл «%1»: %2</translation>
</message>
<message>
- <source>Could not delete file %1: %2</source>
- <translation>Ðевозможно удалить файл %1: %2</translation>
- </message>
- <message>
- <source>Could not restore backup file into %1: %2</source>
- <translation>Ðевозможно воÑÑтановить файл %1 из резервной копии: %2</translation>
+ <source>Cannot restore backup file into &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ воÑÑтановить резервную копию в «%1»: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::DeleteOperation</name>
<message>
- <source>Cannot create backup of %1: %2</source>
- <translation>Ðевозможно Ñоздать резервную копию %1: %2</translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, 1 expected.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 1.</translation>
+ <source>Cannot create backup of file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла «%1»: %2</translation>
</message>
<message>
- <source>Cannot restore backup file for %1: %2</source>
- <translation>Ðевозможно воÑÑтановить резервную копию %1: %2</translation>
+ <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ воÑÑтановить резервную копию «%1»: %2</translation>
</message>
</context>
<context>
@@ -314,14 +279,6 @@
<context>
<name>KDUpdater::HttpDownloader</name>
<message>
- <source>Cannot download %1: Writing to file &apos;%2&apos; failed: %3</source>
- <translation>Ðевозможно загрузить %1: Сбой запиÑи в файл «%2» - %3</translation>
- </message>
- <message>
- <source>Cannot download %1: Could not create %2: %3</source>
- <translation>Ðевозможно загрузить %1: Ðевозможно Ñоздать %2: %3</translation>
- </message>
- <message>
<source>%1 at %2</source>
<translation>%1 в %2</translation>
</message>
@@ -349,146 +306,115 @@
<source>Try again</source>
<translation>Повторить</translation>
</message>
-</context>
-<context>
- <name>KDUpdater::LocalFileDownloader</name>
<message>
- <source>Cannot open source file &apos;%1&apos; for reading.</source>
- <translation>Ðевозможно прочитать иÑходный файл «%1».</translation>
+ <source>Cannot download %1. Writing to file &quot;%2&quot; failed: %3</source>
+ <translation>Ðевозможно загрузить «%1»: Ðе удалоÑÑŒ запиÑать в файл «%2»: %3</translation>
</message>
<message>
- <source>Cannot open destination file &apos;%1&apos; for writing.</source>
- <translation>Ðевозможно запиÑать в файл Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Â«%1».</translation>
- </message>
- <message>
- <source>Writing to %1 failed: %2</source>
- <translation>Ðе удалоÑÑŒ запиÑать в %1: %2</translation>
+ <source>Cannot download %1. Cannot create file &quot;%2&quot;: %3</source>
+ <translation>Ðевозможно загрузить «%1». Ðе удалоÑÑŒ Ñоздать «%2»: %3</translation>
</message>
</context>
<context>
- <name>KDUpdater::MkdirOperation</name>
+ <name>KDUpdater::LocalFileDownloader</name>
<message>
- <source>Invalid arguments: %1 arguments given, 1 expected.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 1.</translation>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение: %2</translation>
</message>
<message>
- <source>Could not create folder %1: Unknown error.</source>
- <translation>Ðевозможно Ñоздать каталог %1: ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°.</translation>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
<message>
- <source>Cannot remove directory %1: %2</source>
- <translation>Ðевозможно удалить каталог: %1: %2</translation>
+ <source>Writing to file &quot;%1&quot; failed: %2</source>
+ <translation>Ðе удалоÑÑŒ запиÑать в «%1»: %2</translation>
</message>
</context>
<context>
- <name>KDUpdater::MoveOperation</name>
- <message>
- <source>Could not backup file %1.</source>
- <translation>Ðевозможно Ñоздать резервную копию файла %1.</translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, 2 expected.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 2.</translation>
- </message>
- <message>
- <source>Could not remove destination file %1: %2</source>
- <translation>Ðевозможно удалить файл Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %1: %2</translation>
- </message>
- <message>
- <source>Could not copy %1 to %2: %3</source>
- <translation>Ðевозможно Ñкопировать %1 в %2: %3</translation>
- </message>
+ <name>KDUpdater::MkdirOperation</name>
<message>
- <source>Cannot copy %1 to %2: %3</source>
- <translation>Ðевозможно Ñкопировать %1 в %2: %3</translation>
+ <source>Cannot create directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать каталог «%1»: %2</translation>
</message>
<message>
- <source>Cannot remove file %1.</source>
- <translation>Ðевозможно удалить файл %1.</translation>
+ <source>Unknown error.</source>
+ <translation>ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°.</translation>
</message>
<message>
- <source>Cannot restore backup file for %1: %2</source>
- <translation>Ðевозможно воÑÑтановить резервную копию %1: %2</translation>
+ <source>Cannot remove directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить каталог «%1»: %2</translation>
</message>
</context>
<context>
- <name>KDUpdater::PackagesInfo</name>
+ <name>KDUpdater::MoveOperation</name>
<message>
- <source>%1 contains invalid content: %2</source>
- <translation>%1 Ñодержит недопуÑтимые данные: %2</translation>
+ <source>Cannot backup file &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла «%1».</translation>
</message>
<message>
- <source>The file %1 does not exist.</source>
- <translation>Файл %1 не ÑущеÑтвует.</translation>
+ <source>Cannot remove file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить файл «%1»: %2</translation>
</message>
<message>
- <source>Could not open %1.</source>
- <translation>Ðевозможно открыть %1.</translation>
+ <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Ðе удалоÑÑŒ Ñкопировать файл «%1» в «%2»: %3</translation>
</message>
<message>
- <source>Parse error in %1 at %2, %3: %4</source>
- <translation>Ошибка разбора в %1 в %2, %3: %4</translation>
+ <source>Cannot remove file &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ удалить файл «%1».</translation>
</message>
<message>
- <source>Root element %1 unexpected, should be &apos;Packages&apos;.</source>
- <translation>Ðепредвиденный корневой Ñлемент %1 - требуетÑÑ Â«Packages».</translation>
+ <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ воÑÑтановить резервную копию «%1»: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::PrependFileOperation</name>
<message>
- <source>Cannot backup file %1: %2</source>
- <translation>Ðевозможно Ñоздать резервную копию файла %1: %2</translation>
- </message>
- <message>
- <source>Invalid arguments: %1 arguments given, 2 expected.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 2.</translation>
+ <source>Cannot backup file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла «%1»: %2</translation>
</message>
<message>
- <source>Could not open file %1 for reading: %2</source>
- <translation>Ðевозможно открыть файл %1 на чтение: %2</translation>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение: %2</translation>
</message>
<message>
- <source>Could not open file %1 for writing: %2</source>
- <translation>Ðевозможно открыть файл %1 на запиÑÑŒ: %2</translation>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
<message>
- <source>Cannot find backup file for %1.</source>
- <translation>Ðевозможно найти резервную копию Ð´Ð»Ñ %1.</translation>
+ <source>Cannot find backup file for &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ найти резервную копию «%1».</translation>
</message>
<message>
- <source>Cannot restore backup file for %1.</source>
- <translation>Ðевозможно найти резервную копию Ð´Ð»Ñ %1.</translation>
+ <source>Cannot restore backup file for &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ воÑÑтановить резервную копию «%1».</translation>
</message>
<message>
- <source>Cannot restore backup file for %1: %2</source>
- <translation>Ðевозможно воÑÑтановить резервную копию %1: %2</translation>
+ <source>Cannot restore backup file for &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ воÑÑтановить резервную копию «%1»: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::ResourceFileDownloader</name>
<message>
- <source>Could not read resource file &quot;%1&quot;. Reason:</source>
- <translation>Ðевозможно прочитать файл реÑурÑов «%1». Причина:</translation>
+ <source>Cannot read resource file &quot;%1&quot;: %2</source>
+ <translation>Ðевозможно прочитать файл реÑурÑов «%1»: %2</translation>
</message>
</context>
<context>
<name>KDUpdater::RmdirOperation</name>
<message>
- <source>Invalid arguments: %1 arguments given, 1 expected.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров: передано %1, требуетÑÑ 1.</translation>
+ <source>Cannot remove directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить каталог «%1»: %2</translation>
</message>
<message>
- <source>Could not remove folder %1: The folder does not exist.</source>
- <translation>Ðевозможно удалить каталог %1: каталог Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем не ÑущеÑтвует.</translation>
+ <source>The directory does not exist.</source>
+ <translation>Каталог не ÑущеÑтвует.</translation>
</message>
<message>
- <source>Could not remove folder %1: %2</source>
- <translation>Ðевозможно удалить каталог %1: %2</translation>
- </message>
- <message>
- <source>Cannot recreate directory %1: %2</source>
- <translation>Ðевозможно воÑÑтановить каталог %1: %2</translation>
+ <source>Cannot recreate directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ переÑоздать каталог «%1»: %2</translation>
</message>
</context>
<context>
@@ -525,13 +451,9 @@
<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>
- <translation>Приложение не может получить доÑтуп к Ñерверам обновлений.</translation>
- </message>
<message numerus="yes">
<source>%n update(s) found.</source>
<translation>
@@ -545,10 +467,6 @@
<translation>ЗагружаетÑÑ Ñ„Ð°Ð¹Ð» Updates.xml Ñ Ñервера обновлений.</translation>
</message>
<message>
- <source>Could not download update source %1 from (&apos;%2&apos;)</source>
- <translation>Ðе удалоÑÑŒ загрузить иÑточник обновлений %1 Ñ («%2»)</translation>
- </message>
- <message>
<source>Updates.xml file(s) downloaded from update sources.</source>
<translation>Загрузка файла Updates.xml завершена.</translation>
</message>
@@ -560,28 +478,13 @@
<source>Application updates computed.</source>
<translation>ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñ‚Ð¾Ð²Ð»ÐµÐ½Ñ‹.</translation>
</message>
-</context>
-<context>
- <name>KDUpdater::UpdateSourcesInfo</name>
<message>
- <source>%1 contains invalid content: %2</source>
- <translation>%1 Ñодержит недопуÑтимые данные: %2</translation>
+ <source>No package sources set for this application.</source>
+ <translation>ИÑходники пакета не заданы Ð´Ð»Ñ Ñтого приложениÑ.</translation>
</message>
<message>
- <source>Could not read &quot;%1&quot;</source>
- <translation>Ðевозможно прочитать «%1»</translation>
- </message>
- <message>
- <source>XML Parse error in %1 at %2, %3: %4</source>
- <translation>Ошибка разбора XML в %1 в %2, %3: %4</translation>
- </message>
- <message>
- <source>Root element %1 unexpected, should be &quot;UpdateSources&quot;</source>
- <translation>Ðепредвиденный корневой Ñлемент %1, требуетÑÑ Â«UpdateSources»</translation>
- </message>
- <message>
- <source>Could not save changes to &quot;%1&quot;: %2</source>
- <translation>Ðевозможно Ñохранить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² «%1»: %2</translation>
+ <source>Cannot download package source %1 from &quot;%2&quot;.</source>
+ <translation>Ðе удалоÑÑŒ загрузить иÑходник пакета «%1» из «%2».</translation>
</message>
</context>
<context>
@@ -591,7 +494,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>
@@ -626,14 +529,6 @@
<context>
<name>Lib7z</name>
<message>
- <source>Could not retrieve number of items in archive</source>
- <translation>Ðе удалоÑÑŒ определить количеÑтво файлов в архиве</translation>
- </message>
- <message>
- <source>Could not retrieve path of archive item %1</source>
- <translation>Ðе удалоÑÑŒ определить путь файла %1 в архиве</translation>
- </message>
- <message>
<source>Unknown exception caught (%1)</source>
<translation>Возникло неизвеÑтное иÑключение (%1)</translation>
</message>
@@ -650,92 +545,102 @@
<translation>Ошибка: %1</translation>
</message>
<message>
- <source>Could not load codecs</source>
- <translation>Ðе удалоÑÑŒ загрузить кодеки</translation>
+ <source>Cannot retrieve property %1 for item %2.</source>
+ <translation>Ðе удалоÑÑŒ получить ÑвойÑтво %1 Ð´Ð»Ñ Ñлемента %2.</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
- <translation>Ðе удалоÑÑŒ определить формат по умолчанию</translation>
+ <source>Property %1 for item %2 not of type VT_FILETIME but %3.</source>
+ <translation>СвойÑтво %1 Ñлемента %2 отноÑитÑÑ Ð½Ðµ к типу VT_FILETIME, а к %3.</translation>
</message>
<message>
- <source>Could not create archive %1. %2</source>
- <translation>Ðе удалоÑÑŒ Ñоздать архив %1. %2</translation>
+ <source>Cannot convert UTC file time to system time.</source>
+ <translation>Ðе удалоÑÑŒ преобразовать UTC Ð²Ñ€ÐµÐ¼Ñ Ñ„Ð°Ð¹Ð»Ð° в ÑиÑтемное времÑ.</translation>
</message>
<message>
- <source>CArc index %1 out of bounds [0, %2]</source>
- <translation>Ð˜Ð½Ð´ÐµÐºÑ CArc %1 вне лимитов [0, %2]</translation>
+ <source>Cannot load codecs.</source>
+ <translation>Ðе удалоÑÑŒ загрузить кодеки.</translation>
</message>
<message>
- <source>Item index %1 out of bounds [0, %2]</source>
- <translation>Ð˜Ð½Ð´ÐµÐºÑ Ñ„Ð°Ð¹Ð»Ð° %1 вне лимитов [0, %2]</translation>
+ <source>Cannot open archive &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ открыть архив «%1».</translation>
</message>
<message>
- <source>Could not create output file for writing: %1</source>
- <translation>Ðе удалоÑÑŒ Ñоздать выходной файл Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи: %1</translation>
+ <source>Cannot retrieve number of items in archive.</source>
+ <translation>Ðе удалоÑÑŒ определить количеÑтво Ñлементов архива.</translation>
</message>
<message>
- <source>Could not convert path: %1.</source>
- <translation>Ðе удалоÑÑŒ преобразовать путь: %1.</translation>
+ <source>Cannot retrieve path of archive item &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ определить путь Ñлемента архива «%1».</translation>
</message>
-</context>
-<context>
- <name>Lib7z::ExtractItemJob</name>
<message>
- <source>Could not list archive: QIODevice not set or already destroyed.</source>
- <translation>Ðевозможно Ñоздать архив: QIODevice не уÑтановлен или уже разрушен.</translation>
+ <source>Unknown exception caught (%1).</source>
+ <translation>Возникло неизвеÑтное иÑключение (%1).</translation>
</message>
<message>
- <source>Error while extracting &apos;%1&apos;: %2</source>
- <translation>Ошибка Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Â«%1»: %2</translation>
+ <source>Cannot create temporary file: %1</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать временный файл: %1</translation>
</message>
<message>
- <source>Unknown exception caught (%1)</source>
- <translation>Возникло неизвеÑтное иÑключение (%1)</translation>
+ <source>Unsupported archive type.</source>
+ <translation>Ðеподдерживаемый тип архива.</translation>
</message>
<message>
- <source>Failed</source>
- <translation>Ðе удалоÑÑŒ</translation>
+ <source>Cannot create archive &quot;%1&quot;</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать архив «%1»</translation>
</message>
-</context>
-<context>
- <name>Lib7z::ListArchiveJob</name>
<message>
- <source>Could not list archive: QIODevice already destroyed.</source>
- <translation>Ðевозможно Ñоздать архив: QIODevice уже разрушен.</translation>
+ <source>Cannot create archive &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать архив «%1»: %2</translation>
</message>
<message>
- <source>Unknown exception caught (%1)</source>
- <translation>Возникло неизвеÑтное иÑключение (%1)</translation>
+ <source>Cannot remove old archive &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить Ñтарый архив «%1»: %2</translation>
</message>
<message>
- <source>Failed</source>
- <translation>Ðе удалоÑÑŒ</translation>
+ <source>Cannot rename temporary archive &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Ðе удалоÑÑŒ переименовать Ñтарый архив «%1» в «%2»: %3</translation>
</message>
</context>
<context>
- <name>OpenArchiveInfo</name>
+ <name>LocalPackageHub</name>
<message>
- <source>Could not load codecs</source>
- <translation>Ðе удалоÑÑŒ загрузить кодеки</translation>
+ <source>%1 contains invalid content: %2</source>
+ <translation>%1 Ñодержит недопуÑтимые данные: %2</translation>
</message>
<message>
- <source>Could not retrieve default format</source>
- <translation>Ðе удалоÑÑŒ определить формат по умолчанию</translation>
+ <source>The file %1 does not exist.</source>
+ <translation>Файл %1 не ÑущеÑтвует.</translation>
</message>
<message>
- <source>Could not open archive</source>
- <translation>Ðе удалоÑÑŒ открыть архив</translation>
+ <source>Cannot open %1.</source>
+ <translation>Ðе удалоÑÑŒ открыть %1.</translation>
</message>
<message>
- <source>No CArc found</source>
- <translation>CArc не найден</translation>
+ <source>Parse error in %1 at %2, %3: %4</source>
+ <translation>Ошибка разбора в %1 в %2, %3: %4</translation>
+ </message>
+ <message>
+ <source>Root element %1 unexpected, should be &apos;Packages&apos;.</source>
+ <translation>Ðепредвиденный корневой Ñлемент %1, должен быть «Packages».</translation>
</message>
</context>
<context>
- <name>QIODeviceSequentialOutStream</name>
+ <name>LockFile</name>
+ <message>
+ <source>Cannot create lock file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать файл блокировки «%1»: %2</translation>
+ </message>
+ <message>
+ <source>Cannot write PID to lock file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ запиÑать PID в файл блокировки «%1»: %2</translation>
+ </message>
<message>
- <source>No device set for output stream</source>
- <translation>УÑтройÑтво Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ потока не задано</translation>
+ <source>Cannot obtain the lock for file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ заблокировать файл «%1»: %2</translation>
+ </message>
+ <message>
+ <source>Cannot release the lock for file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ разблокировать файл «%1»: %2</translation>
</message>
</context>
<context>
@@ -777,35 +682,11 @@
<translation>ИБ</translation>
</message>
<message>
- <source>Could not remove file %1: %2</source>
- <translation>Ðе удалоÑÑŒ удалить файл %1: %2</translation>
- </message>
- <message>
- <source>Could not remove folder %1: %2</source>
- <translation>Ðе удалоÑÑŒ удалить каталог %1: %2</translation>
- </message>
- <message>
- <source>Could not create folder %1</source>
- <translation>Ðе удалоÑÑŒ Ñоздать каталог %1</translation>
- </message>
- <message>
- <source>Could not 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>
- <translation>Ðе удалоÑÑŒ перемеÑтить файл из %1 в %2: %3</translation>
- </message>
- <message>
- <source>Could not 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>
@@ -821,48 +702,52 @@
<translation>Маркер не найден, оÑтановлено поÑле %1.</translation>
</message>
<message>
- <source>Cannot open file %1 for reading: %2</source>
- <translation>Ðевозможно открыть файл %1 на чтение: %2</translation>
+ <source>Read failed after %1 bytes: %2</source>
+ <translation>Ðе удалоÑÑŒ прочитать поÑле %1 байт: %2</translation>
</message>
<message>
- <source>Cannot open file %1 for writing: %2</source>
- <translation>Ðевозможно открыть файл %1 на запиÑÑŒ: %2</translation>
+ <source>Write failed after %1 bytes: %2</source>
+ <translation>Сбой запиÑи Ñ %1 байта: %2</translation>
</message>
<message>
- <source>Read failed after %1 bytes: %2</source>
- <translation>Ðе удалоÑÑŒ прочитать поÑле %1 байт: %2</translation>
+ <source>The specified module could not be found.</source>
+ <translation>Ðе удалоÑÑŒ найти указанный модуль.</translation>
</message>
<message>
- <source>Copy failed. Error: %1</source>
- <translation>Сбой копированиÑ. Ошибка: %1</translation>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение: %2</translation>
</message>
<message>
- <source>Write failed after %1 bytes: %2</source>
- <translation>Сбой запиÑи Ñ %1 байта: %2</translation>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
<message>
- <source>Could not create temporary file</source>
- <translation>Ðе удалоÑÑŒ Ñоздать временный файл</translation>
+ <source>Copy failed: %1</source>
+ <translation>Ðе удалоÑÑŒ Ñкопировать: %1</translation>
</message>
<message>
- <source>Could not retrieve property %1 for item %2</source>
- <translation>Ðе удалоÑÑŒ определить ÑвойÑтво %1 Ð´Ð»Ñ Ñлемента %2</translation>
+ <source>Cannot remove file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить файл «%1»: %2</translation>
</message>
<message>
- <source>Property %1 for item %2 not of type VT_FILETIME but %3</source>
- <translation>СвойÑтво %1 Ñлемента %2 отноÑитÑÑ Ð½Ðµ к типу VT_FILETIME, а к %3</translation>
+ <source>Cannot remove directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить каталог «%1»: %2</translation>
</message>
<message>
- <source>Could not convert file time to local time</source>
- <translation>Ðе удалоÑÑŒ преобразовать Ð²Ñ€ÐµÐ¼Ñ Ñ„Ð°Ð¹Ð»Ð° в локальное времÑ</translation>
+ <source>Cannot create directory &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать каталог «%1».</translation>
</message>
<message>
- <source>Could not convert local file time to system time</source>
- <translation>Ðе удалоÑÑŒ преобразовать Ð²Ñ€ÐµÐ¼Ñ Ñ„Ð°Ð¹Ð»Ð° в ÑиÑтемное времÑ</translation>
+ <source>Cannot copy file from &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Ðе удалоÑÑŒ Ñкопировать файл «%1» в «%2»: %3</translation>
</message>
<message>
- <source>The specified module could not be found.</source>
- <translation>Ðе удалоÑÑŒ найти указанный модуль.</translation>
+ <source>Cannot move file from &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Ðе удалоÑÑŒ перемеÑтить файл «%1» в «%2»: %3</translation>
+ </message>
+ <message>
+ <source>Cannot create directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать каталог «%1»: %2</translation>
</message>
</context>
<context>
@@ -872,32 +757,32 @@
<translation>У компонентов не может быть потомков в режиме обновлениÑ.</translation>
</message>
<message>
- <source>Could not open the requested UI file &apos;%1&apos;. Error: %2</source>
- <translation>Ðевозможно открыть UI файл «%1». Ошибка: %2</translation>
+ <source>Error</source>
+ <translation>Ошибка</translation>
</message>
<message>
- <source>Could not load the requested UI file &apos;%1&apos;. Error: %2</source>
- <translation>Ðевозможно загрузить UI файл «%1». Ошибка: %2</translation>
+ <source>Cannot resolve isDefault in %1</source>
+ <translation>Ðевозможно выполнить метод isDefault в Ñценарии %1</translation>
</message>
<message>
- <source>Could not open the requested license file &apos;%1&apos;. Error: %2</source>
- <translation>Ðевозможно открыть файл лицензии «%1». Ошибка: %2</translation>
+ <source>Update Info: </source>
+ <translation>Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± обновлении:</translation>
</message>
<message>
- <source>Error</source>
- <translation>Ошибка</translation>
+ <source>Cannot open the requested UI file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть запрошенный UI файл «%1»: %2</translation>
</message>
<message>
- <source>Error: Operation %1 does not exist</source>
- <translation>Ошибка: Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ %1 не ÑущеÑтвует</translation>
+ <source>Cannot load the requested UI file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ загрузить запрошенный UI файл «%1»: %2</translation>
</message>
<message>
- <source>Cannot resolve isDefault in %1</source>
- <translation>Ðевозможно выполнить метод isDefault в Ñценарии %1</translation>
+ <source>Cannot open the requested license file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть запрошенный файл лицензии «%1»: %2</translation>
</message>
<message>
- <source>Update Info: </source>
- <translation>Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± обновлении:</translation>
+ <source>Error: Operation %1 does not exist.</source>
+ <translation>Ошибка: Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ %1 не ÑущеÑтвует.</translation>
</message>
</context>
<context>
@@ -1009,71 +894,71 @@
<source>Select the components to install. Deselect installed components to uninstall them.</source>
<translation>Выберите компоненты Ð´Ð»Ñ ÑƒÑтановки.Ð”Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑƒÐ¶Ðµ уÑтановленных компонентов Ñнимите отметки выбора.</translation>
</message>
-</context>
-<context>
- <name>QInstaller::ConsumeOutputOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
+ <source>To install new compressed repository, browse the repositories from your computer</source>
+ <translation type="unfinished">Ð”Ð»Ñ ÑƒÑтановки нового хранилища укажите путь к нему на вашем компьютере</translation>
</message>
<message>
- <source>at least 2</source>
- <translation>по крайней мерe 2</translation>
+ <source>&amp;Browse BSP or 7z files...</source>
+ <translation>&amp;Обзор BSP или 7z файлов...</translation>
</message>
<message>
+ <source>Open File</source>
+ <translation>Открытие файла</translation>
+ </message>
+</context>
+<context>
+ <name>QInstaller::ConsumeOutputOperation</name>
+ <message>
<source>Needed installer object in %1 operation is empty.</source>
<translation>Ð’ операции «%1» необходимый объект уÑтановщика пуÑÑ‚.</translation>
</message>
<message>
- <source>Can not save the output of %1 to an empty installer key value.</source>
- <translation>Ðевозможно Ñохранить вывод операции %1 по пуÑтому ключу.</translation>
+ <source>&lt;to be saved installer key name&gt; &lt;executable&gt; [argument1] [argument2] [...]</source>
+ <translation>&lt;ÑохранÑемое Ð¸Ð¼Ñ ÐºÐ»ÑŽÑ‡Ð° уÑтановщика&gt; &lt;программа&gt; [параметр1] [параметр2] [...]</translation>
+ </message>
+ <message>
+ <source>Cannot save the output of &quot;%1&quot; to an empty installer key value.</source>
+ <translation>Ðевозможно Ñохранить вывод «%1» в пуÑтое значение ключа уÑтановщика.</translation>
</message>
<message>
- <source>File &apos;%1&apos; does not exist or is not an executable binary.</source>
+ <source>File &quot;%1&quot; does not exist or is not an executable binary.</source>
<translation>Файл «%1» не ÑущеÑтвует или не ÑвлÑетÑÑ Ð¸ÑполнÑемым.</translation>
</message>
<message>
- <source>Running &apos;%1&apos; resulted in a crash.</source>
+ <source>Running &quot;%1&quot; resulted in a crash.</source>
<translation>ЗапуÑк «%1» завершилÑÑ ÐºÑ€Ð°Ñ…Ð¾Ð¼.</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>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
+ <source>&lt;source&gt; &lt;target&gt; [&quot;forceOverwrite&quot;]</source>
+ <translation>&lt;иÑточник&gt; &lt;назначение&gt; [&quot;forceOverwrite&quot;]</translation>
</message>
<message>
- <source> (&lt;source&gt; &lt;target&gt; [forceOverwrite])</source>
- <translation> (&lt;иÑточник&gt; &lt;назначение&gt; [forceOverwrite])</translation>
+ <source>Invalid argument in %1: Third argument needs to be forceOverwrite, if specified.</source>
+ <translation>ÐедопуÑтимый параметр в %1: третьим параметром должен быть &quot;forceOverwrite&quot;, еÑли он задан.</translation>
</message>
<message>
- <source>Invalid argument in %0: Third argument needs to be forceOverwrite, if specified</source>
- <translation>ÐедопуÑтимый параметр в %0: третьим параметром должен быть &quot;forceOverwrite&quot;, еÑли он задан</translation>
+ <source>Invalid argument in %1: Directory &quot;%2&quot; is invalid.</source>
+ <translation>ÐедопуÑтимые параметры в %1: Каталог «%2» неверен.</translation>
</message>
<message>
- <source>Invalid arguments in %0: Directories are invalid: %1 %2</source>
- <translation>ÐедопуÑтимые параметры в %0: ÐедопуÑтимые имена папок: %1 %2</translation>
+ <source>Cannot create directory &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать каталог «%1».</translation>
</message>
<message>
- <source>Could not create %0</source>
- <translation>Ðевозможно Ñоздать %0</translation>
+ <source>Failed to overwrite &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ перезапиÑать «%1».</translation>
</message>
<message>
- <source>Failed to overwrite %1</source>
- <translation>Ðе удалоÑÑŒ перезапиÑать %1</translation>
+ <source>Cannot copy file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Ðе удалоÑÑŒ Ñкопировать файл «%1» в «%2»: %3</translation>
</message>
<message>
- <source>Could not copy %0 to %1, error was: %3</source>
- <translation>Ðевозможно Ñкопировать %0 в %1. Ошибка: %3</translation>
- </message>
- <message>
- <source>Could not remove %0</source>
- <translation>Ðевозможно удалить %0</translation>
+ <source>Cannot remove file &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ удалить файл «%1».</translation>
</message>
</context>
<context>
@@ -1083,144 +968,112 @@
<translation>Ðеверное чиÑло Ñлементов task.</translation>
</message>
<message>
- <source>Could not open source &apos;%1&apos; for read. Error: %2.</source>
- <translation>Ðе удалоÑÑŒ открыть иÑточник «%1» Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ. Ошибка: %2.</translation>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение: %2</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
- <translation>Ðе удалоÑÑŒ открыть «%1» Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. Ошибка: %2.</translation>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
<message>
- <source>Writing to target &apos;%1&apos; failed. Error: %2.</source>
- <translation>Сбой запиÑи в «%1». Ошибка %2.</translation>
+ <source>Writing to file &quot;%1&quot; failed: %2</source>
+ <translation>Ðе удалоÑÑŒ запиÑать в «%1»: %2</translation>
</message>
</context>
<context>
<name>QInstaller::CreateDesktopEntryOperation</name>
<message>
- <source>Could not backup file %1: %2</source>
- <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла %1: %2</translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
+ <source>Cannot backup file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла «%1»: %2</translation>
</message>
<message>
- <source>exactly 2</source>
- <translation>ровно 2</translation>
+ <source>Failed to overwrite file &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ перезапиÑать файл «%1».</translation>
</message>
<message>
- <source>Failed to overwrite %1</source>
- <translation>Ðе удалоÑÑŒ перезапиÑать %1</translation>
- </message>
- <message>
- <source>Could not write Desktop Entry at %1</source>
- <translation>Ðевозможно запиÑать Desktop Entry в %1</translation>
+ <source>Cannot write desktop entry to &quot;%1&quot;.</source>
+ <translation>Ðевозможно запиÑать Desktop Entry в «%1».</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLinkOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation>ровно 2</translation>
+ <source>Cannot create link from &quot;%1&quot; to &quot;%2&quot;.</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать ÑÑылку Ñ Â«%1» на «%2».</translation>
</message>
<message>
- <source>Could not create link from %1 to %2.</source>
- <translation>Ðе удалоÑÑŒ Ñоздать ÑÑылку Ñ %1 на %2.</translation>
- </message>
- <message>
- <source>Could not remove link from %1 to %2.</source>
- <translation>Ðе удалоÑÑŒ Ñоздать ÑÑылку Ñ %1 на %2.</translation>
+ <source>Cannot remove link from &quot;%1&quot; to &quot;%2&quot;.</source>
+ <translation>Ðе удалоÑÑŒ удалить ÑÑылку Ñ Â«%1» на «%2».</translation>
</message>
</context>
<context>
<name>QInstaller::CreateLocalRepositoryOperation</name>
<message>
- <source>Could not set file permissions %1!</source>
- <translation>Ðевозможно уÑтановить права доÑтупа Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° %1!</translation>
- </message>
- <message>
- <source>Could not remove file %1: %2</source>
- <translation>Ðе удалоÑÑŒ удалить файл %1: %2</translation>
- </message>
- <message>
- <source>Could not move file %1 to %2. Error: %3</source>
- <translation>Ðевозможно перемеÑтить файл %1 в %2. Ошибка: %3</translation>
+ <source>Unknown exception caught: %1.</source>
+ <translation>Возникло неизвеÑтное иÑключение: %1.</translation>
</message>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1,%3 требуетÑÑ %2.</translation>
+ <source>Cannot set permissions for file &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ уÑтановить права доÑтупа к файлу «%1».</translation>
</message>
<message>
- <source>exactly 2</source>
- <translation>ровно 2</translation>
+ <source>Cannot remove file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить файл «%1»: %2</translation>
</message>
<message>
- <source>Installer needs to be an offline version: %1.</source>
- <translation>Ðеобходима Ð¾Ñ„Ð»Ð°Ð¹Ð½Ð¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ уÑтановки: %1.</translation>
+ <source>Cannot move file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Ðе удалоÑÑŒ перемеÑтить файл «%1» в «%2»: %3</translation>
</message>
<message>
- <source>Could not open file: %1</source>
- <translation>Ðевозможно открыть файл: %1</translation>
+ <source>Installer at &quot;%1&quot; needs to be an offline one.</source>
+ <translation>УÑтановщик в «%1» должен быть оффлайновым.</translation>
</message>
<message>
- <source>Could not read: %1. Error: %2</source>
- <translation>Ðевозможно прочитать: %1. Ошибка: %2</translation>
+ <source>Cannot open file &quot;%1&quot; for reading.</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение.</translation>
</message>
<message>
- <source>Could not open file: %1. Error: %2</source>
- <translation>Ðевозможно открыть файл: %1. Ошибка: %2</translation>
+ <source>Cannot read file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ прочитать файл «%1»: %2</translation>
</message>
<message>
- <source>Could not create target dir: %1.</source>
- <translation>Ðевозможно Ñоздать каталог назначениÑ: %1.</translation>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение: %2</translation>
</message>
<message>
- <source>Unknown exception caught: %1.</source>
- <translation>Возникло неизвеÑтное иÑключение: %1.</translation>
+ <source>Cannot create target directory: &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать целевой каталог «%1».</translation>
</message>
<message>
- <source>Removing file: %0</source>
- <translation>Удаление файла: %0</translation>
+ <source>Removing file &quot;%1&quot;.</source>
+ <translation>Удаление файла «%1».</translation>
</message>
<message>
- <source>Could not remove %0.</source>
- <translation>Ðевозможно удалить %0.</translation>
+ <source>Cannot remove file &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ удалить файл «%1».</translation>
</message>
<message>
- <source>Cannot remove directory %1: %2</source>
- <translation>Ðевозможно удалить каталог %1: %2</translation>
+ <source>Cannot remove directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить каталог «%1»: %2</translation>
</message>
</context>
<context>
<name>QInstaller::CreateShortcutOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
+ <source>&lt;target&gt; &lt;link location&gt; [target arguments] [&quot;workingDirectory=...&quot;] [&quot;iconPath=...&quot;] [&quot;iconId=...&quot;] [&quot;description=...&quot;]</source>
+ <translation>&lt;цель&gt; &lt;размещение ÑÑылки&gt; [параметры цели] [&quot;workingDirectory=...&quot;] [&quot;iconPath=...&quot;] [&quot;iconId=...&quot;] [&quot;description=...&quot;]</translation>
</message>
<message>
- <source>2 or 3</source>
- <translation>2 или 3</translation>
+ <source>Cannot create directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать каталог «%1»: %2</translation>
</message>
<message>
- <source> (optional: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;)</source>
- <translation> (необÑзательно: &apos;workingDirectory=...&apos;, &apos;iconPath=...&apos;, &apos;iconId=...&apos;)</translation>
+ <source>Failed to overwrite &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ перезапиÑать «%1»: %2</translation>
</message>
<message>
- <source>Could not create folder %1: %2.</source>
- <translation>Ðе удалоÑÑŒ Ñоздать каталог: %1: %2.</translation>
- </message>
- <message>
- <source>Failed to overwrite %1: %2</source>
- <translation>Ðе удалоÑÑŒ перезапиÑать %1: %2</translation>
- </message>
- <message>
- <source>Could not create link %1: %2</source>
- <translation>Ðе удалоÑÑŒ Ñоздать ÑÑылку %1: %2</translation>
+ <source>Cannot create link &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать ÑÑылку «%1»: %2</translation>
</message>
</context>
<context>
@@ -1242,153 +1095,123 @@
<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>
- <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>
</message>
<message>
- <source>Downloading archive &apos;%1&apos; for component: %2</source>
- <translation>Загрузка архива «%1» Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð°: %2</translation>
+ <source>Cannot download archive %1: %2</source>
+ <translation>Ðе удалоÑÑŒ загрузить архив «%1»: %2</translation>
</message>
<message>
- <source>Scheme not supported: %1 (%2)</source>
- <translation>Схема не поддерживаетÑÑ: %1 (%2)</translation>
+ <source>Downloading archive &quot;%1&quot; for component %2.</source>
+ <translation>Загрузка архива «%1» Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð° «%2».</translation>
</message>
<message>
- <source>Could not find component for: %1.</source>
- <translation>Ðевозможно найти компонент длÑ: %1.</translation>
+ <source>Scheme %1 not supported (URL: %2).</source>
+ <translation>Схема %1 не поддерживаетÑÑ (URL: %2).</translation>
+ </message>
+ <message>
+ <source>Cannot find component for %1.</source>
+ <translation>Ðе удалоÑÑŒ найти компонент Ð´Ð»Ñ %1.</translation>
</message>
</context>
<context>
<name>QInstaller::Downloader</name>
<message>
- <source>Target &apos;%1&apos; not open for write. Error: %2.</source>
- <extracomment>%2 is a sentence describing the error.</extracomment>
- <translation>«%1» не открыт Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. Ошибка: %2.</translation>
- </message>
- <message>
- <source>Writing to target &apos;%1&apos; failed. Error: %2.</source>
- <extracomment>%2 is a sentence describing the error.</extracomment>
- <translation>Сбой запиÑи в «%1». Ошибка %2.</translation>
- </message>
- <message>
- <source>Redirect loop detected &apos;%1&apos;.</source>
- <translation>Обнаружено кольцо перенаправлений «%1».</translation>
+ <source>Pause and resume not supported by network transfers.</source>
+ <translation>ПриоÑтановка и продолжение не поддерживаютÑÑ Ñетевыми протоколами.</translation>
</message>
<message>
- <source>Checksum mismatch detected &apos;%1&apos;.</source>
- <translation>Обнаружено неÑовпадение контрольной Ñуммы «%1».</translation>
+ <source>Target file &quot;%1&quot; already exists but is not a file.</source>
+ <translation>«%1» уже ÑущеÑтвует, но не ÑвлÑетÑÑ Ñ„Ð°Ð¹Ð»Ð¾Ð¼.</translation>
</message>
<message>
- <source>Network error while downloading &apos;%1&apos;: %2.</source>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
<extracomment>%2 is a sentence describing the error</extracomment>
- <translation>Ð¡ÐµÑ‚ÐµÐ²Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при загрузке «%1»: %2.</translation>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
<message>
- <source>Unknown network error while downloading: %1.</source>
- <extracomment>%1 is a sentence describing the error</extracomment>
- <translation>ÐеизвеÑÑ‚Ð½Ð°Ñ ÑÐµÑ‚ÐµÐ²Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° во Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸: %1.</translation>
+ <source>File &quot;%1&quot; not open for writing: %2</source>
+ <extracomment>%2 is a sentence describing the error.</extracomment>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
<message>
- <source>Pause and resume not supported by network transfers.</source>
- <translation>ПриоÑтановка и продолжение не поддерживаютÑÑ Ñетевыми протоколами.</translation>
+ <source>Writing to file &quot;%1&quot; failed: %2</source>
+ <extracomment>%2 is a sentence describing the error.</extracomment>
+ <translation>Ðе удалоÑÑŒ запиÑать в «%1»: %2</translation>
</message>
<message>
- <source>Invalid source &apos;%1&apos;. Error: %2.</source>
- <extracomment>%2 is a sentence describing the error</extracomment>
- <translation>Ðеверный иÑточник «%1». Ошибка: %2.</translation>
+ <source>Redirect loop detected for &quot;%1&quot;.</source>
+ <translation>Обнаружено кольцо перенаправлений «%1».</translation>
</message>
<message>
- <source>Target file &apos;%1&apos; already exists but is not a file.</source>
- <translation>«%1» уже ÑущеÑтвует, но не ÑвлÑетÑÑ Ñ„Ð°Ð¹Ð»Ð¾Ð¼.</translation>
+ <source>Checksum mismatch detected for &quot;%1&quot;.</source>
+ <translation>Обнаружено неÑовпадение контрольной Ñуммы «%1».</translation>
</message>
<message>
- <source>Could not open target &apos;%1&apos; for write. Error: %2.</source>
+ <source>Network error while downloading &quot;%1&quot;: %2</source>
<extracomment>%2 is a sentence describing the error</extracomment>
- <translation>Ðе удалоÑÑŒ открыть «%1» Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. Ошибка: %2.</translation>
- </message>
-</context>
-<context>
- <name>QInstaller::ElevatedExecuteOperation</name>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
- </message>
- <message>
- <source>at least 1</source>
- <translation>по крайней мере 1</translation>
+ <translation>Возникла ошибка Ñети при загрузке «%1»: %2</translation>
</message>
<message>
- <source>Execution failed: Could not start detached: &quot;%1&quot;</source>
- <translation>Ðе удалоÑÑŒ выполнить: невозможно запуÑтить фоновый процеÑÑ: «%1»</translation>
- </message>
- <message>
- <source>Execution failed: Could not start: &quot;%1&quot;(%2)</source>
- <translation>Ðе удалоÑÑŒ иÑполнить: невозможно запуÑтить: «%1»(%2)</translation>
+ <source>Unknown network error while downloading &quot;%1&quot;.</source>
+ <extracomment>%1 is a sentence describing the error</extracomment>
+ <translation>Возникла неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° Ñети во Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ «%1».</translation>
</message>
<message>
- <source>Execution failed(Crash): &quot;%1&quot;</source>
- <translation>Ðе удалоÑÑŒ иÑполнить(Сбой): «%1»</translation>
+ <source>Network transfers canceled.</source>
+ <translation>Сетевые передачи отменены.</translation>
</message>
<message>
- <source>Execution failed(Unexpected exit code: %1): &quot;%2&quot;</source>
- <translation>Ðе удалоÑÑŒ иÑполнить(Ðепредвиденный код выхода: %1): «%2»</translation>
+ <source>Invalid source URL &quot;%1&quot;: %2</source>
+ <extracomment>%2 is a sentence describing the error</extracomment>
+ <translation>Ðеверный URL иÑточника «%1»: %2</translation>
</message>
</context>
<context>
- <name>QInstaller::EnvironmentVariableOperation</name>
+ <name>QInstaller::ElevatedExecuteOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
+ <source>Cannot start detached: &quot;%1&quot;</source>
+ <translation>Ðе удалоÑÑŒ запуÑтить отцеплённым: «%1»</translation>
</message>
<message>
- <source>2 to 4</source>
- <translation>от 2 до 4</translation>
+ <source>Cannot start: &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ запуÑтить «%1»: %2</translation>
</message>
-</context>
-<context>
- <name>QInstaller::ExtractArchiveOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
+ <source>Program crashed: &quot;%1&quot;</source>
+ <translation>Программа завершилаÑÑŒ крахом: «%1»</translation>
</message>
<message>
- <source>exactly 2</source>
- <translation>ровно 2</translation>
+ <source>Execution failed (Unexpected exit code: %1): &quot;%2&quot;</source>
+ <translation>Ðе удалоÑÑŒ иÑполнить (неожиданный код завершениÑ: %1): «%2»</translation>
</message>
</context>
<context>
<name>QInstaller::ExtractArchiveOperation::Runnable</name>
<message>
- <source>Could not open %1 for reading: %2.</source>
- <translation>Ðевозможно открыть файл %1 на чтение: %2.</translation>
+ <source>Cannot open archive &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть архив «%1» Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ: %2</translation>
</message>
<message>
- <source>Error while extracting &apos;%1&apos;: %2</source>
- <translation>Ошибка Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Â«%1»: %2</translation>
+ <source>Error while extracting archive &quot;%1&quot;: %2</source>
+ <translation>Ошибка Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð· архива «%1»: %2</translation>
</message>
<message>
- <source>Unknown exception caught while extracting %1.</source>
- <translation>Ð’ процеÑÑе Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ %1 возникло неизвеÑтное иÑключение.</translation>
+ <source>Unknown exception caught while extracting &quot;%1&quot;.</source>
+ <translation>Ð’ процеÑÑе Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Â«%1» возникло неизвеÑтное иÑключение.</translation>
</message>
</context>
<context>
<name>QInstaller::FakeStopProcessForUpdateOperation</name>
<message>
- <source>Number of arguments does not match: one is required</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>
@@ -1462,14 +1285,6 @@ Error while loading %2</source>
<translation>Завершение уÑтановки %1</translation>
</message>
<message>
- <source>Click Done to exit the %1 Wizard.</source>
- <translation>Ðажмите &quot;Готово&quot; Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð° из маÑтера уÑтановки %1.</translation>
- </message>
- <message>
- <source>Click Finish to exit the %1 Wizard.</source>
- <translation>Ðажмите &quot;Завершить&quot; Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð° из маÑтера уÑтановки %1.</translation>
- </message>
- <message>
<source>Restart</source>
<translation>ПерезапуÑтить</translation>
</message>
@@ -1481,59 +1296,47 @@ Error while loading %2</source>
<source>The %1 Wizard failed.</source>
<translation>УÑтановка %1 не удалаÑÑŒ.</translation>
</message>
+ <message>
+ <source>Click %1 to exit the %2 Wizard.</source>
+ <translation>Ðажмите «%1» Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð° из маÑтера %2.</translation>
+ </message>
</context>
<context>
<name>QInstaller::GlobalSettingsOperation</name>
<message>
- <source>Settings are not writable</source>
- <translation>Ðевозможно запиÑать наÑтройки</translation>
+ <source>Settings are not writable.</source>
+ <translation>ÐаÑтройки только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ.</translation>
</message>
<message>
- <source>Failed to write settings</source>
- <translation>Ðе удалоÑÑŒ Ñохранить наÑтройки</translation>
- </message>
- <message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
- </message>
- <message>
- <source>3, 4 or 5</source>
- <translation>3, 4 или 5</translation>
+ <source>Failed to write settings.</source>
+ <translation>Ðе удалоÑÑŒ запиÑать наÑтройки.</translation>
</message>
</context>
<context>
<name>QInstaller::InstallIconsOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
- </message>
- <message>
- <source>1 or 2</source>
- <translation>1 или 2</translation>
+ <source>&lt;source path&gt; [vendor prefix]</source>
+ <translation>&lt;путь к иÑходникам&gt; [Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ð²ÐµÐ½Ð´Ð¾Ñ€Ð°]</translation>
</message>
<message>
- <source> (Sourcepath, [Vendorprefix])</source>
- <translation> (иÑточник, [Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ð¿Ð¾Ñтавщика])</translation>
+ <source>Invalid Argument: source directory must not be empty.</source>
+ <translation>Ðеверный параметр: иÑходный каталог не может быть пуÑтым.</translation>
</message>
<message>
- <source>Invalid Argument: source folder must not be empty.</source>
- <translation>ÐедопуÑтимый параметр: иÑходный каталог не может быть пуÑтым.</translation>
+ <source>Cannot backup file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла «%1»: %2</translation>
</message>
<message>
- <source>Could not backup file %1: %2</source>
- <translation>Ðе удалоÑÑŒ Ñоздать резервную копию файла %1: %2</translation>
+ <source>Failed to overwrite &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ перезапиÑать «%1»: %2</translation>
</message>
<message>
- <source>Failed to overwrite %1: %2</source>
- <translation>Ðе удалоÑÑŒ перезапиÑать %1: %2</translation>
+ <source>Failed to copy file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñкопировать файл «%1»: %2</translation>
</message>
<message>
- <source>Failed to copy file %1: %2</source>
- <translation>Ðе удалоÑÑŒ Ñкопировать %1: %2</translation>
- </message>
- <message>
- <source>Could not create folder at %1: %2</source>
- <translation>Ðе удалоÑÑŒ Ñоздать каталог в %1: %2</translation>
+ <source>Cannot create directory &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ Ñоздать каталог «%1»: %2</translation>
</message>
</context>
<context>
@@ -1631,31 +1434,23 @@ Error while loading %2</source>
<translation>Ð’ операции «%1» необходимый объект уÑтановщика пуÑÑ‚.</translation>
</message>
<message>
- <source>Can not write license file: %1.</source>
- <translation>Ðевозможно Ñохранить файл лицензии: %1.</translation>
- </message>
- <message>
<source>No license files found to delete.</source>
<translation>Ðевозможно удалить файл лицензии: файл не найден.</translation>
</message>
+ <message>
+ <source>Can not write license file &quot;%1&quot;.</source>
+ <translation>Ðе удалоÑÑŒ запиÑать файл лицензии «%1».</translation>
+ </message>
</context>
<context>
<name>QInstaller::LineReplaceOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
- </message>
- <message>
- <source>exactly 3</source>
- <translation>ровно 3</translation>
- </message>
- <message>
- <source>Failed to open &apos;%1&apos; for reading.</source>
- <translation>Сбой Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Â«%1» на чтение.</translation>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение: %2</translation>
</message>
<message>
- <source>Failed to open &apos;%1&apos; for writing.</source>
- <translation>Сбой Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Â«%1» на запиÑÑŒ.</translation>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
</context>
<context>
@@ -1701,16 +1496,20 @@ Error while loading %2</source>
<translation>Извлечение метаданных...</translation>
</message>
<message>
- <source>Error while extracting &apos;%1&apos;: %2</source>
- <translation>Ошибка Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Â«%1»: %2</translation>
+ <source>Unpacking compressed repositories...</source>
+ <translation>РаÑпаковка Ñжатых хранилищ...</translation>
</message>
<message>
- <source>Unknown exception caught while extracting %1.</source>
- <translation>Ð’ процеÑÑе Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ %1 возникло неизвеÑтное иÑключение.</translation>
+ <source>Error while extracting archive &quot;%1&quot;: %2</source>
+ <translation>Ошибка Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð· архива «%1»: %2</translation>
</message>
<message>
- <source>Could not open %1 for reading. Error: %2</source>
- <translation>Ðевозможно открыть файл %1 на чтение: %2</translation>
+ <source>Unknown exception caught while extracting archive &quot;%1&quot;.</source>
+ <translation>Ð’ процеÑÑе Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð· архива «%1» возникло неизвеÑтное иÑключение.</translation>
+ </message>
+ <message>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение: %2</translation>
</message>
</context>
<context>
@@ -1726,10 +1525,6 @@ Downloading packages...</source>
Загрузка пакетов...</translation>
</message>
<message>
- <source>Installation canceled by user</source>
- <translation>УÑтановка отменена пользователем</translation>
- </message>
- <message>
<source>All downloads finished.</source>
<translation>Ð’Ñе загрузки завершены.</translation>
</message>
@@ -1742,10 +1537,6 @@ Downloading packages...</source>
<translation>Ошибка аутентификации</translation>
</message>
<message>
- <source>Some components could not be removed completely because admin rights could not be acquired: %1.</source>
- <translation>Ðекоторые компоненты не были удалены полноÑтью. Ð”Ð»Ñ Ð¸Ñ… полного ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ñ‹ права ÐдминиÑтратора: %1.</translation>
- </message>
- <message>
<source>Unknown error.</source>
<translation>ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°.</translation>
</message>
@@ -1754,18 +1545,10 @@ Downloading packages...</source>
<translation>Ðекоторые компоненты не были удалены полноÑтью: возникла неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°.</translation>
</message>
<message>
- <source>Application not running in Package Manager mode!</source>
- <translation>Приложение не запущено в режиме менеджера пакетов!</translation>
- </message>
- <message>
<source>No installed packages found.</source>
<translation>УÑтановленные пакеты не найдены.</translation>
</message>
<message>
- <source>Application running in Uninstaller mode!</source>
- <translation>Приложение запущено в режиме удалениÑ!</translation>
- </message>
- <message>
<source>There is an important update available, please run the updater first.</source>
<translation>ДоÑтупно важное иÑправление, Ñначала запуÑтите программу обновлениÑ.</translation>
</message>
@@ -1781,6 +1564,30 @@ Downloading packages...</source>
<source>invalid</source>
<translation>недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑиÑ</translation>
</message>
+ <message>
+ <source>Installation canceled by user.</source>
+ <translation>УÑтановка отменена пользователем.</translation>
+ </message>
+ <message>
+ <source>Some components could not be removed completely because administrative rights could not be acquired: %1.</source>
+ <translation>Ðекоторые компоненты не были удалены полноÑтью. Ð”Ð»Ñ Ð¸Ñ… полного ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ñ‹ права ÐдминиÑтратора: %1.</translation>
+ </message>
+ <message>
+ <source>Application not running in Package Manager mode.</source>
+ <translation>Приложение не запущено в режиме менеджера пакетов.</translation>
+ </message>
+ <message>
+ <source>Application running in Uninstaller mode.</source>
+ <translation>Приложение запущено в режиме удалениÑ.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve all dependencies.</source>
+ <translation>Ðе удалоÑÑŒ разрешить вÑе завиÑимоÑти.</translation>
+ </message>
+ <message>
+ <source>Components about to be removed.</source>
+ <translation>УдалÑемые компоненты.</translation>
+ </message>
</context>
<context>
<name>QInstaller::PackageManagerCorePrivate</name>
@@ -1797,7 +1604,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>
@@ -1881,19 +1688,11 @@ 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>
- <translation>Ðе удалоÑÑŒ удалить файл данных «%1»: %2</translation>
- </message>
- <message>
- <source>Could not 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>
@@ -1942,27 +1741,35 @@ Installing component %1</source>
<translation>ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°</translation>
</message>
<message>
- <source>Could not retrieve remote tree: %1.</source>
- <translation>Ðевозможно загрузить удалённую Ñтруктуру: %1.</translation>
+ <source>Cannot retrieve meta information: %1</source>
+ <translation>Ðевозможно загрузить метаданные: %1</translation>
</message>
<message>
- <source>Failure to read packages from: %1.</source>
- <translation>Ðе удалоÑÑŒ прочитать пакеты из: %1.</translation>
+ <source>Cannot add temporary update source information.</source>
+ <translation>Ðевозможно добавить информацию о временном Ñервере обновлениÑ.</translation>
</message>
<message>
- <source>Could not retrieve meta information: %1</source>
- <translation>Ðевозможно загрузить метаданные: %1</translation>
+ <source>Cannot find any update source information.</source>
+ <translation>Ðевозможно найти информацию об иÑточниках обновлениÑ.</translation>
</message>
<message>
- <source>Could not add temporary update source information.</source>
- <translation>Ðевозможно добавить информацию о временном Ñервере обновлениÑ.</translation>
+ <source>Cannot remove data file &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ удалить файл данных «%1»: %2</translation>
</message>
<message>
- <source>Could not find any update source information.</source>
- <translation>Ðевозможно найти информацию об иÑточниках обновлениÑ.</translation>
+ <source>Cannot write maintenance tool to &quot;%1&quot;: %2</source>
+ <translation>Ðе удалоÑÑŒ запиÑать программу обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð² «%1»: %2</translation>
</message>
<message>
- <source>Dependency cycle between components detected: &apos;%1&apos; and &apos;%2&apos;.</source>
+ <source>Cannot retrieve remote tree %1.</source>
+ <translation>Ðе удалоÑÑŒ загрузить удалённое дерево: %1.</translation>
+ </message>
+ <message>
+ <source>Failure to read packages from %1.</source>
+ <translation>Ðе удалоÑÑŒ прочитать пакеты из %1.</translation>
+ </message>
+ <message>
+ <source>Dependency cycle between components &quot;%1&quot; and &quot;%2&quot; detected.</source>
<translation>Обнаружена цикличеÑÐºÐ°Ñ Ð·Ð°Ð²Ð¸ÑимоÑÑ‚ÑŒ компонентов «%1» и «%2».</translation>
</message>
</context>
@@ -1997,10 +1804,6 @@ Installing component %1</source>
<translation>Выйти из Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¾Ð±ÑлуживаниÑ?</translation>
</message>
<message>
- <source>Question</source>
- <translation>ВопроÑ</translation>
- </message>
- <message>
<source>Settings</source>
<translation>ÐаÑтройки</translation>
</message>
@@ -2013,6 +1816,11 @@ Installing component %1</source>
Please copy the installer to a local drive</source>
<translation>невозможно произвеÑти уÑтановку из Ñетевого иÑточника. ПожалуйÑта, Ñохраните программу уÑтановки на жёÑктй диÑк Вашего компьютера</translation>
</message>
+ <message>
+ <source>%1 Question</source>
+ <translatorcomment>Вот Ñто непонÑÑ‚Ð½Ð°Ñ Ñ…Ñ€ÐµÐ½ÑŒ.</translatorcomment>
+ <translation>Ð’Ð¾Ð¿Ñ€Ð¾Ñ Ð¿Ð¾ %1</translation>
+ </message>
</context>
<context>
<name>QInstaller::PerformInstallationForm</name>
@@ -2080,7 +1888,7 @@ Please copy the installer to a local drive</source>
</message>
<message>
<source>Proxy Credentials</source>
- <translation>ÐÐ²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° прокÑи-Ñервере</translation>
+ <translation>ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð½Ð° прокÑи-Ñервере</translation>
</message>
</context>
<context>
@@ -2122,18 +1930,6 @@ Please copy the installer to a local drive</source>
<translation>Программа уÑтановки готова начать уÑтановку %1 на ваш компьютер.</translation>
</message>
<message>
- <source>Not enough disk space to store temporary files and the installation! Available space: %1, at least required %2.</source>
- <translation>ÐедоÑтаточно меÑта на диÑке Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… файлов и файлов уÑтановки! ДоÑтупно: %1, требуетÑÑ ÐºÐ°Ðº минимум %2.</translation>
- </message>
- <message>
- <source>Not enough disk space to store all selected components! Available space: %1, at least required: %2.</source>
- <translation>ÐедоÑтаточно меÑта на диÑке Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ñех выбранных компонентов! ДоÑтупно: %1, требуетÑÑ ÐºÐ°Ðº минимум: %2.</translation>
- </message>
- <message>
- <source>Not enough disk space to store temporary files! Available space: %1, at least required: %2.</source>
- <translation>ÐедоÑтаточно меÑта на диÑке Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… файлов! ДоÑтупно: %1, требуетÑÑ ÐºÐ°Ðº минимум %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>Ðа выбранном Вами диÑке доÑтаточно меÑта Ð´Ð»Ñ ÑƒÑтановки. Тем не менее, поÑле Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ ÑƒÑтановки на диÑке оÑтанетÑÑ Ð¼ÐµÐ½ÑŒÑˆÐµ 1% Ñвободного меÑта. %1</translation>
</message>
@@ -2146,25 +1942,21 @@ Please copy the installer to a local drive</source>
<translation>Ð”Ð»Ñ ÑƒÑтановки потребуетÑÑ %1 диÑкового проÑтранÑтва.</translation>
</message>
<message>
- <source>Cannot resolve all dependencies.</source>
- <translation>Ðевозможно разрешить вÑе завиÑимоÑти.</translation>
+ <source>Not enough disk space to store temporary files and the installation. %1 are available, while %2 are at least required.</source>
+ <translation>ÐедоÑтаточно меÑта на диÑке Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… файлов и файлов уÑтановки. ДоÑтупно %1, а требуетÑÑ Ð¼Ð¸Ð½Ð¸Ð¼ÑƒÐ¼ %2.</translation>
</message>
<message>
- <source>Components about to be removed.</source>
- <translation>Компоненты готовы к удалению.</translation>
+ <source>Not enough disk space to store all selected components! %1 are available while %2 are at least required.</source>
+ <translation>ÐедоÑтаточно меÑта на диÑке Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ñех выбранных компонентов. ДоÑтупно %1, а требуетÑÑ Ð¼Ð¸Ð½Ð¸Ð¼ÑƒÐ¼: %2.</translation>
+ </message>
+ <message>
+ <source>Not enough disk space to store temporary files! %1 are available while %2 are at least required.</source>
+ <translation>ÐедоÑтаточно меÑта на диÑке Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… файлов. ДоÑтупно %1, а требуетÑÑ Ð¼Ð¸Ð½Ð¸Ð¼ÑƒÐ¼ %2.</translation>
</message>
</context>
<context>
<name>QInstaller::RegisterFileTypeOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
- </message>
- <message>
- <source>2 to 5</source>
- <translation>от 2 до 5</translation>
- </message>
- <message>
<source>Registering file types is only supported on Windows.</source>
<translation>РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð² файлов возможна только в Windows.</translation>
</message>
@@ -2172,40 +1964,32 @@ Please copy the installer to a local drive</source>
<source>Register File Type: Invalid arguments</source>
<translation>РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð² файлов: недопуÑтимые параметры</translation>
</message>
+ <message>
+ <source>&lt;extension&gt; &lt;command&gt; [description [contentType [icon]]]</source>
+ <translation>&lt;раÑширение&gt; &lt;команда&gt; [опиÑание [типСодержимого [значок]]]</translation>
+ </message>
</context>
<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::ReplaceOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
- </message>
- <message>
- <source>exactly 3</source>
- <translation>ровно 3</translation>
+ <source>Cannot open file &quot;%1&quot; for reading: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на чтение: %2</translation>
</message>
<message>
- <source>Failed to open %1 for reading</source>
- <translation>Сбой Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° %1 на чтение</translation>
- </message>
- <message>
- <source>Failed to open %1 for writing</source>
- <translation>Сбой Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° %1 на запиÑÑŒ</translation>
+ <source>Cannot open file &quot;%1&quot; for writing: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл «%1» на запиÑÑŒ: %2</translation>
</message>
</context>
<context>
<name>QInstaller::Resource</name>
<message>
- <source>Could not open Resource &apos;%1&apos; read-only.</source>
- <translation>Ðе удалоÑÑŒ открыть на чтение реÑÑƒÑ€Ñ Â«%1».</translation>
- </message>
- <message>
<source>Read failed after %1 bytes: %2</source>
<translation>Сбой Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ %1 байта: %2</translation>
</message>
@@ -2213,6 +1997,10 @@ Please copy the installer to a local drive</source>
<source>Write failed after %1 bytes: %2</source>
<translation>Сбой запиÑи Ñ %1 байта: %2</translation>
</message>
+ <message>
+ <source>Cannot open resource %1 for reading.</source>
+ <translation>Ðе удалоÑÑŒ открыть реÑÑƒÑ€Ñ %1 Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ.</translation>
+ </message>
</context>
<context>
<name>QInstaller::RestartPage</name>
@@ -2224,21 +2012,21 @@ 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>
- <translation>Ðе удалоÑÑŒ открыть файл ÑÑ†ÐµÐ½Ð°Ñ€Ð¸Ñ %1: %2.</translation>
+ <source>Cannot open script file at %1: %2</source>
+ <translation>Ðе удалоÑÑŒ открыть файл ÑÑ†ÐµÐ½Ð°Ñ€Ð¸Ñ Â«%1»: %2</translation>
</message>
<message>
- <source>Exception while loading the component script &apos;%1&apos;. (%2)</source>
- <translation>Возникло иÑключение при загрузке ÑÑ†ÐµÐ½Ð°Ñ€Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð° «%1». (%2)</translation>
+ <source>Exception while loading the component script &quot;%1&quot;: %2</source>
+ <translation>Возникло иÑключение при загрузке ÑÑ†ÐµÐ½Ð°Ñ€Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð° «%1»: %2</translation>
+ </message>
+ <message>
+ <source>Unknown error.</source>
+ <translation>ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°.</translation>
</message>
</context>
<context>
<name>QInstaller::SelfRestartOperation</name>
<message>
- <source>Installer object needed in &apos;%1&apos; operation is empty.</source>
- <translation>Ð’ операции «%1» необходимый объект уÑтановщика пуÑÑ‚.</translation>
- </message>
- <message>
<source>Self Restart: Only valid within updater or packagemanager mode.</source>
<translation>ÐвтоматичеÑÐºÐ°Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°: подходит только Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° менеджера пакетов.</translation>
</message>
@@ -2246,6 +2034,10 @@ Please copy the installer to a local drive</source>
<source>Self Restart: Invalid arguments</source>
<translation>ÐвтоматичеÑÐºÐ°Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°: недопуÑтимый параметр</translation>
</message>
+ <message>
+ <source>Installer object needed in operation %1 is empty.</source>
+ <translation>Объект уÑтановщика, необходимый в операции «%1», пуÑÑ‚.</translation>
+ </message>
</context>
<context>
<name>QInstaller::ServerAuthenticationDialog</name>
@@ -2273,39 +2065,31 @@ Please copy the installer to a local drive</source>
<context>
<name>QInstaller::SettingsOperation</name>
<message>
- <source>Missing argument(s) &apos;%1&apos; calling &apos;%2&apos; with arguments &apos;%3&apos;.</source>
- <translation>ОтÑутÑтвуют аргументы «%1» при вызове «%2» Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð°Ð¼Ð¸ «%3».</translation>
+ <source>Missing argument(s) &quot;%1&quot; calling %2 with arguments &quot;%3&quot;.</source>
+ <translation>ОтÑутÑтвуют параметр(Ñ‹) «%1» при вызове «%2» Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ «%3».</translation>
</message>
<message>
- <source>Current method argument calling &apos;%1&apos; with arguments &apos;%2&apos; is not supported. Please use set, remove, add_array_value or remove_array_value.</source>
+ <source>Current method argument calling &quot;%1&quot; with arguments &quot;%2&quot; is not supported. Please use set, remove, add_array_value or remove_array_value.</source>
<translation>Текущий ÑпоÑоб вызова «%1» Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð°Ð¼Ð¸ «%2» не поддерживаетÑÑ. ИÑпользуйте set, remove, add_array_value или remove_array_value.</translation>
</message>
</context>
<context>
<name>QInstaller::SimpleMoveFileOperation</name>
<message>
- <source>Invalid arguments in %0: %1 arguments given, %2 expected%3.</source>
- <translation>ÐедопуÑтимое количеÑтво параметров в %0: передано %1, требуетÑÑ %2%3.</translation>
- </message>
- <message>
- <source>exactly 2</source>
- <translation>ровно 2</translation>
- </message>
- <message>
- <source>None of the arguments can be empty: source &apos;%1&apos;, target &apos;%2&apos;.</source>
+ <source>None of the arguments can be empty: source &quot;%1&quot;, target &quot;%2&quot;.</source>
<translation>Ð’Ñе аргументы должны быть непуÑтыми: иÑточник «%1», назначение «%2».</translation>
</message>
<message>
- <source>Cannot move source &apos;%1&apos; to target &apos;%2&apos;, because target exists and is not removable.</source>
- <translation>Ðевозможно перемеÑтить «%1» в «%2»: файл Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÑущеÑтвует и не может быть удалён.</translation>
+ <source>Cannot move file from &quot;%1&quot; to &quot;%2&quot;, because the target path exists and is not removable.</source>
+ <translation>Ðе удалоÑÑŒ перемеÑтить «%1» в «%2», так как файл Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÑущеÑтвует и не удалÑем.</translation>
</message>
<message>
- <source>Cannot move source &apos;%1&apos; to target &apos;%2&apos;: %3</source>
- <translation>Ðевозможно перемеÑтить «%1» в «%2»: «%3»</translation>
+ <source>Cannot move file &quot;%1&quot; to &quot;%2&quot;: %3</source>
+ <translation>Ðе удалоÑÑŒ перемеÑтить файл «%1» в «%2»: %3</translation>
</message>
<message>
- <source>Move &apos;%1&apos; to &apos;%2&apos;.</source>
- <translation>Перемещение «%1» в «%2».</translation>
+ <source>Moving file &quot;%1&quot; to &quot;%2&quot;.</source>
+ <translation>Перемещение файла «%1» в «%2».</translation>
</message>
</context>
<context>
@@ -2315,8 +2099,8 @@ Please copy the installer to a local drive</source>
<translation>Ярлыки меню &quot;ПуÑк&quot;</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>Выберите папку в меню «ПуÑк» Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñрлыков программы. Чтобы Ñоздать новую папку, введите её имÑ.</translation>
+ <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 directory.</source>
+ <translation>Выберите папку в меню «ПуÑк» Ð´Ð»Ñ Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñрлыков программы. Чтобы Ñоздать новую папку, введите её имÑ.</translation>
</message>
</context>
<context>
@@ -2326,10 +2110,6 @@ Please copy the installer to a local drive</source>
<translation>Каталог уÑтановки</translation>
</message>
<message>
- <source>Please specify the folder where %1 will be installed.</source>
- <translation>Укажите каталог Ð´Ð»Ñ ÑƒÑтановки %1.</translation>
- </message>
- <message>
<source>Alt+R</source>
<comment>browse file system to choose a file</comment>
<translatorcomment>открывает окно выбора файла</translatorcomment>
@@ -2340,28 +2120,10 @@ Please copy the installer to a local drive</source>
<translation>О&amp;бзор...</translation>
</message>
<message>
- <source>The folder you selected already exists and contains an installation. Choose a different target for installation.</source>
- <translation>Выбранный каталог ÑущеÑтвует и Ñодержит уÑтановленное приложение. Выберите другой каталог.</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>Каталог, выбранный Ð´Ð»Ñ ÑƒÑтановки приложениÑ, уже Ñодержит файлы.
-Он будет Ñтёрт вмеÑте Ñо вÑем Ñодержимым при удалении приложениÑ.
-Производить уÑтановку в Ñтот каталог не рекомендуетÑÑ, так как не иÑключён Ñбой.
-Продолжить?</translation>
- </message>
- <message>
<source>You have selected an existing file or symlink, please choose a different target for installation.</source>
<translation>Выбранный файл или ÑÐ¸Ð¼Ð²Ð¾Ð»ÑŒÐ½Ð°Ñ ÑÑылка уже ÑущеÑтвует. Выберите другой каталог уÑтановки.</translation>
</message>
<message>
- <source>The installation path cannot be empty, please specify a valid folder.</source>
- <translation>Ðеобходимо задать путь к каталогу уÑтановки. Выберите подходÑщий каталог.</translation>
- </message>
- <message>
<source>The installation path cannot be relative, please specify an absolute path.</source>
<translation>Путь к каталогу уÑтановки не может быть отноÑительным. Задайте абÑолютный путь.</translation>
</message>
@@ -2386,14 +2148,6 @@ Do you want to continue?</source>
<translation>Указан неверный путь, проверьте Ð¸Ð¼Ñ Ð´Ð¸Ñка.</translation>
</message>
<message>
- <source>The installation path must not end with &apos;.&apos;, please specify a valid folder.</source>
- <translation>Путь к каталогу уÑтановки не может оканчиватьÑÑ Ñ‚Ð¾Ñ‡ÐºÐ¾Ð¹. Выберите другой каталог.</translation>
- </message>
- <message>
- <source>The installation path must not contain &apos;%1&apos;, please specify a valid folder.</source>
- <translation>Путь к каталогу уÑтановки не может Ñодержать «%1». Выберите другой каталог.</translation>
- </message>
- <message>
<source>Error</source>
<translation>Ошибка</translation>
</message>
@@ -2405,6 +2159,36 @@ Do you want to continue?</source>
<source>Select Installation Folder</source>
<translation>Выберите каталог Ð´Ð»Ñ ÑƒÑтановки</translation>
</message>
+ <message>
+ <source>Please specify the directory where %1 will be installed.</source>
+ <translation>Укажите каталог Ð´Ð»Ñ ÑƒÑтановки %1.</translation>
+ </message>
+ <message>
+ <source>The directory you selected already exists and contains an installation. Choose a different target for installation.</source>
+ <translation>Выбранный каталог ÑущеÑтвует и Ñодержит уÑтановленное приложение. Выберите другой каталог.</translation>
+ </message>
+ <message>
+ <source>You have selected an existing, non-empty directory for installation.
+Note that it will be completely wiped on uninstallation of this application.
+It is not advisable to install into this directory as installation might fail.
+Do you want to continue?</source>
+ <translation>Каталог, выбранный Ð´Ð»Ñ ÑƒÑтановки приложениÑ, уже Ñодержит файлы.
+Он будет Ñтёрт вмеÑте Ñо вÑем Ñодержимым при удалении приложениÑ.
+Производить уÑтановку в Ñтот каталог не рекомендуетÑÑ, так как не иÑключён Ñбой.
+Продолжить?</translation>
+ </message>
+ <message>
+ <source>The installation path cannot be empty, please specify a valid directory.</source>
+ <translation>Ðеобходимо задать путь к каталогу уÑтановки. Выберите подходÑщий каталог.</translation>
+ </message>
+ <message>
+ <source>The installation path must not end with &apos;.&apos;, please specify a valid directory.</source>
+ <translation>Путь к каталогу уÑтановки не может оканчиватьÑÑ Ñ‚Ð¾Ñ‡ÐºÐ¾Ð¹. Выберите другой каталог.</translation>
+ </message>
+ <message>
+ <source>The installation path must not contain &quot;%1&quot;, please specify a valid directory.</source>
+ <translation>Путь к каталогу уÑтановки не может Ñодержать «%1». Выберите другой каталог.</translation>
+ </message>
</context>
<context>
<name>QInstaller::TestRepository</name>
@@ -2413,24 +2197,32 @@ Do you want to continue?</source>
<translation>ПуÑтой URL хранилища.</translation>
</message>
<message>
- <source>URL scheme not supported: %1 (%2).</source>
- <translation>Эта Ñхема URL не поддерживаетÑÑ: %1 (%2).</translation>
+ <source>Missing package manager core engine.</source>
+ <translation>ОтÑутÑтвует менеджер пакетов.</translation>
+ </message>
+ <message>
+ <source>Download canceled.</source>
+ <translation>Загрузка отменена.</translation>
</message>
<message>
- <source>Got a timeout while testing: &apos;%1&apos;</source>
- <translation>Таймаут во Ð²Ñ€ÐµÐ¼Ñ Ñ‚ÐµÑта «%1»</translation>
+ <source>Timeout while testing repository &quot;%1&quot;.</source>
+ <translation>ИÑтекло Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ€ÐµÐ¼Ñ Ñ‚ÐµÑтировании хранилища «%1».</translation>
</message>
<message>
- <source>Could not parse Updates.xml! Error: %1.</source>
- <translation>Ðевозможно разобрать Updates.xml! Ошибка: %1.</translation>
+ <source>Cannot parse Updates.xml: %1</source>
+ <translation>Ðе удалоÑÑŒ разобрать Updates.xml: %1</translation>
</message>
<message>
- <source>Updates.xml could not be opened for reading!</source>
- <translation>Ðевозможно открыть Updates.xml на чтение!</translation>
+ <source>Cannot open Updates.xml for reading: %1</source>
+ <translation>Ðе удалоÑÑŒ открыть файл Updates.xml Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ: %1</translation>
</message>
<message>
- <source>Updates.xml could not be found on server!</source>
- <translation>Ðевозможно найти Updates.xml на Ñервере!</translation>
+ <source>Authentication failed.</source>
+ <translation>Ошибка аутентификации.</translation>
+ </message>
+ <message>
+ <source>Unknown error while testing repository &quot;%1&quot;.</source>
+ <translation>Возникла неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при теÑтировании хранилища «%1».</translation>
</message>
</context>
<context>
@@ -2451,33 +2243,45 @@ 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.
+
+Please start the setup program as a user with the appropriate rights.
+Or accept the elevation of access rights if being asked.</source>
+ <translation>Ðе удалоÑÑŒ пройти авторизацию, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð° Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ ÑƒÑтановки.
+
+ЗапуÑтите программу от Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ Ð¿Ð¾Ð´Ñ…Ð¾Ð´Ñщими правами.
+Или разрешите повышение прав, когда об Ñтом будет попрошено.</translation>
+ </message>
+ <message>
+ <source>Cannot 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>
+as a user with the appropriate rights and then clicking OK.</source>
<translation>Ðе удалоÑÑŒ пройти авторизацию, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð° Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ ÑƒÑтановки.
Можно прервать уÑтановку или попытатьÑÑ ÑƒÑтранить проблему запуÑтив
+
%1
-от имени root&apos;а и нажав ОК.</translation>
+
+от Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ Ð¿Ð¾Ð´Ñ…Ð¾Ð´Ñщими правами и нажав ОК.</translation>
</message>
</context>
<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>
@@ -2560,14 +2364,6 @@ as root and then clicking OK.</source>
<translation>ÐдреÑа Ñерверов, которые Ñодержат рабочие репозиторий.</translation>
</message>
<message>
- <source>There was an error testing this repository.</source>
- <translation>Ошибка в процеÑÑе теÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ.</translation>
- </message>
- <message>
- <source>Do you want to disable the tested repository?</source>
- <translation>Вы хотите отключить проверенный репозиторий?</translation>
- </message>
- <message>
<source>Hide Passwords</source>
<translation>Скрыть пароли</translation>
</message>
@@ -2599,20 +2395,72 @@ as root and then clicking OK.</source>
<source>User defined repositories</source>
<translation>ИÑпользовать назначенные репозитории</translation>
</message>
+ <message>
+ <source>An error occurred while testing this repository.</source>
+ <translation>Возникла ошибка при теÑтировании хранилища.</translation>
+ </message>
+ <message>
+ <source>The repository was tested successfully.</source>
+ <translation>Хранилище протеÑтировано уÑпешно.</translation>
+ </message>
+ <message>
+ <source>Do you want to disable the repository?</source>
+ <translation>Желаете отключить хранилище?</translation>
+ </message>
+ <message>
+ <source>Do you want to enable the repository?</source>
+ <translation>Желаете включить хранилище?</translation>
+ </message>
</context>
<context>
<name>UpdateOperation</name>
<message>
- <source>Registry path %1 is not writable</source>
- <translation>Ðевозможно запиÑать ключ %1 в рееÑÑ‚Ñ€</translation>
+ <source>Registry path %1 is not writable.</source>
+ <translation>Путь рееÑтра %1 недоÑтупен Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи.</translation>
+ </message>
+ <message>
+ <source>Cannot write to registry path %1.</source>
+ <translation>Ðе удалоÑÑŒ запиÑать ключ %1 в рееÑÑ‚Ñ€.</translation>
+ </message>
+ <message>
+ <source>exactly %1</source>
+ <translation>точно %1</translation>
+ </message>
+ <message>
+ <source>at least %1</source>
+ <translation>минимум %1</translation>
+ </message>
+ <message>
+ <source>not more than %1</source>
+ <translation>не более %1</translation>
</message>
<message>
- <source>Could not write to registry path %1</source>
- <translation>Ðе удалоÑÑŒ запиÑать ключ %1 в рееÑÑ‚Ñ€</translation>
+ <source>%1 or %2</source>
+ <translation>%1 или %2</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>от %1 до %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>Invalid arguments in %1: %n arguments given, %2 arguments expected.</source>
+ <translation>
+ <numerusform>Ðеверные параметры в %1: %n параметр передан, но %2 требуетÑÑ.</numerusform>
+ <numerusform>Ðеверные параметры в %1: %n параметра передано, но %2 требуетÑÑ.</numerusform>
+ <numerusform>Ðеверные параметры в %1: %n параметров передано, но %2 требуетÑÑ.</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>Invalid arguments in %1: %n arguments given, %2 arguments expected in the form: %3.</source>
+ <translation>
+ <numerusform>Ðеверные параметры в %1: %n параметр передан, но %2 требуетÑÑ Ð² форме: %3.</numerusform>
+ <numerusform>Ðеверные параметры в %1: %n параметра передано, но %2 требуетÑÑ Ð² форме: %3.</numerusform>
+ <numerusform>Ðеверные параметры в %1: %n параметров передано, но %2 требуетÑÑ Ð² форме: %3.</numerusform>
+ </translation>
</message>
<message>
- <source>Renaming %1 into %2 failed with %3.</source>
- <translation>Сбой Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ %1 в %2: %3.</translation>
+ <source>Renaming file &quot;%1&quot; to &quot;%2&quot; failed: %3</source>
+ <translation>Ðе удалоÑÑŒ переименовать «%1» в «%2»: %3</translation>
</message>
</context>
</TS>
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 edbec0eb5..63bac8b9f 100644
--- a/src/sdk/updatechecker.cpp
+++ b/src/sdk/updatechecker.cpp
@@ -32,10 +32,11 @@
#include <component.h>
#include <errors.h>
#include <init.h>
-#include <kdrunoncechecker.h>
+#include <runoncechecker.h>
#include <packagemanagercore.h>
#include <productkeycheck.h>
+#include <QDir>
#include <QDomDocument>
#include <iostream>
@@ -48,13 +49,16 @@ UpdateChecker::UpdateChecker(int &argc, char *argv[])
int UpdateChecker::check()
{
- KDRunOnceChecker runCheck(qApp->applicationDirPath() + QLatin1String("/lockmyApp15021976.lock"));
- if (runCheck.isRunning(KDRunOnceChecker::ConditionFlag::Lockfile)) {
+ RunOnceChecker runCheck(QDir::tempPath()
+ + QLatin1Char('/')
+ + qApp->applicationName()
+ + QLatin1String("15021976.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."));
}
@@ -102,7 +106,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..b963be275 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,11 +1,3 @@
-CONFIG += ordered
TEMPLATE = subdirs
SUBDIRS += libs sdk
-TRANSLATIONS += sdk/translations/de.ts \
- sdk/translations/en.ts \
- sdk/translations/fr.ts \
- sdk/translations/ja.ts \
- sdk/translations/pl.ts \
- sdk/translations/ru.ts \
- sdk/translations/zh_cn.ts \
- sdk/translations/it.ts
+sdk.depends = libs
diff --git a/sync.profile b/sync.profile
index 47784bc9d..40898352a 100644
--- a/sync.profile
+++ b/sync.profile
@@ -1,6 +1,6 @@
%dependencies = (
- "qtbase" => "5.6",
- "qtdeclarative" => "5.6",
- "qttools" => "5.6",
- "qtwinextras" => "5.6",
+ "qtbase" => "",
+ "qtdeclarative" => "",
+ "qttools" => "",
+ "qtwinextras" => "",
);
diff --git a/tests/auto/installer/binaryformat/tst_binaryformat.cpp b/tests/auto/installer/binaryformat/tst_binaryformat.cpp
index 0098ba34e..57f2a37e3 100644
--- a/tests/auto/installer/binaryformat/tst_binaryformat.cpp
+++ b/tests/auto/installer/binaryformat/tst_binaryformat.cpp
@@ -30,7 +30,7 @@
#include <binaryformat.h>
#include <errors.h>
#include <fileio.h>
-#include <kdupdaterupdateoperation.h>
+#include <updateoperation.h>
#include <QTest>
#include <QTemporaryFile>
@@ -51,7 +51,9 @@ struct Layout : public QInstaller::BinaryLayout
class TestOperation : public KDUpdater::UpdateOperation
{
public:
- TestOperation(const QString &name) { setName(name); }
+ TestOperation(const QString &name)
+ : KDUpdater::UpdateOperation(0)
+ { setName(name); }
virtual void backup() {}
virtual bool performOperation() { return true; }
@@ -117,8 +119,6 @@ private slots:
void findMagicCookieWithError()
{
- QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"No marker found, stopped after 71.00 KiB.\" ");
-
QTemporaryFile file;
file.open();
diff --git a/tests/auto/installer/clientserver/tst_clientserver.cpp b/tests/auto/installer/clientserver/tst_clientserver.cpp
index 9bb4d65a2..b3e220c9f 100644
--- a/tests/auto/installer/clientserver/tst_clientserver.cpp
+++ b/tests/auto/installer/clientserver/tst_clientserver.cpp
@@ -207,7 +207,7 @@ private slots:
QLocalSocket socket;
socket.connectToServer(socketName);
- QVERIFY2(socket.waitForConnected(), "Could not connect to server.");
+ QVERIFY2(socket.waitForConnected(), "Cannot connect to server.");
QCOMPARE(socket.state() == QLocalSocket::ConnectedState, true);
sendCommand(&socket, Protocol::Authorize, QString(Protocol::DefaultAuthorizationKey));
@@ -240,7 +240,7 @@ private slots:
QLocalSocket socket;
socket.connectToServer(socketName);
- QVERIFY2(socket.waitForConnected(), "Could not connect to server.");
+ QVERIFY2(socket.waitForConnected(), "Cannot connect to server.");
QCOMPARE(socket.state() == QLocalSocket::ConnectedState, true);
sendCommand(&socket, Protocol::Authorize, QString::fromLatin1("SomeKey"));
@@ -454,8 +454,7 @@ private slots:
}
QSignalSpy spy(&wrapper, SIGNAL(started()));
- QSignalSpy spy2(&wrapper, SIGNAL(finished(int)));
- QSignalSpy spy3(&wrapper, SIGNAL(finished(int, QProcess::ExitStatus)));
+ QSignalSpy spy2(&wrapper, SIGNAL(finished(int, QProcess::ExitStatus)));
#ifdef Q_OS_WIN
wrapper.start(fileName);
@@ -474,10 +473,6 @@ private slots:
QCOMPARE(spy2.count(), 1);
QList<QVariant> arguments = spy2.takeFirst();
QCOMPARE(arguments.first().toInt(), 0);
-
- QCOMPARE(spy3.count(), 1);
- arguments = spy3.takeFirst();
- QCOMPARE(arguments.first().toInt(), 0);
QCOMPARE(arguments.last().toInt(), int(QProcessWrapper::NormalExit));
QFile::remove(fileName);
diff --git a/tests/auto/installer/componentmodel/data/updates.xml b/tests/auto/installer/componentmodel/data/updates.xml
index e1f72de10..2341866ee 100644
--- a/tests/auto/installer/componentmodel/data/updates.xml
+++ b/tests/auto/installer/componentmodel/data/updates.xml
@@ -5,6 +5,8 @@
<PackageUpdate>
<Name>com.vendor.product</Name>
<DisplayName>The root component</DisplayName>
+ <DisplayName xml:lang="ru_RU">ÐšÐ¾Ñ€Ð½ÐµÐ²Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð°</DisplayName>
+ <DisplayName xml:lang="de_DE">Wurzel Komponente</DisplayName>
<Description>Install this example.</Description>
<Version>0.1.0-1</Version>
<ReleaseDate>2010-09-21</ReleaseDate>
@@ -129,4 +131,50 @@
file="license.txt"/>
</Licenses>
</PackageUpdate>
+ <PackageUpdate>
+ <Name>com.vendor.fourth.product.checkable</Name>
+ <DisplayName>A checkable root component</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Checkable>true</Checkable>
+ <Default>false</Default>
+ <Script>installscript.qs</Script>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>com.vendor.fifth.product.noncheckable</Name>
+ <DisplayName>A non-checkable root component</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Script>installscript.qs</Script>
+ <Checkable>false</Checkable>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>com.vendor.fifth.product.noncheckable.sub</Name>
+ <DisplayName>A sub component for non-checkable root component</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Script>installscript.qs</Script>
+ <SortingPriority>0</SortingPriority>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
</Updates>
diff --git a/tests/auto/installer/componentmodel/tst_componentmodel.cpp b/tests/auto/installer/componentmodel/tst_componentmodel.cpp
index 290f0d733..d5cae916c 100644
--- a/tests/auto/installer/componentmodel/tst_componentmodel.cpp
+++ b/tests/auto/installer/componentmodel/tst_componentmodel.cpp
@@ -1,18 +1,16 @@
#include "component.h"
#include "componentmodel.h"
-
-#include "kdupdaterupdatesinfo_p.h"
-#include "kdupdaterupdatesourcesinfo.h"
-
+#include "updatesinfo_p.h"
#include "packagemanagercore.h"
#include <QTest>
+#include <QtCore/QLocale>
using namespace KDUpdater;
using namespace QInstaller;
-#define EXPECTED_COUNT_VIRTUALS_VISIBLE 8
-#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 7
+#define EXPECTED_COUNT_VIRTUALS_VISIBLE 11
+#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 10
static const char vendorProduct[] = "com.vendor.product";
static const char vendorSecondProduct[] = "com.vendor.second.product";
@@ -22,6 +20,15 @@ static const char vendorSecondProductVirtual[] = "com.vendor.second.product.virt
static const char vendorSecondProductSubnode[] = "com.vendor.second.product.subnode";
static const char vendorSecondProductSubnodeSub[] = "com.vendor.second.product.subnode.sub";
static const char vendorThirdProductVirtual[] = "com.vendor.third.product.virtual";
+static const char vendorFourthProductCheckable[] = "com.vendor.fourth.product.checkable";
+static const char vendorFifthProductNonCheckable[] = "com.vendor.fifth.product.noncheckable";
+static const char vendorFifthProductSub[] = "com.vendor.fifth.product.noncheckable.sub";
+
+static const QMap<QString, QString> rootComponentDisplayNames = {
+ {"", QLatin1String("The root component")},
+ {"ru_ru", QString::fromUtf8("ÐšÐ¾Ñ€Ð½ÐµÐ²Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð°")},
+ {"de_de", QString::fromUtf8("Wurzel Komponente")}
+};
class tst_ComponentModel : public QObject
{
@@ -41,7 +48,9 @@ private slots:
m_defaultChecked << vendorProduct << vendorSecondProductSub;
m_defaultPartially << vendorSecondProduct;
m_defaultUnchecked << vendorSecondProductSub1 << vendorSecondProductSubnode
- << vendorSecondProductSubnodeSub;
+ << vendorSecondProductSubnodeSub << vendorFourthProductCheckable
+ << vendorFifthProductSub;
+ m_uncheckable << vendorFifthProductNonCheckable;
}
void testNameToIndexAndIndexToName()
@@ -57,7 +66,7 @@ private slots:
// all names should be resolvable, virtual components are not indexed if they are not visible
QStringList all;
- all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked;
+ all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << m_uncheckable;
foreach (const QString &name, all) {
QVERIFY(model.indexFromComponentName(name).isValid());
QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0);
@@ -81,8 +90,8 @@ private slots:
// all names should be resolvable, including virtual components
QStringList all;
- all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << vendorSecondProductVirtual
- << vendorThirdProductVirtual;
+ all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << m_uncheckable
+ << vendorSecondProductVirtual << vendorThirdProductVirtual;
foreach (const QString &name, all) {
QVERIFY(model.indexFromComponentName(name).isValid());
QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0);
@@ -107,7 +116,8 @@ private slots:
QCOMPARE(model.core(), &m_core);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
- testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked);
+ testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
+ + m_uncheckable);
foreach (Component *const component, rootComponents)
delete component;
@@ -126,9 +136,10 @@ private slots:
testDefaultInheritedModelBehavior(&model, 1);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
- // the virtual components are not checked
- testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
- + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
+ // the virtual and non-checkable components are not checked
+ testModelState(&model, m_defaultChecked, m_defaultPartially,
+ m_defaultUnchecked + m_uncheckable
+ + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
foreach (Component *const component, rootComponents)
delete component;
@@ -147,7 +158,8 @@ private slots:
testDefaultInheritedModelBehavior(&model, 1);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
- testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked);
+ testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
+ + m_uncheckable);
foreach (Component *const component, rootComponents)
delete component;
@@ -167,7 +179,8 @@ private slots:
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
// the virtual components are not checked
- testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
+ testModelState(&model, m_defaultChecked, m_defaultPartially,
+ m_defaultUnchecked + m_uncheckable
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
foreach (Component *const component, rootComponents)
@@ -186,23 +199,25 @@ private slots:
model.setRootComponents(rootComponents);
testDefaultInheritedModelBehavior(&model, 1);
- // select all possible components
+ // select all possible components.
+ // Also uncheckable is checked as that is only 'visually' uncheckedable.
model.setCheckedState(ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::AllChecked);
- testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked, QStringList()
- , QStringList());
+ testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked + m_uncheckable,
+ QStringList(), QStringList());
// deselect all possible components
// as the first root is a forced install, should result in partially checked state
model.setCheckedState(ComponentModel::AllUnchecked);
QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked);
testModelState(&model, QStringList() << vendorProduct, QStringList(), m_defaultPartially
- + m_defaultUnchecked + QStringList(vendorSecondProductSub));
+ + m_defaultUnchecked + QStringList(vendorSecondProductSub) + m_uncheckable);
// reset all possible components
model.setCheckedState(ComponentModel::DefaultChecked);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
- testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked);
+ testModelState(&model, m_defaultChecked, m_defaultPartially,
+ m_defaultUnchecked + m_uncheckable);
foreach (Component *const component, rootComponents)
delete component;
@@ -220,10 +235,10 @@ private slots:
model.setRootComponents(rootComponents);
testDefaultInheritedModelBehavior(&model, 1);
- // select all possible components
+ // select all possible components.
model.setCheckedState(ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::AllChecked);
- testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked
+ testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked + m_uncheckable
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual, QStringList(),
QStringList());
@@ -232,13 +247,14 @@ private slots:
model.setCheckedState(ComponentModel::AllUnchecked);
QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked);
testModelState(&model, QStringList() << vendorProduct, QStringList(), m_defaultPartially
- + m_defaultUnchecked + QStringList(vendorSecondProductSub) << vendorSecondProductVirtual
- << vendorThirdProductVirtual);
+ + m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductSub)
+ << vendorSecondProductVirtual << vendorThirdProductVirtual);
// reset all possible components
model.setCheckedState(ComponentModel::DefaultChecked);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
- testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
+ testModelState(&model, m_defaultChecked, m_defaultPartially,
+ m_defaultUnchecked + m_uncheckable
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
foreach (Component *const component, rootComponents)
@@ -257,22 +273,24 @@ private slots:
model.setRootComponents(rootComponents);
testDefaultInheritedModelBehavior(&model, 1);
- // select all possible components
+ // select all possible components.
model.setCheckedState(ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::AllChecked);
- testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked, QStringList()
- , QStringList());
+ testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked+ m_uncheckable,
+ QStringList(), QStringList());
// deselect all possible components
model.setCheckedState(ComponentModel::AllUnchecked);
QCOMPARE(model.checkedState(), ComponentModel::AllUnchecked);
- testModelState(&model, QStringList(), QStringList(), m_defaultPartially + m_defaultUnchecked
+ testModelState(&model, QStringList(), QStringList(), m_defaultPartially
+ + m_defaultUnchecked + m_uncheckable
+ QStringList(vendorSecondProductSub) << vendorProduct);
// reset all possible components
model.setCheckedState(ComponentModel::DefaultChecked);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
- testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked);
+ testModelState(&model, m_defaultChecked, m_defaultPartially,
+ m_defaultUnchecked + m_uncheckable);
foreach (Component *const component, rootComponents)
delete component;
@@ -290,30 +308,56 @@ private slots:
model.setRootComponents(rootComponents);
testDefaultInheritedModelBehavior(&model, 1);
- // select all possible components
+ // select all possible components.
model.setCheckedState(ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::AllChecked);
- testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked
+ testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked +m_uncheckable
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual, QStringList(),
QStringList());
// deselect all possible components
model.setCheckedState(ComponentModel::AllUnchecked);
QCOMPARE(model.checkedState(), ComponentModel::AllUnchecked);
- testModelState(&model, QStringList(), QStringList(), m_defaultPartially + m_defaultUnchecked
- + QStringList(vendorSecondProductSub) << vendorSecondProductVirtual << vendorProduct
- << vendorThirdProductVirtual);
+ testModelState(&model, QStringList(), QStringList(), m_defaultPartially
+ + m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductSub)
+ << vendorSecondProductVirtual << vendorProduct << vendorThirdProductVirtual);
// reset all possible components
model.setCheckedState(ComponentModel::DefaultChecked);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
- + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
+ + m_uncheckable + QStringList(vendorSecondProductVirtual)
+ << vendorThirdProductVirtual);
foreach (Component *const component, rootComponents)
delete component;
}
+ void testComponentsLocalization()
+ {
+ QStringList localesToTest = { "en_US", "ru_RU", "de_DE", "fr_FR" };
+ foreach (const QString &localeToTest, localesToTest) {
+ QLocale::setDefault(localeToTest);
+ QString expectedName = rootComponentDisplayNames.contains(localeToTest.toLower())
+ ? rootComponentDisplayNames[localeToTest.toLower()]
+ : rootComponentDisplayNames[QString()];
+
+ setPackageManagerOptions(NoFlags);
+
+ QList<Component*> rootComponents = loadComponents();
+ testComponentsLoaded(rootComponents);
+
+ // setup the model with 1 column
+ ComponentModel model(1, &m_core);
+ model.setRootComponents(rootComponents);
+
+ const QModelIndex root = model.indexFromComponentName(vendorProduct);
+ QCOMPARE(model.data(root, Qt::DisplayRole).toString(), expectedName);
+
+ qDeleteAll(rootComponents);
+ }
+ }
+
private:
void setPackageManagerOptions(Options flags) const
{
@@ -323,8 +367,8 @@ private:
void testComponentsLoaded(const QList<Component *> &rootComponents) const
{
- // we need to have three root components
- QCOMPARE(rootComponents.count(), 3);
+ // we need to have five root components
+ QCOMPARE(rootComponents.count(), 5);
QList<Component*> components = rootComponents;
foreach (Component *const component, rootComponents)
@@ -339,9 +383,9 @@ private:
{
// row count with invalid model index should return:
if (m_core.virtualComponentsVisible())
- QCOMPARE(model->rowCount(), 3); // 3 (2 non virtual and 1 virtual root component)
+ QCOMPARE(model->rowCount(), 5); // 5 (4 non virtual and 1 virtual root component)
else
- QCOMPARE(model->rowCount(), 2); // 2 (the 2 non virtual root components)
+ QCOMPARE(model->rowCount(), 4); // 4 (the 4 non virtual root components)
QCOMPARE(model->columnCount(), columnCount);
const QModelIndex firstParent = model->indexFromComponentName(vendorProduct);
@@ -431,6 +475,7 @@ private:
component->setValue("Default", info.data.value("Default").toString());
component->setValue("Virtual", info.data.value("Virtual").toString());
component->setValue("DisplayName", info.data.value("DisplayName").toString());
+ component->setValue("Checkable", info.data.value("Checkable").toString());
QString forced = info.data.value("ForcedInstallation", scFalse).toString().toLower();
if (m_core.noForceInstallation())
@@ -470,6 +515,7 @@ private:
QStringList m_defaultChecked;
QStringList m_defaultPartially;
QStringList m_defaultUnchecked;
+ QStringList m_uncheckable;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(tst_ComponentModel::Options)
diff --git a/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp b/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp
index 9d670542b..885aca81a 100644
--- a/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp
+++ b/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp
@@ -62,7 +62,7 @@ private slots:
void testMissingArguments()
{
- ConsumeOutputOperation operation;
+ ConsumeOutputOperation operation(0);
QVERIFY(operation.testOperation());
QVERIFY(!operation.performOperation());
@@ -73,7 +73,8 @@ private slots:
QCOMPARE(UpdateOperation::Error(operation.error()), UpdateOperation::InvalidArguments);
//qDebug() << operation.errorString();
QString compareString("Invalid arguments in ConsumeOutput: 0 arguments given, at least 2 "
- "expected(<to be saved installer key name>, <executable>, [argument1], [argument2], ...).");
+ "arguments expected in the form: <to be saved installer key name> "
+ "<executable> [argument1] [argument2] [...].");
//qDebug() << compareString;
QCOMPARE(operation.errorString(), compareString);
}
@@ -82,8 +83,7 @@ private slots:
{
QString testOutput = getOutputFrom(QUOTE(QMAKE_BINARY), QStringList("-query"));
- ConsumeOutputOperation operation;
- operation.setValue(QLatin1String("installer"), QVariant::fromValue(&m_core));
+ ConsumeOutputOperation operation(&m_core);
operation.setArguments(QStringList() << "testConsumeOutputKey" << QUOTE(QMAKE_BINARY) << "-query");
QVERIFY2(operation.performOperation(), qPrintable(operation.errorString()));
@@ -107,7 +107,7 @@ private:
QEventLoop loop;
QProcess process;
- QObject::connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
+ QObject::connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), &loop, SLOT(quit()));
process.start(binary, arguments, QIODevice::ReadOnly);
if (process.state() != QProcess::NotRunning)
diff --git a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp
index feae79d18..e55fc89f4 100644
--- a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp
+++ b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp
@@ -27,7 +27,7 @@
**************************************************************************/
#include <init.h>
-#include <kdupdaterupdateoperations.h>
+#include <updateoperations.h>
#include <utils.h>
#include <QDir>
@@ -63,7 +63,8 @@ private slots:
QVERIFY(!op.performOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Invalid arguments: 0 arguments given, 2 expected."));
+ QCOMPARE(op.errorString(), QString("Invalid arguments in Copy: "
+ "0 arguments given, exactly 2 arguments expected."));
}
@@ -82,17 +83,17 @@ private slots:
QFETCH(QString, source);
QFETCH(QString, destination);
- QVERIFY2(QFileInfo(source).exists(), QString("Source '%1' does not exist.").arg(source).toLatin1());
+ QVERIFY2(QFileInfo(source).exists(), QString("Source file \"%1\" does not exist.").arg(source).toLatin1());
CopyOperation op;
op.setArguments(QStringList() << source << destination);
op.backup();
QVERIFY2(op.performOperation(), op.errorString().toLatin1());
- QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), QString("Copying from '%1' to '%2' was "
+ QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), QString("Copying from \"%1\" to \"%2\" was "
"not working: '%3' does not exist").arg(source, destination, m_testDestinationFilePath).toLatin1());
QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
- QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Undo of copying from '%1' to "
- "'%2' was not working.").toLatin1());
+ QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Undo of copying from \"%1\" to "
+ "\"%2\" was not working.").toLatin1());
}
void testCopyIfDestinationExist_data()
@@ -114,7 +115,7 @@ private slots:
QByteArray testFileHash = QInstaller::calculateHash(m_testDestinationFilePath, QCryptographicHash::Sha1);
- QVERIFY2(QFileInfo(source).exists(), QString("Source '%1' does not exist.").arg(source).toLatin1());
+ QVERIFY2(QFileInfo(source).exists(), QString("Source file \"%1\" does not exist.").arg(source).toLatin1());
CopyOperation op;
op.setArguments(QStringList() << source << destination);
op.backup();
@@ -125,8 +126,8 @@ private slots:
QByteArray currentFileHash = QInstaller::calculateHash(m_testDestinationFilePath, QCryptographicHash::Sha1);
QVERIFY(testFileHash != currentFileHash);
- QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), QString("Copying from '%1' to '%2' was "
- "not working: '%3' does not exist").arg(source, destination, m_testDestinationFilePath).toLatin1());
+ QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), QString("Copying from \"%1\" to \"%2\" was "
+ "not working: \"%3\" does not exist").arg(source, destination, m_testDestinationFilePath).toLatin1());
// undo should replace the new one with the old backuped one
QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
@@ -135,7 +136,7 @@ private slots:
}
void init()
{
- QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Destination '%1' should not exist "
+ QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Destination \"%1\" should not exist "
"to test the copy operation.").arg(m_testDestinationFilePath).toLatin1());
QDir().mkpath(m_testDestinationPath);
}
diff --git a/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp b/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp
index 14e34a2d7..40af0d497 100644
--- a/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp
+++ b/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp
@@ -48,20 +48,21 @@ private slots:
void testMissingArguments()
{
- ExtractArchiveOperation op;
+ ExtractArchiveOperation op(0);
QVERIFY(op.testOperation());
QVERIFY(!op.performOperation());
//QVERIFY(!op.undoOperation()); Can't test for failure as we run into Q_ASSERT
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Invalid arguments in Extract: 0 arguments given, exactly 2 expected."));
+ QCOMPARE(op.errorString(), QString("Invalid arguments in Extract: "
+ "0 arguments given, exactly 2 arguments expected."));
}
void testExtractOperationValidFile()
{
- ExtractArchiveOperation op;
+ ExtractArchiveOperation op(0);
op.setArguments(QStringList() << ":///data/valid.7z" << QDir::tempPath());
QVERIFY(op.testOperation());
@@ -71,7 +72,7 @@ private slots:
void testExtractOperationInvalidFile()
{
- ExtractArchiveOperation op;
+ ExtractArchiveOperation op(0);
op.setArguments(QStringList() << ":///data/invalid.7z" << QDir::tempPath());
QVERIFY(op.testOperation());
@@ -79,7 +80,8 @@ private slots:
QVERIFY(op.undoOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError);
- QCOMPARE(op.errorString(), QString("Error while extracting ':///data/invalid.7z': Could not open archive"));
+ QCOMPARE(op.errorString(), QString("Error while extracting archive \":///data/invalid.7z\": "
+ "Cannot open archive \":///data/invalid.7z\"."));
}
};
diff --git a/tests/auto/installer/factory/factory.pro b/tests/auto/installer/factory/factory.pro
new file mode 100644
index 000000000..b87f23bab
--- /dev/null
+++ b/tests/auto/installer/factory/factory.pro
@@ -0,0 +1,5 @@
+include(../../qttest.pri)
+
+QT -= gui
+
+SOURCES += tst_factory.cpp
diff --git a/tests/auto/installer/factory/tst_factory.cpp b/tests/auto/installer/factory/tst_factory.cpp
new file mode 100644
index 000000000..a693a2ce6
--- /dev/null
+++ b/tests/auto/installer/factory/tst_factory.cpp
@@ -0,0 +1,228 @@
+/**************************************************************************
+**
+** 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 <genericfactory.h>
+
+#include <QDebug>
+#include <QTest>
+
+#include <functional>
+
+class Food {
+public:
+ explicit Food(int amount)
+ : m_amount(amount)
+ {}
+ virtual ~Food() {}
+
+ int available() const {
+ return m_amount;
+ }
+ virtual QDate expireDate() const = 0;
+
+ template <typename T, typename... Args>
+ static Food *create(Args... args) {
+ qDebug().nospace().noquote() << "Create function.";
+ return new T(std::forward<Args>(args)...);
+ }
+
+private:
+ int m_amount;
+};
+
+class EggStore : public GenericFactory<Food, QString, int>
+{
+public:
+ static EggStore &instance() {
+ static EggStore factory;
+ return factory;
+ }
+};
+
+class Bread : public Food
+{
+public:
+ Bread(int amount, const QDate &expireDate)
+ : Food(amount)
+ , m_expireDate(expireDate)
+ { qDebug().nospace().noquote() << "Constructor."; }
+ QDate expireDate() const {
+ return m_expireDate;
+ }
+private:
+ QDate m_expireDate;
+};
+
+class Butter : public Food
+{
+public:
+ QDate expireDate() const {
+ return m_expireDate;
+ }
+ static Food *create(int amount, const QDate expireDate) {
+ qDebug().nospace().noquote() << "Create function.";
+ return new Butter(amount, expireDate);
+ }
+
+private:
+ Butter(int amount, const QDate &expireDate)
+ : Food(amount)
+ , m_expireDate(expireDate)
+ { qDebug().nospace().noquote() << "Constructor."; }
+
+private:
+ QDate m_expireDate;
+};
+
+class ColdCuts : public Food
+{
+public:
+ ColdCuts(int amount, const QDate &expireDate)
+ : Food(amount)
+ , m_expireDate(expireDate)
+ { qDebug().nospace().noquote() << "Constructor."; }
+ QDate expireDate() const {
+ return m_expireDate;
+ }
+
+private:
+ QDate m_expireDate;
+};
+
+class FoodStore : public GenericFactory<Food, QString, int, QDate>
+{
+public:
+ static FoodStore &instance() {
+ static FoodStore factory;
+ return factory;
+ }
+};
+
+class tst_Factory : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void testSingleArg()
+ {
+ class Egg : public Food
+ {
+ public:
+ explicit Egg(int amount)
+ : Food(amount)
+ { qDebug().nospace().noquote() << "Constructor."; }
+ QDate expireDate() const {
+ return QDate::currentDate().addDays(1);
+ }
+ private:
+ QDate m_expireDate;
+ };
+ class EggStore : public GenericFactory<Food, QString, int>
+ {
+ public:
+ static EggStore &instance() {
+ static EggStore factory;
+ return factory;
+ }
+ };
+
+ EggStore::instance().registerProduct<Egg>("Egg");
+ QCOMPARE(EggStore::instance().containsProduct("Egg"), true);
+ // EggStore::instance().registerProduct<Bread>("Bread"); // Does not compile.
+
+ QTest::ignoreMessage(QtDebugMsg, "Constructor.");
+ auto food = EggStore::instance().create("Egg", 100);
+ QCOMPARE(food->available(), 100);
+ QCOMPARE(food->expireDate(), QDate::currentDate().addDays(1));
+
+ QTest::ignoreMessage(QtDebugMsg, "Create function.");
+ QTest::ignoreMessage(QtDebugMsg, "Constructor.");
+ EggStore::instance().registerProduct("Egg", &Egg::create<Egg, int>);
+ food = EggStore::instance().create("Egg", 10);
+ QCOMPARE(food->available(), 10);
+ QCOMPARE(food->expireDate(), QDate::currentDate().addDays(1));
+
+ auto lambda = [](int amount) -> Food* { return new Egg(amount); };
+ EggStore::instance().registerProduct("Egg", lambda);
+
+ QTest::ignoreMessage(QtDebugMsg, "Constructor.");
+ food = EggStore::instance().create("Egg", 20);
+ QCOMPARE(food->available(), 20);
+ QCOMPARE(food->expireDate(), QDate::currentDate().addDays(1));
+ }
+
+ void testMultiArg()
+ {
+ FoodStore::instance().registerProduct<Bread>("Bread");
+ FoodStore::instance().registerProduct("Butter", &Butter::create);
+ FoodStore::instance().registerProduct<ColdCuts>("ColdCuts");
+ // FoodStore::instance().registerProduct<Eggs>("Eggs"); // Does not compile.
+
+ QCOMPARE(FoodStore::instance().containsProduct("Bread"), true);
+ QCOMPARE(FoodStore::instance().containsProduct("Butter"), true);
+ QCOMPARE(FoodStore::instance().containsProduct("ColdCuts"), true);
+ QCOMPARE(FoodStore::instance().containsProduct("Sandwich"), false);
+
+ QTest::ignoreMessage(QtDebugMsg, "Constructor.");
+ auto food = FoodStore::instance().create("Bread", 10, QDate::currentDate().addDays(7));
+ QCOMPARE(food->available(), 10);
+ QCOMPARE(food->expireDate(), QDate::currentDate().addDays(7));
+
+ QTest::ignoreMessage(QtDebugMsg, "Create function.");
+ QTest::ignoreMessage(QtDebugMsg, "Constructor.");
+ food = FoodStore::instance().create("Butter", 2, QDate::currentDate().addDays(3));
+ QCOMPARE(food->available(), 2);
+ QCOMPARE(food->expireDate(), QDate::currentDate().addDays(3));
+
+ QTest::ignoreMessage(QtDebugMsg, "Constructor.");
+ food = FoodStore::instance().create("ColdCuts", 50, QDate::currentDate().addDays(5));
+ QCOMPARE(food->available(), 50);
+ QCOMPARE(food->expireDate(), QDate::currentDate().addDays(5));
+
+ food = FoodStore::instance().create("Sandwich", 50, QDate::currentDate());
+ QCOMPARE(food == Q_NULLPTR, true);
+
+ // overwrites the existing registration
+ FoodStore::instance().registerProduct("ColdCuts", &ColdCuts::create<ColdCuts, int, QDate>);
+ QTest::ignoreMessage(QtDebugMsg, "Create function.");
+ QTest::ignoreMessage(QtDebugMsg, "Constructor.");
+ food = FoodStore::instance().create("ColdCuts", 100, QDate::currentDate().addDays(4));
+ QCOMPARE(food->available(), 100);
+ QCOMPARE(food->expireDate(), QDate::currentDate().addDays(4));
+ }
+};
+
+QTEST_MAIN(tst_Factory)
+
+#include "tst_factory.moc"
diff --git a/tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp b/tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp
index c8b314657..583bb26f0 100644
--- a/tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp
+++ b/tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp
@@ -15,20 +15,20 @@ class tst_FakeStopProcessForUpdateOperation : public QObject
private slots:
void testMissingArgument()
{
- FakeStopProcessForUpdateOperation op;
- op.setValue(QLatin1String("installer"), QVariant::fromValue(&m_core));
+ FakeStopProcessForUpdateOperation op(&m_core);
QVERIFY(op.testOperation());
QVERIFY(op.performOperation());
QVERIFY(!op.undoOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Number of arguments does not match: one is required"));
+ QCOMPARE(op.errorString(), QString("Invalid arguments in FakeStopProcessForUpdate: "
+ "0 arguments given, exactly 1 arguments expected."));
}
void testMissingPackageManagerCore()
{
- FakeStopProcessForUpdateOperation op;
+ FakeStopProcessForUpdateOperation op(0);
op.setArguments(QStringList() << QFileInfo(QCoreApplication::applicationFilePath()).fileName());
QVERIFY(op.testOperation());
@@ -36,16 +36,15 @@ private slots:
QVERIFY(!op.undoOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError);
- QCOMPARE(op.errorString(), QString("Could not get package manager core."));
+ QCOMPARE(op.errorString(), QString("Cannot get package manager core."));
}
void testRunningApplication()
{
const QString app = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
- FakeStopProcessForUpdateOperation op;
+ FakeStopProcessForUpdateOperation op(&m_core);
op.setArguments(QStringList() << app);
- op.setValue(QLatin1String("installer"), QVariant::fromValue(&m_core));
QVERIFY(op.testOperation());
QVERIFY(op.performOperation());
@@ -58,9 +57,8 @@ private slots:
void testRunningNonApplication()
{
- FakeStopProcessForUpdateOperation op;
+ FakeStopProcessForUpdateOperation op(&m_core);
op.setArguments(QStringList() << "dummy.exe");
- op.setValue(QLatin1String("installer"), QVariant::fromValue(&m_core));
QVERIFY(op.testOperation());
QVERIFY(op.performOperation());
diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro
index 0bd5e8690..ba2dd0244 100644
--- a/tests/auto/installer/installer.pro
+++ b/tests/auto/installer/installer.pro
@@ -8,6 +8,7 @@ SUBDIRS += \
messageboxhandler \
extractarchiveoperationtest \
lib7zfacade \
+ unicodeexecutable \
scriptengine \
consumeoutputoperationtest \
mkdiroperationtest \
@@ -17,4 +18,10 @@ SUBDIRS += \
packagemanagercore \
settingsoperation \
task \
- clientserver
+ clientserver \
+ factory
+
+win32 {
+ SUBDIRS += registerfiletypeoperation
+}
+scriptengine.depends += unicodeexecutable
diff --git a/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp b/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp
index 75b7bf148..ffc5b330a 100644
--- a/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp
+++ b/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp
@@ -26,8 +26,10 @@
**
**************************************************************************/
-#include "init.h"
-#include "lib7z_facade.h"
+#include <lib7z_create.h>
+#include <lib7z_extract.h>
+#include <lib7z_facade.h>
+#include <lib7z_list.h>
#include <QDir>
#include <QObject>
@@ -41,7 +43,7 @@ class tst_lib7zfacade : public QObject
private slots:
void initTestCase()
{
- QInstaller::init();
+ Lib7z::initSevenZ();
m_file.path = "valid";
m_file.permissions = 0;
@@ -49,7 +51,7 @@ private slots:
m_file.uncompressedSize = 5242880;
m_file.isDirectory = false;
m_file.archiveIndex = QPoint(0, 0);
- m_file.mtime = QDateTime(QDate::fromJulianDay(2456413), QTime(12, 50, 42));
+ m_file.utcTime = QDateTime(QDate::fromJulianDay(2456413), QTime(10, 50, 42), Qt::UTC);
}
void testIsSupportedArchive()
@@ -57,109 +59,111 @@ private slots:
QCOMPARE(Lib7z::isSupportedArchive(":///data/valid.7z"), true);
QCOMPARE(Lib7z::isSupportedArchive(":///data/invalid.7z"), false);
- {
+ try {
QFile file(":///data/valid.7z");
QVERIFY(file.open(QIODevice::ReadOnly));
QCOMPARE(Lib7z::isSupportedArchive(&file), true);
+ } catch (...) {
+ QFAIL("Unexpected error during Lib7z::isSupportedArchive.");
}
- {
+ try {
QFile file(":///data/invalid.7z");
QVERIFY(file.open(QIODevice::ReadOnly));
QCOMPARE(Lib7z::isSupportedArchive(&file), false);
+ } catch (...) {
+ QFAIL("Unexpected error during Lib7z::isSupportedArchive.");
}
}
void testListArchive()
{
- // TODO: this should work without scope, there's a bug in Lib7z::OpenArchiveInfo
- // caused by the fact that we keep a pointer to the device, not the devices target
- {
+ try {
QFile file(":///data/valid.7z");
QVERIFY(file.open(QIODevice::ReadOnly));
QVector<Lib7z::File> files = Lib7z::listArchive(&file);
QCOMPARE(files.count(), 1);
-#ifdef Q_OS_UNIX
- QSKIP("This test requires the time handling to be repaired first.");
-#endif
QCOMPARE(files.first(), m_file);
+ } catch (...) {
+ QFAIL("Unexpected error during list archive.");
}
- {
- try {
- QFile file(":///data/invalid.7z");
- QVERIFY(file.open(QIODevice::ReadOnly));
- QVector<Lib7z::File> files = Lib7z::listArchive(&file);
- } catch (const Lib7z::SevenZipException& e) {
- QCOMPARE(e.message(), QString("Could not open archive"));
- } catch (...) {
- QFAIL("Unexpected error during list archive!");
- }
+ try {
+ QFile file(":///data/invalid.7z");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QVector<Lib7z::File> files = Lib7z::listArchive(&file);
+ } catch (const Lib7z::SevenZipException& e) {
+ QCOMPARE(e.message(), QString("Cannot open archive \":///data/invalid.7z\"."));
+ } catch (...) {
+ QFAIL("Unexpected error during list archive.");
}
}
void testCreateArchive()
{
- QTemporaryFile target;
- QVERIFY(target.open());
-
try {
- // TODO: we do not get any information about success
- Lib7z::createArchive(&target, QStringList() << ":///data/invalid.7z");
+ const QString path = tempSourceFile("Source File 1.");
+ const QString path2 = tempSourceFile("Source File 2.");
+
+ QTemporaryFile target;
+ QVERIFY(target.open());
+ Lib7z::createArchive(&target, QStringList() << path << path2);
+ QCOMPARE(Lib7z::listArchive(&target).count(), 2);
} catch (const Lib7z::SevenZipException& e) {
QFAIL(e.message().toUtf8());
} catch (...) {
- QFAIL("Unexpected error during create archive!");
+ QFAIL("Unexpected error during create archive.");
}
- }
-
- void testExtractArchive()
- {
- QFile source(":///data/valid.7z");
- QVERIFY(source.open(QIODevice::ReadOnly));
try {
- // TODO: we do not get any information about success
- Lib7z::extractArchive(&source, QDir::tempPath());
+ const QString path1 = tempSourceFile(
+ "Source File 1.",
+ QDir::tempPath() + "/temp file with spaces.XXXXXX"
+ );
+ const QString path2 = tempSourceFile(
+ "Source File 2.",
+ QDir::tempPath() + "/temp file with spaces.XXXXXX"
+ );
+
+ QTemporaryFile target(QDir::tempPath() + "/target file with spaces.XXXXXX");
+ QVERIFY(target.open());
+ Lib7z::createArchive(&target, QStringList() << path1 << path2);
+ QCOMPARE(Lib7z::listArchive(&target).count(), 2);
} catch (const Lib7z::SevenZipException& e) {
QFAIL(e.message().toUtf8());
} catch (...) {
- QFAIL("Unexpected error during extract archive!");
+ QFAIL("Unexpected error during create archive.");
}
+
}
- void testExtractFileFromArchive()
+ void testExtractArchive()
{
QFile source(":///data/valid.7z");
QVERIFY(source.open(QIODevice::ReadOnly));
- QTemporaryFile target;
- QVERIFY(target.open());
-
try {
- // TODO: we do not get any information about success
- Lib7z::extractFileFromArchive(&source, m_file, &target);
+ Lib7z::extractArchive(&source, QDir::tempPath());
+ QCOMPARE(QFile::exists(QDir::tempPath() + QString("/valid")), true);
} catch (const Lib7z::SevenZipException& e) {
QFAIL(e.message().toUtf8());
} catch (...) {
- QFAIL("Unexpected error during extract file from archive!");
+ QFAIL("Unexpected error during extract archive.");
}
}
- void testExtractFileFromArchive2()
+private:
+ QString tempSourceFile(const QByteArray &data, const QString &templateName = QString())
{
- QFile source(":///data/valid.7z");
- QVERIFY(source.open(QIODevice::ReadOnly));
-
- try {
- // TODO: we do not get any information about success
- Lib7z::extractFileFromArchive(&source, m_file, QDir::tempPath());
- } catch (const Lib7z::SevenZipException& e) {
- QFAIL(e.message().toUtf8());
- } catch (...) {
- QFAIL("Unexpected error during extract file from archive!");
+ QTemporaryFile source;
+ if (!templateName.isEmpty()) {
+ source.setFileTemplate(templateName);
}
+ source.open();
+ source.write(data);
+ source.setAutoRemove(false);
+ return source.fileName();
}
private:
diff --git a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp
index d032b973f..dd127f626 100644
--- a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp
+++ b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp
@@ -12,6 +12,17 @@
using namespace QInstaller;
+QT_BEGIN_NAMESPACE
+namespace QTest {
+ template<>
+ char *toString(const QMessageBox::StandardButton &button)
+ {
+ QString buttonAsString(QString::number(button));
+ return qstrdup(buttonAsString.toLatin1().data());
+ }
+}
+QT_END_NAMESPACE
+
class tst_MessageBoxHandler : public QObject
{
Q_OBJECT
@@ -56,8 +67,8 @@ private slots:
void testDefaultAction()
{
- const char ignoreMessage[] = "\"created critical message box TestError: 'A test error', "
- "This is a test error message.\" ";
+ const char ignoreMessage[] = "Created critical message box \"TestError\": \"A test error\", "
+ "\"This is a test error message.\"";
srand(time(0)); /* initialize random seed: */
int standardButtons = QMessageBox::NoButton;
@@ -85,7 +96,7 @@ private slots:
wantedButton = button;
}
- QVERIFY2(wantedButton != QMessageBox::NoButton, "Could not find a wantedButton.");
+ QVERIFY2(wantedButton != QMessageBox::NoButton, "Cannot find a wantedButton.");
QCOMPARE(static_cast<QMessageBox::StandardButton>(returnButton), wantedButton);
} while (standardButtons < m_maxStandardButtons);
}
diff --git a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
index b18cae3a0..f52c27d0f 100644
--- a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
+++ b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
@@ -27,7 +27,7 @@
**************************************************************************/
#include "init.h"
-#include "kdupdaterupdateoperations.h"
+#include "updateoperations.h"
#include <QDir>
#include <QObject>
@@ -60,7 +60,8 @@ private slots:
QVERIFY(!op.performOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Invalid arguments: 0 arguments given, 1 expected."));
+ QCOMPARE(op.errorString(), QString("Invalid arguments in Mkdir: "
+ "0 arguments given, exactly 1 arguments expected."));
}
@@ -116,7 +117,7 @@ private slots:
file.close();
QVERIFY2(!op.undoOperation(), op.errorString().toLatin1());
QVERIFY2(file.exists(), filepath.toLatin1());
- QVERIFY2(QDir(filepath).remove(filepath), "Could not remove file");
+ QVERIFY2(QDir(filepath).remove(filepath), "Cannot remove file");
QVERIFY2(!file.exists(), filepath.toLatin1());
QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
QVERIFY2(!QDir(path).exists(), path.toLatin1());
diff --git a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp
index 42be8038e..47fb41bf1 100644
--- a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp
+++ b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp
@@ -84,26 +84,19 @@ class tst_PackageManagerCore : public QObject
private:
void setIgnoreMessage(const QString &testDirectory)
{
-#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
- const QString message = "\"\t- arguments: %1\" ";
-#else
- const QString message = "\"\\t- arguments: %1\" ";
-#endif
+ const QString message = "\t- arguments: %1";
QTest::ignoreMessage(QtDebugMsg, "Operations sanity check succeeded.");
- QTest::ignoreMessage(QtDebugMsg, "\"backup operation: Mkdir\" ");
+ QTest::ignoreMessage(QtDebugMsg, "backup operation: Mkdir");
QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(testDirectory)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(testDirectory)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(testDirectory)));
- QTest::ignoreMessage(QtDebugMsg, "\"perform operation: Mkdir\" ");
- QTest::ignoreMessage(QtDebugMsg, "Install size: 1 components ");
- QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Force crash to test rollback!\" ");
- QTest::ignoreMessage(QtDebugMsg, "\"created critical message box installationError: 'Error"
- "', Force crash to test rollback!\" ");
- QTest::ignoreMessage(QtDebugMsg, "ROLLING BACK operations= 1 ");
- QTest::ignoreMessage(QtDebugMsg, "\"undo operation: Mkdir\" ");
- QTest::ignoreMessage(QtDebugMsg, "Done ");
- QTest::ignoreMessage(QtDebugMsg, "Done ");
- QTest::ignoreMessage(QtDebugMsg, "Done ");
+ QTest::ignoreMessage(QtDebugMsg, "perform operation: Mkdir");
+ QTest::ignoreMessage(QtDebugMsg, "Install size: 1 components");
+ QTest::ignoreMessage(QtDebugMsg, "ROLLING BACK operations= 1");
+ QTest::ignoreMessage(QtDebugMsg, "undo operation: Mkdir");
+ QTest::ignoreMessage(QtDebugMsg, "Done");
+ QTest::ignoreMessage(QtDebugMsg, "Done");
+ QTest::ignoreMessage(QtDebugMsg, "Done");
}
private slots:
@@ -202,8 +195,6 @@ private slots:
Component *root = new NamedComponent(&core, QLatin1String("root1"));
try {
- QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Components cannot "
- "have children in updater mode.\" ");
root->appendComponent(new NamedComponent(&core, QLatin1String("root1.foo")));
QFAIL("Components cannot have children in updater mode.");
} catch (const QInstaller::Error &error) {
diff --git a/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro b/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro
new file mode 100644
index 000000000..0e541ceed
--- /dev/null
+++ b/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro
@@ -0,0 +1,6 @@
+include(../../qttest.pri)
+
+QT -= gui
+QT += testlib network
+
+SOURCES = tst_registerfiletypeoperation.cpp
diff --git a/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp b/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp
new file mode 100644
index 000000000..7afc372b4
--- /dev/null
+++ b/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp
@@ -0,0 +1,126 @@
+/**************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** 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 "init.h"
+#include "registerfiletypeoperation.h"
+#include "packagemanagercore.h"
+
+#include <QDir>
+#include <QObject>
+#include <QTest>
+#include <QFile>
+#include <QTextStream>
+#include <QSettings>
+#include "qsettingswrapper.h"
+
+using namespace KDUpdater;
+using namespace QInstaller;
+
+class tst_registerfiletypeoperation : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase()
+ {
+ QInstaller::init();
+ QString randomString = "";
+ const QString possible = "abcdefghijklmnopqrstuvwxyz0123456789";
+ qsrand(QTime::currentTime().msec());
+ for (int i = 0; i < 5; i++) {
+ int index = qrand() % possible.length();
+ QChar nextChar = possible.at(index);
+ randomString.append(nextChar);
+
+ }
+ m_fileType = randomString;
+
+ m_command = m_core.environmentVariable("SystemRoot") + "\\notepad.exe";
+ m_progId = "QtProject.QtInstallerFramework." + m_fileType;
+
+ }
+
+ void testMissingArguments()
+ {
+ RegisterFileTypeOperation op(&m_core);
+
+ QVERIFY(op.testOperation());
+ QVERIFY(!op.performOperation());
+
+ QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
+ QCOMPARE(op.errorString(), QString("Invalid arguments in RegisterFileType: 0 arguments given, "
+ "2 to 5 arguments expected in the form: <extension> <command> [description [contentType [icon]]]."));
+
+ }
+ void testRegisterFileType()
+ {
+ RegisterFileTypeOperation op(&m_core);
+ op.setArguments(QStringList() << m_fileType << m_command << "test filetype" <<
+ "text/plain" << 0 << "ProgId="+m_progId);
+
+ const QString settingsPath = QString::fromLatin1("HKEY_CURRENT_USER\\Software\\Classes\\");
+ QSettings settings(settingsPath, QSettings::NativeFormat);
+
+
+ QVERIFY(op.testOperation());
+ QVERIFY(op.performOperation());
+
+ QString defaultKey = "."+m_fileType+ "/Default";
+ QString openWithProgIdkey = "." + m_fileType + "/OpenWithProgIds/" +m_progId;
+ QString shellKey = m_progId + "/shell/Open/Command/Default/";
+ QString shellAppkey = "/Applications/" + m_progId + "/shell/Open/Command/Default/";
+
+ QCOMPARE(settings.value(defaultKey).toString(), m_progId);
+ QCOMPARE(settings.value(openWithProgIdkey).toString(), QString());
+ QCOMPARE(settings.value(shellKey).toString(), m_command);
+ QCOMPARE(settings.value(shellAppkey).toString(), m_command);
+
+ QVERIFY(op.undoOperation());
+
+ //Test that values have been removed after undo operation
+ QCOMPARE(settings.value(defaultKey).toString(), QString());
+ QCOMPARE(settings.value(openWithProgIdkey).toString(), QString());
+ QCOMPARE(settings.value(shellKey).toString(), QString());
+ QCOMPARE(settings.value(shellAppkey).toString(), QString());
+ }
+
+private:
+ QString m_fileType;
+ QString m_command;
+ QString m_progId;
+ PackageManagerCore m_core;
+};
+
+QTEST_MAIN(tst_registerfiletypeoperation)
+
+#include "tst_registerfiletypeoperation.moc"
diff --git a/tests/auto/installer/scriptengine/data/addOperation.qs b/tests/auto/installer/scriptengine/data/addOperation.qs
new file mode 100644
index 000000000..d7d505a6b
--- /dev/null
+++ b/tests/auto/installer/scriptengine/data/addOperation.qs
@@ -0,0 +1,52 @@
+/**************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** 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$
+**
+**************************************************************************/
+
+function Component()
+{
+}
+
+Component.prototype.createOperations = function ()
+{
+ console.log("Component::createOperations()");
+ component.createOperations();
+
+ component.addOperation("EmptyArg", "Arg", "Arg2", "");
+ component.addOperation("EmptyArg", "Arg", "", "Arg3");
+ component.addOperation("EmptyArg", "", "Arg2", "Arg3");
+ component.addOperation("EmptyArg", ["Arg", "Arg2", ""]);
+
+ component.addElevatedOperation("EmptyArg", "eArg", "eArg2", "");
+ component.addElevatedOperation("EmptyArg", "eArg", "", "eArg3");
+ component.addElevatedOperation("EmptyArg", "", "eArg2", "eArg3");
+ component.addElevatedOperation("EmptyArg", ["eArg", "eArg2", ""]);
+}
diff --git a/tests/auto/installer/scriptengine/scriptengine.pro b/tests/auto/installer/scriptengine/scriptengine.pro
index 71d8196a1..50aa859a3 100644
--- a/tests/auto/installer/scriptengine/scriptengine.pro
+++ b/tests/auto/installer/scriptengine/scriptengine.pro
@@ -4,5 +4,7 @@ QT += qml widgets
SOURCES += tst_scriptengine.cpp
+DEFINES += "BUILDDIR=\\\"$$OUT_PWD\\\""
+
RESOURCES += \
scriptengine.qrc
diff --git a/tests/auto/installer/scriptengine/scriptengine.qrc b/tests/auto/installer/scriptengine/scriptengine.qrc
index d630f3196..9c72e686f 100644
--- a/tests/auto/installer/scriptengine/scriptengine.qrc
+++ b/tests/auto/installer/scriptengine/scriptengine.qrc
@@ -8,5 +8,6 @@
<file>data/enteringpage.qs</file>
<file>data/form.ui</file>
<file>data/userinterface.qs</file>
+ <file>data/addOperation.qs</file>
</qresource>
</RCC>
diff --git a/tests/auto/installer/scriptengine/tst_scriptengine.cpp b/tests/auto/installer/scriptengine/tst_scriptengine.cpp
index 5b7404557..186e341c7 100644
--- a/tests/auto/installer/scriptengine/tst_scriptengine.cpp
+++ b/tests/auto/installer/scriptengine/tst_scriptengine.cpp
@@ -28,10 +28,14 @@
#include <component.h>
#include <errors.h>
+#include <updateoperation.h>
+#include <updateoperationfactory.h>
#include <packagemanagercore.h>
#include <packagemanagergui.h>
#include <scriptengine.h>
+#include <../unicodeexecutable/stringdata.h>
+
#include <QTest>
#include <QSet>
#include <QFile>
@@ -151,6 +155,29 @@ signals:
void emitted();
};
+class EmptyArgOperation : public KDUpdater::UpdateOperation
+{
+public:
+ explicit EmptyArgOperation(QInstaller::PackageManagerCore *core)
+ : KDUpdater::UpdateOperation(core)
+ {
+ setName("EmptyArg");
+ }
+
+ void backup() {}
+ bool performOperation() {
+ return true;
+ }
+ bool undoOperation() {
+ return true;
+ }
+ bool testOperation() {
+ return true;
+ }
+};
+
+
+// -- tst_ScriptEngine
class tst_ScriptEngine : public QObject
{
@@ -166,6 +193,9 @@ private slots:
m_component->setValue("Default", "Script");
m_component->setValue(scName, "component.test.name");
+ Component *component = new Component(&m_core);
+ component->setValue(scName, "component.test.addOperation");
+ m_core.appendRootComponent(component);
m_scriptEngine = m_core.componentScriptEngine();
}
@@ -245,9 +275,9 @@ private slots:
QCOMPARE(context.isError(), false);
// ignore Output from script
- setExpectedScriptOutput("\"function receive()\"");
+ setExpectedScriptOutput("function receive()");
- QTest::ignoreMessage(QtWarningMsg, ":10: ReferenceError: foo is not defined");
+ QTest::ignoreMessage(QtWarningMsg, ":43: ReferenceError: foo is not defined");
emiter.produceSignal();
const QJSValue value = m_scriptEngine->evaluate("");
@@ -256,7 +286,7 @@ private slots:
void testScriptPrint()
{
- setExpectedScriptOutput("\"test\"");
+ setExpectedScriptOutput("test");
const QJSValue value = m_scriptEngine->evaluate("print(\"test\");");
if (value.isError()) {
QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg(
@@ -266,7 +296,7 @@ private slots:
void testExistingInstallerObject()
{
- setExpectedScriptOutput("\"object\"");
+ setExpectedScriptOutput("object");
const QJSValue value = m_scriptEngine->evaluate("print(typeof installer)");
if (value.isError()) {
QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg(
@@ -280,7 +310,7 @@ private slots:
"\n"
"print(component.name);").arg(m_component->name());
- setExpectedScriptOutput("\"component.test.name\"");
+ setExpectedScriptOutput("component.test.name");
const QJSValue value = m_scriptEngine->evaluate(script);
if (value.isError()) {
QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg(
@@ -304,7 +334,7 @@ private slots:
"\n"
"print(components[0].name);");
- setExpectedScriptOutput("\"component.test.name\"");
+ setExpectedScriptOutput("component.test.name");
const QJSValue value = m_scriptEngine->evaluate(script);
if (value.isError()) {
QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg(
@@ -316,28 +346,28 @@ private slots:
{
try {
// ignore retranslateUi which is called by loadComponentScript
- setExpectedScriptOutput("\"Component constructor - OK\"");
- setExpectedScriptOutput("\"retranslateUi - OK\"");
+ setExpectedScriptOutput("Component constructor - OK");
+ setExpectedScriptOutput("retranslateUi - OK");
m_component->loadComponentScript(":///data/component1.qs");
- setExpectedScriptOutput("\"retranslateUi - OK\"");
+ setExpectedScriptOutput("retranslateUi - OK");
m_component->languageChanged();
- setExpectedScriptOutput("\"createOperationsForPath - OK\"");
+ setExpectedScriptOutput("createOperationsForPath - OK");
m_component->createOperationsForPath(":///data/");
- setExpectedScriptOutput("\"createOperationsForArchive - OK\"");
+ setExpectedScriptOutput("createOperationsForArchive - OK");
// ignore createOperationsForPath which is called by createOperationsForArchive
- setExpectedScriptOutput("\"createOperationsForPath - OK\"");
+ setExpectedScriptOutput("createOperationsForPath - OK");
m_component->createOperationsForArchive("test.7z");
- setExpectedScriptOutput("\"beginInstallation - OK\"");
+ setExpectedScriptOutput("beginInstallation - OK");
m_component->beginInstallation();
- setExpectedScriptOutput("\"createOperations - OK\"");
+ setExpectedScriptOutput("createOperations - OK");
m_component->createOperations();
- setExpectedScriptOutput("\"isDefault - OK\"");
+ setExpectedScriptOutput("isDefault - OK");
bool returnIsDefault = m_component->isDefault();
QCOMPARE(returnIsDefault, false);
@@ -354,23 +384,22 @@ private slots:
// m_core becomes the owner of testComponent, it will delete it in the destructor
m_core.appendRootComponent(testComponent);
- const QString debugMesssage(
- "create Error-Exception: \"Exception while loading the component script '"
- ":///data/component2.qs'. (ReferenceError: broken is not defined)\"");
try {
// ignore Output from script
- setExpectedScriptOutput("\"script function: Component\"");
- setExpectedScriptOutput(qPrintable(debugMesssage));
+ setExpectedScriptOutput("script function: Component");
testComponent->loadComponentScript(":///data/component2.qs");
} catch (const Error &error) {
- QVERIFY2(debugMesssage.contains(error.message()), "(ReferenceError: broken is not defined)");
+ const QString debugMessage(
+ QString("create Error-Exception: \"Exception while loading the component script \"%1\": "
+ "ReferenceError: broken is not defined\"").arg(QDir::toNativeSeparators(":///data/component2.qs")));
+ QVERIFY2(debugMessage.contains(error.message()), "(ReferenceError: broken is not defined)");
}
}
void loadComponentUserInterfaces()
{
try {
- setExpectedScriptOutput("\"checked: false\"");
+ setExpectedScriptOutput("checked: false");
m_component->loadUserInterfaces(QDir(":///data"), QStringList() << QLatin1String("form.ui"));
m_component->loadComponentScript(":///data/userinterface.qs");
} catch (const Error &error) {
@@ -392,7 +421,7 @@ private slots:
QTest::ignoreMessage(QtWarningMsg, "Button with type: \"unknown button\" not found! ");
testGui.callProtectedDelayedExecuteControlScript(PackageManagerCore::ComponentSelection);
- setExpectedScriptOutput("\"FinishedPageCallback - OK\"");
+ setExpectedScriptOutput("FinishedPageCallback - OK");
testGui.callProtectedDelayedExecuteControlScript(PackageManagerCore::InstallationFinished);
} catch (const Error &error) {
QFAIL(qPrintable(error.message()));
@@ -439,6 +468,56 @@ private slots:
QCOMPARE(gui.widget()->property("complete").toString(), QString("true"));
}
+ void testInstallerExecuteEncodings_data()
+ {
+ QTest::addColumn<QString>("argumentsToInstallerExecute");
+ QTest::addColumn<QString>("expectedOutput");
+ QTest::addColumn<int>("expectedExitCode");
+
+ QTest::newRow("default_encoding_ascii_output_exit_code_0")
+ << QString::fromLatin1("['ascii', '0']") << QString::fromLatin1(asciiText) << 0;
+ QTest::newRow("default_encoding_ascii_output_exit_code_52")
+ << QString::fromLatin1("['ascii', '52']") << QString::fromLatin1(asciiText) << 52;
+
+ QTest::newRow("latin1_encoding_ascii_output")
+ << QString::fromLatin1("['ascii', '0'], '', 'latin1', 'latin1'") << QString::fromLatin1(asciiText) << 0;
+ QTest::newRow("latin1_encoding_utf8_output")
+ << QString::fromLatin1("['utf8', '0'], '', 'latin1', 'latin1'") << QString::fromLatin1(utf8Text) << 0;
+
+ QTest::newRow("utf8_encoding_ascii_output")
+ << QString::fromLatin1("['ascii', '0'], '', 'utf8', 'utf8'") << QString::fromUtf8(asciiText) << 0;
+ QTest::newRow("utf8_encoding_utf8_output")
+ << QString::fromLatin1("['utf8', '0'], '', 'utf8', 'utf8'") << QString::fromUtf8(utf8Text) << 0;
+ }
+
+ void testInstallerExecuteEncodings()
+ {
+ QString unicodeExecutableName = QLatin1String(BUILDDIR "/../unicodeexecutable/unicodeexecutable");
+#if defined(Q_OS_WIN)
+ unicodeExecutableName += QLatin1String(".exe");
+#endif
+
+ QFileInfo unicodeExecutable(unicodeExecutableName);
+ if (!unicodeExecutable.isExecutable()) {
+ QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error: test program %1 is not executable")
+ .arg(unicodeExecutable.absoluteFilePath())));
+ return;
+ }
+
+ const QString testProgramPath = unicodeExecutable.absoluteFilePath();
+
+ QFETCH(QString, argumentsToInstallerExecute);
+ QFETCH(QString, expectedOutput);
+ QFETCH(int, expectedExitCode);
+
+ QJSValue result = m_scriptEngine->evaluate(QString::fromLatin1("installer.execute('%1', %2);")
+ .arg(testProgramPath)
+ .arg(argumentsToInstallerExecute));
+ QCOMPARE(result.isArray(), true);
+ QCOMPARE(result.property(0).toString(), expectedOutput);
+ QCOMPARE(result.property(1).toString(), QString::number(expectedExitCode));
+ }
+
void checkEnteringCalledBeforePageCallback()
{
EnteringGui gui(&m_core);
@@ -454,6 +533,47 @@ private slots:
QCOMPARE(enteringPage->invocationOrder(), expectedOrder);
}
+ void testAddOperation_AddElevatedOperation()
+ {
+#if QT_VERSION < 0x50600
+ QSKIP("Behavior changed from 5.6.0 onwards.");
+#endif
+ using namespace KDUpdater;
+ UpdateOperationFactory &factory = UpdateOperationFactory::instance();
+ factory.registerUpdateOperation<EmptyArgOperation>(QLatin1String("EmptyArg"));
+
+ try {
+ m_core.setPackageManager();
+ Component *component = m_core.componentByName("component.test.addOperation");
+ component->loadComponentScript(":///data/addOperation.qs");
+
+ setExpectedScriptOutput("Component::createOperations()");
+ component->createOperations();
+
+ const OperationList operations = component->operations();
+ QCOMPARE(operations.count(), 8);
+
+ struct {
+ const char* args[3];
+ const char* operator[](int i) const {
+ return args[i];
+ }
+ } expectedArgs[] = {
+ { "Arg", "Arg2", "" }, { "Arg", "", "Arg3" }, { "", "Arg2", "Arg3" }, { "Arg", "Arg2", "" },
+ { "eArg", "eArg2", "" }, { "eArg", "", "eArg3" }, { "", "eArg2", "eArg3" }, { "eArg", "eArg2", "" }
+ };
+
+ for (int i = 0; i < operations.count(); ++i) {
+ const QStringList arguments = operations[i]->arguments();
+ QCOMPARE(arguments.count(), 3);
+ for (int j = 0; j < 3; ++j)
+ QCOMPARE(arguments[j], QString(expectedArgs[i][j]));
+ }
+ } catch (const QInstaller::Error &error) {
+ QFAIL(qPrintable(error.message()));
+ }
+ }
+
private:
void setExpectedScriptOutput(const char *message)
{
diff --git a/tests/auto/installer/settings/data/full_config.xml b/tests/auto/installer/settings/data/full_config.xml
index 5479fa353..272a1b0d7 100644
--- a/tests/auto/installer/settings/data/full_config.xml
+++ b/tests/auto/installer/settings/data/full_config.xml
@@ -37,6 +37,7 @@ File should contain all elements we allow in a config.xml
<DependsOnLocalInstallerBinary>true</DependsOnLocalInstallerBinary>
<AllowSpaceInPath>true</AllowSpaceInPath>
<AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>
+ <DisableAuthorizationFallback>true</DisableAuthorizationFallback>
<RepositorySettingsPageVisible>false</RepositorySettingsPageVisible>
<CreateLocalRepository>false</CreateLocalRepository>
<TargetConfigurationFile>components.xml</TargetConfigurationFile>
@@ -56,4 +57,6 @@ File should contain all elements we allow in a config.xml
</Translations>
<ControlScript>controlscript.js</ControlScript>
+
+ <SupportsModify>true</SupportsModify>
</Installer>
diff --git a/tests/auto/installer/settings/data/length_units_invalid.xml b/tests/auto/installer/settings/data/length_units_invalid.xml
new file mode 100644
index 000000000..b1dc5aa62
--- /dev/null
+++ b/tests/auto/installer/settings/data/length_units_invalid.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+ <Name>Your application</Name>
+ <Version>1.2.3</Version>
+ <WizardDefaultWidth>800pt</WizardDefaultWidth>
+ <WizardDefaultHeight>600pt</WizardDefaultHeight>
+</Installer>
diff --git a/tests/auto/installer/settings/data/length_units_valid_em.xml b/tests/auto/installer/settings/data/length_units_valid_em.xml
new file mode 100644
index 000000000..af087fdfe
--- /dev/null
+++ b/tests/auto/installer/settings/data/length_units_valid_em.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+ <Name>Your application</Name>
+ <Version>1.2.3</Version>
+ <WizardDefaultWidth>800em</WizardDefaultWidth>
+ <WizardDefaultHeight>600em</WizardDefaultHeight>
+</Installer>
diff --git a/tests/auto/installer/settings/data/length_units_valid_ex.xml b/tests/auto/installer/settings/data/length_units_valid_ex.xml
new file mode 100644
index 000000000..3b39cf7a7
--- /dev/null
+++ b/tests/auto/installer/settings/data/length_units_valid_ex.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+ <Name>Your application</Name>
+ <Version>1.2.3</Version>
+ <WizardDefaultWidth>800ex</WizardDefaultWidth>
+ <WizardDefaultHeight>600ex</WizardDefaultHeight>
+</Installer>
diff --git a/tests/auto/installer/settings/data/length_units_valid_px.xml b/tests/auto/installer/settings/data/length_units_valid_px.xml
new file mode 100644
index 000000000..3553dd7d8
--- /dev/null
+++ b/tests/auto/installer/settings/data/length_units_valid_px.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Installer>
+ <Name>Your application</Name>
+ <Version>1.2.3</Version>
+ <WizardDefaultWidth>800px</WizardDefaultWidth>
+ <WizardDefaultHeight>600px</WizardDefaultHeight>
+</Installer>
diff --git a/tests/auto/installer/settings/settings.qrc b/tests/auto/installer/settings/settings.qrc
index c86847993..092805980 100644
--- a/tests/auto/installer/settings/settings.qrc
+++ b/tests/auto/installer/settings/settings.qrc
@@ -9,5 +9,9 @@
<file>data/minimal_config_tag_defaults.xml</file>
<file>data/unexpectedtag_config.xml</file>
<file>data/unexpectedattribute_config.xml</file>
+ <file>data/length_units_valid_px.xml</file>
+ <file>data/length_units_valid_em.xml</file>
+ <file>data/length_units_valid_ex.xml</file>
+ <file>data/length_units_invalid.xml</file>
</qresource>
</RCC>
diff --git a/tests/auto/installer/settings/tst_settings.cpp b/tests/auto/installer/settings/tst_settings.cpp
index bf45f4856..fc49f4ed8 100644
--- a/tests/auto/installer/settings/tst_settings.cpp
+++ b/tests/auto/installer/settings/tst_settings.cpp
@@ -23,6 +23,8 @@ private slots:
void loadMinimalConfigTagDefaults();
void loadUnexpectedAttributeConfig();
void loadUnexpectedTagConfig();
+ void loadConfigWithValidLengthUnits();
+ void loadConfigWithInvalidLengthUnits();
};
void tst_Settings::loadTutorialConfig()
@@ -72,7 +74,9 @@ void tst_Settings::loadTutorialConfig()
QCOMPARE(settings.repositorySettingsPageVisible(), true);
QCOMPARE(settings.allowSpaceInPath(), true);
QCOMPARE(settings.allowNonAsciiCharacters(), false);
+ QCOMPARE(settings.disableAuthorizationFallback(), false);
QCOMPARE(settings.createLocalRepository(), false);
+ QCOMPARE(settings.installActionColumnVisible(), false);
QCOMPARE(settings.hasReplacementRepos(), false);
QCOMPARE(settings.repositories(), QSet<Repository>());
@@ -86,6 +90,8 @@ void tst_Settings::loadTutorialConfig()
QCOMPARE(settings.translations(), QStringList());
QCOMPARE(settings.controlScript(), QString());
+
+ QCOMPARE(settings.supportsModify(), true);
}
void tst_Settings::loadFullConfig()
@@ -95,8 +101,6 @@ void tst_Settings::loadFullConfig()
void tst_Settings::loadEmptyConfig()
{
- QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Missing or empty <Name> tag in "
- ":/data/empty_config.xml.\" ");
try {
Settings::fromFileAndPrefix(":/data/empty_config.xml", ":/data");
} catch (const Error &error) {
@@ -115,13 +119,13 @@ void tst_Settings::loadNotExistingConfig()
if (!file.open(QIODevice::ReadOnly)) {
errorString = file.errorString();
}
- QTest::ignoreMessage(QtDebugMsg, QString::fromLatin1("create Error-Exception: \"Could not open"
+ QTest::ignoreMessage(QtDebugMsg, QString::fromLatin1("create Error-Exception: \"Cannot open"
" settings file %1 for reading: %2\"")
.arg(configFile).arg(errorString).toLatin1());
try {
Settings::fromFileAndPrefix(configFile, ":/data");
} catch (const Error &error) {
- QCOMPARE(error.message(), QString::fromLatin1("Could not open settings file "
+ QCOMPARE(error.message(), QString::fromLatin1("Cannot open settings file "
"%1 for reading: %2").arg(configFile).arg(errorString));
return;
}
@@ -130,8 +134,6 @@ void tst_Settings::loadNotExistingConfig()
void tst_Settings::loadMalformedConfig()
{
- QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Error in :/data/malformed_config.xml, "
- "line 9, column 0: Premature end of document.\" ");
try {
Settings::fromFileAndPrefix(":/data/malformed_config.xml", ":/data");
} catch (const Error &error) {
@@ -144,13 +146,11 @@ void tst_Settings::loadMalformedConfig()
void tst_Settings::loadUnknownElementConfigInStrictParseMode()
{
- QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Error in :/data/unknown_element_config.xml, "
- "line 5, column 13: Unexpected element 'unknown'.\" ");
try {
Settings::fromFileAndPrefix(":/data/unknown_element_config.xml", ":/data");
} catch (const Error &error) {
QCOMPARE(error.message(), QLatin1String("Error in :/data/unknown_element_config.xml, line 5, "
- "column 13: Unexpected element 'unknown'."));
+ "column 13: Unexpected element \"unknown\"."));
return;
}
QFAIL("No exception thrown");
@@ -158,8 +158,8 @@ void tst_Settings::loadUnknownElementConfigInStrictParseMode()
void tst_Settings::loadUnknownElementConfigInRelaxedParseMode()
{
- QTest::ignoreMessage(QtWarningMsg, "\"Ignoring following settings reader error in "
- ":/data/unknown_element_config.xml, line 5, column 13: Unexpected element 'unknown'.\" ");
+ QTest::ignoreMessage(QtWarningMsg, "Ignoring following settings reader error in "
+ ":/data/unknown_element_config.xml, line 5, column 13: Unexpected element \"unknown\".");
try {
Settings settings = Settings::fromFileAndPrefix(":/data/unknown_element_config.xml", ":/data",
Settings::RelaxedParseMode);
@@ -183,15 +183,11 @@ void tst_Settings::loadMinimalConfigTagDefaults()
void tst_Settings::loadUnexpectedAttributeConfig()
{
- QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Error in "
- ":///data/unexpectedattribute_config.xml, line 6, column 27: Unexpected attribute "
- "for element 'Argument'.\" ");
-
try {
Settings::fromFileAndPrefix(":///data/unexpectedattribute_config.xml", ":///data");
} catch (const Error &error) {
QCOMPARE(error.message(), QLatin1String("Error in :///data/unexpectedattribute_config.xml,"
- " line 6, column 27: Unexpected attribute for element 'Argument'."));
+ " line 6, column 27: Unexpected attribute for element \"Argument\"."));
return;
}
QFAIL("No exception thrown");
@@ -201,14 +197,11 @@ void tst_Settings::loadUnexpectedAttributeConfig()
void tst_Settings::loadUnexpectedTagConfig()
{
- QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Error in "
- ":///data/unexpectedtag_config.xml, line 6, column 12: Unexpected element 'Foo'.\" ");
-
try {
Settings::fromFileAndPrefix(":///data/unexpectedtag_config.xml", ":///data");
} catch (const Error &error) {
QCOMPARE(error.message(), QLatin1String("Error in :///data/unexpectedtag_config.xml,"
- " line 6, column 12: Unexpected element 'Foo'."));
+ " line 6, column 12: Unexpected element \"Foo\"."));
return;
}
QFAIL("No exception thrown");
@@ -216,6 +209,33 @@ void tst_Settings::loadUnexpectedTagConfig()
return;
}
+void tst_Settings::loadConfigWithValidLengthUnits()
+{
+ try {
+ Settings settings = Settings::fromFileAndPrefix(":///data/length_units_valid_px.xml", ":///data");
+ QCOMPARE(settings.wizardDefaultWidth(), 800);
+ QCOMPARE(settings.wizardDefaultHeight(), 600);
+
+ // Cannot test the parsed values for these units portably since the
+ // pixel value depends on the font metrics. Let's just check for parse
+ // errors.
+ (void)Settings::fromFileAndPrefix(":///data/length_units_valid_em.xml", ":///data");
+ (void)Settings::fromFileAndPrefix(":///data/length_units_valid_ex.xml", ":///data");
+ } catch (const Error &error) {
+ QFAIL(qPrintable(QString::fromLatin1("Exception caught: %1").arg(error.message())));
+ }
+}
+
+void tst_Settings::loadConfigWithInvalidLengthUnits()
+{
+ try {
+ Settings settings = Settings::fromFileAndPrefix(":///data/length_units_invalid.xml", ":///data");
+ QCOMPARE(settings.wizardDefaultWidth(), 0);
+ QCOMPARE(settings.wizardDefaultHeight(), 0);
+ } catch (const Error &error) {
+ QFAIL(qPrintable(QString::fromLatin1("Exception caught: %1").arg(error.message())));
+ }
+}
QTEST_MAIN(tst_Settings)
diff --git a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp
index 93d8cd99a..7530910b6 100644
--- a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp
+++ b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp
@@ -60,7 +60,7 @@ private slots:
void testWrongArguments()
{
- SettingsOperation noArgumentsOperation;
+ SettingsOperation noArgumentsOperation(0);
QVERIFY(noArgumentsOperation.testOperation());
@@ -69,14 +69,14 @@ private slots:
QCOMPARE(UpdateOperation::Error(noArgumentsOperation.error()),
UpdateOperation::InvalidArguments);
- QString compareString("Missing argument(s) 'path; method; key; value' calling 'Settings' "
- "with arguments ''.");
+ QString compareString("Missing argument(s) \"path; method; key; value\" calling Settings "
+ "with arguments \"\".");
QCOMPARE(noArgumentsOperation.errorString(), compareString);
// same for undo
QCOMPARE(noArgumentsOperation.undoOperation(), false);
- SettingsOperation wrongMethodArgumentOperation;
+ SettingsOperation wrongMethodArgumentOperation(0);
wrongMethodArgumentOperation.setArguments(QStringList() << "path=first" << "method=second"
<< "key=third" << "value=fourth");
@@ -87,8 +87,8 @@ private slots:
QCOMPARE(UpdateOperation::Error(wrongMethodArgumentOperation.error()),
UpdateOperation::InvalidArguments);
- compareString = "Current method argument calling 'Settings' with arguments 'path=first; "
- "method=second; key=third; value=fourth' is not supported. Please use set, remove, "
+ compareString = "Current method argument calling \"Settings\" with arguments \"path=first; "
+ "method=second; key=third; value=fourth\" is not supported. Please use set, remove, "
"add_array_value or remove_array_value.";
QCOMPARE(wrongMethodArgumentOperation.errorString(), compareString);
@@ -109,14 +109,14 @@ private slots:
testSettings.setValue(key, value);
}
- SettingsOperation settingsOperation;
+ SettingsOperation settingsOperation(0);
settingsOperation.setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
"method=set" << QString("key=%1").arg(key) << QString("value=%1").arg(value));
settingsOperation.backup();
QVERIFY2(settingsOperation.performOperation(), settingsOperation.errorString().toLatin1());
- QVERIFY2(compareFiles(verifyFilePath, testFilePath), QString("'%1' and '%2' are different")
+ QVERIFY2(compareFiles(verifyFilePath, testFilePath), QString("\"%1\" and \"%2\" are different.")
.arg(verifyFilePath, testFilePath).toLatin1());
}
@@ -127,7 +127,7 @@ private slots:
const QString key = "key";
const QString value = "value";
- SettingsOperation settingsOperation;
+ SettingsOperation settingsOperation(0);
settingsOperation.setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
"method=set" << QString("key=%1").arg(key) << QString("value=%1").arg(value));
settingsOperation.backup();
@@ -154,7 +154,7 @@ private slots:
}
QCOMPARE(testValueString.isEmpty(), false);
- SettingsOperation settingsOperation;
+ SettingsOperation settingsOperation(0);
settingsOperation.setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
"method=remove" << QString("key=%1").arg(key));
settingsOperation.backup();
@@ -189,10 +189,10 @@ private slots:
testFile.close();
QMap<QString, SettingsOperation*> testSettingsOperationMap;
- testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation;
- testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation;
- testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation;
- testSettingsOperationMap["testcategory/categoryarrayvalue4"] = new SettingsOperation;
+ testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation(0);
+ testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation(0);
+ testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation(0);
+ testSettingsOperationMap["testcategory/categoryarrayvalue4"] = new SettingsOperation(0);
QMap<QString, SettingsOperation*>::iterator i = testSettingsOperationMap.begin();
while (i != testSettingsOperationMap.end()) {
@@ -256,9 +256,9 @@ private slots:
testFile.close();
QMap<QString, SettingsOperation*> testSettingsOperationMap;
- testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation;
- testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation;
- testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation;
+ testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation(0);
+ testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation(0);
+ testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation(0);
QMap<QString, SettingsOperation*>::iterator i = testSettingsOperationMap.begin();
while (i != testSettingsOperationMap.end()) {
diff --git a/tests/auto/installer/solver/tst_solver.cpp b/tests/auto/installer/solver/tst_solver.cpp
index 5ccf0b2c8..5829621f2 100644
--- a/tests/auto/installer/solver/tst_solver.cpp
+++ b/tests/auto/installer/solver/tst_solver.cpp
@@ -155,15 +155,19 @@ private slots:
componentA->appendComponent(componentAA);
componentA->appendComponent(componentAB);
NamedComponent *componentB = new NamedComponent(core, QLatin1String("B"));
+ NamedComponent *componentB_NewVersion = new NamedComponent(core, QLatin1String("B_version"), QLatin1String("2.0.0"));
componentB->addDependency(QLatin1String("A.B"));
+ componentAB->addDependency(QLatin1String("B_version->=2.0.0"));
core->appendRootComponent(componentA);
core->appendRootComponent(componentB);
+ core->appendRootComponent(componentB_NewVersion);
QTest::newRow("Installer resolved") << core
<< (QList<Component *>() << componentB)
- << (QList<Component *>() << componentAB << componentB)
+ << (QList<Component *>() << componentB_NewVersion << componentAB << componentB)
<< (QList<int>()
<< InstallerCalculator::Dependent
+ << InstallerCalculator::Dependent
<< InstallerCalculator::Resolved);
}
@@ -186,6 +190,40 @@ private slots:
delete core;
}
+ void unresolvedDependencyVersion_data()
+ {
+ QTest::addColumn<PackageManagerCore *>("core");
+ QTest::addColumn<QList<Component *> >("selectedComponents");
+ QTest::addColumn<QList<Component *> >("expectedResult");
+
+ PackageManagerCore *core = new PackageManagerCore();
+ core->setPackageManager();
+ NamedComponent *componentA = new NamedComponent(core, QLatin1String("A"));
+ NamedComponent *componentB = new NamedComponent(core, QLatin1String("B"), QLatin1String("1.0.0"));
+ componentA->addDependency(QLatin1String("B->=2.0.0"));
+ core->appendRootComponent(componentA);
+ core->appendRootComponent(componentB);
+
+ QTest::newRow("Installer resolved") << core
+ << (QList<Component *>() << componentA)
+ << (QList<Component *>());
+ }
+
+ void unresolvedDependencyVersion()
+ {
+ QFETCH(PackageManagerCore *, core);
+ QFETCH(QList<Component *> , selectedComponents);
+ QFETCH(QList<Component *> , expectedResult);
+
+ InstallerCalculator calc(core->components(PackageManagerCore::ComponentType::AllNoReplacements));
+ QTest::ignoreMessage(QtWarningMsg, "Cannot find missing dependency \"B->=2.0.0\" for \"A\".");
+ calc.appendComponentsToInstall(selectedComponents);
+
+ QList<Component *> result = calc.orderedComponentsToInstall();
+ QCOMPARE(result.count(), expectedResult.count());
+ delete core;
+ }
+
void resolveUninstaller_data()
{
QTest::addColumn<PackageManagerCore *>("core");
diff --git a/tests/auto/installer/unicodeexecutable/main.c b/tests/auto/installer/unicodeexecutable/main.c
new file mode 100644
index 000000000..d82e0cb60
--- /dev/null
+++ b/tests/auto/installer/unicodeexecutable/main.c
@@ -0,0 +1,54 @@
+/**************************************************************************
+**
+** Copyright (C) 2016 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 "stringdata.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+ assert(argc == 3 || !"incorrect number of arguments");
+
+ if (!strcmp(argv[1], "utf8")) {
+ printf("%s", utf8Text);
+ } else {
+ printf("%s", asciiText);
+ }
+
+ return atoi(argv[2]);
+}
+
diff --git a/tests/auto/installer/unicodeexecutable/stringdata.h b/tests/auto/installer/unicodeexecutable/stringdata.h
new file mode 100644
index 000000000..901fac31a
--- /dev/null
+++ b/tests/auto/installer/unicodeexecutable/stringdata.h
@@ -0,0 +1,41 @@
+/**************************************************************************
+**
+** Copyright (C) 2016 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 STRINGDATA_H
+#define STRINGDATA_H
+
+const char asciiText[] = "This is some ASCII text.";
+const char utf8Text[] = "\x46\x6F\x6F\x20\xC2\xA9\x20\x62\x61\x72\x20\xF0\x9D\x8C\x86\x20\x62\x61\x7A\x20\xE2\x98\x83\x20\x71\x75\x78";
+
+#endif // !defined(STRINGDATA_H)
diff --git a/tests/auto/installer/unicodeexecutable/unicodeexecutable.pro b/tests/auto/installer/unicodeexecutable/unicodeexecutable.pro
new file mode 100644
index 000000000..742a8b168
--- /dev/null
+++ b/tests/auto/installer/unicodeexecutable/unicodeexecutable.pro
@@ -0,0 +1,8 @@
+SOURCES = main.c
+
+CONFIG -= qt app_bundle
+CONFIG += console
+
+win32: DESTDIR = $$OUT_PWD
+
+QT =
diff --git a/tests/downloadspeed/main.cpp b/tests/downloadspeed/main.cpp
index 9b896f576..d4249e0f9 100644
--- a/tests/downloadspeed/main.cpp
+++ b/tests/downloadspeed/main.cpp
@@ -26,8 +26,8 @@
**
**************************************************************************/
-#include <kdupdaterfiledownloader.h>
-#include <kdupdaterfiledownloaderfactory.h>
+#include <filedownloader.h>
+#include <filedownloaderfactory.h>
#include <fileutils.h>
@@ -159,16 +159,16 @@ int main(int argc, char *argv[])
loader->setProxyFactory(new ProxyFactory());
Receiver r;
- r.connect(loader, SIGNAL(downloadStarted()), &r, SLOT(downloadStarted()));
- r.connect(loader, SIGNAL(downloadCanceled()), &r, SLOT(downloadFinished()));
- r.connect(loader, SIGNAL(downloadCompleted()), &r, SLOT(downloadFinished()));
- r.connect(loader, SIGNAL(downloadAborted(QString)), &r, SLOT(downloadAborted(QString)));
+ r.connect(loader, &KDUpdater::FileDownloader::downloadStarted, &r, &Receiver::downloadStarted);
+ r.connect(loader, &KDUpdater::FileDownloader::downloadCanceled, &r, &Receiver::downloadFinished);
+ r.connect(loader, &KDUpdater::FileDownloader::downloadCompleted, &r, &Receiver::downloadFinished);
+ r.connect(loader, &KDUpdater::FileDownloader::downloadAborted, &r, &Receiver::downloadAborted);
- r.connect(loader, SIGNAL(downloadSpeed(qint64)), &r, SLOT(downloadSpeed(qint64)));
- r.connect(loader, SIGNAL(downloadStatus(QString)), &r, SLOT(downloadStatus(QString)));
+ r.connect(loader, &KDUpdater::FileDownloader::downloadSpeed, &r, &Receiver::downloadSpeed);
+ r.connect(loader, &KDUpdater::FileDownloader::downloadStatus, &r, &Receiver::downloadStatus);
r.connect(loader, SIGNAL(downloadProgress(double)), &r, SLOT(downloadProgress(double)));
- r.connect(loader, SIGNAL(estimatedDownloadTime(int)), &r, SLOT(estimatedDownloadTime(int)));
- r.connect(loader, SIGNAL(downloadProgress(qint64, qint64)), &r, SLOT(downloadProgress(qint64, qint64)));
+ r.connect(loader, &KDUpdater::FileDownloader::estimatedDownloadTime, &r, &Receiver::estimatedDownloadTime);
+ r.connect(loader, SIGNAL(downloadProgress(qint64,qint64)), &r, SLOT(downloadProgress(qint64,qint64)));
loader->download();
while (!r.downloaded())
diff --git a/tests/environmentvariable/environmentvariabletest.cpp b/tests/environmentvariable/environmentvariabletest.cpp
index 81062532c..802be2077 100644
--- a/tests/environmentvariable/environmentvariabletest.cpp
+++ b/tests/environmentvariable/environmentvariabletest.cpp
@@ -31,8 +31,6 @@
#include "init.h"
-#include <kdupdaterapplication.h>
-
#include <QDir>
#include <QDirIterator>
#include <QFileInfo>
@@ -49,10 +47,9 @@ void EnvironmentVariableTest::testPersistentNonSystem()
#ifndef Q_OS_WIN
QSKIP("This operation only works on Windows");
#endif
- KDUpdater::Application app;
QString key = QLatin1String("IFW_TestKey");
QString value = QLatin1String("IFW_TestValue");
- QInstaller::EnvironmentVariableOperation op;
+ QInstaller::EnvironmentVariableOperation op(0);
op.setArguments( QStringList() << key
<< value
<< QLatin1String("true")
@@ -78,10 +75,9 @@ void EnvironmentVariableTest::testNonPersistentNonSystem()
#ifndef Q_OS_WIN
QSKIP("This operation only works on Windows");
#endif
- KDUpdater::Application app;
QString key = QLatin1String("IFW_TestKey");
QString value = QLatin1String("IFW_TestValue");
- QInstaller::EnvironmentVariableOperation op;
+ QInstaller::EnvironmentVariableOperation op(0);
op.setArguments( QStringList() << key
<< value
<< QLatin1String("false")
diff --git a/tests/tests.pro b/tests/tests.pro
index 1e8963ed2..318579000 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -1,4 +1,3 @@
-CONFIG += ordered
TEMPLATE = subdirs
SUBDIRS = \
diff --git a/tools/archivegen/archive.cpp b/tools/archivegen/archive.cpp
index 97c82cec2..eac794585 100644
--- a/tools/archivegen/archive.cpp
+++ b/tools/archivegen/archive.cpp
@@ -25,47 +25,178 @@
** $QT_END_LICENSE$
**
**************************************************************************/
-#include "common/repositorygen.h"
#include <errors.h>
-#include <init.h>
+#include <lib7z_create.h>
#include <lib7z_facade.h>
#include <utils.h>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QFileInfo>
-#include <QtCore/QStringList>
+#include <QCoreApplication>
+#include <QCommandLineParser>
+#include <QDir>
#include <iostream>
-using namespace Lib7z;
using namespace QInstaller;
-static void printUsage()
+class FailOnErrorCallback : public Lib7z::UpdateCallback
{
- std::cout << "Usage: " << QFileInfo(QCoreApplication::applicationFilePath()).fileName()
- << " directory.7z [files | directories]" << std::endl;
-}
+ HRESULT OpenFileError(const wchar_t*, DWORD) {
+ return S_FALSE;
+ }
+
+ HRESULT CanNotFindError(const wchar_t*, DWORD) {
+ return S_FALSE;
+ }
+
+ HRESULT OpenResult(const wchar_t*, HRESULT result, const wchar_t*) {
+ return result;
+ }
+};
+
+class VerbosePrinterCallback : public Lib7z::UpdateCallback
+{
+public:
+ ~VerbosePrinterCallback() {
+ m_PercentPrinter.ClosePrint();
+ }
+
+private:
+ HRESULT SetTotal(UInt64 size) {
+ m_PercentPrinter.SetTotal(size);
+ return S_OK;
+ }
+
+ HRESULT SetCompleted(const UInt64 *size) {
+ if (size) {
+ m_PercentPrinter.SetRatio(*size);
+ m_PercentPrinter.PrintRatio();
+ }
+ return S_OK;
+ }
+
+ HRESULT OpenResult(const wchar_t *file, HRESULT result, const wchar_t*) {
+ if (result != S_OK) {
+ printBlock(QCoreApplication::translate("archivegen", "Cannot update file \"%1\". "
+ "Unsupported archive.").arg(QDir::toNativeSeparators(QString::fromWCharArray(file))), Q_NULLPTR);
+ }
+ return result;
+ }
+
+ HRESULT OpenFileError(const wchar_t *file, DWORD) {
+ printBlock(QCoreApplication::translate("archivegen", "Cannot open file "), file);
+ return S_FALSE;
+ }
+
+ HRESULT CanNotFindError(const wchar_t *file, DWORD) {
+ printBlock(QCoreApplication::translate("archivegen", "Cannot find file "), file);
+ return S_FALSE;
+ }
+
+ HRESULT StartArchive(const wchar_t *name, bool) {
+ printLine(QCoreApplication::translate("archivegen", "Create archive."));
+ if (name) {
+ m_PercentPrinter.PrintNewLine();
+ m_PercentPrinter.PrintString(name);
+ }
+ return S_OK;
+ }
+
+ HRESULT FinishArchive() {
+ m_PercentPrinter.PrintNewLine();
+ printLine(QCoreApplication::translate("archivegen", "Finished archive."));
+ return S_OK;
+ }
+
+ void printLine(const QString &message) {
+ m_PercentPrinter.PrintString(message.toStdWString().c_str());
+ }
+
+ void printBlock(const QString &message, const wchar_t *message2) {
+ m_PercentPrinter.PrintNewLine();
+ m_PercentPrinter.PrintString(message.toStdWString().c_str());
+ if (message2)
+ m_PercentPrinter.PrintString(message2);
+ m_PercentPrinter.PrintNewLine();
+ }
+
+ Lib7z::PercentPrinter m_PercentPrinter;
+};
int main(int argc, char *argv[])
{
try {
QCoreApplication app(argc, argv);
+#define QUOTE_(x) #x
+#define QUOTE(x) QUOTE_(x)
+ QCoreApplication::setApplicationVersion(QLatin1String(QUOTE(IFW_VERSION_STR)));
+#undef QUOTE
+#undef QUOTE_
+
+ QCommandLineParser parser;
+ const QCommandLineOption help = parser.addHelpOption();
+ const QCommandLineOption version = parser.addVersionOption();
+ QCommandLineOption verbose(QLatin1String("verbose"),
+ QCoreApplication::translate("archivegen", "Verbose mode. Prints out more information."));
+ const QCommandLineOption compression = QCommandLineOption(QStringList()
+ << QLatin1String("c") << QLatin1String("compression"),
+ QCoreApplication::translate("archivegen",
+ "0 (No compression)\n"
+ "1 (Fastest compressing)\n"
+ "3 (Fast compressing)\n"
+ "5 (Normal compressing)\n"
+ "7 (Maximum compressing)\n"
+ "9 (Ultra compressing)\n"
+ "Defaults to 5 (Normal compression)."
+ ), QLatin1String("5"), QLatin1String("5"));
+
+ parser.addOption(verbose);
+ parser.addOption(compression);
+ parser.addPositionalArgument(QLatin1String("archive"),
+ QCoreApplication::translate("archivegen", "Compressed archive to create."));
+ parser.addPositionalArgument(QLatin1String("sources"),
+ QCoreApplication::translate("archivegen", "List of files and directories to compress."));
+
+ parser.parse(app.arguments());
+ if (parser.isSet(help)) {
+ std::cout << parser.helpText() << std::endl;
+ return EXIT_SUCCESS;
+ }
- if (app.arguments().count() < 3) {
- printUsage();
+ if (parser.isSet(version)) {
+ parser.showVersion();
+ return EXIT_SUCCESS;
+ }
+
+ const QStringList args = parser.positionalArguments();
+ if (args.count() < 2) {
+ std::cerr << QCoreApplication::translate("archivegen", "Wrong argument count. See "
+ "'archivgen --help'.") << std::endl;
return EXIT_FAILURE;
}
- QInstaller::init();
- QInstaller::setVerbose(true);
- const QStringList sourceDirectories = app.arguments().mid(2);
- QInstallerTools::compressPaths(sourceDirectories, app.arguments().at(1));
+ bool ok = false;
+ const int values[6] = { 0, 1, 3, 5, 7, 9 };
+ const int value = parser.value(compression).toInt(&ok);
+ if (!ok || (std::find(std::begin(values), std::end(values), value) == std::end(values))) {
+ throw QInstaller::Error(QCoreApplication::translate("archivegen",
+ "Unknown compression level \"%1\". See 'archivgen --help'.").arg(value));
+ }
+
+ Lib7z::initSevenZ();
+ Lib7z::createArchive(args[0], args.mid(1), Lib7z::QTmpFile::No, Lib7z::Compression(value),
+ [&] () -> Lib7z::UpdateCallback * {
+ if (parser.isSet(verbose))
+ return new VerbosePrinterCallback;
+ return new FailOnErrorCallback;
+ } ()
+ );
return EXIT_SUCCESS;
- } catch (const Lib7z::SevenZipException &e) {
- std::cerr << "caught 7zip exception: " << e.message() << std::endl;
} catch (const QInstaller::Error &e) {
- std::cerr << "caught exception: " << e.message() << std::endl;
+ std::cerr << e.message() << std::endl;
+ } catch (...) {
+ std::cerr << QCoreApplication::translate("archivegen", "Unknown exception caught.")
+ << std::endl;
}
return EXIT_FAILURE;
}
diff --git a/tools/archivegen/archivegen.pro b/tools/archivegen/archivegen.pro
index da4d4b2ec..2cb8b6bdc 100644
--- a/tools/archivegen/archivegen.pro
+++ b/tools/archivegen/archivegen.pro
@@ -7,6 +7,7 @@ include(../../installerfw.pri)
QT -= gui
QT += qml xml
+LIBS += -l7z
CONFIG += console
DESTDIR = $$IFW_APP_PATH
diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp
index 270440310..1d57b0d55 100644
--- a/tools/binarycreator/binarycreator.cpp
+++ b/tools/binarycreator/binarycreator.cpp
@@ -99,7 +99,7 @@ static void chmod755(const QString &absolutFilePath)
}
#endif
-static int assemble(Input input, const QInstaller::Settings &settings)
+static int assemble(Input input, const QInstaller::Settings &settings, const QString &signingIdentity)
{
#ifdef Q_OS_OSX
if (QInstaller::isInBundle(input.installerExePath)) {
@@ -154,34 +154,34 @@ static int assemble(Input input, const QInstaller::Settings &settings)
infoPList.open(QIODevice::WriteOnly);
QTextStream plistStream(&infoPList);
plistStream << QLatin1String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") << endl;
- plistStream << QLatin1String("<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs"
- "/PropertyList.dtd\">") << endl;
- plistStream << QLatin1String("<plist version=\"0.9\">") << endl;
+ plistStream << QLatin1String("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
+ "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">") << endl;
+ plistStream << QLatin1String("<plist version=\"1.0\">") << endl;
plistStream << QLatin1String("<dict>") << endl;
- plistStream << QLatin1String(" <key>CFBundleIconFile</key>") << endl;
- plistStream << QLatin1String(" <string>") << iconTargetFile << QLatin1String("</string>")
+ plistStream << QLatin1String("\t<key>CFBundleIconFile</key>") << endl;
+ plistStream << QLatin1String("\t<string>") << iconTargetFile << QLatin1String("</string>")
<< endl;
- plistStream << QLatin1String(" <key>CFBundlePackageType</key>") << endl;
- plistStream << QLatin1String(" <string>APPL</string>") << endl;
- plistStream << QLatin1String(" <key>CFBundleGetInfoString</key>") << endl;
+ plistStream << QLatin1String("\t<key>CFBundlePackageType</key>") << endl;
+ plistStream << QLatin1String("\t<string>APPL</string>") << endl;
+ plistStream << QLatin1String("\t<key>CFBundleGetInfoString</key>") << endl;
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
- plistStream << QLatin1String(" <string>") << QLatin1String(QUOTE(IFW_VERSION_STR)) << ("</string>")
+ plistStream << QLatin1String("\t<string>") << QLatin1String(QUOTE(IFW_VERSION_STR)) << ("</string>")
<< endl;
#undef QUOTE
#undef QUOTE_
- plistStream << QLatin1String(" <key>CFBundleSignature</key>") << endl;
- plistStream << QLatin1String(" <string> ???? </string>") << endl;
- plistStream << QLatin1String(" <key>CFBundleExecutable</key>") << endl;
- plistStream << QLatin1String(" <string>") << fi.completeBaseName() << QLatin1String("</string>")
+ plistStream << QLatin1String("\t<key>CFBundleSignature</key>") << endl;
+ plistStream << QLatin1String("\t<string>\?\?\?\?</string>") << endl;
+ plistStream << QLatin1String("\t<key>CFBundleExecutable</key>") << endl;
+ plistStream << QLatin1String("\t<string>") << fi.completeBaseName() << QLatin1String("</string>")
<< endl;
- plistStream << QLatin1String(" <key>CFBundleIdentifier</key>") << endl;
- plistStream << QLatin1String(" <string>com.yourcompany.installerbase</string>") << endl;
- plistStream << QLatin1String(" <key>NOTE</key>") << endl;
- plistStream << QLatin1String(" <string>This file was generated by Qt Installer Framework.</string>")
+ plistStream << QLatin1String("\t<key>CFBundleIdentifier</key>") << endl;
+ plistStream << QLatin1String("\t<string>com.yourcompany.installerbase</string>") << endl;
+ plistStream << QLatin1String("\t<key>NOTE</key>") << endl;
+ plistStream << QLatin1String("\t<string>This file was generated by Qt Installer Framework.</string>")
<< endl;
- plistStream << QLatin1String(" <key>NSPrincipalClass</key>") << endl;
- plistStream << QLatin1String(" <string>NSApplication</string>") << endl;
+ plistStream << QLatin1String("\t<key>NSPrincipalClass</key>") << endl;
+ plistStream << QLatin1String("\t<string>NSApplication</string>") << endl;
plistStream << QLatin1String("</dict>") << endl;
plistStream << QLatin1String("</plist>") << endl;
@@ -194,7 +194,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
QTemporaryFile file(input.outputPath);
if (!file.open()) {
- throw Error(QString::fromLatin1("Could not copy %1 to %2: %3").arg(input.installerExePath,
+ throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(input.installerExePath,
input.outputPath, file.errorString()));
}
@@ -204,7 +204,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
QFile instExe(input.installerExePath);
if (!instExe.copy(tempFile)) {
- throw Error(QString::fromLatin1("Could not copy %1 to %2: %3").arg(instExe.fileName(),
+ throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(instExe.fileName(),
tempFile, instExe.errorString()));
}
@@ -229,7 +229,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
chmod755(copyscript);
QProcess p;
p.start(copyscript, QStringList() << bundle);
- p.waitForFinished();
+ p.waitForFinished(-1);
QFile::rename(input.outputPath, tempFile);
QFile::remove(copyscript);
}
@@ -247,7 +247,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
{
QFile target(targetName);
if (target.exists() && !target.remove()) {
- qCritical("Could not remove target %s: %s", qPrintable(target.fileName()),
+ qCritical("Cannot remove target %s: %s", qPrintable(target.fileName()),
qPrintable(target.errorString()));
QFile::remove(tempFile);
return EXIT_FAILURE;
@@ -260,7 +260,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
#ifdef Q_OS_OSX
if (!exe.copy(input.outputPath)) {
- throw Error(QString::fromLatin1("Could not copy %1 to %2: %3").arg(exe.fileName(),
+ throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(exe.fileName(),
input.outputPath, exe.errorString()));
}
#else
@@ -275,8 +275,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
qDebug() << "Creating resource archive for" << info.name;
foreach (const QString &file, info.copiedFiles) {
const QSharedPointer<Resource> resource(new Resource(file));
- qDebug() << QString::fromLatin1("Appending %1 (%2)").arg(file,
- humanReadableSize(resource->size()));
+ qDebug().nospace() << "Appending " << file << " (" << humanReadableSize(resource->size()) << ")";
collection.appendResource(resource);
}
input.manager.insertCollection(collection);
@@ -292,7 +291,7 @@ static int assemble(Input input, const QInstaller::Settings &settings)
}
if (!out.rename(targetName)) {
- qCritical("Could not write installer to %s: %s", targetName.toUtf8().constData(),
+ qCritical("Cannot write installer to %s: %s", targetName.toUtf8().constData(),
out.errorString().toUtf8().constData());
QFile::remove(tempFile);
return EXIT_FAILURE;
@@ -305,21 +304,66 @@ static int assemble(Input input, const QInstaller::Settings &settings)
QFile::remove(tempFile);
#ifdef Q_OS_OSX
+ if (isBundle && !signingIdentity.isEmpty()) {
+ qDebug() << "Signing .app bundle...";
+
+ QProcess p;
+ p.start(QLatin1String("codesign"),
+ QStringList() << QLatin1String("--force")
+ << QLatin1String("--deep")
+ << QLatin1String("--sign") << signingIdentity
+ << bundle);
+
+ if (!p.waitForFinished(-1)) {
+ qCritical("Failed to sign app bundle: error while running '%s %s': %s",
+ p.program().toUtf8().constData(),
+ p.arguments().join(QLatin1Char(' ')).toUtf8().constData(),
+ p.errorString().toUtf8().constData());
+ return EXIT_FAILURE;
+ }
+
+ if (p.exitStatus() == QProcess::NormalExit) {
+ if (p.exitCode() != 0) {
+ qCritical("Failed to sign app bundle: running codesign failed "
+ "with exit code %d: %s", p.exitCode(),
+ p.readAllStandardError().constData());
+ return EXIT_FAILURE;
+ }
+ }
+
+ qDebug() << "done.";
+ }
+
bundleBackup.release();
if (createDMG) {
qDebug() << "creating a DMG disk image...";
- // no error handling as this is not fatal
- const QString mkdmgscript = QDir::temp().absoluteFilePath(QLatin1String("mkdmg.sh"));
- QFile::copy(QLatin1String(":/resources/mkdmg.sh"), mkdmgscript);
- chmod755(mkdmgscript);
+ const QString volumeName = QFileInfo(input.outputPath).fileName();
+ const QString imagePath = QString::fromLatin1("%1/%2.dmg")
+ .arg(QFileInfo(bundle).path())
+ .arg(volumeName);
+
+ // no error handling as this is not fatal
QProcess p;
- p.start(mkdmgscript, QStringList() << QFileInfo(input.outputPath).fileName() << bundle);
- p.waitForFinished();
- QFile::remove(mkdmgscript);
- qDebug() << "done." << mkdmgscript;
+ p.start(QLatin1String("/usr/bin/hdiutil"),
+ QStringList() << QLatin1String("create")
+ << imagePath
+ << QLatin1String("-srcfolder")
+ << bundle
+ << QLatin1String("-ov")
+ << QLatin1String("-volname")
+ << volumeName
+ << QLatin1String("-fs")
+ << QLatin1String("HFS+"));
+ qDebug() << "running " << p.program() << p.arguments();
+ p.waitForFinished(-1);
+ qDebug() << "removing" << bundle;
+ QDir(bundle).removeRecursively();
+ qDebug() << "done.";
}
+#else
+ Q_UNUSED(signingIdentity)
#endif
return EXIT_SUCCESS;
}
@@ -368,7 +412,7 @@ static QSharedPointer<QInstaller::Resource> createDefaultResourceFile(const QStr
{
QTemporaryFile projectFile(directory + QLatin1String("/rccprojectXXXXXX.qrc"));
if (!projectFile.open())
- throw Error(QString::fromLatin1("Could not create temporary file for generated rcc project file"));
+ throw Error(QString::fromLatin1("Cannot create temporary file for generated rcc project file"));
projectFile.close();
const WorkingDirectoryChange wd(directory);
@@ -377,13 +421,13 @@ static QSharedPointer<QInstaller::Resource> createDefaultResourceFile(const QStr
// 1. create the .qrc file
if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-project") << QLatin1String("-o")
<< projectFileName) != EXIT_SUCCESS) {
- throw Error(QString::fromLatin1("Could not create rcc project file."));
+ throw Error(QString::fromLatin1("Cannot create rcc project file."));
}
// 2. create the binary resource file from the .qrc file
if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-binary") << QLatin1String("-o")
<< binaryName << projectFileName) != EXIT_SUCCESS) {
- throw Error(QString::fromLatin1("Could not compile rcc project file."));
+ throw Error(QString::fromLatin1("Cannot compile rcc project file."));
}
return QSharedPointer<QInstaller::Resource>(new QInstaller::Resource(binaryName, binaryName
@@ -442,6 +486,10 @@ static void printUsage()
std::cout << " -rcc|--compile-resource Compiles the default resource and outputs the result into"
<< std::endl;
std::cout << " 'update.rcc' in the current path." << std::endl;
+#ifdef Q_OS_OSX
+ std::cout << " -s|--sign identity Sign generated app bundle using the given code " << std::endl;
+ std::cout << " signing identity" << std::endl;
+#endif
std::cout << std::endl;
std::cout << "Packages are to be found in the current working directory and get listed as "
"their names" << std::endl << std::endl;
@@ -488,7 +536,7 @@ void copyConfigData(const QString &configFile, const QString &targetDir)
const QString tagName = domElement.tagName();
const QString elementText = domElement.text();
- qDebug() << QString::fromLatin1("Read dom element: <%1>%2</%1>.").arg(tagName, elementText);
+ qDebug().noquote() << QString::fromLatin1("Read dom element: <%1>%2</%1>.").arg(tagName, elementText);
QString newName = domElement.text().replace(QRegExp(QLatin1String("\\\\|/|\\.|:")),
QLatin1String("_"));
@@ -557,6 +605,7 @@ int main(int argc, char **argv)
QStringList filteredPackages;
QInstallerTools::FilterType ftype = QInstallerTools::Exclude;
bool compileResource = false;
+ QString signingIdentity;
const QStringList args = app.arguments().mid(1);
for (QStringList::const_iterator it = args.begin(); it != args.end(); ++it) {
@@ -644,6 +693,13 @@ int main(int argc, char **argv)
continue;
} else if (*it == QLatin1String("-rcc") || *it == QLatin1String("--compile-resource")) {
compileResource = true;
+#ifdef Q_OS_OSX
+ } else if (*it == QLatin1String("-s") || *it == QLatin1String("--sign")) {
+ ++it;
+ if (it == args.end() || it->startsWith(QLatin1String("-")))
+ return printErrorAndUsageAndExit(QString::fromLatin1("Error: No code signing identity specified."));
+ signingIdentity = *it;
+#endif
} else {
if (it->startsWith(QLatin1String("-"))) {
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Unknown option \"%1\" used. Maybe you "
@@ -715,8 +771,11 @@ int main(int argc, char **argv)
{
QSettings confInternal(tmpMetaDir + QLatin1String("/config/config-internal.ini")
, QSettings::IniFormat);
- // assume offline installer if there are no repositories
- offlineOnly |= settings.repositories().isEmpty();
+ // assume offline installer if there are no repositories and no
+ //--online-only not set
+ offlineOnly = offlineOnly | settings.repositories().isEmpty();
+ if (onlineOnly)
+ offlineOnly = !onlineOnly;
confInternal.setValue(QLatin1String("offlineOnly"), offlineOnly);
}
@@ -738,7 +797,7 @@ int main(int argc, char **argv)
input.installerExePath = templateBinary;
qDebug() << "Creating the binary";
- exitCode = assemble(input, settings);
+ exitCode = assemble(input, settings, signingIdentity);
} else {
createDefaultResourceFile(tmpMetaDir, QDir::currentPath() + QLatin1String("/update.rcc"));
exitCode = EXIT_SUCCESS;
diff --git a/tools/binarycreator/binarycreator.qrc b/tools/binarycreator/binarycreator.qrc
index a32a88e27..b64e3a21a 100644
--- a/tools/binarycreator/binarycreator.qrc
+++ b/tools/binarycreator/binarycreator.qrc
@@ -2,7 +2,6 @@
<qresource>
<file>resources/default_icon_mac.icns</file>
<file>resources/copylibsintobundle.sh</file>
- <file>resources/mkdmg.sh</file>
<file alias="resources/installerbase.ico">../../src/sdk/installerbase.ico</file>
</qresource>
</RCC>
diff --git a/tools/binarycreator/rcc/rcc.cpp b/tools/binarycreator/rcc/rcc.cpp
index ce19d5e42..2361e43e0 100644
--- a/tools/binarycreator/rcc/rcc.cpp
+++ b/tools/binarycreator/rcc/rcc.cpp
@@ -709,25 +709,25 @@ bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &errorDevice)
if (m_verbose)
m_errorDevice->write("Outputting code\n");
if (!writeHeader()) {
- m_errorDevice->write("Could not write header\n");
+ m_errorDevice->write("Cannot write header\n");
return false;
}
if (m_root) {
if (!writeDataBlobs()) {
- m_errorDevice->write("Could not write data blobs.\n");
+ m_errorDevice->write("Cannot write data blobs.\n");
return false;
}
if (!writeDataNames()) {
- m_errorDevice->write("Could not write file names\n");
+ m_errorDevice->write("Cannot write file names\n");
return false;
}
if (!writeDataStructure()) {
- m_errorDevice->write("Could not write data tree\n");
+ m_errorDevice->write("Cannot write data tree\n");
return false;
}
}
if (!writeInitializer()) {
- m_errorDevice->write("Could not write footer\n");
+ m_errorDevice->write("Cannot write footer\n");
return false;
}
outDevice.write(m_out.constData(), m_out.size());
diff --git a/tools/binarycreator/resources/mkdmg.sh b/tools/binarycreator/resources/mkdmg.sh
deleted file mode 100644
index 7c6467ed7..000000000
--- a/tools/binarycreator/resources/mkdmg.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/bin/sh
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the Qt Installer Framework.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-#
-# Creates a disk image (dmg) on Mac OS X from the command line.
-# usage:
-# mkdmg <volname> <vers> <srcdir>
-#
-# Where <volname> is the name to use for the mounted image, <vers> is the version
-# number of the volume and <srcdir> is where the contents to put on the dmg are.
-#
-# The result will be a file called <volname>-<vers>.dmg
-
-if [ $# != 2 ]; then
- echo "usage: mkdmg.sh volname srcdir"
- exit 0
-fi
-
-VOL="$1"
-FILES="$2"
-PATHNAME=`dirname $FILES`
-
-DMG=`mktemp "/tmp/$VOL.XXXXXX.dmg"`
-
-# create temporary disk image and format, ejecting when done
-SIZE=`du -sk ${FILES} | sed -n 's,^\([0-9]*\).*,\1,p'`
-SIZE=$((${SIZE}/1000+1))
-hdiutil create "$DMG" -megabytes ${SIZE} -ov -volname "$VOL" -type UDIF -fs HFS+ >/dev/null
-DISK=`hdid "$DMG" | sed -ne 's,^\(.*\) *Apple_H.*,\1,p'`
-MOUNT=`hdid "$DMG" | sed -ne 's,^.*Apple_HFS[^/]*\(/.*\)$,\1,p'`
-
-# mount and copy files onto volume
-cp -R "$PATHNAME/`basename $FILES`" "$MOUNT"
-hdiutil eject $DISK >/dev/null
-
-# convert to compressed image, delete temp image
-rm -f "$PATHNAME/${VOL}.dmg"
-hdiutil convert "$DMG" -format UDZO -o "$PATHNAME/${VOL}.dmg" >/dev/null
-rm -f "$DMG"
diff --git a/tools/common/repositorygen.cpp b/tools/common/repositorygen.cpp
index a2b4fd5f4..4c7dba3b4 100644
--- a/tools/common/repositorygen.cpp
+++ b/tools/common/repositorygen.cpp
@@ -31,13 +31,15 @@
#include <fileutils.h>
#include <errors.h>
#include <globals.h>
+#include <lib7z_create.h>
#include <lib7z_facade.h>
+#include <lib7z_list.h>
#include <settings.h>
#include <qinstallerglobal.h>
#include <utils.h>
#include <scriptengine.h>
-#include <kdupdater.h>
+#include <updater.h>
#include <QtCore/QDirIterator>
#include <QtCore/QRegExp>
@@ -70,7 +72,7 @@ QString QInstallerTools::makePathAbsolute(const QString &path)
void QInstallerTools::copyWithException(const QString &source, const QString &target, const QString &kind)
{
- qDebug() << QString::fromLatin1("Copying associated %1 file '%2'").arg(kind, source);
+ qDebug() << "Copying associated" << kind << "file" << source;
const QFileInfo targetFileInfo(target);
if (!targetFileInfo.dir().exists())
@@ -79,8 +81,8 @@ void QInstallerTools::copyWithException(const QString &source, const QString &ta
QFile sourceFile(source);
if (!sourceFile.copy(target)) {
qDebug() << "failed!\n";
- throw QInstaller::Error(QString::fromLatin1("Could not copy the %1 file from\n'%2' to '%3'\nError: "
- "'%4'.").arg(kind, source, target,
+ throw QInstaller::Error(QString::fromLatin1("Cannot copy the %1 file from \"%2\" to \"%3\": "
+ "%4").arg(kind, QDir::toNativeSeparators(source), QDir::toNativeSeparators(target),
/* in case of an existing target the error String does not show the file */
(targetFileInfo.exists() ? QLatin1String("Target already exist.") : sourceFile.errorString())));
}
@@ -88,13 +90,6 @@ void QInstallerTools::copyWithException(const QString &source, const QString &ta
qDebug() << "done.\n";
}
-void QInstallerTools::compressPaths(const QStringList &paths, const QString &archivePath)
-{
- QFile archive(archivePath);
- QInstaller::openForWrite(&archive);
- Lib7z::createArchive(&archive, paths);
-}
-
static QStringList copyFilesFromNode(const QString &parentNode, const QString &childNode, const QString &attr,
const QString &kind, const QDomNode &package, const PackageInfo &info, const QString &targetDir)
{
@@ -109,8 +104,8 @@ static QStringList copyFilesFromNode(const QString &parentNode, const QString &c
const QString filter = attr.isEmpty() ? node.toElement().text() : node.toElement().attribute(attr);
const QStringList files = dir.entryList(QStringList(filter), QDir::Files);
if (files.isEmpty()) {
- throw QInstaller::Error(QString::fromLatin1("Could not find any %1 matching '%2' "
- "while copying %1 of '%3'.").arg(kind, filter, info.name));
+ throw QInstaller::Error(QString::fromLatin1("Cannot find any %1 matching \"%2\" "
+ "while copying %1 of \"%3\".").arg(kind, filter, info.name));
}
foreach (const QString &file, files) {
@@ -160,11 +155,10 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
foreach (const PackageInfo &info, packages) {
if (!QDir(targetDir).mkpath(info.name))
- throw QInstaller::Error(QString::fromLatin1("Could not create directory '%1'.").arg(info.name));
+ throw QInstaller::Error(QString::fromLatin1("Cannot create directory \"%1\".").arg(info.name));
const QString packageXmlPath = QString::fromLatin1("%1/meta/package.xml").arg(info.directory);
- qDebug() << QString::fromLatin1("Copy meta data for package '%1' using '%2'.").arg(info.name,
- packageXmlPath);
+ qDebug() << "Copy meta data for package" << info.name << "using" << packageXmlPath;
QFile file(packageXmlPath);
QInstaller::openForRead(&file);
@@ -174,8 +168,8 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
int column = 0;
QDomDocument packageXml;
if (!packageXml.setContent(&file, &errMsg, &line, &column)) {
- throw QInstaller::Error(QString::fromLatin1("Could not parse '%1': line: %2, column: %3: %4 (%5)")
- .arg(packageXmlPath).arg(line).arg(column).arg(errMsg, info.name));
+ throw QInstaller::Error(QString::fromLatin1("Cannot parse \"%1\": line: %2, column: %3: %4 (%5)")
+ .arg(QDir::toNativeSeparators(packageXmlPath)).arg(line).arg(column).arg(errMsg, info.name));
}
QDomElement update = doc.createElement(QLatin1String("PackageUpdate"));
@@ -191,6 +185,7 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
bool foundVirtual = false;
bool foundDisplayName = false;
bool foundDownloadableArchives = false;
+ bool foundCheckable = false;
const QDomNode package = packageXml.firstChildElement(QLatin1String("Package"));
const QDomNodeList childNodes = package.childNodes();
for (int i = 0; i < childNodes.count(); ++i) {
@@ -205,6 +200,8 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
foundDisplayName = true;
if (key == QLatin1String("DownloadableArchives"))
foundDownloadableArchives = true;
+ if (key == QLatin1String("Checkable"))
+ foundCheckable = true;
if (node.isComment() || blackList.contains(key))
continue; // just skip comments and some tags...
@@ -218,12 +215,17 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
if (foundDefault && foundVirtual) {
throw QInstaller::Error(QString::fromLatin1("Error: <Default> and <Virtual> elements are "
- "mutually exclusive. File: '%0'").arg(packageXmlPath));
+ "mutually exclusive in file \"%1\".").arg(QDir::toNativeSeparators(packageXmlPath)));
+ }
+
+ if (foundDefault && foundCheckable) {
+ throw QInstaller::Error(QString::fromLatin1("Error: <Default> and <Checkable>"
+ "elements are mutually exclusive in file \"%1\".")
+ .arg(QDir::toNativeSeparators(packageXmlPath)));
}
if (!foundDisplayName) {
- qWarning() << QString::fromLatin1("No DisplayName tag found at '%1', using component Name instead."
- ).arg(info.name);
+ qWarning() << "No DisplayName tag found at" << info.name << ", using component Name instead.";
QDomElement displayNameElement = doc.createElement(QLatin1String("DisplayName"));
update.appendChild(displayNameElement).appendChild(doc.createTextNode(info.name));
}
@@ -236,7 +238,7 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
const QDir dataDir = QString::fromLatin1("%1/%2/data").arg(metaDataDir, info.name);
const QFileInfoList entries = dataDir.exists() ? dataDir.entryInfoList(filters | QDir::Dirs)
: QDir(QString::fromLatin1("%1/%2").arg(metaDataDir, info.name)).entryInfoList(filters);
- qDebug() << QString::fromLatin1("calculate size of directory: %1").arg(dataDir.absolutePath());
+ qDebug() << "calculate size of directory" << dataDir.absolutePath();
foreach (const QFileInfo &fi, entries) {
try {
if (fi.isDir()) {
@@ -264,7 +266,7 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
compressedComponentSize += size;
}
} catch (const QInstaller::Error &error) {
- qDebug() << error.message();
+ qDebug().noquote() << error.message();
} catch(...) {
// ignore, that's just about the sizes - and size doesn't matter, you know?
}
@@ -284,8 +286,8 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
if (!script.isEmpty()) {
QFile scriptFile(QString::fromLatin1("%1/meta/%2").arg(info.directory, script));
if (!scriptFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- throw QInstaller::Error(QString::fromLatin1("Could not open component script: '%1'")
- .arg(scriptFile.fileName()));
+ throw QInstaller::Error(QString::fromLatin1("Cannot open component script at \"%1\".")
+ .arg(QDir::toNativeSeparators(scriptFile.fileName())));
}
const QString scriptContent = QLatin1String("(function() {")
@@ -303,8 +305,9 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
const QJSValue value = testScriptEngine.evaluate(scriptContent, scriptFile.fileName());
if (value.isError()) {
throw QInstaller::Error(QString::fromLatin1("Exception while loading component "
- "script: '%1'. (%2)").arg(scriptFile.fileName(), value.toString().isEmpty() ?
- QString::fromLatin1("Unknown error.") : value.toString()));
+ "script at \"%1\": %2").arg(QDir::toNativeSeparators(scriptFile.fileName()),
+ value.toString().isEmpty() ?
+ QString::fromLatin1("Unknown error.") : value.toString()));
}
const QString toLocation(QString::fromLatin1("%1/%2/%3").arg(targetDir, info.name, script));
@@ -383,7 +386,7 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
QFileInfoList entries;
foreach (const QString &packagesDirectory, packagesDirectories)
entries.append(QDir(packagesDirectory).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot));
- for (QFileInfoList::const_iterator it = entries.begin(); it != entries.end(); ++it) {
+ for (QFileInfoList::const_iterator it = entries.constBegin(); it != entries.constEnd(); ++it) {
if (filterType == Exclude) {
// Check for current file in exclude list, if found, skip it and remove it from exclude list
if (packagesToFilter->contains(it->fileName())) {
@@ -396,14 +399,14 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
continue;
packagesToFilter->removeAll(it->fileName());
}
- qDebug() << QString::fromLatin1("found subdirectory '%1'").arg(it->fileName());
+ qDebug() << "Found subdirectory" << it->fileName();
// because the filter is QDir::Dirs - filename means the name of the subdirectory
if (it->fileName().contains(QLatin1Char('-'))) {
if (ignoreInvalidPackages)
continue;
- throw QInstaller::Error(QString::fromLatin1("Component '%1' must not contain '-'. This is not "
+ throw QInstaller::Error(QString::fromLatin1("Component \"%1\" must not contain '-'. This is not "
"allowed, because dashes are used as the separator between the component name and the "
- "version number internally.").arg(it->fileName()));
+ "version number internally.").arg(QDir::toNativeSeparators(it->fileName())));
}
QFile file(QString::fromLatin1("%1/meta/package.xml").arg(it->filePath()));
@@ -411,8 +414,8 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
if (!fileInfo.exists()) {
if (ignoreInvalidPackages)
continue;
- throw QInstaller::Error(QString::fromLatin1("Component '%1' does not contain a package "
- "description (meta/package.xml is missing).").arg(it->fileName()));
+ throw QInstaller::Error(QString::fromLatin1("Component \"%1\" does not contain a package "
+ "description (meta/package.xml is missing).").arg(QDir::toNativeSeparators(it->fileName())));
}
file.open(QIODevice::ReadOnly);
@@ -424,21 +427,23 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
if (!doc.setContent(&file, &error, &errorLine, &errorColumn)) {
if (ignoreInvalidPackages)
continue;
- throw QInstaller::Error(QString::fromLatin1("Component package description in '%1' is invalid. "
- "Error at line: %2, column: %3 -> %4").arg(fileInfo.absoluteFilePath(), QString::number(errorLine),
- QString::number(errorColumn), error));
+ throw QInstaller::Error(QString::fromLatin1("Component package description in \"%1\" is invalid. "
+ "Error at line: %2, column: %3 -> %4").arg(QDir::toNativeSeparators(fileInfo.absoluteFilePath()),
+ QString::number(errorLine),
+ QString::number(errorColumn), error));
}
const QDomElement packageElement = doc.firstChildElement(QLatin1String("Package"));
const QString name = packageElement.firstChildElement(QLatin1String("Name")).text();
if (!name.isEmpty() && name != it->fileName()) {
- qWarning() << QString::fromLatin1("The <Name> tag in the '%1' is ignored - the installer uses the "
- "path element right before the 'meta' ('%2').").arg(fileInfo.absoluteFilePath(), it->fileName());
+ qWarning().nospace() << "The <Name> tag in the file " << fileInfo.absoluteFilePath()
+ << " is ignored - the installer uses the path element right before the 'meta'"
+ << " (" << it->fileName() << ")";
}
QString releaseDate = packageElement.firstChildElement(QLatin1String("ReleaseDate")).text();
if (releaseDate.isEmpty()) {
- qWarning("Release date for '%s' is empty! Using the current date instead.",
+ qWarning("Release date for \"%s\" is empty! Using the current date instead.",
qPrintable(fileInfo.absoluteFilePath()));
releaseDate = QDate::currentDate().toString(Qt::ISODate);
}
@@ -446,8 +451,9 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
if (!QDate::fromString(releaseDate, Qt::ISODate).isValid()) {
if (ignoreInvalidPackages)
continue;
- throw QInstaller::Error(QString::fromLatin1("Release date for '%1' is invalid! <ReleaseDate>%2"
- "</ReleaseDate>. Supported format: YYYY-MM-DD").arg(fileInfo.absoluteFilePath(), releaseDate));
+ throw QInstaller::Error(QString::fromLatin1("Release date for \"%1\" is invalid! <ReleaseDate>%2"
+ "</ReleaseDate>. Supported format: YYYY-MM-DD").arg(QDir::toNativeSeparators(fileInfo.absoluteFilePath()),
+ releaseDate));
}
PackageInfo info;
@@ -456,15 +462,15 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa
if (!QRegExp(QLatin1String("[0-9]+((\\.|-)[0-9]+)*")).exactMatch(info.version)) {
if (ignoreInvalidPackages)
continue;
- throw QInstaller::Error(QString::fromLatin1("Component version for '%1' is invalid! <Version>%2</Version>")
- .arg(fileInfo.absoluteFilePath(), info.version));
+ throw QInstaller::Error(QString::fromLatin1("Component version for \"%1\" is invalid! <Version>%2</Version>")
+ .arg(QDir::toNativeSeparators(fileInfo.absoluteFilePath()), info.version));
}
info.dependencies = packageElement.firstChildElement(QLatin1String("Dependencies")).text()
.split(QInstaller::commaRegExp(), QString::SkipEmptyParts);
info.directory = it->filePath();
dict.push_back(info);
- qDebug() << QString::fromLatin1("- it provides the package %1 - %2").arg(info.name, info.version);
+ qDebug() << "- it provides the package" << info.name << " - " << info.version;
}
if (!packagesToFilter->isEmpty() && packagesToFilter->at(0) != QString::fromLatin1(
@@ -509,7 +515,7 @@ void QInstallerTools::compressMetaDirectories(const QString &repoDir, const QStr
// use existing Updates.xml, if any
QFile existingUpdatesXml(QFileInfo(QDir(repoDir), QLatin1String("Updates.xml")).absoluteFilePath());
if (!existingUpdatesXml.open(QIODevice::ReadOnly) || !doc.setContent(&existingUpdatesXml)) {
- qDebug() << "Could not find Updates.xml";
+ qDebug() << "Cannot find Updates.xml";
} else {
root = doc.documentElement();
}
@@ -528,7 +534,7 @@ void QInstallerTools::compressMetaDirectories(const QString &repoDir, const QStr
const QString absPath = sd.absolutePath();
const QString fn = QLatin1String(versionPrefix.toLatin1() + "meta.7z");
const QString tmpTarget = repoDir + QLatin1String("/") +fn;
- compressPaths(QStringList() << absPath, tmpTarget);
+ Lib7z::createArchive(tmpTarget, QStringList() << absPath, Lib7z::QTmpFile::No);
// remove the files that got compressed
QInstaller::removeFiles(absPath, true);
@@ -539,8 +545,8 @@ void QInstallerTools::compressMetaDirectories(const QString &repoDir, const QStr
writeSHA1ToNodeWithName(doc, elements, sha1Sum, path);
const QString finalTarget = absPath + QLatin1String("/") + fn;
if (!tmp.rename(finalTarget)) {
- throw QInstaller::Error(QString::fromLatin1("Could not move '%1' to '%2'").arg(tmpTarget,
- finalTarget));
+ throw QInstaller::Error(QString::fromLatin1("Cannot move file \"%1\" to \"%2\".").arg(
+ QDir::toNativeSeparators(tmpTarget), QDir::toNativeSeparators(finalTarget)));
}
}
@@ -559,7 +565,7 @@ void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QS
const QString namedRepoDir = QString::fromLatin1("%1/%2").arg(repoDir, name);
if (!QDir().mkpath(namedRepoDir)) {
- throw QInstaller::Error(QString::fromLatin1("Could not create repository folder for component '%1'")
+ throw QInstaller::Error(QString::fromLatin1("Cannot create repository directory for component \"%1\".")
.arg(name));
}
@@ -574,11 +580,10 @@ void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QS
if (Lib7z::isSupportedArchive(absoluteEntryFilePath)) {
QFile tmp(absoluteEntryFilePath);
QString target = QString::fromLatin1("%1/%3%2").arg(namedRepoDir, entry, info.version);
- qDebug() << QString::fromLatin1("Copying archive from '%1' to '%2'").arg(tmp.fileName(),
- target);
+ qDebug() << "Copying archive from" << tmp.fileName() << "to" << target;
if (!tmp.copy(target)) {
- throw QInstaller::Error(QString::fromLatin1("Could not copy '%1' to '%2': %3")
- .arg(tmp.fileName(), target, tmp.errorString()));
+ throw QInstaller::Error(QString::fromLatin1("Cannot copy file \"%1\" to \"%2\": %3")
+ .arg(QDir::toNativeSeparators(tmp.fileName()), QDir::toNativeSeparators(target), tmp.errorString()));
}
compressedFiles.append(target);
} else {
@@ -587,7 +592,8 @@ void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QS
} else if (fileInfo.isDir()) {
qDebug() << "Compressing data directory" << entry;
QString target = QString::fromLatin1("%1/%3%2.7z").arg(namedRepoDir, entry, info.version);
- QInstallerTools::compressPaths(QStringList() << dataDir.absoluteFilePath(entry), target);
+ Lib7z::createArchive(target, QStringList() << dataDir.absoluteFilePath(entry),
+ Lib7z::QTmpFile::No);
compressedFiles.append(target);
} else if (fileInfo.isSymLink()) {
filesToCompress.append(dataDir.absoluteFilePath(entry));
@@ -599,7 +605,7 @@ void QInstallerTools::copyComponentData(const QStringList &packageDirs, const QS
qDebug() << "Compressing files found in data directory:" << filesToCompress;
QString target = QString::fromLatin1("%1/%3%2").arg(namedRepoDir, QLatin1String("content.7z"),
info.version);
- QInstallerTools::compressPaths(filesToCompress, target);
+ Lib7z::createArchive(target, filesToCompress, Lib7z::QTmpFile::No);
compressedFiles.append(target);
}
diff --git a/tools/common/repositorygen.h b/tools/common/repositorygen.h
index f983cfde5..769f48729 100644
--- a/tools/common/repositorygen.h
+++ b/tools/common/repositorygen.h
@@ -60,7 +60,6 @@ PackageInfoVector createListOfPackages(const QStringList &packagesDirectories, Q
FilterType ftype);
QHash<QString, QString> buildPathToVersionMapping(const PackageInfoVector &info);
-void compressPaths(const QStringList &paths, const QString &archivePath);
void compressMetaDirectories(const QString &repoDir, const QString &baseDir,
const QHash<QString, QString> &versionMapping);
diff --git a/tools/devtool/binarydump.cpp b/tools/devtool/binarydump.cpp
index 418b827ca..ad5093837 100644
--- a/tools/devtool/binarydump.cpp
+++ b/tools/devtool/binarydump.cpp
@@ -42,19 +42,19 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
QDir targetDir(QFileInfo(target).absoluteFilePath());
if (targetDir.exists()) {
if (!targetDir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty()) {
- std::cerr << qPrintable(QString::fromLatin1("Target directory '%1' already exists and "
- "is not empty.").arg(targetDir.path())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Target directory \"%1\" already exists and "
+ "is not empty.").arg(QDir::toNativeSeparators(targetDir.path()))) << std::endl;
return EXIT_FAILURE;
}
} else {
if (!QDir().mkpath(targetDir.path())) {
- std::cerr << qPrintable(QString::fromLatin1("Could not create '%1'.").arg(targetDir
- .path())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot create \"%1\".").arg(
+ QDir::toNativeSeparators(targetDir.path()))) << std::endl;
return EXIT_FAILURE;
}
}
- QInstaller::CopyDirectoryOperation copyMetadata;
+ QInstaller::CopyDirectoryOperation copyMetadata(0);
copyMetadata.setArguments(QStringList() << QLatin1String(":/")
<< (targetDir.path() + QLatin1Char('/'))); // Add "/" at the end to make operation work.
if (!copyMetadata.performOperation()) {
@@ -63,8 +63,8 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
}
if (!targetDir.cd(QLatin1String("metadata"))) {
- std::cerr << qPrintable(QString::fromLatin1("Could not switch to '%1/metadata'.")
- .arg(targetDir.path())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot switch to \"%1/metadata\".")
+ .arg(QDir::toNativeSeparators(targetDir.path()))) << std::endl;
return EXIT_FAILURE;
}
@@ -76,8 +76,8 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
QString error;
QDomDocument doc;
if (!doc.setContent(&updatesXml, &error)) {
- throw QInstaller::Error(QString::fromLatin1("Could not read: '%1'. %2").arg(updatesXml
- .fileName(), error));
+ throw QInstaller::Error(QString::fromLatin1("Cannot read: \"%1\": %2").arg(
+ QDir::toNativeSeparators(updatesXml.fileName()), error));
}
QHash<QString, QString> versionMap;
@@ -108,7 +108,7 @@ int BinaryDump::dump(const QInstaller::ResourceCollectionManager &manager, const
continue;
if (!targetDir.mkpath(name)) {
- throw QInstaller::Error(QString::fromLatin1("Could not create target dir: %1.")
+ throw QInstaller::Error(QString::fromLatin1("Cannot create target dir: %1.")
.arg(targetDir.filePath(name)));
}
diff --git a/tools/devtool/binaryreplace.cpp b/tools/devtool/binaryreplace.cpp
index 26a2c0664..7497f2199 100644
--- a/tools/devtool/binaryreplace.cpp
+++ b/tools/devtool/binaryreplace.cpp
@@ -34,7 +34,9 @@
#include <errors.h>
#include <fileio.h>
#include <fileutils.h>
+#include <lib7z_extract.h>
#include <lib7z_facade.h>
+#include <lib7z_list.h>
#include <QDir>
#include <QFutureWatcher>
@@ -76,19 +78,19 @@ int BinaryReplace::replace(const QString &source, const QString &target)
.path;
result = EXIT_SUCCESS;
} catch (const Lib7z::SevenZipException& e) {
- std::cerr << qPrintable(QString::fromLatin1("Error while extracting '%1': %2.")
- .arg(newInstallerBasePath, e.message())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Error while extracting \"%1\": %2")
+ .arg(QDir::toNativeSeparators(newInstallerBasePath), e.message())) << std::endl;
} catch (...) {
std::cerr << qPrintable(QString::fromLatin1("Unknown exception caught while "
- "extracting '%1'.").arg(newInstallerBasePath)) << std::endl;
+ "extracting \"%1\".").arg(QDir::toNativeSeparators(newInstallerBasePath))) << std::endl;
}
} else {
- std::cerr << qPrintable(QString::fromLatin1("Could not open '%1' for reading: %2.")
- .arg(newInstallerBasePath, archive.errorString())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot open \"%1\" for reading: %2")
+ .arg(QDir::toNativeSeparators(newInstallerBasePath), archive.errorString())) << std::endl;
}
if (!archive.remove()) {
- std::cerr << qPrintable(QString::fromLatin1("Could not delete file '%1': %2.")
- .arg(newInstallerBasePath, archive.errorString())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot delete file \"%1\": %2")
+ .arg(QDir::toNativeSeparators(newInstallerBasePath), archive.errorString())) << std::endl;
}
if (result != EXIT_SUCCESS)
return result;
@@ -125,19 +127,19 @@ int BinaryReplace::replace(const QString &source, const QString &target)
#endif
QFile backup(installerBaseOld.fileName() + QLatin1String(".bak"));
if (backup.exists() && (!backup.remove())) {
- std::cerr << qPrintable(QString::fromLatin1("Could not delete '%1'. %2")
- .arg(backup.fileName(), backup.errorString())) << std::endl;
+ std::cerr << qPrintable(QString::fromLatin1("Cannot delete \"%1\": %2")
+ .arg(QDir::toNativeSeparators(backup.fileName()), backup.errorString())) << std::endl;
}
const QString oldBasePath = installerBaseOld.fileName();
if (!installerBaseOld.rename(oldBasePath + QLatin1String(".bak"))) {
- std::cerr << qPrintable(QString::fromLatin1("Could not rename '%1' to '%2'. %3")
+ std::cerr << qPrintable(QString::fromLatin1("Cannot rename \"%1\" to \"%2\": %3")
.arg(oldBasePath, oldBasePath + QLatin1String(".bak"),
installerBaseOld.errorString())) << std::endl;
}
if (!installerBaseNew.rename(oldBasePath)) {
- std::cerr << qPrintable(QString::fromLatin1("Could not copy '%1' to '%2'. %3")
+ std::cerr << qPrintable(QString::fromLatin1("Cannot copy \"%1\" to \"%2\": %3")
.arg(installerBaseNew.fileName(), oldBasePath, installerBaseNew.errorString()))
<< std::endl;
} else {
diff --git a/tools/devtool/main.cpp b/tools/devtool/main.cpp
index b83ae3429..7418efda6 100644
--- a/tools/devtool/main.cpp
+++ b/tools/devtool/main.cpp
@@ -31,7 +31,6 @@
#include "operationrunner.h"
#include <binarycontent.h>
-#include <binaryformat.h>
#include <binaryformatenginehandler.h>
#include <errors.h>
#include <fileio.h>
@@ -44,39 +43,122 @@
#include <QFileInfo>
#include <QResource>
+#include <iomanip>
#include <iostream>
+struct Command
+{
+ const char* command;
+ const char* description;
+ qint32 argC;
+ const char* arguments;
+ const char* argDescription;
+} Commands[] = {
+ { "dump", "Dumps the binary content that belongs to an installer or maintenance tool into "
+ "target directory.", 2, "<binary> <targetdirecory>", "The <binary> containing the data to "
+ "dump.\nThe <targetdirectory> to dump the data in."
+ },
+
+ { "update", "Updates existing installer or maintenance tool with a new installer base.", 2,
+ "<binary> <installerbase>", "The <binary> to update.\nThe <installerbase> to use as update."
+ },
+
+ { "operation", "Executes an operation with with a given mode and a list of arguments. ", 2,
+ "<binary> <mode,name,args,...>", "The <binary> to run the operation with.\n"
+ "<mode,name,args,...> 'mode' can be DO or UNDO. 'name' of the operation. 'args,...' "
+ "used to run the operation."
+ }
+};
+
+#define DESCRITION_LENGTH 60
+#define SETW_ALIGNLEFT(X) std::setw(X) << std::setiosflags(std::ios::left)
+
+static int fail(const QString &message)
+{
+ std::cerr << qPrintable(message) << " See 'devtool --help'." << std::endl;
+ return EXIT_FAILURE;
+}
+
+static QStringList split(int index, const QString &description)
+{
+ QStringList result;
+ if (description.length() <= DESCRITION_LENGTH)
+ return result << description;
+
+ const int lastIndexOf = description.left(index + DESCRITION_LENGTH)
+ .lastIndexOf(QLatin1Char(' '));
+ result << description.left(lastIndexOf);
+ return result + split(lastIndexOf + 1, description.mid(lastIndexOf + 1));
+}
+
+// -- main
+
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
app.setApplicationVersion(QLatin1String("1.0.0"));
- QCommandLineOption verbose(QLatin1String("verbose"),
- QLatin1String("Verbose mode. Prints out more information."));
- QCommandLineOption dump(QLatin1String("dump"),
- QLatin1String("Dumps the binary content that belongs to an installer or maintenance tool "
- "into target."), QLatin1String("folder"));
- QCommandLineOption run(QLatin1String("operation"),
- QLatin1String("Executes an operation with a list of arguments. Mode can be DO or UNDO."),
- QLatin1String("mode,name,args,..."));
- QCommandLineOption update(QLatin1String("update"),
- QLatin1String("Updates existing installer or maintenance tool with a new installer base."),
- QLatin1String("file"));
-
QCommandLineParser parser;
- parser.addHelpOption();
- parser.addVersionOption();
+ QCommandLineOption help = parser.addHelpOption();
+ QCommandLineOption version = parser.addVersionOption();
+ QCommandLineOption verbose(QLatin1String("verbose"), QLatin1String("Verbose mode. Prints out "
+ "more information."));
parser.addOption(verbose);
- parser.addOption(update);
- parser.addOption(dump);
- parser.addOption(run);
- parser.addPositionalArgument(QLatin1String("binary"), QLatin1String("Existing installer or "
- "maintenance tool."));
- parser.process(app.arguments());
- const QStringList arguments = parser.positionalArguments();
- if (arguments.isEmpty() || (arguments.count() > 1))
- parser.showHelp(EXIT_FAILURE);
+ parser.parse(app.arguments());
+ if (parser.isSet(version)) {
+ parser.showVersion();
+ return EXIT_SUCCESS;
+ }
+
+ if (parser.isSet(help)) {
+ const QString command = parser.positionalArguments().value(0);
+ if (!command.isEmpty()) {
+ for (const auto &c : Commands) {
+ if (QLatin1String(c.command) == command) {
+ parser.clearPositionalArguments();
+ parser.addPositionalArgument(QString::fromLatin1("%1 %2").arg(QLatin1String(c
+ .command), QLatin1String(c.arguments)), QLatin1String(c.argDescription));
+ parser.showHelp(EXIT_SUCCESS);
+ }
+ }
+ return fail(QString::fromLatin1("\"%1\" is not a devtool command.").arg(command));
+ }
+
+ QString helpText = parser.helpText();
+ helpText.insert(helpText.indexOf(QLatin1Char(']')) + 1, QLatin1String(" command <args>"));
+ std::cout << qPrintable(helpText) << std::endl;
+ std::cout << "Available commands (mutually exclusive):" << std::endl;
+ for (const auto &c : Commands) {
+ QStringList lines = split(0, QLatin1String(c.description));
+ std::cout << SETW_ALIGNLEFT(2) << " " << SETW_ALIGNLEFT(16) << c.command
+ << SETW_ALIGNLEFT(DESCRITION_LENGTH) << qPrintable(lines.takeFirst()) << std::endl;
+ foreach (const QString &line, lines) {
+ std::cout << SETW_ALIGNLEFT(18) << QByteArray(18, ' ').constData()
+ << qPrintable(line) << std::endl;
+ }
+ }
+ std::cout << std::endl << "Use 'devtool --help <command>' to read about a specific command."
+ << std::endl;
+ return EXIT_SUCCESS;
+ }
+
+ QStringList arguments = parser.positionalArguments();
+ if (arguments.isEmpty())
+ return fail(QLatin1String("Missing command."));
+
+ bool found = false;
+ const QString command = arguments.takeFirst();
+ for (const auto &c : Commands) {
+ if ((found = (QLatin1String(c.command) == command))) {
+ if (arguments.count() != c.argC)
+ return fail(QString::fromLatin1("%1: wrong argument count.").arg(command));
+ break;
+ }
+ }
+
+ if (!found)
+ return fail(QString::fromLatin1("\"%1\" is not a devtool command.").arg(command));
QInstaller::init();
QInstaller::setVerbose(parser.isSet(verbose));
@@ -95,7 +177,7 @@ int main(int argc, char *argv[])
QInstaller::openForRead(&tmp);
if (!tmp.seek(QInstaller::BinaryContent::findMagicCookie(&tmp, cookie) - sizeof(qint64)))
- throw QInstaller::Error(QLatin1String("Could not seek to read magic marker."));
+ throw QInstaller::Error(QLatin1String("Cannot seek to read magic marker."));
QInstaller::BinaryLayout layout;
layout.magicMarker = QInstaller::retrieveInt64(&tmp);
@@ -115,9 +197,9 @@ int main(int argc, char *argv[])
layout = QInstaller::BinaryContent::binaryLayout(&tmp, cookie);
tmp.close();
- if (parser.isSet(update)) {
+ if (command == QLatin1String("update")) {
BinaryReplace br(layout); // To update the binary we do not need any mapping.
- return br.replace(parser.value(update), QFileInfo(arguments.first())
+ return br.replace(arguments.last(), QFileInfo(arguments.first())
.absoluteFilePath());
}
}
@@ -140,28 +222,29 @@ int main(int argc, char *argv[])
const QByteArray ba = resource->readAll();
if (!QResource::registerResource((const uchar*) ba.data(), QLatin1String(":/metadata")))
- throw QInstaller::Error(QLatin1String("Could not register in-binary resource."));
+ throw QInstaller::Error(QLatin1String("Cannot register in-binary resource."));
resourceMappings.append(ba);
if (!isOpen)
resource->close();
}
- if (parser.isSet(dump)) {
+ if (command == QLatin1String("dump")) {
// To dump the content we do not need the binary format engine.
BinaryDump bd;
- result = bd.dump(manager, parser.value(dump));
- } else if (parser.isSet(run)) {
+ result = bd.dump(manager, arguments.last());
+ } else if (command == QLatin1String("operation")) {
QInstaller::BinaryFormatEngineHandler::instance()->registerResources(manager
.collections()); // setup the binary format engine
OperationRunner runner(magicMarker, operations);
- const QStringList arguments = parser.value(run).split(QLatin1Char(','));
+ const QStringList arguments = arguments.last().split(QLatin1Char(','));
if (arguments.first() == QLatin1String("DO"))
result = runner.runOperation(arguments.mid(1), OperationRunner::RunMode::Do);
else if (arguments.first() == QLatin1String("UNDO"))
result = runner.runOperation(arguments.mid(1), OperationRunner::RunMode::Undo);
else
- std::cerr << "Malformed argument: " << qPrintable(parser.value(run)) << std::endl;
+ std::cerr << "Malformed argument: " << qPrintable(arguments.last()) << std::endl;
+
}
} catch (const QInstaller::Error &error) {
std::cerr << qPrintable(error.message()) << std::endl;
diff --git a/tools/devtool/operationrunner.cpp b/tools/devtool/operationrunner.cpp
index d84a90ae9..679264326 100644
--- a/tools/devtool/operationrunner.cpp
+++ b/tools/devtool/operationrunner.cpp
@@ -29,7 +29,7 @@
#include "operationrunner.h"
#include <errors.h>
-#include <kdupdaterupdateoperationfactory.h>
+#include <updateoperationfactory.h>
#include <packagemanagercore.h>
#include <QMetaObject>
@@ -54,7 +54,7 @@ int OperationRunner::runOperation(QStringList arguments, RunMode mode)
try {
const QString name = arguments.takeFirst();
QScopedPointer<QInstaller::Operation> op(KDUpdater::UpdateOperationFactory::instance()
- .create(name));
+ .create(name, m_core));
if (!op) {
std::cerr << "Cannot instantiate operation: " << qPrintable(name) << std::endl;
return EXIT_FAILURE;
@@ -66,8 +66,6 @@ int OperationRunner::runOperation(QStringList arguments, RunMode mode)
connect(object, SIGNAL(outputTextChanged(QString)), this, SLOT(print(QString)));
}
op->setArguments(arguments);
- op->setValue(QLatin1String("installer"), QVariant::fromValue(m_core));
-
bool readyPerformed = false;
if (mode == RunMode::Do)
diff --git a/tools/repocompare/main.cpp b/tools/repocompare/main.cpp
index e125fea32..bfd0806ac 100644
--- a/tools/repocompare/main.cpp
+++ b/tools/repocompare/main.cpp
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
RepositoryManager manager;
manager.setProductionRepository(productionRepo);
manager.setUpdateRepository(updateRepo);
- a.connect(&manager, SIGNAL(repositoriesCompared()), &a, SLOT(quit()));
+ a.connect(&manager, &RepositoryManager::repositoriesCompared, &a, &QApplication::quit);
qDebug() << "Waiting for server reply...";
a.exec();
qDebug() << "Writing into " << outputFile;
diff --git a/tools/repocompare/mainwindow.cpp b/tools/repocompare/mainwindow.cpp
index 0d1ac158b..8d018f95c 100644
--- a/tools/repocompare/mainwindow.cpp
+++ b/tools/repocompare/mainwindow.cpp
@@ -72,11 +72,11 @@ MainWindow::MainWindow(QWidget *parent) :
ui->productionRepo->insertItems(0, settings.value(productionIdentifier).toStringList());
ui->updateRepo->insertItems(0, settings.value(updateIdentifier).toStringList());
- connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(close()));
- connect(ui->productionButton, SIGNAL(clicked()), this, SLOT(getProductionRepository()));
- connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(getUpdateRepository()));
- connect(ui->exportButton, SIGNAL(clicked()), this, SLOT(createExportFile()));
- connect(&manager, SIGNAL(repositoriesCompared()), this, SLOT(displayRepositories()));
+ connect(ui->actionExit, &QAction::triggered, this, &QWidget::close);
+ connect(ui->productionButton, &QAbstractButton::clicked, this, &MainWindow::getProductionRepository);
+ connect(ui->updateButton, &QAbstractButton::clicked, this, &MainWindow::getUpdateRepository);
+ connect(ui->exportButton, &QAbstractButton::clicked, this, &MainWindow::createExportFile);
+ connect(&manager, &RepositoryManager::repositoriesCompared, this, &MainWindow::displayRepositories);
}
MainWindow::~MainWindow()
diff --git a/tools/repocompare/repositorymanager.cpp b/tools/repocompare/repositorymanager.cpp
index fe6c44f52..7d24b9620 100644
--- a/tools/repocompare/repositorymanager.cpp
+++ b/tools/repocompare/repositorymanager.cpp
@@ -28,6 +28,7 @@
#include "repositorymanager.h"
#include <QDebug>
+#include <QDir>
#include <QFile>
#include <QStringList>
#include <QUrl>
@@ -61,7 +62,7 @@ RepositoryManager::RepositoryManager(QObject *parent) :
QObject(parent)
{
manager = new QNetworkAccessManager(this);
- connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveRepository(QNetworkReply*)));
+ connect(manager, &QNetworkAccessManager::finished, this, &RepositoryManager::receiveRepository);
productionMap.clear();
updateMap.clear();
}
@@ -180,13 +181,15 @@ void RepositoryManager::writeUpdateFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
- QMessageBox::critical(0, QLatin1String("Error"), QLatin1String("Could not open File for saving"));
+ QMessageBox::critical(0, QLatin1String("Error"),
+ QString::fromLatin1("Cannot open file \"%1\" for writing: %2").arg(
+ QDir::toNativeSeparators(fileName), file.errorString()));
return;
}
QStringList items;
- for (QMap<QString, ComponentDescription>::const_iterator it = updateMap.begin(); it != updateMap.end();
- ++it) {
+ for (QMap<QString, ComponentDescription>::const_iterator it = updateMap.constBegin();
+ it != updateMap.constEnd(); ++it) {
if (it.value().update)
items.append(it.key());
}
diff --git a/tools/repogen/repogen.cpp b/tools/repogen/repogen.cpp
index 60fd37cb1..67184c49e 100644
--- a/tools/repogen/repogen.cpp
+++ b/tools/repogen/repogen.cpp
@@ -30,7 +30,7 @@
#include <errors.h>
#include <fileutils.h>
#include <init.h>
-#include <kdupdater.h>
+#include <updater.h>
#include <settings.h>
#include <utils.h>
#include <lib7z_facade.h>
@@ -46,7 +46,6 @@
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
-using namespace Lib7z;
using namespace QInstaller;
static void printUsage()
@@ -188,7 +187,7 @@ int main(int argc, char** argv)
QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) {
throw QInstaller::Error(QCoreApplication::translate("QInstaller",
- "Repository target folder %1 already exists!").arg(repositoryDir));
+ "Repository target directory \"%1\" already exists.").arg(QDir::toNativeSeparators(repositoryDir)));
}
QInstallerTools::PackageInfoVector packages = QInstallerTools::createListOfPackages(packagesDirectories,
@@ -201,7 +200,7 @@ int main(int argc, char** argv)
const QDomElement root = doc.documentElement();
if (root.tagName() != QLatin1String("Updates")) {
throw QInstaller::Error(QCoreApplication::translate("QInstaller",
- "Invalid content in '%1'.").arg(file.fileName()));
+ "Invalid content in \"%1\".").arg(QDir::toNativeSeparators(file.fileName())));
}
file.close(); // close the file, we read the content already
@@ -216,7 +215,7 @@ int main(int argc, char** argv)
for (int j = 0; j < c2.count(); ++j) {
if (c2.at(j).toElement().tagName() == scName)
info.name = c2.at(j).toElement().text();
- else if (c2.at(j).toElement().tagName() == scRemoteVersion)
+ else if (c2.at(j).toElement().tagName() == scVersion)
info.version = c2.at(j).toElement().text();
}
hash.insert(info.name, info);
@@ -234,7 +233,7 @@ int main(int argc, char** argv)
}
if (packages.isEmpty()) {
- std::cout << QString::fromLatin1("Could not find new components to update '%1'.")
+ std::cout << QString::fromLatin1("Cannot find new components to update \"%1\".")
.arg(repositoryDir) << std::endl;
return EXIT_SUCCESS;
}
diff --git a/tools/tools.pro b/tools/tools.pro
index 25a646252..cf72dba39 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -1,4 +1,3 @@
-CONFIG += ordered
TEMPLATE = subdirs
SUBDIRS += \