Imported Upstream version 9.20 87/187687/1 upstream upstream/9.20
authorSunmin Lee <sunm.lee@samsung.com>
Thu, 23 Aug 2018 09:51:13 +0000 (18:51 +0900)
committerSunmin Lee <sunm.lee@samsung.com>
Thu, 23 Aug 2018 09:53:02 +0000 (18:53 +0900)
Change-Id: Ie09e1f813646623a752a2b433187dd0a105f4242

454 files changed:
7zC.txt [new file with mode: 0755]
7zFormat.txt [new file with mode: 0755]
7zr.exe [new file with mode: 0755]
Asm/arm/7zCrcOpt.asm [new file with mode: 0755]
Asm/x86/7zAsm.asm [new file with mode: 0755]
Asm/x86/7zCrcOpt.asm [new file with mode: 0755]
Asm/x86/AesOpt.asm [new file with mode: 0755]
C/7z.h [new file with mode: 0755]
C/7zAlloc.c [new file with mode: 0755]
C/7zAlloc.h [new file with mode: 0755]
C/7zBuf.c [new file with mode: 0755]
C/7zBuf.h [new file with mode: 0755]
C/7zBuf2.c [new file with mode: 0755]
C/7zCrc.c [new file with mode: 0755]
C/7zCrc.h [new file with mode: 0755]
C/7zCrcOpt.c [new file with mode: 0755]
C/7zDec.c [new file with mode: 0755]
C/7zFile.c [new file with mode: 0755]
C/7zFile.h [new file with mode: 0755]
C/7zIn.c [new file with mode: 0755]
C/7zStream.c [new file with mode: 0755]
C/7zVersion.h [new file with mode: 0755]
C/Alloc.c [new file with mode: 0755]
C/Alloc.h [new file with mode: 0755]
C/Bcj2.c [new file with mode: 0755]
C/Bcj2.h [new file with mode: 0755]
C/Bra.c [new file with mode: 0755]
C/Bra.h [new file with mode: 0755]
C/Bra86.c [new file with mode: 0755]
C/BraIA64.c [new file with mode: 0755]
C/CpuArch.c [new file with mode: 0755]
C/CpuArch.h [new file with mode: 0755]
C/Delta.c [new file with mode: 0755]
C/Delta.h [new file with mode: 0755]
C/LzFind.c [new file with mode: 0755]
C/LzFind.h [new file with mode: 0755]
C/LzFindMt.c [new file with mode: 0755]
C/LzFindMt.h [new file with mode: 0755]
C/LzHash.h [new file with mode: 0755]
C/Lzma2Dec.c [new file with mode: 0755]
C/Lzma2Dec.h [new file with mode: 0755]
C/Lzma2Enc.c [new file with mode: 0755]
C/Lzma2Enc.h [new file with mode: 0755]
C/Lzma86.h [new file with mode: 0755]
C/Lzma86Dec.c [new file with mode: 0755]
C/Lzma86Enc.c [new file with mode: 0755]
C/LzmaDec.c [new file with mode: 0755]
C/LzmaDec.h [new file with mode: 0755]
C/LzmaEnc.c [new file with mode: 0755]
C/LzmaEnc.h [new file with mode: 0755]
C/LzmaLib.c [new file with mode: 0755]
C/LzmaLib.h [new file with mode: 0755]
C/MtCoder.c [new file with mode: 0755]
C/MtCoder.h [new file with mode: 0755]
C/Ppmd.h [new file with mode: 0755]
C/Ppmd7.c [new file with mode: 0755]
C/Ppmd7.h [new file with mode: 0755]
C/Ppmd7Dec.c [new file with mode: 0755]
C/Ppmd7Enc.c [new file with mode: 0755]
C/RotateDefs.h [new file with mode: 0755]
C/Sha256.c [new file with mode: 0755]
C/Sha256.h [new file with mode: 0755]
C/Threads.c [new file with mode: 0755]
C/Threads.h [new file with mode: 0755]
C/Types.h [new file with mode: 0755]
C/Util/7z/7z.dsp [new file with mode: 0755]
C/Util/7z/7z.dsw [new file with mode: 0755]
C/Util/7z/7zMain.c [new file with mode: 0755]
C/Util/7z/makefile [new file with mode: 0755]
C/Util/7z/makefile.gcc [new file with mode: 0755]
C/Util/Lzma/LzmaUtil.c [new file with mode: 0755]
C/Util/Lzma/LzmaUtil.dsp [new file with mode: 0755]
C/Util/Lzma/LzmaUtil.dsw [new file with mode: 0755]
C/Util/Lzma/makefile [new file with mode: 0755]
C/Util/Lzma/makefile.gcc [new file with mode: 0755]
C/Util/LzmaLib/LzmaLib.def [new file with mode: 0755]
C/Util/LzmaLib/LzmaLib.dsp [new file with mode: 0755]
C/Util/LzmaLib/LzmaLib.dsw [new file with mode: 0755]
C/Util/LzmaLib/LzmaLibExports.c [new file with mode: 0755]
C/Util/LzmaLib/makefile [new file with mode: 0755]
C/Util/LzmaLib/resource.rc [new file with mode: 0755]
C/Util/SfxSetup/SfxSetup.c [new file with mode: 0755]
C/Util/SfxSetup/SfxSetup.dsp [new file with mode: 0755]
C/Util/SfxSetup/SfxSetup.dsw [new file with mode: 0755]
C/Util/SfxSetup/makefile [new file with mode: 0755]
C/Util/SfxSetup/makefile_con [new file with mode: 0755]
C/Util/SfxSetup/resource.rc [new file with mode: 0755]
C/Util/SfxSetup/setup.ico [new file with mode: 0755]
C/Xz.c [new file with mode: 0755]
C/Xz.h [new file with mode: 0755]
C/XzCrc64.c [new file with mode: 0755]
C/XzCrc64.h [new file with mode: 0755]
C/XzDec.c [new file with mode: 0755]
C/XzEnc.c [new file with mode: 0755]
C/XzEnc.h [new file with mode: 0755]
C/XzIn.c [new file with mode: 0755]
CPP/7zip/Aes.mak [new file with mode: 0755]
CPP/7zip/Archive/7z/7zCompressionMode.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zCompressionMode.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zDecode.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zDecode.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zEncode.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zEncode.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zExtract.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zFolderInStream.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zFolderInStream.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zFolderOutStream.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zFolderOutStream.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zHandler.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zHandler.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zHandlerOut.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zHeader.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zHeader.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zIn.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zIn.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zItem.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zOut.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zOut.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zProperties.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zProperties.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zRegister.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zSpecStream.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zSpecStream.h [new file with mode: 0755]
CPP/7zip/Archive/7z/7zUpdate.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/7zUpdate.h [new file with mode: 0755]
CPP/7zip/Archive/7z/StdAfx.cpp [new file with mode: 0755]
CPP/7zip/Archive/7z/StdAfx.h [new file with mode: 0755]
CPP/7zip/Archive/Archive.def [new file with mode: 0755]
CPP/7zip/Archive/Archive2.def [new file with mode: 0755]
CPP/7zip/Archive/ArchiveExports.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/CoderMixer2.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/CoderMixer2.h [new file with mode: 0755]
CPP/7zip/Archive/Common/CoderMixer2MT.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/CoderMixer2MT.h [new file with mode: 0755]
CPP/7zip/Archive/Common/CrossThreadProgress.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/CrossThreadProgress.h [new file with mode: 0755]
CPP/7zip/Archive/Common/DummyOutStream.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/DummyOutStream.h [new file with mode: 0755]
CPP/7zip/Archive/Common/HandlerOut.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/HandlerOut.h [new file with mode: 0755]
CPP/7zip/Archive/Common/InStreamWithCRC.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/InStreamWithCRC.h [new file with mode: 0755]
CPP/7zip/Archive/Common/ItemNameUtils.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/ItemNameUtils.h [new file with mode: 0755]
CPP/7zip/Archive/Common/MultiStream.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/MultiStream.h [new file with mode: 0755]
CPP/7zip/Archive/Common/OutStreamWithCRC.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/OutStreamWithCRC.h [new file with mode: 0755]
CPP/7zip/Archive/Common/ParseProperties.cpp [new file with mode: 0755]
CPP/7zip/Archive/Common/ParseProperties.h [new file with mode: 0755]
CPP/7zip/Archive/Common/StdAfx.h [new file with mode: 0755]
CPP/7zip/Archive/DllExports2.cpp [new file with mode: 0755]
CPP/7zip/Archive/IArchive.h [new file with mode: 0755]
CPP/7zip/Archive/Icons/7z.ico [new file with mode: 0755]
CPP/7zip/Archive/LzmaHandler.cpp [new file with mode: 0755]
CPP/7zip/Archive/SplitHandler.cpp [new file with mode: 0755]
CPP/7zip/Archive/StdAfx.h [new file with mode: 0755]
CPP/7zip/Archive/XzHandler.cpp [new file with mode: 0755]
CPP/7zip/Asm.mak [new file with mode: 0755]
CPP/7zip/Bundles/Alone7z/Alone.dsp [new file with mode: 0755]
CPP/7zip/Bundles/Alone7z/Alone.dsw [new file with mode: 0755]
CPP/7zip/Bundles/Alone7z/StdAfx.cpp [new file with mode: 0755]
CPP/7zip/Bundles/Alone7z/StdAfx.h [new file with mode: 0755]
CPP/7zip/Bundles/Alone7z/makefile [new file with mode: 0755]
CPP/7zip/Bundles/Alone7z/resource.rc [new file with mode: 0755]
CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp [new file with mode: 0755]
CPP/7zip/Bundles/Format7zExtractR/StdAfx.h [new file with mode: 0755]
CPP/7zip/Bundles/Format7zExtractR/makefile [new file with mode: 0755]
CPP/7zip/Bundles/Format7zExtractR/resource.rc [new file with mode: 0755]
CPP/7zip/Bundles/Format7zR/StdAfx.cpp [new file with mode: 0755]
CPP/7zip/Bundles/Format7zR/StdAfx.h [new file with mode: 0755]
CPP/7zip/Bundles/Format7zR/makefile [new file with mode: 0755]
CPP/7zip/Bundles/Format7zR/resource.rc [new file with mode: 0755]
CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp [new file with mode: 0755]
CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp [new file with mode: 0755]
CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw [new file with mode: 0755]
CPP/7zip/Bundles/LzmaCon/StdAfx.cpp [new file with mode: 0755]
CPP/7zip/Bundles/LzmaCon/StdAfx.h [new file with mode: 0755]
CPP/7zip/Bundles/LzmaCon/makefile [new file with mode: 0755]
CPP/7zip/Bundles/LzmaCon/makefile.gcc [new file with mode: 0755]
CPP/7zip/Common/CWrappers.cpp [new file with mode: 0755]
CPP/7zip/Common/CWrappers.h [new file with mode: 0755]
CPP/7zip/Common/CreateCoder.cpp [new file with mode: 0755]
CPP/7zip/Common/CreateCoder.h [new file with mode: 0755]
CPP/7zip/Common/FilePathAutoRename.cpp [new file with mode: 0755]
CPP/7zip/Common/FilePathAutoRename.h [new file with mode: 0755]
CPP/7zip/Common/FileStreams.cpp [new file with mode: 0755]
CPP/7zip/Common/FileStreams.h [new file with mode: 0755]
CPP/7zip/Common/FilterCoder.cpp [new file with mode: 0755]
CPP/7zip/Common/FilterCoder.h [new file with mode: 0755]
CPP/7zip/Common/InBuffer.cpp [new file with mode: 0755]
CPP/7zip/Common/InBuffer.h [new file with mode: 0755]
CPP/7zip/Common/InOutTempBuffer.cpp [new file with mode: 0755]
CPP/7zip/Common/InOutTempBuffer.h [new file with mode: 0755]
CPP/7zip/Common/LimitedStreams.cpp [new file with mode: 0755]
CPP/7zip/Common/LimitedStreams.h [new file with mode: 0755]
CPP/7zip/Common/LockedStream.cpp [new file with mode: 0755]
CPP/7zip/Common/LockedStream.h [new file with mode: 0755]
CPP/7zip/Common/MethodId.cpp [new file with mode: 0755]
CPP/7zip/Common/MethodId.h [new file with mode: 0755]
CPP/7zip/Common/MethodProps.cpp [new file with mode: 0755]
CPP/7zip/Common/MethodProps.h [new file with mode: 0755]
CPP/7zip/Common/OffsetStream.cpp [new file with mode: 0755]
CPP/7zip/Common/OffsetStream.h [new file with mode: 0755]
CPP/7zip/Common/OutBuffer.cpp [new file with mode: 0755]
CPP/7zip/Common/OutBuffer.h [new file with mode: 0755]
CPP/7zip/Common/ProgressUtils.cpp [new file with mode: 0755]
CPP/7zip/Common/ProgressUtils.h [new file with mode: 0755]
CPP/7zip/Common/RegisterArc.h [new file with mode: 0755]
CPP/7zip/Common/RegisterCodec.h [new file with mode: 0755]
CPP/7zip/Common/StdAfx.h [new file with mode: 0755]
CPP/7zip/Common/StreamBinder.cpp [new file with mode: 0755]
CPP/7zip/Common/StreamBinder.h [new file with mode: 0755]
CPP/7zip/Common/StreamObjects.cpp [new file with mode: 0755]
CPP/7zip/Common/StreamObjects.h [new file with mode: 0755]
CPP/7zip/Common/StreamUtils.cpp [new file with mode: 0755]
CPP/7zip/Common/StreamUtils.h [new file with mode: 0755]
CPP/7zip/Common/VirtThread.cpp [new file with mode: 0755]
CPP/7zip/Common/VirtThread.h [new file with mode: 0755]
CPP/7zip/Compress/Bcj2Coder.cpp [new file with mode: 0755]
CPP/7zip/Compress/Bcj2Coder.h [new file with mode: 0755]
CPP/7zip/Compress/Bcj2Register.cpp [new file with mode: 0755]
CPP/7zip/Compress/BcjCoder.cpp [new file with mode: 0755]
CPP/7zip/Compress/BcjCoder.h [new file with mode: 0755]
CPP/7zip/Compress/BcjRegister.cpp [new file with mode: 0755]
CPP/7zip/Compress/BranchCoder.cpp [new file with mode: 0755]
CPP/7zip/Compress/BranchCoder.h [new file with mode: 0755]
CPP/7zip/Compress/BranchMisc.cpp [new file with mode: 0755]
CPP/7zip/Compress/BranchMisc.h [new file with mode: 0755]
CPP/7zip/Compress/BranchRegister.cpp [new file with mode: 0755]
CPP/7zip/Compress/ByteSwap.cpp [new file with mode: 0755]
CPP/7zip/Compress/CodecExports.cpp [new file with mode: 0755]
CPP/7zip/Compress/CopyCoder.cpp [new file with mode: 0755]
CPP/7zip/Compress/CopyCoder.h [new file with mode: 0755]
CPP/7zip/Compress/CopyRegister.cpp [new file with mode: 0755]
CPP/7zip/Compress/DeltaFilter.cpp [new file with mode: 0755]
CPP/7zip/Compress/Lzma2Decoder.cpp [new file with mode: 0755]
CPP/7zip/Compress/Lzma2Decoder.h [new file with mode: 0755]
CPP/7zip/Compress/Lzma2Encoder.cpp [new file with mode: 0755]
CPP/7zip/Compress/Lzma2Encoder.h [new file with mode: 0755]
CPP/7zip/Compress/Lzma2Register.cpp [new file with mode: 0755]
CPP/7zip/Compress/LzmaDecoder.cpp [new file with mode: 0755]
CPP/7zip/Compress/LzmaDecoder.h [new file with mode: 0755]
CPP/7zip/Compress/LzmaEncoder.cpp [new file with mode: 0755]
CPP/7zip/Compress/LzmaEncoder.h [new file with mode: 0755]
CPP/7zip/Compress/LzmaRegister.cpp [new file with mode: 0755]
CPP/7zip/Compress/PpmdDecoder.h [new file with mode: 0755]
CPP/7zip/Compress/PpmdEncoder.cpp [new file with mode: 0755]
CPP/7zip/Compress/PpmdRegister.cpp [new file with mode: 0755]
CPP/7zip/Compress/RangeCoder.h [new file with mode: 0755]
CPP/7zip/Compress/RangeCoderBit.h [new file with mode: 0755]
CPP/7zip/Compress/StdAfx.h [new file with mode: 0755]
CPP/7zip/Crc.mak [new file with mode: 0755]
CPP/7zip/Guid.txt [new file with mode: 0755]
CPP/7zip/ICoder.h [new file with mode: 0755]
CPP/7zip/IDecl.h [new file with mode: 0755]
CPP/7zip/IPassword.h [new file with mode: 0755]
CPP/7zip/IProgress.h [new file with mode: 0755]
CPP/7zip/IStream.h [new file with mode: 0755]
CPP/7zip/MyVersion.h [new file with mode: 0755]
CPP/7zip/MyVersionInfo.rc [new file with mode: 0755]
CPP/7zip/PropID.h [new file with mode: 0755]
CPP/7zip/SubBuild.mak [new file with mode: 0755]
CPP/7zip/UI/Client7z/Client7z.cpp [new file with mode: 0755]
CPP/7zip/UI/Client7z/Client7z.dsp [new file with mode: 0755]
CPP/7zip/UI/Client7z/Client7z.dsw [new file with mode: 0755]
CPP/7zip/UI/Client7z/StdAfx.cpp [new file with mode: 0755]
CPP/7zip/UI/Client7z/StdAfx.h [new file with mode: 0755]
CPP/7zip/UI/Client7z/makefile [new file with mode: 0755]
CPP/7zip/UI/Common/ArchiveCommandLine.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/ArchiveCommandLine.h [new file with mode: 0755]
CPP/7zip/UI/Common/ArchiveExtractCallback.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/ArchiveExtractCallback.h [new file with mode: 0755]
CPP/7zip/UI/Common/ArchiveName.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/ArchiveName.h [new file with mode: 0755]
CPP/7zip/UI/Common/ArchiveOpenCallback.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/ArchiveOpenCallback.h [new file with mode: 0755]
CPP/7zip/UI/Common/Bench.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/Bench.h [new file with mode: 0755]
CPP/7zip/UI/Common/DefaultName.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/DefaultName.h [new file with mode: 0755]
CPP/7zip/UI/Common/DirItem.h [new file with mode: 0755]
CPP/7zip/UI/Common/EnumDirItems.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/EnumDirItems.h [new file with mode: 0755]
CPP/7zip/UI/Common/ExitCode.h [new file with mode: 0755]
CPP/7zip/UI/Common/Extract.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/Extract.h [new file with mode: 0755]
CPP/7zip/UI/Common/ExtractMode.h [new file with mode: 0755]
CPP/7zip/UI/Common/ExtractingFilePath.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/ExtractingFilePath.h [new file with mode: 0755]
CPP/7zip/UI/Common/IFileExtractCallback.h [new file with mode: 0755]
CPP/7zip/UI/Common/LoadCodecs.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/LoadCodecs.h [new file with mode: 0755]
CPP/7zip/UI/Common/OpenArchive.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/OpenArchive.h [new file with mode: 0755]
CPP/7zip/UI/Common/PropIDUtils.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/PropIDUtils.h [new file with mode: 0755]
CPP/7zip/UI/Common/Property.h [new file with mode: 0755]
CPP/7zip/UI/Common/SetProperties.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/SetProperties.h [new file with mode: 0755]
CPP/7zip/UI/Common/SortUtils.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/SortUtils.h [new file with mode: 0755]
CPP/7zip/UI/Common/StdAfx.h [new file with mode: 0755]
CPP/7zip/UI/Common/TempFiles.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/TempFiles.h [new file with mode: 0755]
CPP/7zip/UI/Common/Update.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/Update.h [new file with mode: 0755]
CPP/7zip/UI/Common/UpdateAction.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/UpdateAction.h [new file with mode: 0755]
CPP/7zip/UI/Common/UpdateCallback.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/UpdateCallback.h [new file with mode: 0755]
CPP/7zip/UI/Common/UpdatePair.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/UpdatePair.h [new file with mode: 0755]
CPP/7zip/UI/Common/UpdateProduce.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/UpdateProduce.h [new file with mode: 0755]
CPP/7zip/UI/Common/WorkDir.cpp [new file with mode: 0755]
CPP/7zip/UI/Common/WorkDir.h [new file with mode: 0755]
CPP/7zip/UI/Common/ZipRegistry.h [new file with mode: 0755]
CPP/7zip/UI/Console/BenchCon.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/BenchCon.h [new file with mode: 0755]
CPP/7zip/UI/Console/ConsoleClose.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/ConsoleClose.h [new file with mode: 0755]
CPP/7zip/UI/Console/ExtractCallbackConsole.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/ExtractCallbackConsole.h [new file with mode: 0755]
CPP/7zip/UI/Console/List.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/List.h [new file with mode: 0755]
CPP/7zip/UI/Console/Main.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/MainAr.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/OpenCallbackConsole.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/OpenCallbackConsole.h [new file with mode: 0755]
CPP/7zip/UI/Console/PercentPrinter.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/PercentPrinter.h [new file with mode: 0755]
CPP/7zip/UI/Console/StdAfx.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/StdAfx.h [new file with mode: 0755]
CPP/7zip/UI/Console/UpdateCallbackConsole.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/UpdateCallbackConsole.h [new file with mode: 0755]
CPP/7zip/UI/Console/UserInputUtils.cpp [new file with mode: 0755]
CPP/7zip/UI/Console/UserInputUtils.h [new file with mode: 0755]
CPP/7zip/UI/Console/makefile [new file with mode: 0755]
CPP/7zip/UI/Console/resource.rc [new file with mode: 0755]
CPP/Build.mak [new file with mode: 0755]
CPP/Common/AutoPtr.h [new file with mode: 0755]
CPP/Common/Buffer.h [new file with mode: 0755]
CPP/Common/CRC.cpp [new file with mode: 0755]
CPP/Common/C_FileIO.cpp [new file with mode: 0755]
CPP/Common/C_FileIO.h [new file with mode: 0755]
CPP/Common/ComTry.h [new file with mode: 0755]
CPP/Common/CommandLineParser.cpp [new file with mode: 0755]
CPP/Common/CommandLineParser.h [new file with mode: 0755]
CPP/Common/Defs.h [new file with mode: 0755]
CPP/Common/DynamicBuffer.h [new file with mode: 0755]
CPP/Common/IntToString.cpp [new file with mode: 0755]
CPP/Common/IntToString.h [new file with mode: 0755]
CPP/Common/ListFileUtils.cpp [new file with mode: 0755]
CPP/Common/ListFileUtils.h [new file with mode: 0755]
CPP/Common/MyCom.h [new file with mode: 0755]
CPP/Common/MyException.h [new file with mode: 0755]
CPP/Common/MyGuidDef.h [new file with mode: 0755]
CPP/Common/MyInitGuid.h [new file with mode: 0755]
CPP/Common/MyString.cpp [new file with mode: 0755]
CPP/Common/MyString.h [new file with mode: 0755]
CPP/Common/MyUnknown.h [new file with mode: 0755]
CPP/Common/MyVector.cpp [new file with mode: 0755]
CPP/Common/MyVector.h [new file with mode: 0755]
CPP/Common/MyWindows.h [new file with mode: 0755]
CPP/Common/NewHandler.cpp [new file with mode: 0755]
CPP/Common/NewHandler.h [new file with mode: 0755]
CPP/Common/StdAfx.h [new file with mode: 0755]
CPP/Common/StdInStream.cpp [new file with mode: 0755]
CPP/Common/StdInStream.h [new file with mode: 0755]
CPP/Common/StdOutStream.cpp [new file with mode: 0755]
CPP/Common/StdOutStream.h [new file with mode: 0755]
CPP/Common/StringConvert.cpp [new file with mode: 0755]
CPP/Common/StringConvert.h [new file with mode: 0755]
CPP/Common/StringToInt.cpp [new file with mode: 0755]
CPP/Common/StringToInt.h [new file with mode: 0755]
CPP/Common/Types.h [new file with mode: 0755]
CPP/Common/UTFConvert.cpp [new file with mode: 0755]
CPP/Common/UTFConvert.h [new file with mode: 0755]
CPP/Common/Wildcard.cpp [new file with mode: 0755]
CPP/Common/Wildcard.h [new file with mode: 0755]
CPP/Windows/DLL.cpp [new file with mode: 0755]
CPP/Windows/DLL.h [new file with mode: 0755]
CPP/Windows/Defs.h [new file with mode: 0755]
CPP/Windows/Error.cpp [new file with mode: 0755]
CPP/Windows/Error.h [new file with mode: 0755]
CPP/Windows/FileDir.cpp [new file with mode: 0755]
CPP/Windows/FileDir.h [new file with mode: 0755]
CPP/Windows/FileFind.cpp [new file with mode: 0755]
CPP/Windows/FileFind.h [new file with mode: 0755]
CPP/Windows/FileIO.cpp [new file with mode: 0755]
CPP/Windows/FileIO.h [new file with mode: 0755]
CPP/Windows/FileMapping.cpp [new file with mode: 0755]
CPP/Windows/FileMapping.h [new file with mode: 0755]
CPP/Windows/FileName.cpp [new file with mode: 0755]
CPP/Windows/FileName.h [new file with mode: 0755]
CPP/Windows/Handle.h [new file with mode: 0755]
CPP/Windows/MemoryLock.cpp [new file with mode: 0755]
CPP/Windows/MemoryLock.h [new file with mode: 0755]
CPP/Windows/NtCheck.h [new file with mode: 0755]
CPP/Windows/PropVariant.cpp [new file with mode: 0755]
CPP/Windows/PropVariant.h [new file with mode: 0755]
CPP/Windows/PropVariantConversions.cpp [new file with mode: 0755]
CPP/Windows/PropVariantConversions.h [new file with mode: 0755]
CPP/Windows/Registry.cpp [new file with mode: 0755]
CPP/Windows/Registry.h [new file with mode: 0755]
CPP/Windows/StdAfx.h [new file with mode: 0755]
CPP/Windows/Synchronization.cpp [new file with mode: 0755]
CPP/Windows/Synchronization.h [new file with mode: 0755]
CPP/Windows/System.cpp [new file with mode: 0755]
CPP/Windows/System.h [new file with mode: 0755]
CPP/Windows/Thread.h [new file with mode: 0755]
CPP/Windows/Time.cpp [new file with mode: 0755]
CPP/Windows/Time.h [new file with mode: 0755]
CS/7zip/Common/CRC.cs [new file with mode: 0755]
CS/7zip/Common/CommandLineParser.cs [new file with mode: 0755]
CS/7zip/Common/InBuffer.cs [new file with mode: 0755]
CS/7zip/Common/OutBuffer.cs [new file with mode: 0755]
CS/7zip/Compress/LZ/IMatchFinder.cs [new file with mode: 0755]
CS/7zip/Compress/LZ/LzBinTree.cs [new file with mode: 0755]
CS/7zip/Compress/LZ/LzInWindow.cs [new file with mode: 0755]
CS/7zip/Compress/LZ/LzOutWindow.cs [new file with mode: 0755]
CS/7zip/Compress/LZMA/LzmaBase.cs [new file with mode: 0755]
CS/7zip/Compress/LZMA/LzmaDecoder.cs [new file with mode: 0755]
CS/7zip/Compress/LZMA/LzmaEncoder.cs [new file with mode: 0755]
CS/7zip/Compress/LzmaAlone/LzmaAlone.cs [new file with mode: 0755]
CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj [new file with mode: 0755]
CS/7zip/Compress/LzmaAlone/LzmaAlone.sln [new file with mode: 0755]
CS/7zip/Compress/LzmaAlone/LzmaBench.cs [new file with mode: 0755]
CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs [new file with mode: 0755]
CS/7zip/Compress/LzmaAlone/Properties/Resources.cs [new file with mode: 0755]
CS/7zip/Compress/LzmaAlone/Properties/Settings.cs [new file with mode: 0755]
CS/7zip/Compress/RangeCoder/RangeCoder.cs [new file with mode: 0755]
CS/7zip/Compress/RangeCoder/RangeCoderBit.cs [new file with mode: 0755]
CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs [new file with mode: 0755]
CS/7zip/ICoder.cs [new file with mode: 0755]
Java/SevenZip/CRC.java [new file with mode: 0755]
Java/SevenZip/Compression/LZ/BinTree.java [new file with mode: 0755]
Java/SevenZip/Compression/LZ/InWindow.java [new file with mode: 0755]
Java/SevenZip/Compression/LZ/OutWindow.java [new file with mode: 0755]
Java/SevenZip/Compression/LZMA/Base.java [new file with mode: 0755]
Java/SevenZip/Compression/LZMA/Decoder.java [new file with mode: 0755]
Java/SevenZip/Compression/LZMA/Encoder.java [new file with mode: 0755]
Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java [new file with mode: 0755]
Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java [new file with mode: 0755]
Java/SevenZip/Compression/RangeCoder/Decoder.java [new file with mode: 0755]
Java/SevenZip/Compression/RangeCoder/Encoder.java [new file with mode: 0755]
Java/SevenZip/ICodeProgress.java [new file with mode: 0755]
Java/SevenZip/LzmaAlone.java [new file with mode: 0755]
Java/SevenZip/LzmaBench.java [new file with mode: 0755]
Methods.txt [new file with mode: 0755]
history.txt [new file with mode: 0755]
lzma.exe [new file with mode: 0755]
lzma.txt [new file with mode: 0755]

diff --git a/7zC.txt b/7zC.txt
new file mode 100755 (executable)
index 0000000..4ff6325
--- /dev/null
+++ b/7zC.txt
@@ -0,0 +1,194 @@
+7z ANSI-C Decoder 4.62\r
+----------------------\r
+\r
+7z ANSI-C provides 7z/LZMA decoding.\r
+7z ANSI-C version is simplified version ported from C++ code.\r
+\r
+LZMA is default and general compression method of 7z format\r
+in 7-Zip compression program (www.7-zip.org). LZMA provides high \r
+compression ratio and very fast decompression.\r
+\r
+\r
+LICENSE\r
+-------\r
+\r
+7z ANSI-C Decoder is part of the LZMA SDK.\r
+LZMA SDK is written and placed in the public domain by Igor Pavlov.\r
+\r
+Files\r
+---------------------\r
+\r
+7zDecode.*   - Low level 7z decoding\r
+7zExtract.*  - High level 7z decoding\r
+7zHeader.*   - .7z format constants\r
+7zIn.*       - .7z archive opening\r
+7zItem.*     - .7z structures\r
+7zMain.c     - Test application\r
+\r
+\r
+How To Use\r
+----------\r
+\r
+You must download 7-Zip program from www.7-zip.org.\r
+\r
+You can create .7z archive with 7z.exe or 7za.exe:\r
+\r
+  7za.exe a archive.7z *.htm -r -mx -m0fb=255\r
+\r
+If you have big number of files in archive, and you need fast extracting, \r
+you can use partly-solid archives:\r
+  \r
+  7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K\r
+\r
+In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only \r
+512KB for extracting one file from such archive.\r
+\r
+\r
+Limitations of current version of 7z ANSI-C Decoder\r
+---------------------------------------------------\r
+\r
+ - It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive.\r
+ - It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters.\r
+ - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names.\r
\r
+These limitations will be fixed in future versions.\r
+\r
+\r
+Using 7z ANSI-C Decoder Test application:\r
+-----------------------------------------\r
+\r
+Usage: 7zDec <command> <archive_name>\r
+\r
+<Command>:\r
+  e: Extract files from archive\r
+  l: List contents of archive\r
+  t: Test integrity of archive\r
+\r
+Example: \r
+\r
+  7zDec l archive.7z\r
+\r
+lists contents of archive.7z\r
+\r
+  7zDec e archive.7z\r
+\r
+extracts files from archive.7z to current folder.\r
+\r
+\r
+How to use .7z Decoder\r
+----------------------\r
+\r
+Memory allocation\r
+~~~~~~~~~~~~~~~~~\r
+\r
+7z Decoder uses two memory pools:\r
+1) Temporary pool\r
+2) Main pool\r
+Such scheme can allow you to avoid fragmentation of allocated blocks.\r
+\r
+\r
+Steps for using 7z decoder\r
+--------------------------\r
+\r
+Use code at 7zMain.c as example.\r
+\r
+1) Declare variables:\r
+  inStream                 /* implements ILookInStream interface */\r
+  CSzArEx db;              /* 7z archive database structure */\r
+  ISzAlloc allocImp;       /* memory functions for main pool */\r
+  ISzAlloc allocTempImp;   /* memory functions for temporary pool */\r
+\r
+2) call CrcGenerateTable(); function to initialize CRC structures.\r
+\r
+3) call SzArEx_Init(&db); function to initialize db structures.\r
+\r
+4) call SzArEx_Open(&db, inStream, &allocMain, &allocTemp) to open archive\r
+\r
+This function opens archive "inStream" and reads headers to "db".\r
+All items in "db" will be allocated with "allocMain" functions.\r
+SzArEx_Open function allocates and frees temporary structures by "allocTemp" functions.\r
+\r
+5) List items or Extract items\r
+\r
+  Listing code:\r
+  ~~~~~~~~~~~~~\r
+    {\r
+      UInt32 i;\r
+      for (i = 0; i < db.db.NumFiles; i++)\r
+      {\r
+        CFileItem *f = db.db.Files + i;\r
+        printf("%10d  %s\n", (int)f->Size, f->Name);\r
+      }\r
+    }\r
+\r
+  Extracting code:\r
+  ~~~~~~~~~~~~~~~~\r
+\r
+  SZ_RESULT SzAr_Extract(\r
+    CArchiveDatabaseEx *db,\r
+    ILookInStream *inStream, \r
+    UInt32 fileIndex,         /* index of file */\r
+    UInt32 *blockIndex,       /* index of solid block */\r
+    Byte **outBuffer,         /* pointer to pointer to output buffer (allocated with allocMain) */\r
+    size_t *outBufferSize,    /* buffer size for output buffer */\r
+    size_t *offset,           /* offset of stream for required file in *outBuffer */\r
+    size_t *outSizeProcessed, /* size of file in *outBuffer */\r
+    ISzAlloc *allocMain,\r
+    ISzAlloc *allocTemp);\r
+\r
+  If you need to decompress more than one file, you can send these values from previous call:\r
+    blockIndex, \r
+    outBuffer, \r
+    outBufferSize,\r
+  You can consider "outBuffer" as cache of solid block. If your archive is solid, \r
+  it will increase decompression speed.\r
+\r
+  After decompressing you must free "outBuffer":\r
+  allocImp.Free(outBuffer);\r
+\r
+6) call SzArEx_Free(&db, allocImp.Free) to free allocated items in "db".\r
+\r
+\r
+\r
+\r
+Memory requirements for .7z decoding \r
+------------------------------------\r
+\r
+Memory usage for Archive opening:\r
+  - Temporary pool:\r
+     - Memory for uncompressed .7z headers\r
+     - some other temporary blocks\r
+  - Main pool:\r
+     - Memory for database: \r
+       Estimated size of one file structures in solid archive:\r
+         - Size (4 or 8 Bytes)\r
+         - CRC32 (4 bytes)\r
+         - LastWriteTime (8 bytes)\r
+         - Some file information (4 bytes)\r
+         - File Name (variable length) + pointer + allocation structures\r
+\r
+Memory usage for archive Decompressing:\r
+  - Temporary pool:\r
+     - Memory for LZMA decompressing structures\r
+  - Main pool:\r
+     - Memory for decompressed solid block\r
+     - Memory for temprorary buffers, if BCJ2 fileter is used. Usually these \r
+       temprorary buffers can be about 15% of solid block size. \r
+  \r
+\r
+7z Decoder doesn't allocate memory for compressed blocks. \r
+Instead of this, you must allocate buffer with desired \r
+size before calling 7z Decoder. Use 7zMain.c as example.\r
+\r
+\r
+Defines\r
+-------\r
+\r
+_SZ_ALLOC_DEBUG   - define it if you want to debug alloc/free operations to stderr.\r
+\r
+\r
+---\r
+\r
+http://www.7-zip.org\r
+http://www.7-zip.org/sdk.html\r
+http://www.7-zip.org/support.html\r
diff --git a/7zFormat.txt b/7zFormat.txt
new file mode 100755 (executable)
index 0000000..f084c05
--- /dev/null
@@ -0,0 +1,471 @@
+7z Format description (2.30 Beta 25)\r
+-----------------------------------\r
+\r
+This file contains description of 7z archive format. \r
+7z archive can contain files compressed with any method.\r
+See "Methods.txt" for description for defined compressing methods.\r
+\r
+\r
+Format structure Overview\r
+-------------------------\r
+\r
+Some fields can be optional.\r
+\r
+Archive structure\r
+~~~~~~~~~~~~~~~~~  \r
+SignatureHeader\r
+[PackedStreams]\r
+[PackedStreamsForHeaders]\r
+[\r
+  Header \r
+  or \r
+  {\r
+    Packed Header\r
+    HeaderInfo\r
+  }\r
+]\r
+\r
+\r
+\r
+Header structure\r
+~~~~~~~~~~~~~~~~  \r
+{\r
+  ArchiveProperties\r
+  AdditionalStreams\r
+  {\r
+    PackInfo\r
+    {\r
+      PackPos\r
+      NumPackStreams\r
+      Sizes[NumPackStreams]\r
+      CRCs[NumPackStreams]\r
+    }\r
+    CodersInfo\r
+    {\r
+      NumFolders\r
+      Folders[NumFolders]\r
+      {\r
+        NumCoders\r
+        CodersInfo[NumCoders]\r
+        {\r
+          ID\r
+          NumInStreams;\r
+          NumOutStreams;\r
+          PropertiesSize\r
+          Properties[PropertiesSize]\r
+        }\r
+        NumBindPairs\r
+        BindPairsInfo[NumBindPairs]\r
+        {\r
+          InIndex;\r
+          OutIndex;\r
+        }\r
+        PackedIndices\r
+      }\r
+      UnPackSize[Folders][Folders.NumOutstreams]\r
+      CRCs[NumFolders]\r
+    }\r
+    SubStreamsInfo\r
+    {\r
+      NumUnPackStreamsInFolders[NumFolders];\r
+      UnPackSizes[]\r
+      CRCs[]\r
+    }\r
+  }\r
+  MainStreamsInfo\r
+  {\r
+    (Same as in AdditionalStreams)\r
+  }\r
+  FilesInfo\r
+  {\r
+    NumFiles\r
+    Properties[]\r
+    {\r
+      ID\r
+      Size\r
+      Data\r
+    }\r
+  }\r
+}\r
+\r
+HeaderInfo structure\r
+~~~~~~~~~~~~~~~~~~~~\r
+{\r
+  (Same as in AdditionalStreams)\r
+}\r
+\r
+\r
+\r
+Notes about Notation and encoding\r
+---------------------------------\r
+\r
+7z uses little endian encoding.\r
+\r
+7z archive format has optional headers that are marked as\r
+[]\r
+Header\r
+[]\r
+\r
+REAL_UINT64 means real UINT64.\r
+\r
+UINT64 means real UINT64 encoded with the following scheme:\r
+\r
+  Size of encoding sequence depends from first byte:\r
+  First_Byte  Extra_Bytes        Value\r
+  (binary)   \r
+  0xxxxxxx               : ( xxxxxxx           )\r
+  10xxxxxx    BYTE y[1]  : (  xxxxxx << (8 * 1)) + y\r
+  110xxxxx    BYTE y[2]  : (   xxxxx << (8 * 2)) + y\r
+  ...\r
+  1111110x    BYTE y[6]  : (       x << (8 * 6)) + y\r
+  11111110    BYTE y[7]  :                         y\r
+  11111111    BYTE y[8]  :                         y\r
+\r
+\r
+\r
+Property IDs\r
+------------\r
+\r
+0x00 = kEnd,\r
+\r
+0x01 = kHeader,\r
+\r
+0x02 = kArchiveProperties,\r
+    \r
+0x03 = kAdditionalStreamsInfo,\r
+0x04 = kMainStreamsInfo,\r
+0x05 = kFilesInfo,\r
+    \r
+0x06 = kPackInfo,\r
+0x07 = kUnPackInfo,\r
+0x08 = kSubStreamsInfo,\r
+\r
+0x09 = kSize,\r
+0x0A = kCRC,\r
+\r
+0x0B = kFolder,\r
+\r
+0x0C = kCodersUnPackSize,\r
+0x0D = kNumUnPackStream,\r
+\r
+0x0E = kEmptyStream,\r
+0x0F = kEmptyFile,\r
+0x10 = kAnti,\r
+\r
+0x11 = kName,\r
+0x12 = kCreationTime,\r
+0x13 = kLastAccessTime,\r
+0x14 = kLastWriteTime,\r
+0x15 = kWinAttributes,\r
+0x16 = kComment,\r
+\r
+0x17 = kEncodedHeader,\r
+\r
+\r
+7z format headers\r
+-----------------\r
+\r
+SignatureHeader\r
+~~~~~~~~~~~~~~~\r
+  BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};\r
+\r
+  ArchiveVersion\r
+  {\r
+    BYTE Major;   // now = 0\r
+    BYTE Minor;   // now = 2\r
+  };\r
+\r
+  UINT32 StartHeaderCRC;\r
+\r
+  StartHeader\r
+  {\r
+    REAL_UINT64 NextHeaderOffset\r
+    REAL_UINT64 NextHeaderSize\r
+    UINT32 NextHeaderCRC\r
+  }\r
+\r
+\r
+...........................\r
+\r
+\r
+ArchiveProperties\r
+~~~~~~~~~~~~~~~~~\r
+BYTE NID::kArchiveProperties (0x02)\r
+for (;;)\r
+{\r
+  BYTE PropertyType;\r
+  if (aType == 0)\r
+    break;\r
+  UINT64 PropertySize;\r
+  BYTE PropertyData[PropertySize];\r
+}\r
+\r
+\r
+Digests (NumStreams)\r
+~~~~~~~~~~~~~~~~~~~~~\r
+  BYTE AllAreDefined\r
+  if (AllAreDefined == 0)\r
+  {\r
+    for(NumStreams)\r
+      BIT Defined\r
+  }\r
+  UINT32 CRCs[NumDefined]\r
+\r
+\r
+PackInfo\r
+~~~~~~~~~~~~\r
+  BYTE NID::kPackInfo  (0x06)\r
+  UINT64 PackPos\r
+  UINT64 NumPackStreams\r
+\r
+  []\r
+  BYTE NID::kSize    (0x09)\r
+  UINT64 PackSizes[NumPackStreams]\r
+  []\r
+\r
+  []\r
+  BYTE NID::kCRC      (0x0A)\r
+  PackStreamDigests[NumPackStreams]\r
+  []\r
+\r
+  BYTE NID::kEnd\r
+\r
+\r
+Folder\r
+~~~~~~\r
+  UINT64 NumCoders;\r
+  for (NumCoders)\r
+  {\r
+    BYTE \r
+    {\r
+      0:3 DecompressionMethod.IDSize\r
+      4:\r
+        0 - IsSimple\r
+        1 - Is not simple\r
+      5:\r
+        0 - No Attributes\r
+        1 - There Are Attributes\r
+      7:\r
+        0 - Last Method in Alternative_Method_List\r
+        1 - There are more alternative methods\r
+    } \r
+    BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]\r
+    if (!IsSimple)\r
+    {\r
+      UINT64 NumInStreams;\r
+      UINT64 NumOutStreams;\r
+    }\r
+    if (DecompressionMethod[0] != 0)\r
+    {\r
+      UINT64 PropertiesSize\r
+      BYTE Properties[PropertiesSize]\r
+    }\r
+  }\r
+    \r
+  NumBindPairs = NumOutStreamsTotal - 1;\r
+\r
+  for (NumBindPairs)\r
+  {\r
+    UINT64 InIndex;\r
+    UINT64 OutIndex;\r
+  }\r
+\r
+  NumPackedStreams = NumInStreamsTotal - NumBindPairs;\r
+  if (NumPackedStreams > 1)\r
+    for(NumPackedStreams)\r
+    {\r
+      UINT64 Index;\r
+    };\r
+\r
+\r
+\r
+\r
+Coders Info\r
+~~~~~~~~~~~\r
+\r
+  BYTE NID::kUnPackInfo  (0x07)\r
+\r
+\r
+  BYTE NID::kFolder  (0x0B)\r
+  UINT64 NumFolders\r
+  BYTE External\r
+  switch(External)\r
+  {\r
+    case 0:\r
+      Folders[NumFolders]\r
+    case 1:\r
+      UINT64 DataStreamIndex\r
+  }\r
+\r
+\r
+  BYTE ID::kCodersUnPackSize  (0x0C)\r
+  for(Folders)\r
+    for(Folder.NumOutStreams)\r
+     UINT64 UnPackSize;\r
+\r
+\r
+  []\r
+  BYTE NID::kCRC   (0x0A)\r
+  UnPackDigests[NumFolders]\r
+  []\r
+\r
+  \r
+\r
+  BYTE NID::kEnd\r
+\r
+\r
+\r
+SubStreams Info\r
+~~~~~~~~~~~~~~\r
+  BYTE NID::kSubStreamsInfo; (0x08)\r
+\r
+  []\r
+  BYTE NID::kNumUnPackStream; (0x0D)\r
+  UINT64 NumUnPackStreamsInFolders[NumFolders];\r
+  []\r
+\r
+\r
+  []\r
+  BYTE NID::kSize  (0x09)\r
+  UINT64 UnPackSizes[]\r
+  []\r
+\r
+\r
+  []\r
+  BYTE NID::kCRC  (0x0A)\r
+  Digests[Number of streams with unknown CRC]\r
+  []\r
+\r
+  \r
+  BYTE NID::kEnd\r
+\r
+\r
+Streams Info\r
+~~~~~~~~~~~~\r
+\r
+  []\r
+  PackInfo\r
+  []\r
+\r
+\r
+  []\r
+  CodersInfo\r
+  []\r
+\r
+\r
+  []\r
+  SubStreamsInfo\r
+  []\r
+\r
+  BYTE NID::kEnd\r
+\r
+\r
+FilesInfo\r
+~~~~~~~~~\r
+  BYTE NID::kFilesInfo;  (0x05)\r
+  UINT64 NumFiles\r
+\r
+  for (;;)\r
+  {\r
+    BYTE PropertyType;\r
+    if (aType == 0)\r
+      break;\r
+\r
+    UINT64 Size;\r
+\r
+    switch(PropertyType)\r
+    {\r
+      kEmptyStream:   (0x0E)\r
+        for(NumFiles)\r
+          BIT IsEmptyStream\r
+\r
+      kEmptyFile:     (0x0F)\r
+        for(EmptyStreams)\r
+          BIT IsEmptyFile\r
+\r
+      kAnti:          (0x10)\r
+        for(EmptyStreams)\r
+          BIT IsAntiFile\r
+      \r
+      case kCreationTime:   (0x12)\r
+      case kLastAccessTime: (0x13)\r
+      case kLastWriteTime:  (0x14)\r
+        BYTE AllAreDefined\r
+        if (AllAreDefined == 0)\r
+        {\r
+          for(NumFiles)\r
+            BIT TimeDefined\r
+        }\r
+        BYTE External;\r
+        if(External != 0)\r
+          UINT64 DataIndex\r
+        []\r
+        for(Definded Items)\r
+          UINT32 Time\r
+        []\r
+      \r
+      kNames:     (0x11)\r
+        BYTE External;\r
+        if(External != 0)\r
+          UINT64 DataIndex\r
+        []\r
+        for(Files)\r
+        {\r
+          wchar_t Names[NameSize];\r
+          wchar_t 0;\r
+        }\r
+        []\r
+\r
+      kAttributes:  (0x15)\r
+        BYTE AllAreDefined\r
+        if (AllAreDefined == 0)\r
+        {\r
+          for(NumFiles)\r
+            BIT AttributesAreDefined\r
+        }\r
+        BYTE External;\r
+        if(External != 0)\r
+          UINT64 DataIndex\r
+        []\r
+        for(Definded Attributes)\r
+          UINT32 Attributes\r
+        []\r
+    }\r
+  }\r
+\r
+\r
+Header\r
+~~~~~~\r
+  BYTE NID::kHeader (0x01)\r
+\r
+  []\r
+  ArchiveProperties\r
+  []\r
+\r
+  []\r
+  BYTE NID::kAdditionalStreamsInfo; (0x03)\r
+  StreamsInfo\r
+  []\r
+\r
+  []\r
+  BYTE NID::kMainStreamsInfo;    (0x04)\r
+  StreamsInfo\r
+  []\r
+\r
+  []\r
+  FilesInfo\r
+  []\r
+\r
+  BYTE NID::kEnd\r
+\r
+\r
+HeaderInfo\r
+~~~~~~~~~~\r
+  []\r
+  BYTE NID::kEncodedHeader; (0x17)\r
+  StreamsInfo for Encoded Header\r
+  []\r
+\r
+\r
+---\r
+End of document\r
diff --git a/7zr.exe b/7zr.exe
new file mode 100755 (executable)
index 0000000..2dbefa9
Binary files /dev/null and b/7zr.exe differ
diff --git a/Asm/arm/7zCrcOpt.asm b/Asm/arm/7zCrcOpt.asm
new file mode 100755 (executable)
index 0000000..f008d65
--- /dev/null
@@ -0,0 +1,100 @@
+       CODE32\r
+\r
+       EXPORT  |CrcUpdateT4@16|\r
+\r
+       AREA    |.text|, CODE, ARM\r
+\r
+       MACRO\r
+       CRC32_STEP_1\r
+\r
+       ldrb    r4, [r1], #1\r
+       subs    r2, r2, #1\r
+       eor     r4, r4, r0\r
+       and     r4, r4, #0xFF\r
+       ldr     r4, [r3, +r4, lsl #2]\r
+       eor     r0, r4, r0, lsr #8\r
+\r
+       MEND\r
+\r
+\r
+       MACRO\r
+       CRC32_STEP_4 $STREAM_WORD\r
+       \r
+       eor     r7, r7, r8\r
+       eor     r7, r7, r9\r
+       eor     r0, r0, r7\r
+       eor     r0, r0, $STREAM_WORD\r
+       ldr     $STREAM_WORD, [r1], #4\r
+       \r
+       and     r7, r0, #0xFF\r
+       and     r8, r0, #0xFF00\r
+       and     r9, r0, #0xFF0000\r
+       and     r0, r0, #0xFF000000\r
+\r
+       ldr     r7, [r6, +r7, lsl #2]\r
+       ldr     r8, [r5, +r8, lsr #6]\r
+       ldr     r9, [r4, +r9, lsr #14]\r
+       ldr     r0, [r3, +r0, lsr #22]\r
+       \r
+       MEND\r
+\r
+\r
+|CrcUpdateT4@16| PROC\r
+\r
+       stmdb   sp!, {r4-r11, lr}\r
+       cmp     r2, #0\r
+       beq     |$fin|\r
+\r
+|$v1|\r
+       tst     r1, #7\r
+       beq     |$v2|\r
+       CRC32_STEP_1\r
+       bne     |$v1|\r
+\r
+|$v2|\r
+       cmp     r2, #16\r
+       blo     |$v3|\r
+\r
+       ldr     r10, [r1], #4\r
+       ldr     r11, [r1], #4\r
+\r
+       add     r4, r3, #0x400 \r
+       add     r5, r3, #0x800\r
+       add     r6, r3, #0xC00\r
+\r
+       mov     r7, #0\r
+       mov     r8, #0\r
+       mov     r9, #0\r
+\r
+       sub     r2, r2, #16\r
+\r
+|$loop|\r
+       ; pld     [r1, #0x40]\r
+\r
+       CRC32_STEP_4 r10\r
+       CRC32_STEP_4 r11\r
+\r
+       subs    r2, r2, #8\r
+       bhs     |$loop|\r
+\r
+       sub     r1, r1, #8\r
+       add     r2, r2, #16\r
+\r
+       eor     r7, r7, r8\r
+       eor     r7, r7, r9\r
+       eor     r0, r0, r7\r
+\r
+|$v3|\r
+       cmp     r2, #0\r
+       beq     |$fin|\r
+\r
+|$v4|\r
+       CRC32_STEP_1\r
+       bne     |$v4|\r
+\r
+|$fin|\r
+       ldmia   sp!, {r4-r11, pc}\r
+\r
+|CrcUpdateT4@16| ENDP\r
+\r
+       END\r
diff --git a/Asm/x86/7zAsm.asm b/Asm/x86/7zAsm.asm
new file mode 100755 (executable)
index 0000000..5a5f271
--- /dev/null
@@ -0,0 +1,93 @@
+; 7zAsm.asm -- ASM macros\r
+; 2009-12-12 : Igor Pavlov : Public domain\r
+\r
+MY_ASM_START macro\r
+  ifdef x64\r
+    .code\r
+  else\r
+    .386\r
+    .model flat\r
+    _TEXT$00 SEGMENT PARA PUBLIC 'CODE'\r
+  endif\r
+endm\r
+\r
+MY_PROC macro name:req, numParams:req\r
+  align 16\r
+  proc_numParams equ numParams\r
+  ifdef x64\r
+    proc_name equ name\r
+    name PROC\r
+  else\r
+    proc_fastcall_name equ @CatStr(@,name,@, %numParams * 4)\r
+    public proc_fastcall_name\r
+    proc_fastcall_name:\r
+  endif\r
+endm\r
+\r
+MY_ENDP macro\r
+  ifdef x64\r
+    ret\r
+    proc_name ENDP\r
+  else\r
+    ret (proc_numParams - 2) * 4\r
+  endif\r
+endm\r
+\r
+ifdef x64\r
+  REG_SIZE equ 8\r
+else\r
+  REG_SIZE equ 4\r
+endif\r
+\r
+  x0 equ EAX\r
+  x1 equ ECX\r
+  x2 equ EDX\r
+  x3 equ EBX\r
+  x4 equ ESP\r
+  x5 equ EBP\r
+  x6 equ ESI\r
+  x7 equ EDI\r
+\r
+  x0_L equ AL\r
+  x1_L equ CL\r
+  x2_L equ DL\r
+  x3_L equ BL\r
+\r
+  x0_H equ AH\r
+  x1_H equ CH\r
+  x2_H equ DH\r
+  x3_H equ BH\r
+\r
+ifdef x64\r
+  r0 equ RAX\r
+  r1 equ RCX\r
+  r2 equ RDX\r
+  r3 equ RBX\r
+  r4 equ RSP\r
+  r5 equ RBP\r
+  r6 equ RSI\r
+  r7 equ RDI\r
+else\r
+  r0 equ x0\r
+  r1 equ x1\r
+  r2 equ x2\r
+  r3 equ x3\r
+  r4 equ x4\r
+  r5 equ x5\r
+  r6 equ x6\r
+  r7 equ x7\r
+endif\r
+\r
+MY_PUSH_4_REGS macro\r
+    push    r3\r
+    push    r5\r
+    push    r6\r
+    push    r7\r
+endm\r
+\r
+MY_POP_4_REGS macro\r
+    pop     r7\r
+    pop     r6\r
+    pop     r5\r
+    pop     r3\r
+endm\r
diff --git a/Asm/x86/7zCrcOpt.asm b/Asm/x86/7zCrcOpt.asm
new file mode 100755 (executable)
index 0000000..2de5171
--- /dev/null
@@ -0,0 +1,147 @@
+; 7zCrcOpt.asm -- CRC32 calculation : optimized version\r
+; 2009-12-12 : Igor Pavlov : Public domain\r
+\r
+include 7zAsm.asm\r
+\r
+MY_ASM_START\r
+\r
+rD   equ  r2\r
+rN   equ  r7\r
+\r
+ifdef x64\r
+    num_VAR     equ r8\r
+    table_VAR   equ r9\r
+else\r
+    data_size   equ (REG_SIZE * 5)\r
+    crc_table   equ (REG_SIZE + data_size)\r
+    num_VAR     equ [r4 + data_size]\r
+    table_VAR   equ [r4 + crc_table]\r
+endif\r
+\r
+SRCDAT  equ  rN + rD + 4 *\r
+\r
+CRC macro op:req, dest:req, src:req, t:req\r
+    op      dest, DWORD PTR [r5 + src * 4 + 0400h * t]\r
+endm\r
+\r
+CRC_XOR macro dest:req, src:req, t:req\r
+    CRC xor, dest, src, t\r
+endm\r
+\r
+CRC_MOV macro dest:req, src:req, t:req\r
+    CRC mov, dest, src, t\r
+endm\r
+\r
+CRC1b macro\r
+    movzx   x6, BYTE PTR [rD]\r
+    inc     rD\r
+    movzx   x3, x0_L\r
+    xor     x6, x3\r
+    shr     x0, 8\r
+    CRC     xor, x0, r6, 0\r
+    dec     rN\r
+endm\r
+\r
+MY_PROLOG macro crc_end:req\r
+    MY_PUSH_4_REGS\r
+    \r
+    mov     x0, x1\r
+    mov     rN, num_VAR\r
+    mov     r5, table_VAR\r
+    test    rN, rN\r
+    jz      crc_end\r
+  @@:\r
+    test    rD, 7\r
+    jz      @F\r
+    CRC1b\r
+    jnz     @B\r
+  @@:\r
+    cmp     rN, 16\r
+    jb      crc_end\r
+    add     rN, rD\r
+    mov     num_VAR, rN\r
+    sub     rN, 8\r
+    and     rN, NOT 7\r
+    sub     rD, rN\r
+    xor     x0, [SRCDAT 0]\r
+endm\r
+\r
+MY_EPILOG macro crc_end:req\r
+    xor     x0, [SRCDAT 0]\r
+    mov     rD, rN\r
+    mov     rN, num_VAR\r
+    sub     rN, rD\r
+  crc_end:\r
+    test    rN, rN\r
+    jz      @F\r
+    CRC1b\r
+    jmp     crc_end\r
+  @@:\r
+    MY_POP_4_REGS\r
+endm\r
+\r
+MY_PROC CrcUpdateT8, 4\r
+    MY_PROLOG crc_end_8\r
+    mov     x1, [SRCDAT 1]\r
+    align 16\r
+  main_loop_8:\r
+    mov     x6, [SRCDAT 2]\r
+    movzx   x3, x1_L\r
+    CRC_XOR x6, r3, 3\r
+    movzx   x3, x1_H\r
+    CRC_XOR x6, r3, 2\r
+    shr     x1, 16\r
+    movzx   x3, x1_L\r
+    movzx   x1, x1_H\r
+    CRC_XOR x6, r3, 1\r
+    movzx   x3, x0_L\r
+    CRC_XOR x6, r1, 0\r
+\r
+    mov     x1, [SRCDAT 3]\r
+    CRC_XOR x6, r3, 7\r
+    movzx   x3, x0_H\r
+    shr     x0, 16\r
+    CRC_XOR x6, r3, 6\r
+    movzx   x3, x0_L\r
+    CRC_XOR x6, r3, 5\r
+    movzx   x3, x0_H\r
+    CRC_MOV x0, r3, 4\r
+    xor     x0, x6\r
+    add     rD, 8\r
+    jnz     main_loop_8\r
+\r
+    MY_EPILOG crc_end_8\r
+MY_ENDP\r
+\r
+MY_PROC CrcUpdateT4, 4\r
+    MY_PROLOG crc_end_4\r
+    align 16\r
+  main_loop_4:\r
+    movzx   x1, x0_L\r
+    movzx   x3, x0_H\r
+    shr     x0, 16\r
+    movzx   x6, x0_H\r
+    and     x0, 0FFh\r
+    CRC_MOV x1, r1, 3\r
+    xor     x1, [SRCDAT 1]\r
+    CRC_XOR x1, r3, 2\r
+    CRC_XOR x1, r6, 0\r
+    CRC_XOR x1, r0, 1\r
\r
+    movzx   x0, x1_L\r
+    movzx   x3, x1_H\r
+    shr     x1, 16\r
+    movzx   x6, x1_H\r
+    and     x1, 0FFh\r
+    CRC_MOV x0, r0, 3\r
+    xor     x0, [SRCDAT 2]\r
+    CRC_XOR x0, r3, 2\r
+    CRC_XOR x0, r6, 0\r
+    CRC_XOR x0, r1, 1\r
+    add     rD, 8\r
+    jnz     main_loop_4\r
+\r
+    MY_EPILOG crc_end_4\r
+MY_ENDP\r
+\r
+end\r
diff --git a/Asm/x86/AesOpt.asm b/Asm/x86/AesOpt.asm
new file mode 100755 (executable)
index 0000000..c32e48f
--- /dev/null
@@ -0,0 +1,237 @@
+; AesOpt.asm -- Intel's AES.\r
+; 2009-12-12 : Igor Pavlov : Public domain\r
+\r
+include 7zAsm.asm\r
+\r
+MY_ASM_START\r
+\r
+ifndef x64\r
+    .xmm\r
+endif\r
+\r
+ifdef x64\r
+    num     equ r8\r
+else\r
+    num     equ [r4 + REG_SIZE * 4]\r
+endif\r
+\r
+rD equ r2\r
+rN equ r0\r
+\r
+MY_PROLOG macro reg:req\r
+    ifdef x64\r
+    movdqa  [r4 + 8], xmm6\r
+    movdqa  [r4 + 8 + 16], xmm7\r
+    endif\r
+\r
+    push    r3\r
+    push    r5\r
+    push    r6\r
+\r
+    mov     rN, num\r
+    mov     x6, [r1 + 16]\r
+    shl     x6, 5\r
+\r
+    movdqa  reg, [r1]\r
+    add     r1, 32\r
+endm\r
+\r
+MY_EPILOG macro\r
+    pop     r6\r
+    pop     r5\r
+    pop     r3\r
+\r
+    ifdef x64\r
+    movdqa  xmm6, [r4 + 8]\r
+    movdqa  xmm7, [r4 + 8 + 16]\r
+    endif\r
+\r
+    MY_ENDP\r
+endm\r
+\r
+ways equ 4\r
+ways16 equ (ways * 16)\r
+\r
+OP_W macro op, op2\r
+    i = 0\r
+    rept ways\r
+    op @CatStr(xmm,%i), op2\r
+    i = i + 1\r
+    endm\r
+endm\r
+\r
+LOAD_OP macro op:req, offs:req\r
+    op      xmm0, [r1 + r3 offs]\r
+endm\r
+  \r
+LOAD_OP_W macro op:req, offs:req\r
+    movdqa  xmm7, [r1 + r3 offs]\r
+    OP_W    op, xmm7\r
+endm\r
+\r
+\r
+; ---------- AES-CBC Decode ----------\r
+\r
+CBC_DEC_UPDATE macro reg, offs\r
+    pxor    reg, xmm6\r
+    movdqa  xmm6, [rD + offs]\r
+    movdqa  [rD + offs], reg\r
+endm\r
+\r
+DECODE macro op:req\r
+    op      aesdec, +16\r
+  @@:\r
+    op      aesdec, +0\r
+    op      aesdec, -16\r
+    sub     x3, 32\r
+    jnz     @B\r
+    op      aesdeclast, +0\r
+endm\r
+\r
+MY_PROC AesCbc_Decode_Intel, 3\r
+    MY_PROLOG xmm6\r
+\r
+    sub     x6, 32\r
+\r
+    jmp     check2\r
+\r
+  align 16\r
+  nextBlocks2:\r
+    mov     x3, x6\r
+    OP_W    movdqa, [rD + i * 16]\r
+    LOAD_OP_W  pxor, +32\r
+    DECODE  LOAD_OP_W\r
+    OP_W    CBC_DEC_UPDATE, i * 16\r
+    add     rD, ways16\r
+  check2:\r
+    sub     rN, ways\r
+    jnc     nextBlocks2\r
+\r
+    add     rN, ways\r
+    jmp     check\r
+\r
+  nextBlock:\r
+    mov     x3, x6\r
+    movdqa  xmm1, [rD]\r
+    LOAD_OP movdqa, +32\r
+    pxor    xmm0, xmm1\r
+    DECODE  LOAD_OP\r
+    pxor    xmm0, xmm6\r
+    movdqa  [rD], xmm0\r
+    movdqa  xmm6, xmm1\r
+    add     rD, 16\r
+  check:\r
+    sub     rN, 1\r
+    jnc     nextBlock\r
+\r
+    movdqa  [r1 - 32], xmm6\r
+    MY_EPILOG\r
+\r
+\r
+; ---------- AES-CBC Encode ----------\r
+\r
+ENCODE macro op:req\r
+    op      aesenc, -16\r
+  @@:\r
+    op      aesenc, +0\r
+    op      aesenc, +16\r
+    add     r3, 32\r
+    jnz     @B\r
+    op      aesenclast, +0\r
+endm\r
+\r
+MY_PROC AesCbc_Encode_Intel, 3\r
+    MY_PROLOG xmm0\r
+\r
+    add     r1, r6\r
+    neg     r6\r
+    add     r6, 32\r
+\r
+    jmp     check_e\r
+\r
+  align 16\r
+  nextBlock_e:\r
+    mov     r3, r6\r
+    pxor    xmm0, [rD]\r
+    pxor    xmm0, [r1 + r3 - 32]\r
+    ENCODE  LOAD_OP\r
+    movdqa  [rD], xmm0\r
+    add     rD, 16\r
+  check_e:\r
+    sub     rN, 1\r
+    jnc     nextBlock_e\r
+\r
+    movdqa  [r1 + r6 - 64], xmm0\r
+    MY_EPILOG\r
+\r
+\r
+; ---------- AES-CTR ----------\r
+\r
+XOR_UPD_1 macro reg, offs\r
+    pxor    reg, [rD + offs]\r
+endm\r
+\r
+XOR_UPD_2 macro reg, offs\r
+    movdqa  [rD + offs], reg\r
+endm\r
+\r
+MY_PROC AesCtr_Code_Intel, 3\r
+    MY_PROLOG xmm6\r
+\r
+    mov     r5, r4\r
+    shr     r5, 4\r
+    dec     r5\r
+    shl     r5, 4\r
+\r
+    mov     DWORD PTR [r5], 1\r
+    mov     DWORD PTR [r5 + 4], 0\r
+    mov     DWORD PTR [r5 + 8], 0\r
+    mov     DWORD PTR [r5 + 12], 0\r
+    \r
+    add     r1, r6\r
+    neg     r6\r
+    add     r6, 32\r
+\r
+    jmp     check2_c\r
+\r
+  align 16\r
+  nextBlocks2_c:\r
+    movdqa  xmm7, [r5]\r
+\r
+    i = 0\r
+    rept ways\r
+    paddq   xmm6, xmm7\r
+    movdqa  @CatStr(xmm,%i), xmm6\r
+    i = i + 1\r
+    endm\r
+\r
+    mov     r3, r6\r
+    LOAD_OP_W  pxor, -32\r
+    ENCODE  LOAD_OP_W\r
+    OP_W    XOR_UPD_1, i * 16\r
+    OP_W    XOR_UPD_2, i * 16\r
+    add     rD, ways16\r
+  check2_c:\r
+    sub     rN, ways\r
+    jnc     nextBlocks2_c\r
+\r
+    add     rN, ways\r
+    jmp     check_c\r
+\r
+  nextBlock_c:\r
+    paddq   xmm6, [r5]\r
+    mov     r3, r6\r
+    movdqa  xmm0, [r1 + r3 - 32]\r
+    pxor    xmm0, xmm6\r
+    ENCODE  LOAD_OP\r
+    XOR_UPD_1 xmm0, 0\r
+    XOR_UPD_2 xmm0, 0\r
+    add     rD, 16\r
+  check_c:\r
+    sub     rN, 1\r
+    jnc     nextBlock_c\r
+\r
+    movdqa  [r1 + r6 - 64], xmm6\r
+    MY_EPILOG\r
+\r
+end\r
diff --git a/C/7z.h b/C/7z.h
new file mode 100755 (executable)
index 0000000..b7edd3b
--- /dev/null
+++ b/C/7z.h
@@ -0,0 +1,203 @@
+/* 7z.h -- 7z interface\r
+2010-03-11 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __7Z_H\r
+#define __7Z_H\r
+\r
+#include "7zBuf.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+#define k7zStartHeaderSize 0x20\r
+#define k7zSignatureSize 6\r
+extern Byte k7zSignature[k7zSignatureSize];\r
+#define k7zMajorVersion 0\r
+\r
+enum EIdEnum\r
+{\r
+  k7zIdEnd,\r
+  k7zIdHeader,\r
+  k7zIdArchiveProperties,\r
+  k7zIdAdditionalStreamsInfo,\r
+  k7zIdMainStreamsInfo,\r
+  k7zIdFilesInfo,\r
+  k7zIdPackInfo,\r
+  k7zIdUnpackInfo,\r
+  k7zIdSubStreamsInfo,\r
+  k7zIdSize,\r
+  k7zIdCRC,\r
+  k7zIdFolder,\r
+  k7zIdCodersUnpackSize,\r
+  k7zIdNumUnpackStream,\r
+  k7zIdEmptyStream,\r
+  k7zIdEmptyFile,\r
+  k7zIdAnti,\r
+  k7zIdName,\r
+  k7zIdCTime,\r
+  k7zIdATime,\r
+  k7zIdMTime,\r
+  k7zIdWinAttributes,\r
+  k7zIdComment,\r
+  k7zIdEncodedHeader,\r
+  k7zIdStartPos,\r
+  k7zIdDummy\r
+};\r
+\r
+typedef struct\r
+{\r
+  UInt32 NumInStreams;\r
+  UInt32 NumOutStreams;\r
+  UInt64 MethodID;\r
+  CBuf Props;\r
+} CSzCoderInfo;\r
+\r
+void SzCoderInfo_Init(CSzCoderInfo *p);\r
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);\r
+\r
+typedef struct\r
+{\r
+  UInt32 InIndex;\r
+  UInt32 OutIndex;\r
+} CSzBindPair;\r
+\r
+typedef struct\r
+{\r
+  CSzCoderInfo *Coders;\r
+  CSzBindPair *BindPairs;\r
+  UInt32 *PackStreams;\r
+  UInt64 *UnpackSizes;\r
+  UInt32 NumCoders;\r
+  UInt32 NumBindPairs;\r
+  UInt32 NumPackStreams;\r
+  int UnpackCRCDefined;\r
+  UInt32 UnpackCRC;\r
+\r
+  UInt32 NumUnpackStreams;\r
+} CSzFolder;\r
+\r
+void SzFolder_Init(CSzFolder *p);\r
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);\r
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);\r
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);\r
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);\r
+\r
+SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,\r
+    ILookInStream *stream, UInt64 startPos,\r
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);\r
+\r
+typedef struct\r
+{\r
+  UInt32 Low;\r
+  UInt32 High;\r
+} CNtfsFileTime;\r
+\r
+typedef struct\r
+{\r
+  CNtfsFileTime MTime;\r
+  UInt64 Size;\r
+  UInt32 Crc;\r
+  UInt32 Attrib;\r
+  Byte HasStream;\r
+  Byte IsDir;\r
+  Byte IsAnti;\r
+  Byte CrcDefined;\r
+  Byte MTimeDefined;\r
+  Byte AttribDefined;\r
+} CSzFileItem;\r
+\r
+void SzFile_Init(CSzFileItem *p);\r
+\r
+typedef struct\r
+{\r
+  UInt64 *PackSizes;\r
+  Byte *PackCRCsDefined;\r
+  UInt32 *PackCRCs;\r
+  CSzFolder *Folders;\r
+  CSzFileItem *Files;\r
+  UInt32 NumPackStreams;\r
+  UInt32 NumFolders;\r
+  UInt32 NumFiles;\r
+} CSzAr;\r
+\r
+void SzAr_Init(CSzAr *p);\r
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc);\r
+\r
+\r
+/*\r
+  SzExtract extracts file from archive\r
+\r
+  *outBuffer must be 0 before first call for each new archive.\r
+\r
+  Extracting cache:\r
+    If you need to decompress more than one file, you can send\r
+    these values from previous call:\r
+      *blockIndex,\r
+      *outBuffer,\r
+      *outBufferSize\r
+    You can consider "*outBuffer" as cache of solid block. If your archive is solid,\r
+    it will increase decompression speed.\r
+  \r
+    If you use external function, you can declare these 3 cache variables\r
+    (blockIndex, outBuffer, outBufferSize) as static in that external function.\r
+    \r
+    Free *outBuffer and set *outBuffer to 0, if you want to flush cache.\r
+*/\r
+\r
+typedef struct\r
+{\r
+  CSzAr db;\r
+  \r
+  UInt64 startPosAfterHeader;\r
+  UInt64 dataPos;\r
+\r
+  UInt32 *FolderStartPackStreamIndex;\r
+  UInt64 *PackStreamStartPositions;\r
+  UInt32 *FolderStartFileIndex;\r
+  UInt32 *FileIndexToFolderIndexMap;\r
+\r
+  size_t *FileNameOffsets; /* in 2-byte steps */\r
+  CBuf FileNames;  /* UTF-16-LE */\r
+} CSzArEx;\r
+\r
+void SzArEx_Init(CSzArEx *p);\r
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);\r
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);\r
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);\r
+\r
+/*\r
+if dest == NULL, the return value specifies the required size of the buffer,\r
+  in 16-bit characters, including the null-terminating character.\r
+if dest != NULL, the return value specifies the number of 16-bit characters that\r
+  are written to the dest, including the null-terminating character. */\r
+\r
+size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);\r
+\r
+SRes SzArEx_Extract(\r
+    const CSzArEx *db,\r
+    ILookInStream *inStream,\r
+    UInt32 fileIndex,         /* index of file */\r
+    UInt32 *blockIndex,       /* index of solid block */\r
+    Byte **outBuffer,         /* pointer to pointer to output buffer (allocated with allocMain) */\r
+    size_t *outBufferSize,    /* buffer size for output buffer */\r
+    size_t *offset,           /* offset of stream for required file in *outBuffer */\r
+    size_t *outSizeProcessed, /* size of file in *outBuffer */\r
+    ISzAlloc *allocMain,\r
+    ISzAlloc *allocTemp);\r
+\r
+\r
+/*\r
+SzArEx_Open Errors:\r
+SZ_ERROR_NO_ARCHIVE\r
+SZ_ERROR_ARCHIVE\r
+SZ_ERROR_UNSUPPORTED\r
+SZ_ERROR_MEM\r
+SZ_ERROR_CRC\r
+SZ_ERROR_INPUT_EOF\r
+SZ_ERROR_FAIL\r
+*/\r
+\r
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/7zAlloc.c b/C/7zAlloc.c
new file mode 100755 (executable)
index 0000000..8874496
--- /dev/null
@@ -0,0 +1,76 @@
+/* 7zAlloc.c -- Allocation functions\r
+2010-10-29 : Igor Pavlov : Public domain */\r
+\r
+#include "7zAlloc.h"\r
+\r
+/* #define _SZ_ALLOC_DEBUG */\r
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */\r
+\r
+#ifdef _SZ_ALLOC_DEBUG\r
+\r
+#ifdef _WIN32\r
+#include <windows.h>\r
+#endif\r
+\r
+#include <stdio.h>\r
+int g_allocCount = 0;\r
+int g_allocCountTemp = 0;\r
+\r
+#endif\r
+\r
+void *SzAlloc(void *p, size_t size)\r
+{\r
+  p = p;\r
+  if (size == 0)\r
+    return 0;\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);\r
+  g_allocCount++;\r
+  #endif\r
+  return malloc(size);\r
+}\r
+\r
+void SzFree(void *p, void *address)\r
+{\r
+  p = p;\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  if (address != 0)\r
+  {\r
+    g_allocCount--;\r
+    fprintf(stderr, "\nFree; count = %10d", g_allocCount);\r
+  }\r
+  #endif\r
+  free(address);\r
+}\r
+\r
+void *SzAllocTemp(void *p, size_t size)\r
+{\r
+  p = p;\r
+  if (size == 0)\r
+    return 0;\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  fprintf(stderr, "\nAlloc_temp %10d bytes;  count = %10d", size, g_allocCountTemp);\r
+  g_allocCountTemp++;\r
+  #ifdef _WIN32\r
+  return HeapAlloc(GetProcessHeap(), 0, size);\r
+  #endif\r
+  #endif\r
+  return malloc(size);\r
+}\r
+\r
+void SzFreeTemp(void *p, void *address)\r
+{\r
+  p = p;\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  if (address != 0)\r
+  {\r
+    g_allocCountTemp--;\r
+    fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);\r
+  }\r
+  #ifdef _WIN32\r
+  HeapFree(GetProcessHeap(), 0, address);\r
+  return;\r
+  #endif\r
+  #endif\r
+  free(address);\r
+}\r
diff --git a/C/7zAlloc.h b/C/7zAlloc.h
new file mode 100755 (executable)
index 0000000..860f116
--- /dev/null
@@ -0,0 +1,15 @@
+/* 7zAlloc.h -- Allocation functions\r
+2010-10-29 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __7Z_ALLOC_H\r
+#define __7Z_ALLOC_H\r
+\r
+#include <stdlib.h>\r
+\r
+void *SzAlloc(void *p, size_t size);\r
+void SzFree(void *p, void *address);\r
+\r
+void *SzAllocTemp(void *p, size_t size);\r
+void SzFreeTemp(void *p, void *address);\r
+\r
+#endif\r
diff --git a/C/7zBuf.c b/C/7zBuf.c
new file mode 100755 (executable)
index 0000000..a35fa2f
--- /dev/null
+++ b/C/7zBuf.c
@@ -0,0 +1,36 @@
+/* 7zBuf.c -- Byte Buffer\r
+2008-03-28\r
+Igor Pavlov\r
+Public domain */\r
+\r
+#include "7zBuf.h"\r
+\r
+void Buf_Init(CBuf *p)\r
+{\r
+  p->data = 0;\r
+  p->size = 0;\r
+}\r
+\r
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)\r
+{\r
+  p->size = 0;\r
+  if (size == 0)\r
+  {\r
+    p->data = 0;\r
+    return 1;\r
+  }\r
+  p->data = (Byte *)alloc->Alloc(alloc, size);\r
+  if (p->data != 0)\r
+  {\r
+    p->size = size;\r
+    return 1;\r
+  }\r
+  return 0;\r
+}\r
+\r
+void Buf_Free(CBuf *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->data);\r
+  p->data = 0;\r
+  p->size = 0;\r
+}\r
diff --git a/C/7zBuf.h b/C/7zBuf.h
new file mode 100755 (executable)
index 0000000..88ff0c2
--- /dev/null
+++ b/C/7zBuf.h
@@ -0,0 +1,39 @@
+/* 7zBuf.h -- Byte Buffer\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __7Z_BUF_H\r
+#define __7Z_BUF_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef struct\r
+{\r
+  Byte *data;\r
+  size_t size;\r
+} CBuf;\r
+\r
+void Buf_Init(CBuf *p);\r
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);\r
+void Buf_Free(CBuf *p, ISzAlloc *alloc);\r
+\r
+typedef struct\r
+{\r
+  Byte *data;\r
+  size_t size;\r
+  size_t pos;\r
+} CDynBuf;\r
+\r
+void DynBuf_Construct(CDynBuf *p);\r
+void DynBuf_SeekToBeg(CDynBuf *p);\r
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);\r
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/7zBuf2.c b/C/7zBuf2.c
new file mode 100755 (executable)
index 0000000..1c8b931
--- /dev/null
@@ -0,0 +1,45 @@
+/* 7zBuf2.c -- Byte Buffer\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#include <string.h>\r
+#include "7zBuf.h"\r
+\r
+void DynBuf_Construct(CDynBuf *p)\r
+{\r
+  p->data = 0;\r
+  p->size = 0;\r
+  p->pos = 0;\r
+}\r
+\r
+void DynBuf_SeekToBeg(CDynBuf *p)\r
+{\r
+  p->pos = 0;\r
+}\r
+\r
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)\r
+{\r
+  if (size > p->size - p->pos)\r
+  {\r
+    size_t newSize = p->pos + size;\r
+    Byte *data;\r
+    newSize += newSize / 4;\r
+    data = (Byte *)alloc->Alloc(alloc, newSize);\r
+    if (data == 0)\r
+      return 0;\r
+    p->size = newSize;\r
+    memcpy(data, p->data, p->pos);\r
+    alloc->Free(alloc, p->data);\r
+    p->data = data;\r
+  }\r
+  memcpy(p->data + p->pos, buf, size);\r
+  p->pos += size;\r
+  return 1;\r
+}\r
+\r
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->data);\r
+  p->data = 0;\r
+  p->size = 0;\r
+  p->pos = 0;\r
+}\r
diff --git a/C/7zCrc.c b/C/7zCrc.c
new file mode 100755 (executable)
index 0000000..5801dab
--- /dev/null
+++ b/C/7zCrc.c
@@ -0,0 +1,74 @@
+/* 7zCrc.c -- CRC32 calculation\r
+2009-11-23 : Igor Pavlov : Public domain */\r
+\r
+#include "7zCrc.h"\r
+#include "CpuArch.h"\r
+\r
+#define kCrcPoly 0xEDB88320\r
+\r
+#ifdef MY_CPU_LE\r
+#define CRC_NUM_TABLES 8\r
+#else\r
+#define CRC_NUM_TABLES 1\r
+#endif\r
+\r
+typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);\r
+\r
+static CRC_FUNC g_CrcUpdate;\r
+UInt32 g_CrcTable[256 * CRC_NUM_TABLES];\r
+\r
+#if CRC_NUM_TABLES == 1\r
+\r
+#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))\r
+\r
+static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)\r
+{\r
+  const Byte *p = (const Byte *)data;\r
+  for (; size > 0; size--, p++)\r
+    v = CRC_UPDATE_BYTE_2(v, *p);\r
+  return v;\r
+}\r
+\r
+#else\r
+\r
+UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);\r
+UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);\r
+\r
+#endif\r
+\r
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)\r
+{\r
+  return g_CrcUpdate(v, data, size, g_CrcTable);\r
+}\r
+\r
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)\r
+{\r
+  return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;\r
+}\r
+\r
+void MY_FAST_CALL CrcGenerateTable()\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < 256; i++)\r
+  {\r
+    UInt32 r = i;\r
+    unsigned j;\r
+    for (j = 0; j < 8; j++)\r
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));\r
+    g_CrcTable[i] = r;\r
+  }\r
+  #if CRC_NUM_TABLES == 1\r
+  g_CrcUpdate = CrcUpdateT1;\r
+  #else\r
+  for (; i < 256 * CRC_NUM_TABLES; i++)\r
+  {\r
+    UInt32 r = g_CrcTable[i - 256];\r
+    g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);\r
+  }\r
+  g_CrcUpdate = CrcUpdateT4;\r
+  #ifdef MY_CPU_X86_OR_AMD64\r
+  if (!CPU_Is_InOrder())\r
+    g_CrcUpdate = CrcUpdateT8;\r
+  #endif\r
+  #endif\r
+}\r
diff --git a/C/7zCrc.h b/C/7zCrc.h
new file mode 100755 (executable)
index 0000000..4a1ec38
--- /dev/null
+++ b/C/7zCrc.h
@@ -0,0 +1,25 @@
+/* 7zCrc.h -- CRC32 calculation\r
+2009-11-21 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __7Z_CRC_H\r
+#define __7Z_CRC_H\r
+\r
+#include "Types.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+extern UInt32 g_CrcTable[];\r
+\r
+/* Call CrcGenerateTable one time before other CRC functions */\r
+void MY_FAST_CALL CrcGenerateTable(void);\r
+\r
+#define CRC_INIT_VAL 0xFFFFFFFF\r
+#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)\r
+#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))\r
+\r
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);\r
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/7zCrcOpt.c b/C/7zCrcOpt.c
new file mode 100755 (executable)
index 0000000..6205d71
--- /dev/null
@@ -0,0 +1,34 @@
+/* 7zCrcOpt.c -- CRC32 calculation : optimized version\r
+2009-11-23 : Igor Pavlov : Public domain */\r
+\r
+#include "CpuArch.h"\r
+\r
+#ifdef MY_CPU_LE\r
+\r
+#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))\r
+\r
+UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)\r
+{\r
+  const Byte *p = (const Byte *)data;\r
+  for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)\r
+    v = CRC_UPDATE_BYTE_2(v, *p);\r
+  for (; size >= 4; size -= 4, p += 4)\r
+  {\r
+    v ^= *(const UInt32 *)p;\r
+    v =\r
+      table[0x300 + (v & 0xFF)] ^\r
+      table[0x200 + ((v >> 8) & 0xFF)] ^\r
+      table[0x100 + ((v >> 16) & 0xFF)] ^\r
+      table[0x000 + ((v >> 24))];\r
+  }\r
+  for (; size > 0; size--, p++)\r
+    v = CRC_UPDATE_BYTE_2(v, *p);\r
+  return v;\r
+}\r
+\r
+UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)\r
+{\r
+  return CrcUpdateT4(v, data, size, table);\r
+}\r
+\r
+#endif\r
diff --git a/C/7zDec.c b/C/7zDec.c
new file mode 100755 (executable)
index 0000000..3386807
--- /dev/null
+++ b/C/7zDec.c
@@ -0,0 +1,470 @@
+/* 7zDec.c -- Decoding from 7z folder\r
+2010-11-02 : Igor Pavlov : Public domain */\r
+\r
+#include <string.h>\r
+\r
+/* #define _7ZIP_PPMD_SUPPPORT */\r
+\r
+#include "7z.h"\r
+\r
+#include "Bcj2.h"\r
+#include "Bra.h"\r
+#include "CpuArch.h"\r
+#include "LzmaDec.h"\r
+#include "Lzma2Dec.h"\r
+#ifdef _7ZIP_PPMD_SUPPPORT\r
+#include "Ppmd7.h"\r
+#endif\r
+\r
+#define k_Copy 0\r
+#define k_LZMA2 0x21\r
+#define k_LZMA  0x30101\r
+#define k_BCJ   0x03030103\r
+#define k_PPC   0x03030205\r
+#define k_ARM   0x03030501\r
+#define k_ARMT  0x03030701\r
+#define k_SPARC 0x03030805\r
+#define k_BCJ2  0x0303011B\r
+\r
+#ifdef _7ZIP_PPMD_SUPPPORT\r
+\r
+#define k_PPMD 0x30401\r
+\r
+typedef struct\r
+{\r
+  IByteIn p;\r
+  const Byte *cur;\r
+  const Byte *end;\r
+  const Byte *begin;\r
+  UInt64 processed;\r
+  Bool extra;\r
+  SRes res;\r
+  ILookInStream *inStream;\r
+} CByteInToLook;\r
+\r
+static Byte ReadByte(void *pp)\r
+{\r
+  CByteInToLook *p = (CByteInToLook *)pp;\r
+  if (p->cur != p->end)\r
+    return *p->cur++;\r
+  if (p->res == SZ_OK)\r
+  {\r
+    size_t size = p->cur - p->begin;\r
+    p->processed += size;\r
+    p->res = p->inStream->Skip(p->inStream, size);\r
+    size = (1 << 25);\r
+    p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);\r
+    p->cur = p->begin;\r
+    p->end = p->begin + size;\r
+    if (size != 0)\r
+      return *p->cur++;;\r
+  }\r
+  p->extra = True;\r
+  return 0;\r
+}\r
+\r
+static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,\r
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)\r
+{\r
+  CPpmd7 ppmd;\r
+  CByteInToLook s;\r
+  SRes res = SZ_OK;\r
+\r
+  s.p.Read = ReadByte;\r
+  s.inStream = inStream;\r
+  s.begin = s.end = s.cur = NULL;\r
+  s.extra = False;\r
+  s.res = SZ_OK;\r
+  s.processed = 0;\r
+\r
+  if (coder->Props.size != 5)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+\r
+  {\r
+    unsigned order = coder->Props.data[0];\r
+    UInt32 memSize = GetUi32(coder->Props.data + 1);\r
+    if (order < PPMD7_MIN_ORDER ||\r
+        order > PPMD7_MAX_ORDER ||\r
+        memSize < PPMD7_MIN_MEM_SIZE ||\r
+        memSize > PPMD7_MAX_MEM_SIZE)\r
+      return SZ_ERROR_UNSUPPORTED;\r
+    Ppmd7_Construct(&ppmd);\r
+    if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))\r
+      return SZ_ERROR_MEM;\r
+    Ppmd7_Init(&ppmd, order);\r
+  }\r
+  {\r
+    CPpmd7z_RangeDec rc;\r
+    Ppmd7z_RangeDec_CreateVTable(&rc);\r
+    rc.Stream = &s.p;\r
+    if (!Ppmd7z_RangeDec_Init(&rc))\r
+      res = SZ_ERROR_DATA;\r
+    else if (s.extra)\r
+      res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);\r
+    else\r
+    {\r
+      SizeT i;\r
+      for (i = 0; i < outSize; i++)\r
+      {\r
+        int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);\r
+        if (s.extra || sym < 0)\r
+          break;\r
+        outBuffer[i] = (Byte)sym;\r
+      }\r
+      if (i != outSize)\r
+        res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);\r
+      else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))\r
+        res = SZ_ERROR_DATA;\r
+    }\r
+  }\r
+  Ppmd7_Free(&ppmd, allocMain);\r
+  return res;\r
+}\r
+\r
+#endif\r
+\r
+\r
+static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,\r
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)\r
+{\r
+  CLzmaDec state;\r
+  SRes res = SZ_OK;\r
+\r
+  LzmaDec_Construct(&state);\r
+  RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));\r
+  state.dic = outBuffer;\r
+  state.dicBufSize = outSize;\r
+  LzmaDec_Init(&state);\r
+\r
+  for (;;)\r
+  {\r
+    Byte *inBuf = NULL;\r
+    size_t lookahead = (1 << 18);\r
+    if (lookahead > inSize)\r
+      lookahead = (size_t)inSize;\r
+    res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);\r
+    if (res != SZ_OK)\r
+      break;\r
+\r
+    {\r
+      SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;\r
+      ELzmaStatus status;\r
+      res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);\r
+      lookahead -= inProcessed;\r
+      inSize -= inProcessed;\r
+      if (res != SZ_OK)\r
+        break;\r
+      if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))\r
+      {\r
+        if (state.dicBufSize != outSize || lookahead != 0 ||\r
+            (status != LZMA_STATUS_FINISHED_WITH_MARK &&\r
+             status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))\r
+          res = SZ_ERROR_DATA;\r
+        break;\r
+      }\r
+      res = inStream->Skip((void *)inStream, inProcessed);\r
+      if (res != SZ_OK)\r
+        break;\r
+    }\r
+  }\r
+\r
+  LzmaDec_FreeProbs(&state, allocMain);\r
+  return res;\r
+}\r
+\r
+static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,\r
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)\r
+{\r
+  CLzma2Dec state;\r
+  SRes res = SZ_OK;\r
+\r
+  Lzma2Dec_Construct(&state);\r
+  if (coder->Props.size != 1)\r
+    return SZ_ERROR_DATA;\r
+  RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));\r
+  state.decoder.dic = outBuffer;\r
+  state.decoder.dicBufSize = outSize;\r
+  Lzma2Dec_Init(&state);\r
+\r
+  for (;;)\r
+  {\r
+    Byte *inBuf = NULL;\r
+    size_t lookahead = (1 << 18);\r
+    if (lookahead > inSize)\r
+      lookahead = (size_t)inSize;\r
+    res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);\r
+    if (res != SZ_OK)\r
+      break;\r
+\r
+    {\r
+      SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;\r
+      ELzmaStatus status;\r
+      res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);\r
+      lookahead -= inProcessed;\r
+      inSize -= inProcessed;\r
+      if (res != SZ_OK)\r
+        break;\r
+      if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))\r
+      {\r
+        if (state.decoder.dicBufSize != outSize || lookahead != 0 ||\r
+            (status != LZMA_STATUS_FINISHED_WITH_MARK))\r
+          res = SZ_ERROR_DATA;\r
+        break;\r
+      }\r
+      res = inStream->Skip((void *)inStream, inProcessed);\r
+      if (res != SZ_OK)\r
+        break;\r
+    }\r
+  }\r
+\r
+  Lzma2Dec_FreeProbs(&state, allocMain);\r
+  return res;\r
+}\r
+\r
+static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)\r
+{\r
+  while (inSize > 0)\r
+  {\r
+    void *inBuf;\r
+    size_t curSize = (1 << 18);\r
+    if (curSize > inSize)\r
+      curSize = (size_t)inSize;\r
+    RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));\r
+    if (curSize == 0)\r
+      return SZ_ERROR_INPUT_EOF;\r
+    memcpy(outBuffer, inBuf, curSize);\r
+    outBuffer += curSize;\r
+    inSize -= curSize;\r
+    RINOK(inStream->Skip((void *)inStream, curSize));\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+static Bool IS_MAIN_METHOD(UInt32 m)\r
+{\r
+  switch(m)\r
+  {\r
+    case k_Copy:\r
+    case k_LZMA:\r
+    case k_LZMA2:\r
+    #ifdef _7ZIP_PPMD_SUPPPORT\r
+    case k_PPMD:\r
+    #endif\r
+      return True;\r
+  }\r
+  return False;\r
+}\r
+\r
+static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)\r
+{\r
+  return\r
+      c->NumInStreams == 1 &&\r
+      c->NumOutStreams == 1 &&\r
+      c->MethodID <= (UInt32)0xFFFFFFFF &&\r
+      IS_MAIN_METHOD((UInt32)c->MethodID);\r
+}\r
+\r
+#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)\r
+\r
+static SRes CheckSupportedFolder(const CSzFolder *f)\r
+{\r
+  if (f->NumCoders < 1 || f->NumCoders > 4)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  if (!IS_SUPPORTED_CODER(&f->Coders[0]))\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  if (f->NumCoders == 1)\r
+  {\r
+    if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)\r
+      return SZ_ERROR_UNSUPPORTED;\r
+    return SZ_OK;\r
+  }\r
+  if (f->NumCoders == 2)\r
+  {\r
+    CSzCoderInfo *c = &f->Coders[1];\r
+    if (c->MethodID > (UInt32)0xFFFFFFFF ||\r
+        c->NumInStreams != 1 ||\r
+        c->NumOutStreams != 1 ||\r
+        f->NumPackStreams != 1 ||\r
+        f->PackStreams[0] != 0 ||\r
+        f->NumBindPairs != 1 ||\r
+        f->BindPairs[0].InIndex != 1 ||\r
+        f->BindPairs[0].OutIndex != 0)\r
+      return SZ_ERROR_UNSUPPORTED;\r
+    switch ((UInt32)c->MethodID)\r
+    {\r
+      case k_BCJ:\r
+      case k_ARM:\r
+        break;\r
+      default:\r
+        return SZ_ERROR_UNSUPPORTED;\r
+    }\r
+    return SZ_OK;\r
+  }\r
+  if (f->NumCoders == 4)\r
+  {\r
+    if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||\r
+        !IS_SUPPORTED_CODER(&f->Coders[2]) ||\r
+        !IS_BCJ2(&f->Coders[3]))\r
+      return SZ_ERROR_UNSUPPORTED;\r
+    if (f->NumPackStreams != 4 ||\r
+        f->PackStreams[0] != 2 ||\r
+        f->PackStreams[1] != 6 ||\r
+        f->PackStreams[2] != 1 ||\r
+        f->PackStreams[3] != 0 ||\r
+        f->NumBindPairs != 3 ||\r
+        f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||\r
+        f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||\r
+        f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)\r
+      return SZ_ERROR_UNSUPPORTED;\r
+    return SZ_OK;\r
+  }\r
+  return SZ_ERROR_UNSUPPORTED;\r
+}\r
+\r
+static UInt64 GetSum(const UInt64 *values, UInt32 index)\r
+{\r
+  UInt64 sum = 0;\r
+  UInt32 i;\r
+  for (i = 0; i < index; i++)\r
+    sum += values[i];\r
+  return sum;\r
+}\r
+\r
+#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;\r
+\r
+static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,\r
+    ILookInStream *inStream, UInt64 startPos,\r
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,\r
+    Byte *tempBuf[])\r
+{\r
+  UInt32 ci;\r
+  SizeT tempSizes[3] = { 0, 0, 0};\r
+  SizeT tempSize3 = 0;\r
+  Byte *tempBuf3 = 0;\r
+\r
+  RINOK(CheckSupportedFolder(folder));\r
+\r
+  for (ci = 0; ci < folder->NumCoders; ci++)\r
+  {\r
+    CSzCoderInfo *coder = &folder->Coders[ci];\r
+\r
+    if (IS_MAIN_METHOD((UInt32)coder->MethodID))\r
+    {\r
+      UInt32 si = 0;\r
+      UInt64 offset;\r
+      UInt64 inSize;\r
+      Byte *outBufCur = outBuffer;\r
+      SizeT outSizeCur = outSize;\r
+      if (folder->NumCoders == 4)\r
+      {\r
+        UInt32 indices[] = { 3, 2, 0 };\r
+        UInt64 unpackSize = folder->UnpackSizes[ci];\r
+        si = indices[ci];\r
+        if (ci < 2)\r
+        {\r
+          Byte *temp;\r
+          outSizeCur = (SizeT)unpackSize;\r
+          if (outSizeCur != unpackSize)\r
+            return SZ_ERROR_MEM;\r
+          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);\r
+          if (temp == 0 && outSizeCur != 0)\r
+            return SZ_ERROR_MEM;\r
+          outBufCur = tempBuf[1 - ci] = temp;\r
+          tempSizes[1 - ci] = outSizeCur;\r
+        }\r
+        else if (ci == 2)\r
+        {\r
+          if (unpackSize > outSize) /* check it */\r
+            return SZ_ERROR_PARAM;\r
+          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);\r
+          tempSize3 = outSizeCur = (SizeT)unpackSize;\r
+        }\r
+        else\r
+          return SZ_ERROR_UNSUPPORTED;\r
+      }\r
+      offset = GetSum(packSizes, si);\r
+      inSize = packSizes[si];\r
+      RINOK(LookInStream_SeekTo(inStream, startPos + offset));\r
+\r
+      if (coder->MethodID == k_Copy)\r
+      {\r
+        if (inSize != outSizeCur) /* check it */\r
+          return SZ_ERROR_DATA;\r
+        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));\r
+      }\r
+      else if (coder->MethodID == k_LZMA)\r
+      {\r
+        RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));\r
+      }\r
+      else if (coder->MethodID == k_LZMA2)\r
+      {\r
+        RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));\r
+      }\r
+      else\r
+      {\r
+        #ifdef _7ZIP_PPMD_SUPPPORT\r
+        RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));\r
+        #else\r
+        return SZ_ERROR_UNSUPPORTED;\r
+        #endif\r
+      }\r
+    }\r
+    else if (coder->MethodID == k_BCJ2)\r
+    {\r
+      UInt64 offset = GetSum(packSizes, 1);\r
+      UInt64 s3Size = packSizes[1];\r
+      SRes res;\r
+      if (ci != 3)\r
+        return SZ_ERROR_UNSUPPORTED;\r
+      RINOK(LookInStream_SeekTo(inStream, startPos + offset));\r
+      tempSizes[2] = (SizeT)s3Size;\r
+      if (tempSizes[2] != s3Size)\r
+        return SZ_ERROR_MEM;\r
+      tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);\r
+      if (tempBuf[2] == 0 && tempSizes[2] != 0)\r
+        return SZ_ERROR_MEM;\r
+      res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);\r
+      RINOK(res)\r
+\r
+      res = Bcj2_Decode(\r
+          tempBuf3, tempSize3,\r
+          tempBuf[0], tempSizes[0],\r
+          tempBuf[1], tempSizes[1],\r
+          tempBuf[2], tempSizes[2],\r
+          outBuffer, outSize);\r
+      RINOK(res)\r
+    }\r
+    else\r
+    {\r
+      if (ci != 1)\r
+        return SZ_ERROR_UNSUPPORTED;\r
+      switch(coder->MethodID)\r
+      {\r
+        case k_BCJ:\r
+        {\r
+          UInt32 state;\r
+          x86_Convert_Init(state);\r
+          x86_Convert(outBuffer, outSize, 0, &state, 0);\r
+          break;\r
+        }\r
+        CASE_BRA_CONV(ARM)\r
+        default:\r
+          return SZ_ERROR_UNSUPPORTED;\r
+      }\r
+    }\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,\r
+    ILookInStream *inStream, UInt64 startPos,\r
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)\r
+{\r
+  Byte *tempBuf[3] = { 0, 0, 0};\r
+  int i;\r
+  SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,\r
+      outBuffer, (SizeT)outSize, allocMain, tempBuf);\r
+  for (i = 0; i < 3; i++)\r
+    IAlloc_Free(allocMain, tempBuf[i]);\r
+  return res;\r
+}\r
diff --git a/C/7zFile.c b/C/7zFile.c
new file mode 100755 (executable)
index 0000000..6d82c79
--- /dev/null
@@ -0,0 +1,284 @@
+/* 7zFile.c -- File IO\r
+2009-11-24 : Igor Pavlov : Public domain */\r
+\r
+#include "7zFile.h"\r
+\r
+#ifndef USE_WINDOWS_FILE\r
+\r
+#ifndef UNDER_CE\r
+#include <errno.h>\r
+#endif\r
+\r
+#else\r
+\r
+/*\r
+   ReadFile and WriteFile functions in Windows have BUG:\r
+   If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)\r
+   from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES\r
+   (Insufficient system resources exist to complete the requested service).\r
+   Probably in some version of Windows there are problems with other sizes:\r
+   for 32 MB (maybe also for 16 MB).\r
+   And message can be "Network connection was lost"\r
+*/\r
+\r
+#define kChunkSizeMax (1 << 22)\r
+\r
+#endif\r
+\r
+void File_Construct(CSzFile *p)\r
+{\r
+  #ifdef USE_WINDOWS_FILE\r
+  p->handle = INVALID_HANDLE_VALUE;\r
+  #else\r
+  p->file = NULL;\r
+  #endif\r
+}\r
+\r
+#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)\r
+static WRes File_Open(CSzFile *p, const char *name, int writeMode)\r
+{\r
+  #ifdef USE_WINDOWS_FILE\r
+  p->handle = CreateFileA(name,\r
+      writeMode ? GENERIC_WRITE : GENERIC_READ,\r
+      FILE_SHARE_READ, NULL,\r
+      writeMode ? CREATE_ALWAYS : OPEN_EXISTING,\r
+      FILE_ATTRIBUTE_NORMAL, NULL);\r
+  return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();\r
+  #else\r
+  p->file = fopen(name, writeMode ? "wb+" : "rb");\r
+  return (p->file != 0) ? 0 :\r
+    #ifdef UNDER_CE\r
+    2; /* ENOENT */\r
+    #else\r
+    errno;\r
+    #endif\r
+  #endif\r
+}\r
+\r
+WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }\r
+WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }\r
+#endif\r
+\r
+#ifdef USE_WINDOWS_FILE\r
+static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)\r
+{\r
+  p->handle = CreateFileW(name,\r
+      writeMode ? GENERIC_WRITE : GENERIC_READ,\r
+      FILE_SHARE_READ, NULL,\r
+      writeMode ? CREATE_ALWAYS : OPEN_EXISTING,\r
+      FILE_ATTRIBUTE_NORMAL, NULL);\r
+  return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();\r
+}\r
+WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }\r
+WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }\r
+#endif\r
+\r
+WRes File_Close(CSzFile *p)\r
+{\r
+  #ifdef USE_WINDOWS_FILE\r
+  if (p->handle != INVALID_HANDLE_VALUE)\r
+  {\r
+    if (!CloseHandle(p->handle))\r
+      return GetLastError();\r
+    p->handle = INVALID_HANDLE_VALUE;\r
+  }\r
+  #else\r
+  if (p->file != NULL)\r
+  {\r
+    int res = fclose(p->file);\r
+    if (res != 0)\r
+      return res;\r
+    p->file = NULL;\r
+  }\r
+  #endif\r
+  return 0;\r
+}\r
+\r
+WRes File_Read(CSzFile *p, void *data, size_t *size)\r
+{\r
+  size_t originalSize = *size;\r
+  if (originalSize == 0)\r
+    return 0;\r
+\r
+  #ifdef USE_WINDOWS_FILE\r
+\r
+  *size = 0;\r
+  do\r
+  {\r
+    DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;\r
+    DWORD processed = 0;\r
+    BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);\r
+    data = (void *)((Byte *)data + processed);\r
+    originalSize -= processed;\r
+    *size += processed;\r
+    if (!res)\r
+      return GetLastError();\r
+    if (processed == 0)\r
+      break;\r
+  }\r
+  while (originalSize > 0);\r
+  return 0;\r
+\r
+  #else\r
+  \r
+  *size = fread(data, 1, originalSize, p->file);\r
+  if (*size == originalSize)\r
+    return 0;\r
+  return ferror(p->file);\r
+  \r
+  #endif\r
+}\r
+\r
+WRes File_Write(CSzFile *p, const void *data, size_t *size)\r
+{\r
+  size_t originalSize = *size;\r
+  if (originalSize == 0)\r
+    return 0;\r
+  \r
+  #ifdef USE_WINDOWS_FILE\r
+\r
+  *size = 0;\r
+  do\r
+  {\r
+    DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;\r
+    DWORD processed = 0;\r
+    BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);\r
+    data = (void *)((Byte *)data + processed);\r
+    originalSize -= processed;\r
+    *size += processed;\r
+    if (!res)\r
+      return GetLastError();\r
+    if (processed == 0)\r
+      break;\r
+  }\r
+  while (originalSize > 0);\r
+  return 0;\r
+\r
+  #else\r
+\r
+  *size = fwrite(data, 1, originalSize, p->file);\r
+  if (*size == originalSize)\r
+    return 0;\r
+  return ferror(p->file);\r
+  \r
+  #endif\r
+}\r
+\r
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)\r
+{\r
+  #ifdef USE_WINDOWS_FILE\r
+\r
+  LARGE_INTEGER value;\r
+  DWORD moveMethod;\r
+  value.LowPart = (DWORD)*pos;\r
+  value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */\r
+  switch (origin)\r
+  {\r
+    case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;\r
+    case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;\r
+    case SZ_SEEK_END: moveMethod = FILE_END; break;\r
+    default: return ERROR_INVALID_PARAMETER;\r
+  }\r
+  value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);\r
+  if (value.LowPart == 0xFFFFFFFF)\r
+  {\r
+    WRes res = GetLastError();\r
+    if (res != NO_ERROR)\r
+      return res;\r
+  }\r
+  *pos = ((Int64)value.HighPart << 32) | value.LowPart;\r
+  return 0;\r
+\r
+  #else\r
+  \r
+  int moveMethod;\r
+  int res;\r
+  switch (origin)\r
+  {\r
+    case SZ_SEEK_SET: moveMethod = SEEK_SET; break;\r
+    case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;\r
+    case SZ_SEEK_END: moveMethod = SEEK_END; break;\r
+    default: return 1;\r
+  }\r
+  res = fseek(p->file, (long)*pos, moveMethod);\r
+  *pos = ftell(p->file);\r
+  return res;\r
+  \r
+  #endif\r
+}\r
+\r
+WRes File_GetLength(CSzFile *p, UInt64 *length)\r
+{\r
+  #ifdef USE_WINDOWS_FILE\r
+  \r
+  DWORD sizeHigh;\r
+  DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);\r
+  if (sizeLow == 0xFFFFFFFF)\r
+  {\r
+    DWORD res = GetLastError();\r
+    if (res != NO_ERROR)\r
+      return res;\r
+  }\r
+  *length = (((UInt64)sizeHigh) << 32) + sizeLow;\r
+  return 0;\r
+  \r
+  #else\r
+  \r
+  long pos = ftell(p->file);\r
+  int res = fseek(p->file, 0, SEEK_END);\r
+  *length = ftell(p->file);\r
+  fseek(p->file, pos, SEEK_SET);\r
+  return res;\r
+  \r
+  #endif\r
+}\r
+\r
+\r
+/* ---------- FileSeqInStream ---------- */\r
+\r
+static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)\r
+{\r
+  CFileSeqInStream *p = (CFileSeqInStream *)pp;\r
+  return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;\r
+}\r
+\r
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p)\r
+{\r
+  p->s.Read = FileSeqInStream_Read;\r
+}\r
+\r
+\r
+/* ---------- FileInStream ---------- */\r
+\r
+static SRes FileInStream_Read(void *pp, void *buf, size_t *size)\r
+{\r
+  CFileInStream *p = (CFileInStream *)pp;\r
+  return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;\r
+}\r
+\r
+static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)\r
+{\r
+  CFileInStream *p = (CFileInStream *)pp;\r
+  return File_Seek(&p->file, pos, origin);\r
+}\r
+\r
+void FileInStream_CreateVTable(CFileInStream *p)\r
+{\r
+  p->s.Read = FileInStream_Read;\r
+  p->s.Seek = FileInStream_Seek;\r
+}\r
+\r
+\r
+/* ---------- FileOutStream ---------- */\r
+\r
+static size_t FileOutStream_Write(void *pp, const void *data, size_t size)\r
+{\r
+  CFileOutStream *p = (CFileOutStream *)pp;\r
+  File_Write(&p->file, data, &size);\r
+  return size;\r
+}\r
+\r
+void FileOutStream_CreateVTable(CFileOutStream *p)\r
+{\r
+  p->s.Write = FileOutStream_Write;\r
+}\r
diff --git a/C/7zFile.h b/C/7zFile.h
new file mode 100755 (executable)
index 0000000..5d85787
--- /dev/null
@@ -0,0 +1,83 @@
+/* 7zFile.h -- File IO\r
+2009-11-24 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __7Z_FILE_H\r
+#define __7Z_FILE_H\r
+\r
+#ifdef _WIN32\r
+#define USE_WINDOWS_FILE\r
+#endif\r
+\r
+#ifdef USE_WINDOWS_FILE\r
+#include <windows.h>\r
+#else\r
+#include <stdio.h>\r
+#endif\r
+\r
+#include "Types.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+/* ---------- File ---------- */\r
+\r
+typedef struct\r
+{\r
+  #ifdef USE_WINDOWS_FILE\r
+  HANDLE handle;\r
+  #else\r
+  FILE *file;\r
+  #endif\r
+} CSzFile;\r
+\r
+void File_Construct(CSzFile *p);\r
+#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)\r
+WRes InFile_Open(CSzFile *p, const char *name);\r
+WRes OutFile_Open(CSzFile *p, const char *name);\r
+#endif\r
+#ifdef USE_WINDOWS_FILE\r
+WRes InFile_OpenW(CSzFile *p, const WCHAR *name);\r
+WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);\r
+#endif\r
+WRes File_Close(CSzFile *p);\r
+\r
+/* reads max(*size, remain file's size) bytes */\r
+WRes File_Read(CSzFile *p, void *data, size_t *size);\r
+\r
+/* writes *size bytes */\r
+WRes File_Write(CSzFile *p, const void *data, size_t *size);\r
+\r
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);\r
+WRes File_GetLength(CSzFile *p, UInt64 *length);\r
+\r
+\r
+/* ---------- FileInStream ---------- */\r
+\r
+typedef struct\r
+{\r
+  ISeqInStream s;\r
+  CSzFile file;\r
+} CFileSeqInStream;\r
+\r
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p);\r
+\r
+\r
+typedef struct\r
+{\r
+  ISeekInStream s;\r
+  CSzFile file;\r
+} CFileInStream;\r
+\r
+void FileInStream_CreateVTable(CFileInStream *p);\r
+\r
+\r
+typedef struct\r
+{\r
+  ISeqOutStream s;\r
+  CSzFile file;\r
+} CFileOutStream;\r
+\r
+void FileOutStream_CreateVTable(CFileOutStream *p);\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/7zIn.c b/C/7zIn.c
new file mode 100755 (executable)
index 0000000..f1a4492
--- /dev/null
+++ b/C/7zIn.c
@@ -0,0 +1,1402 @@
+/* 7zIn.c -- 7z Input functions\r
+2010-10-29 : Igor Pavlov : Public domain */\r
+\r
+#include <string.h>\r
+\r
+#include "7z.h"\r
+#include "7zCrc.h"\r
+#include "CpuArch.h"\r
+\r
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};\r
+\r
+#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }\r
+\r
+#define NUM_FOLDER_CODERS_MAX 32\r
+#define NUM_CODER_STREAMS_MAX 32\r
+\r
+void SzCoderInfo_Init(CSzCoderInfo *p)\r
+{\r
+  Buf_Init(&p->Props);\r
+}\r
+\r
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)\r
+{\r
+  Buf_Free(&p->Props, alloc);\r
+  SzCoderInfo_Init(p);\r
+}\r
+\r
+void SzFolder_Init(CSzFolder *p)\r
+{\r
+  p->Coders = 0;\r
+  p->BindPairs = 0;\r
+  p->PackStreams = 0;\r
+  p->UnpackSizes = 0;\r
+  p->NumCoders = 0;\r
+  p->NumBindPairs = 0;\r
+  p->NumPackStreams = 0;\r
+  p->UnpackCRCDefined = 0;\r
+  p->UnpackCRC = 0;\r
+  p->NumUnpackStreams = 0;\r
+}\r
+\r
+void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)\r
+{\r
+  UInt32 i;\r
+  if (p->Coders)\r
+    for (i = 0; i < p->NumCoders; i++)\r
+      SzCoderInfo_Free(&p->Coders[i], alloc);\r
+  IAlloc_Free(alloc, p->Coders);\r
+  IAlloc_Free(alloc, p->BindPairs);\r
+  IAlloc_Free(alloc, p->PackStreams);\r
+  IAlloc_Free(alloc, p->UnpackSizes);\r
+  SzFolder_Init(p);\r
+}\r
+\r
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)\r
+{\r
+  UInt32 result = 0;\r
+  UInt32 i;\r
+  for (i = 0; i < p->NumCoders; i++)\r
+    result += p->Coders[i].NumOutStreams;\r
+  return result;\r
+}\r
+\r
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < p->NumBindPairs; i++)\r
+    if (p->BindPairs[i].InIndex == inStreamIndex)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+\r
+int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < p->NumBindPairs; i++)\r
+    if (p->BindPairs[i].OutIndex == outStreamIndex)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p)\r
+{\r
+  int i = (int)SzFolder_GetNumOutStreams(p);\r
+  if (i == 0)\r
+    return 0;\r
+  for (i--; i >= 0; i--)\r
+    if (SzFolder_FindBindPairForOutStream(p, i) < 0)\r
+      return p->UnpackSizes[i];\r
+  /* throw 1; */\r
+  return 0;\r
+}\r
+\r
+void SzFile_Init(CSzFileItem *p)\r
+{\r
+  p->HasStream = 1;\r
+  p->IsDir = 0;\r
+  p->IsAnti = 0;\r
+  p->CrcDefined = 0;\r
+  p->MTimeDefined = 0;\r
+}\r
+\r
+void SzAr_Init(CSzAr *p)\r
+{\r
+  p->PackSizes = 0;\r
+  p->PackCRCsDefined = 0;\r
+  p->PackCRCs = 0;\r
+  p->Folders = 0;\r
+  p->Files = 0;\r
+  p->NumPackStreams = 0;\r
+  p->NumFolders = 0;\r
+  p->NumFiles = 0;\r
+}\r
+\r
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc)\r
+{\r
+  UInt32 i;\r
+  if (p->Folders)\r
+    for (i = 0; i < p->NumFolders; i++)\r
+      SzFolder_Free(&p->Folders[i], alloc);\r
+\r
+  IAlloc_Free(alloc, p->PackSizes);\r
+  IAlloc_Free(alloc, p->PackCRCsDefined);\r
+  IAlloc_Free(alloc, p->PackCRCs);\r
+  IAlloc_Free(alloc, p->Folders);\r
+  IAlloc_Free(alloc, p->Files);\r
+  SzAr_Init(p);\r
+}\r
+\r
+\r
+void SzArEx_Init(CSzArEx *p)\r
+{\r
+  SzAr_Init(&p->db);\r
+  p->FolderStartPackStreamIndex = 0;\r
+  p->PackStreamStartPositions = 0;\r
+  p->FolderStartFileIndex = 0;\r
+  p->FileIndexToFolderIndexMap = 0;\r
+  p->FileNameOffsets = 0;\r
+  Buf_Init(&p->FileNames);\r
+}\r
+\r
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)\r
+{\r
+  IAlloc_Free(alloc, p->FolderStartPackStreamIndex);\r
+  IAlloc_Free(alloc, p->PackStreamStartPositions);\r
+  IAlloc_Free(alloc, p->FolderStartFileIndex);\r
+  IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);\r
+\r
+  IAlloc_Free(alloc, p->FileNameOffsets);\r
+  Buf_Free(&p->FileNames, alloc);\r
+\r
+  SzAr_Free(&p->db, alloc);\r
+  SzArEx_Init(p);\r
+}\r
+\r
+/*\r
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const\r
+{\r
+  return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];\r
+}\r
+\r
+UInt64 GetFilePackSize(int fileIndex) const\r
+{\r
+  int folderIndex = FileIndexToFolderIndexMap[fileIndex];\r
+  if (folderIndex >= 0)\r
+  {\r
+    const CSzFolder &folderInfo = Folders[folderIndex];\r
+    if (FolderStartFileIndex[folderIndex] == fileIndex)\r
+    return GetFolderFullPackSize(folderIndex);\r
+  }\r
+  return 0;\r
+}\r
+*/\r
+\r
+#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \\r
+  if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }\r
+\r
+static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)\r
+{\r
+  UInt32 startPos = 0;\r
+  UInt64 startPosSize = 0;\r
+  UInt32 i;\r
+  UInt32 folderIndex = 0;\r
+  UInt32 indexInFolder = 0;\r
+  MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);\r
+  for (i = 0; i < p->db.NumFolders; i++)\r
+  {\r
+    p->FolderStartPackStreamIndex[i] = startPos;\r
+    startPos += p->db.Folders[i].NumPackStreams;\r
+  }\r
+\r
+  MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);\r
+\r
+  for (i = 0; i < p->db.NumPackStreams; i++)\r
+  {\r
+    p->PackStreamStartPositions[i] = startPosSize;\r
+    startPosSize += p->db.PackSizes[i];\r
+  }\r
+\r
+  MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);\r
+  MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);\r
+\r
+  for (i = 0; i < p->db.NumFiles; i++)\r
+  {\r
+    CSzFileItem *file = p->db.Files + i;\r
+    int emptyStream = !file->HasStream;\r
+    if (emptyStream && indexInFolder == 0)\r
+    {\r
+      p->FileIndexToFolderIndexMap[i] = (UInt32)-1;\r
+      continue;\r
+    }\r
+    if (indexInFolder == 0)\r
+    {\r
+      /*\r
+      v3.13 incorrectly worked with empty folders\r
+      v4.07: Loop for skipping empty folders\r
+      */\r
+      for (;;)\r
+      {\r
+        if (folderIndex >= p->db.NumFolders)\r
+          return SZ_ERROR_ARCHIVE;\r
+        p->FolderStartFileIndex[folderIndex] = i;\r
+        if (p->db.Folders[folderIndex].NumUnpackStreams != 0)\r
+          break;\r
+        folderIndex++;\r
+      }\r
+    }\r
+    p->FileIndexToFolderIndexMap[i] = folderIndex;\r
+    if (emptyStream)\r
+      continue;\r
+    indexInFolder++;\r
+    if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)\r
+    {\r
+      folderIndex++;\r
+      indexInFolder = 0;\r
+    }\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+\r
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)\r
+{\r
+  return p->dataPos +\r
+    p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];\r
+}\r
+\r
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)\r
+{\r
+  UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];\r
+  CSzFolder *folder = p->db.Folders + folderIndex;\r
+  UInt64 size = 0;\r
+  UInt32 i;\r
+  for (i = 0; i < folder->NumPackStreams; i++)\r
+  {\r
+    UInt64 t = size + p->db.PackSizes[packStreamIndex + i];\r
+    if (t < size) /* check it */\r
+      return SZ_ERROR_FAIL;\r
+    size = t;\r
+  }\r
+  *resSize = size;\r
+  return SZ_OK;\r
+}\r
+\r
+\r
+/*\r
+SRes SzReadTime(const CObjectVector<CBuf> &dataVector,\r
+    CObjectVector<CSzFileItem> &files, UInt64 type)\r
+{\r
+  CBoolVector boolVector;\r
+  RINOK(ReadBoolVector2(files.Size(), boolVector))\r
+\r
+  CStreamSwitch streamSwitch;\r
+  RINOK(streamSwitch.Set(this, &dataVector));\r
+\r
+  for (int i = 0; i < files.Size(); i++)\r
+  {\r
+    CSzFileItem &file = files[i];\r
+    CArchiveFileTime fileTime;\r
+    bool defined = boolVector[i];\r
+    if (defined)\r
+    {\r
+      UInt32 low, high;\r
+      RINOK(SzReadUInt32(low));\r
+      RINOK(SzReadUInt32(high));\r
+      fileTime.dwLowDateTime = low;\r
+      fileTime.dwHighDateTime = high;\r
+    }\r
+    switch(type)\r
+    {\r
+      case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;\r
+      case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;\r
+      case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;\r
+    }\r
+  }\r
+  return SZ_OK;\r
+}\r
+*/\r
+\r
+static int TestSignatureCandidate(Byte *testBytes)\r
+{\r
+  size_t i;\r
+  for (i = 0; i < k7zSignatureSize; i++)\r
+    if (testBytes[i] != k7zSignature[i])\r
+      return 0;\r
+  return 1;\r
+}\r
+\r
+typedef struct _CSzState\r
+{\r
+  Byte *Data;\r
+  size_t Size;\r
+}CSzData;\r
+\r
+static SRes SzReadByte(CSzData *sd, Byte *b)\r
+{\r
+  if (sd->Size == 0)\r
+    return SZ_ERROR_ARCHIVE;\r
+  sd->Size--;\r
+  *b = *sd->Data++;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)\r
+{\r
+  size_t i;\r
+  for (i = 0; i < size; i++)\r
+  {\r
+    RINOK(SzReadByte(sd, data + i));\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadUInt32(CSzData *sd, UInt32 *value)\r
+{\r
+  int i;\r
+  *value = 0;\r
+  for (i = 0; i < 4; i++)\r
+  {\r
+    Byte b;\r
+    RINOK(SzReadByte(sd, &b));\r
+    *value |= ((UInt32)(b) << (8 * i));\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadNumber(CSzData *sd, UInt64 *value)\r
+{\r
+  Byte firstByte;\r
+  Byte mask = 0x80;\r
+  int i;\r
+  RINOK(SzReadByte(sd, &firstByte));\r
+  *value = 0;\r
+  for (i = 0; i < 8; i++)\r
+  {\r
+    Byte b;\r
+    if ((firstByte & mask) == 0)\r
+    {\r
+      UInt64 highPart = firstByte & (mask - 1);\r
+      *value += (highPart << (8 * i));\r
+      return SZ_OK;\r
+    }\r
+    RINOK(SzReadByte(sd, &b));\r
+    *value |= ((UInt64)b << (8 * i));\r
+    mask >>= 1;\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadNumber32(CSzData *sd, UInt32 *value)\r
+{\r
+  UInt64 value64;\r
+  RINOK(SzReadNumber(sd, &value64));\r
+  if (value64 >= 0x80000000)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  *value = (UInt32)value64;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadID(CSzData *sd, UInt64 *value)\r
+{\r
+  return SzReadNumber(sd, value);\r
+}\r
+\r
+static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)\r
+{\r
+  if (size > sd->Size)\r
+    return SZ_ERROR_ARCHIVE;\r
+  sd->Size -= (size_t)size;\r
+  sd->Data += (size_t)size;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzSkeepData(CSzData *sd)\r
+{\r
+  UInt64 size;\r
+  RINOK(SzReadNumber(sd, &size));\r
+  return SzSkeepDataSize(sd, size);\r
+}\r
+\r
+static SRes SzReadArchiveProperties(CSzData *sd)\r
+{\r
+  for (;;)\r
+  {\r
+    UInt64 type;\r
+    RINOK(SzReadID(sd, &type));\r
+    if (type == k7zIdEnd)\r
+      break;\r
+    SzSkeepData(sd);\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)\r
+{\r
+  for (;;)\r
+  {\r
+    UInt64 type;\r
+    RINOK(SzReadID(sd, &type));\r
+    if (type == attribute)\r
+      return SZ_OK;\r
+    if (type == k7zIdEnd)\r
+      return SZ_ERROR_ARCHIVE;\r
+    RINOK(SzSkeepData(sd));\r
+  }\r
+}\r
+\r
+static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)\r
+{\r
+  Byte b = 0;\r
+  Byte mask = 0;\r
+  size_t i;\r
+  MY_ALLOC(Byte, *v, numItems, alloc);\r
+  for (i = 0; i < numItems; i++)\r
+  {\r
+    if (mask == 0)\r
+    {\r
+      RINOK(SzReadByte(sd, &b));\r
+      mask = 0x80;\r
+    }\r
+    (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);\r
+    mask >>= 1;\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)\r
+{\r
+  Byte allAreDefined;\r
+  size_t i;\r
+  RINOK(SzReadByte(sd, &allAreDefined));\r
+  if (allAreDefined == 0)\r
+    return SzReadBoolVector(sd, numItems, v, alloc);\r
+  MY_ALLOC(Byte, *v, numItems, alloc);\r
+  for (i = 0; i < numItems; i++)\r
+    (*v)[i] = 1;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadHashDigests(\r
+    CSzData *sd,\r
+    size_t numItems,\r
+    Byte **digestsDefined,\r
+    UInt32 **digests,\r
+    ISzAlloc *alloc)\r
+{\r
+  size_t i;\r
+  RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));\r
+  MY_ALLOC(UInt32, *digests, numItems, alloc);\r
+  for (i = 0; i < numItems; i++)\r
+    if ((*digestsDefined)[i])\r
+    {\r
+      RINOK(SzReadUInt32(sd, (*digests) + i));\r
+    }\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadPackInfo(\r
+    CSzData *sd,\r
+    UInt64 *dataOffset,\r
+    UInt32 *numPackStreams,\r
+    UInt64 **packSizes,\r
+    Byte **packCRCsDefined,\r
+    UInt32 **packCRCs,\r
+    ISzAlloc *alloc)\r
+{\r
+  UInt32 i;\r
+  RINOK(SzReadNumber(sd, dataOffset));\r
+  RINOK(SzReadNumber32(sd, numPackStreams));\r
+\r
+  RINOK(SzWaitAttribute(sd, k7zIdSize));\r
+\r
+  MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);\r
+\r
+  for (i = 0; i < *numPackStreams; i++)\r
+  {\r
+    RINOK(SzReadNumber(sd, (*packSizes) + i));\r
+  }\r
+\r
+  for (;;)\r
+  {\r
+    UInt64 type;\r
+    RINOK(SzReadID(sd, &type));\r
+    if (type == k7zIdEnd)\r
+      break;\r
+    if (type == k7zIdCRC)\r
+    {\r
+      RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));\r
+      continue;\r
+    }\r
+    RINOK(SzSkeepData(sd));\r
+  }\r
+  if (*packCRCsDefined == 0)\r
+  {\r
+    MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);\r
+    MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);\r
+    for (i = 0; i < *numPackStreams; i++)\r
+    {\r
+      (*packCRCsDefined)[i] = 0;\r
+      (*packCRCs)[i] = 0;\r
+    }\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadSwitch(CSzData *sd)\r
+{\r
+  Byte external;\r
+  RINOK(SzReadByte(sd, &external));\r
+  return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;\r
+}\r
+\r
+static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)\r
+{\r
+  UInt32 numCoders, numBindPairs, numPackStreams, i;\r
+  UInt32 numInStreams = 0, numOutStreams = 0;\r
+  \r
+  RINOK(SzReadNumber32(sd, &numCoders));\r
+  if (numCoders > NUM_FOLDER_CODERS_MAX)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  folder->NumCoders = numCoders;\r
+  \r
+  MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);\r
+\r
+  for (i = 0; i < numCoders; i++)\r
+    SzCoderInfo_Init(folder->Coders + i);\r
+\r
+  for (i = 0; i < numCoders; i++)\r
+  {\r
+    Byte mainByte;\r
+    CSzCoderInfo *coder = folder->Coders + i;\r
+    {\r
+      unsigned idSize, j;\r
+      Byte longID[15];\r
+      RINOK(SzReadByte(sd, &mainByte));\r
+      idSize = (unsigned)(mainByte & 0xF);\r
+      RINOK(SzReadBytes(sd, longID, idSize));\r
+      if (idSize > sizeof(coder->MethodID))\r
+        return SZ_ERROR_UNSUPPORTED;\r
+      coder->MethodID = 0;\r
+      for (j = 0; j < idSize; j++)\r
+        coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);\r
+\r
+      if ((mainByte & 0x10) != 0)\r
+      {\r
+        RINOK(SzReadNumber32(sd, &coder->NumInStreams));\r
+        RINOK(SzReadNumber32(sd, &coder->NumOutStreams));\r
+        if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||\r
+            coder->NumOutStreams > NUM_CODER_STREAMS_MAX)\r
+          return SZ_ERROR_UNSUPPORTED;\r
+      }\r
+      else\r
+      {\r
+        coder->NumInStreams = 1;\r
+        coder->NumOutStreams = 1;\r
+      }\r
+      if ((mainByte & 0x20) != 0)\r
+      {\r
+        UInt64 propertiesSize = 0;\r
+        RINOK(SzReadNumber(sd, &propertiesSize));\r
+        if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))\r
+          return SZ_ERROR_MEM;\r
+        RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));\r
+      }\r
+    }\r
+    while ((mainByte & 0x80) != 0)\r
+    {\r
+      RINOK(SzReadByte(sd, &mainByte));\r
+      RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));\r
+      if ((mainByte & 0x10) != 0)\r
+      {\r
+        UInt32 n;\r
+        RINOK(SzReadNumber32(sd, &n));\r
+        RINOK(SzReadNumber32(sd, &n));\r
+      }\r
+      if ((mainByte & 0x20) != 0)\r
+      {\r
+        UInt64 propertiesSize = 0;\r
+        RINOK(SzReadNumber(sd, &propertiesSize));\r
+        RINOK(SzSkeepDataSize(sd, propertiesSize));\r
+      }\r
+    }\r
+    numInStreams += coder->NumInStreams;\r
+    numOutStreams += coder->NumOutStreams;\r
+  }\r
+\r
+  if (numOutStreams == 0)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+\r
+  folder->NumBindPairs = numBindPairs = numOutStreams - 1;\r
+  MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);\r
+\r
+  for (i = 0; i < numBindPairs; i++)\r
+  {\r
+    CSzBindPair *bp = folder->BindPairs + i;\r
+    RINOK(SzReadNumber32(sd, &bp->InIndex));\r
+    RINOK(SzReadNumber32(sd, &bp->OutIndex));\r
+  }\r
+\r
+  if (numInStreams < numBindPairs)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+\r
+  folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;\r
+  MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);\r
+\r
+  if (numPackStreams == 1)\r
+  {\r
+    for (i = 0; i < numInStreams ; i++)\r
+      if (SzFolder_FindBindPairForInStream(folder, i) < 0)\r
+        break;\r
+    if (i == numInStreams)\r
+      return SZ_ERROR_UNSUPPORTED;\r
+    folder->PackStreams[0] = i;\r
+  }\r
+  else\r
+    for (i = 0; i < numPackStreams; i++)\r
+    {\r
+      RINOK(SzReadNumber32(sd, folder->PackStreams + i));\r
+    }\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadUnpackInfo(\r
+    CSzData *sd,\r
+    UInt32 *numFolders,\r
+    CSzFolder **folders,  /* for alloc */\r
+    ISzAlloc *alloc,\r
+    ISzAlloc *allocTemp)\r
+{\r
+  UInt32 i;\r
+  RINOK(SzWaitAttribute(sd, k7zIdFolder));\r
+  RINOK(SzReadNumber32(sd, numFolders));\r
+  {\r
+    RINOK(SzReadSwitch(sd));\r
+\r
+    MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);\r
+\r
+    for (i = 0; i < *numFolders; i++)\r
+      SzFolder_Init((*folders) + i);\r
+\r
+    for (i = 0; i < *numFolders; i++)\r
+    {\r
+      RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));\r
+    }\r
+  }\r
+\r
+  RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));\r
+\r
+  for (i = 0; i < *numFolders; i++)\r
+  {\r
+    UInt32 j;\r
+    CSzFolder *folder = (*folders) + i;\r
+    UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);\r
+\r
+    MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);\r
+\r
+    for (j = 0; j < numOutStreams; j++)\r
+    {\r
+      RINOK(SzReadNumber(sd, folder->UnpackSizes + j));\r
+    }\r
+  }\r
+\r
+  for (;;)\r
+  {\r
+    UInt64 type;\r
+    RINOK(SzReadID(sd, &type));\r
+    if (type == k7zIdEnd)\r
+      return SZ_OK;\r
+    if (type == k7zIdCRC)\r
+    {\r
+      SRes res;\r
+      Byte *crcsDefined = 0;\r
+      UInt32 *crcs = 0;\r
+      res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);\r
+      if (res == SZ_OK)\r
+      {\r
+        for (i = 0; i < *numFolders; i++)\r
+        {\r
+          CSzFolder *folder = (*folders) + i;\r
+          folder->UnpackCRCDefined = crcsDefined[i];\r
+          folder->UnpackCRC = crcs[i];\r
+        }\r
+      }\r
+      IAlloc_Free(allocTemp, crcs);\r
+      IAlloc_Free(allocTemp, crcsDefined);\r
+      RINOK(res);\r
+      continue;\r
+    }\r
+    RINOK(SzSkeepData(sd));\r
+  }\r
+}\r
+\r
+static SRes SzReadSubStreamsInfo(\r
+    CSzData *sd,\r
+    UInt32 numFolders,\r
+    CSzFolder *folders,\r
+    UInt32 *numUnpackStreams,\r
+    UInt64 **unpackSizes,\r
+    Byte **digestsDefined,\r
+    UInt32 **digests,\r
+    ISzAlloc *allocTemp)\r
+{\r
+  UInt64 type = 0;\r
+  UInt32 i;\r
+  UInt32 si = 0;\r
+  UInt32 numDigests = 0;\r
+\r
+  for (i = 0; i < numFolders; i++)\r
+    folders[i].NumUnpackStreams = 1;\r
+  *numUnpackStreams = numFolders;\r
+\r
+  for (;;)\r
+  {\r
+    RINOK(SzReadID(sd, &type));\r
+    if (type == k7zIdNumUnpackStream)\r
+    {\r
+      *numUnpackStreams = 0;\r
+      for (i = 0; i < numFolders; i++)\r
+      {\r
+        UInt32 numStreams;\r
+        RINOK(SzReadNumber32(sd, &numStreams));\r
+        folders[i].NumUnpackStreams = numStreams;\r
+        *numUnpackStreams += numStreams;\r
+      }\r
+      continue;\r
+    }\r
+    if (type == k7zIdCRC || type == k7zIdSize)\r
+      break;\r
+    if (type == k7zIdEnd)\r
+      break;\r
+    RINOK(SzSkeepData(sd));\r
+  }\r
+\r
+  if (*numUnpackStreams == 0)\r
+  {\r
+    *unpackSizes = 0;\r
+    *digestsDefined = 0;\r
+    *digests = 0;\r
+  }\r
+  else\r
+  {\r
+    *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));\r
+    RINOM(*unpackSizes);\r
+    *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));\r
+    RINOM(*digestsDefined);\r
+    *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));\r
+    RINOM(*digests);\r
+  }\r
+\r
+  for (i = 0; i < numFolders; i++)\r
+  {\r
+    /*\r
+    v3.13 incorrectly worked with empty folders\r
+    v4.07: we check that folder is empty\r
+    */\r
+    UInt64 sum = 0;\r
+    UInt32 j;\r
+    UInt32 numSubstreams = folders[i].NumUnpackStreams;\r
+    if (numSubstreams == 0)\r
+      continue;\r
+    if (type == k7zIdSize)\r
+    for (j = 1; j < numSubstreams; j++)\r
+    {\r
+      UInt64 size;\r
+      RINOK(SzReadNumber(sd, &size));\r
+      (*unpackSizes)[si++] = size;\r
+      sum += size;\r
+    }\r
+    (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;\r
+  }\r
+  if (type == k7zIdSize)\r
+  {\r
+    RINOK(SzReadID(sd, &type));\r
+  }\r
+\r
+  for (i = 0; i < *numUnpackStreams; i++)\r
+  {\r
+    (*digestsDefined)[i] = 0;\r
+    (*digests)[i] = 0;\r
+  }\r
+\r
+\r
+  for (i = 0; i < numFolders; i++)\r
+  {\r
+    UInt32 numSubstreams = folders[i].NumUnpackStreams;\r
+    if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)\r
+      numDigests += numSubstreams;\r
+  }\r
+\r
\r
+  si = 0;\r
+  for (;;)\r
+  {\r
+    if (type == k7zIdCRC)\r
+    {\r
+      int digestIndex = 0;\r
+      Byte *digestsDefined2 = 0;\r
+      UInt32 *digests2 = 0;\r
+      SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);\r
+      if (res == SZ_OK)\r
+      {\r
+        for (i = 0; i < numFolders; i++)\r
+        {\r
+          CSzFolder *folder = folders + i;\r
+          UInt32 numSubstreams = folder->NumUnpackStreams;\r
+          if (numSubstreams == 1 && folder->UnpackCRCDefined)\r
+          {\r
+            (*digestsDefined)[si] = 1;\r
+            (*digests)[si] = folder->UnpackCRC;\r
+            si++;\r
+          }\r
+          else\r
+          {\r
+            UInt32 j;\r
+            for (j = 0; j < numSubstreams; j++, digestIndex++)\r
+            {\r
+              (*digestsDefined)[si] = digestsDefined2[digestIndex];\r
+              (*digests)[si] = digests2[digestIndex];\r
+              si++;\r
+            }\r
+          }\r
+        }\r
+      }\r
+      IAlloc_Free(allocTemp, digestsDefined2);\r
+      IAlloc_Free(allocTemp, digests2);\r
+      RINOK(res);\r
+    }\r
+    else if (type == k7zIdEnd)\r
+      return SZ_OK;\r
+    else\r
+    {\r
+      RINOK(SzSkeepData(sd));\r
+    }\r
+    RINOK(SzReadID(sd, &type));\r
+  }\r
+}\r
+\r
+\r
+static SRes SzReadStreamsInfo(\r
+    CSzData *sd,\r
+    UInt64 *dataOffset,\r
+    CSzAr *p,\r
+    UInt32 *numUnpackStreams,\r
+    UInt64 **unpackSizes, /* allocTemp */\r
+    Byte **digestsDefined,   /* allocTemp */\r
+    UInt32 **digests,        /* allocTemp */\r
+    ISzAlloc *alloc,\r
+    ISzAlloc *allocTemp)\r
+{\r
+  for (;;)\r
+  {\r
+    UInt64 type;\r
+    RINOK(SzReadID(sd, &type));\r
+    if ((UInt64)(int)type != type)\r
+      return SZ_ERROR_UNSUPPORTED;\r
+    switch((int)type)\r
+    {\r
+      case k7zIdEnd:\r
+        return SZ_OK;\r
+      case k7zIdPackInfo:\r
+      {\r
+        RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,\r
+            &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));\r
+        break;\r
+      }\r
+      case k7zIdUnpackInfo:\r
+      {\r
+        RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));\r
+        break;\r
+      }\r
+      case k7zIdSubStreamsInfo:\r
+      {\r
+        RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,\r
+            numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));\r
+        break;\r
+      }\r
+      default:\r
+        return SZ_ERROR_UNSUPPORTED;\r
+    }\r
+  }\r
+}\r
+\r
+size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)\r
+{\r
+  size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];\r
+  if (dest != 0)\r
+  {\r
+    size_t i;\r
+    const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2);\r
+    for (i = 0; i < len; i++)\r
+      dest[i] = GetUi16(src + i * 2);\r
+  }\r
+  return len;\r
+}\r
+\r
+static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes)\r
+{\r
+  UInt32 i;\r
+  size_t pos = 0;\r
+  for (i = 0; i < numFiles; i++)\r
+  {\r
+    sizes[i] = pos;\r
+    for (;;)\r
+    {\r
+      if (pos >= size)\r
+        return SZ_ERROR_ARCHIVE;\r
+      if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0)\r
+        break;\r
+      pos++;\r
+    }\r
+    pos++;\r
+  }\r
+  sizes[i] = pos;\r
+  return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;\r
+}\r
+\r
+static SRes SzReadHeader2(\r
+    CSzArEx *p,   /* allocMain */\r
+    CSzData *sd,\r
+    UInt64 **unpackSizes,  /* allocTemp */\r
+    Byte **digestsDefined,    /* allocTemp */\r
+    UInt32 **digests,         /* allocTemp */\r
+    Byte **emptyStreamVector, /* allocTemp */\r
+    Byte **emptyFileVector,   /* allocTemp */\r
+    Byte **lwtVector,         /* allocTemp */\r
+    ISzAlloc *allocMain,\r
+    ISzAlloc *allocTemp)\r
+{\r
+  UInt64 type;\r
+  UInt32 numUnpackStreams = 0;\r
+  UInt32 numFiles = 0;\r
+  CSzFileItem *files = 0;\r
+  UInt32 numEmptyStreams = 0;\r
+  UInt32 i;\r
+\r
+  RINOK(SzReadID(sd, &type));\r
+\r
+  if (type == k7zIdArchiveProperties)\r
+  {\r
+    RINOK(SzReadArchiveProperties(sd));\r
+    RINOK(SzReadID(sd, &type));\r
+  }\r
\r
\r
+  if (type == k7zIdMainStreamsInfo)\r
+  {\r
+    RINOK(SzReadStreamsInfo(sd,\r
+        &p->dataPos,\r
+        &p->db,\r
+        &numUnpackStreams,\r
+        unpackSizes,\r
+        digestsDefined,\r
+        digests, allocMain, allocTemp));\r
+    p->dataPos += p->startPosAfterHeader;\r
+    RINOK(SzReadID(sd, &type));\r
+  }\r
+\r
+  if (type == k7zIdEnd)\r
+    return SZ_OK;\r
+  if (type != k7zIdFilesInfo)\r
+    return SZ_ERROR_ARCHIVE;\r
+  \r
+  RINOK(SzReadNumber32(sd, &numFiles));\r
+  p->db.NumFiles = numFiles;\r
+\r
+  MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);\r
+\r
+  p->db.Files = files;\r
+  for (i = 0; i < numFiles; i++)\r
+    SzFile_Init(files + i);\r
+\r
+  for (;;)\r
+  {\r
+    UInt64 type;\r
+    UInt64 size;\r
+    RINOK(SzReadID(sd, &type));\r
+    if (type == k7zIdEnd)\r
+      break;\r
+    RINOK(SzReadNumber(sd, &size));\r
+    if (size > sd->Size)\r
+      return SZ_ERROR_ARCHIVE;\r
+    if ((UInt64)(int)type != type)\r
+    {\r
+      RINOK(SzSkeepDataSize(sd, size));\r
+    }\r
+    else\r
+    switch((int)type)\r
+    {\r
+      case k7zIdName:\r
+      {\r
+        size_t namesSize;\r
+        RINOK(SzReadSwitch(sd));\r
+        namesSize = (size_t)size - 1;\r
+        if ((namesSize & 1) != 0)\r
+          return SZ_ERROR_ARCHIVE;\r
+        if (!Buf_Create(&p->FileNames, namesSize, allocMain))\r
+          return SZ_ERROR_MEM;\r
+        MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);\r
+        memcpy(p->FileNames.data, sd->Data, namesSize);\r
+        RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets))\r
+        RINOK(SzSkeepDataSize(sd, namesSize));\r
+        break;\r
+      }\r
+      case k7zIdEmptyStream:\r
+      {\r
+        RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));\r
+        numEmptyStreams = 0;\r
+        for (i = 0; i < numFiles; i++)\r
+          if ((*emptyStreamVector)[i])\r
+            numEmptyStreams++;\r
+        break;\r
+      }\r
+      case k7zIdEmptyFile:\r
+      {\r
+        RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));\r
+        break;\r
+      }\r
+      case k7zIdWinAttributes:\r
+      {\r
+        RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));\r
+        RINOK(SzReadSwitch(sd));\r
+        for (i = 0; i < numFiles; i++)\r
+        {\r
+          CSzFileItem *f = &files[i];\r
+          Byte defined = (*lwtVector)[i];\r
+          f->AttribDefined = defined;\r
+          f->Attrib = 0;\r
+          if (defined)\r
+          {\r
+            RINOK(SzReadUInt32(sd, &f->Attrib));\r
+          }\r
+        }\r
+        IAlloc_Free(allocTemp, *lwtVector);\r
+        *lwtVector = NULL;\r
+        break;\r
+      }\r
+      case k7zIdMTime:\r
+      {\r
+        RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));\r
+        RINOK(SzReadSwitch(sd));\r
+        for (i = 0; i < numFiles; i++)\r
+        {\r
+          CSzFileItem *f = &files[i];\r
+          Byte defined = (*lwtVector)[i];\r
+          f->MTimeDefined = defined;\r
+          f->MTime.Low = f->MTime.High = 0;\r
+          if (defined)\r
+          {\r
+            RINOK(SzReadUInt32(sd, &f->MTime.Low));\r
+            RINOK(SzReadUInt32(sd, &f->MTime.High));\r
+          }\r
+        }\r
+        IAlloc_Free(allocTemp, *lwtVector);\r
+        *lwtVector = NULL;\r
+        break;\r
+      }\r
+      default:\r
+      {\r
+        RINOK(SzSkeepDataSize(sd, size));\r
+      }\r
+    }\r
+  }\r
+\r
+  {\r
+    UInt32 emptyFileIndex = 0;\r
+    UInt32 sizeIndex = 0;\r
+    for (i = 0; i < numFiles; i++)\r
+    {\r
+      CSzFileItem *file = files + i;\r
+      file->IsAnti = 0;\r
+      if (*emptyStreamVector == 0)\r
+        file->HasStream = 1;\r
+      else\r
+        file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);\r
+      if (file->HasStream)\r
+      {\r
+        file->IsDir = 0;\r
+        file->Size = (*unpackSizes)[sizeIndex];\r
+        file->Crc = (*digests)[sizeIndex];\r
+        file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex];\r
+        sizeIndex++;\r
+      }\r
+      else\r
+      {\r
+        if (*emptyFileVector == 0)\r
+          file->IsDir = 1;\r
+        else\r
+          file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);\r
+        emptyFileIndex++;\r
+        file->Size = 0;\r
+        file->Crc = 0;\r
+        file->CrcDefined = 0;\r
+      }\r
+    }\r
+  }\r
+  return SzArEx_Fill(p, allocMain);\r
+}\r
+\r
+static SRes SzReadHeader(\r
+    CSzArEx *p,\r
+    CSzData *sd,\r
+    ISzAlloc *allocMain,\r
+    ISzAlloc *allocTemp)\r
+{\r
+  UInt64 *unpackSizes = 0;\r
+  Byte *digestsDefined = 0;\r
+  UInt32 *digests = 0;\r
+  Byte *emptyStreamVector = 0;\r
+  Byte *emptyFileVector = 0;\r
+  Byte *lwtVector = 0;\r
+  SRes res = SzReadHeader2(p, sd,\r
+      &unpackSizes, &digestsDefined, &digests,\r
+      &emptyStreamVector, &emptyFileVector, &lwtVector,\r
+      allocMain, allocTemp);\r
+  IAlloc_Free(allocTemp, unpackSizes);\r
+  IAlloc_Free(allocTemp, digestsDefined);\r
+  IAlloc_Free(allocTemp, digests);\r
+  IAlloc_Free(allocTemp, emptyStreamVector);\r
+  IAlloc_Free(allocTemp, emptyFileVector);\r
+  IAlloc_Free(allocTemp, lwtVector);\r
+  return res;\r
+}\r
+\r
+static SRes SzReadAndDecodePackedStreams2(\r
+    ILookInStream *inStream,\r
+    CSzData *sd,\r
+    CBuf *outBuffer,\r
+    UInt64 baseOffset,\r
+    CSzAr *p,\r
+    UInt64 **unpackSizes,\r
+    Byte **digestsDefined,\r
+    UInt32 **digests,\r
+    ISzAlloc *allocTemp)\r
+{\r
+\r
+  UInt32 numUnpackStreams = 0;\r
+  UInt64 dataStartPos;\r
+  CSzFolder *folder;\r
+  UInt64 unpackSize;\r
+  SRes res;\r
+\r
+  RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,\r
+      &numUnpackStreams,  unpackSizes, digestsDefined, digests,\r
+      allocTemp, allocTemp));\r
+  \r
+  dataStartPos += baseOffset;\r
+  if (p->NumFolders != 1)\r
+    return SZ_ERROR_ARCHIVE;\r
+\r
+  folder = p->Folders;\r
+  unpackSize = SzFolder_GetUnpackSize(folder);\r
+  \r
+  RINOK(LookInStream_SeekTo(inStream, dataStartPos));\r
+\r
+  if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))\r
+    return SZ_ERROR_MEM;\r
+  \r
+  res = SzFolder_Decode(folder, p->PackSizes,\r
+          inStream, dataStartPos,\r
+          outBuffer->data, (size_t)unpackSize, allocTemp);\r
+  RINOK(res);\r
+  if (folder->UnpackCRCDefined)\r
+    if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)\r
+      return SZ_ERROR_CRC;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes SzReadAndDecodePackedStreams(\r
+    ILookInStream *inStream,\r
+    CSzData *sd,\r
+    CBuf *outBuffer,\r
+    UInt64 baseOffset,\r
+    ISzAlloc *allocTemp)\r
+{\r
+  CSzAr p;\r
+  UInt64 *unpackSizes = 0;\r
+  Byte *digestsDefined = 0;\r
+  UInt32 *digests = 0;\r
+  SRes res;\r
+  SzAr_Init(&p);\r
+  res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,\r
+    &p, &unpackSizes, &digestsDefined, &digests,\r
+    allocTemp);\r
+  SzAr_Free(&p, allocTemp);\r
+  IAlloc_Free(allocTemp, unpackSizes);\r
+  IAlloc_Free(allocTemp, digestsDefined);\r
+  IAlloc_Free(allocTemp, digests);\r
+  return res;\r
+}\r
+\r
+static SRes SzArEx_Open2(\r
+    CSzArEx *p,\r
+    ILookInStream *inStream,\r
+    ISzAlloc *allocMain,\r
+    ISzAlloc *allocTemp)\r
+{\r
+  Byte header[k7zStartHeaderSize];\r
+  Int64 startArcPos;\r
+  UInt64 nextHeaderOffset, nextHeaderSize;\r
+  size_t nextHeaderSizeT;\r
+  UInt32 nextHeaderCRC;\r
+  CBuf buffer;\r
+  SRes res;\r
+\r
+  startArcPos = 0;\r
+  RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));\r
+\r
+  RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));\r
+\r
+  if (!TestSignatureCandidate(header))\r
+    return SZ_ERROR_NO_ARCHIVE;\r
+  if (header[6] != k7zMajorVersion)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+\r
+  nextHeaderOffset = GetUi64(header + 12);\r
+  nextHeaderSize = GetUi64(header + 20);\r
+  nextHeaderCRC = GetUi32(header + 28);\r
+\r
+  p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;\r
+  \r
+  if (CrcCalc(header + 12, 20) != GetUi32(header + 8))\r
+    return SZ_ERROR_CRC;\r
+\r
+  nextHeaderSizeT = (size_t)nextHeaderSize;\r
+  if (nextHeaderSizeT != nextHeaderSize)\r
+    return SZ_ERROR_MEM;\r
+  if (nextHeaderSizeT == 0)\r
+    return SZ_OK;\r
+  if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||\r
+      nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)\r
+    return SZ_ERROR_NO_ARCHIVE;\r
+\r
+  {\r
+    Int64 pos = 0;\r
+    RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));\r
+    if ((UInt64)pos < startArcPos + nextHeaderOffset ||\r
+        (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||\r
+        (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)\r
+      return SZ_ERROR_INPUT_EOF;\r
+  }\r
+\r
+  RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));\r
+\r
+  if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))\r
+    return SZ_ERROR_MEM;\r
+\r
+  res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);\r
+  if (res == SZ_OK)\r
+  {\r
+    res = SZ_ERROR_ARCHIVE;\r
+    if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)\r
+    {\r
+      CSzData sd;\r
+      UInt64 type;\r
+      sd.Data = buffer.data;\r
+      sd.Size = buffer.size;\r
+      res = SzReadID(&sd, &type);\r
+      if (res == SZ_OK)\r
+      {\r
+        if (type == k7zIdEncodedHeader)\r
+        {\r
+          CBuf outBuffer;\r
+          Buf_Init(&outBuffer);\r
+          res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);\r
+          if (res != SZ_OK)\r
+            Buf_Free(&outBuffer, allocTemp);\r
+          else\r
+          {\r
+            Buf_Free(&buffer, allocTemp);\r
+            buffer.data = outBuffer.data;\r
+            buffer.size = outBuffer.size;\r
+            sd.Data = buffer.data;\r
+            sd.Size = buffer.size;\r
+            res = SzReadID(&sd, &type);\r
+          }\r
+        }\r
+      }\r
+      if (res == SZ_OK)\r
+      {\r
+        if (type == k7zIdHeader)\r
+          res = SzReadHeader(p, &sd, allocMain, allocTemp);\r
+        else\r
+          res = SZ_ERROR_UNSUPPORTED;\r
+      }\r
+    }\r
+  }\r
+  Buf_Free(&buffer, allocTemp);\r
+  return res;\r
+}\r
+\r
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)\r
+{\r
+  SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);\r
+  if (res != SZ_OK)\r
+    SzArEx_Free(p, allocMain);\r
+  return res;\r
+}\r
+\r
+SRes SzArEx_Extract(\r
+    const CSzArEx *p,\r
+    ILookInStream *inStream,\r
+    UInt32 fileIndex,\r
+    UInt32 *blockIndex,\r
+    Byte **outBuffer,\r
+    size_t *outBufferSize,\r
+    size_t *offset,\r
+    size_t *outSizeProcessed,\r
+    ISzAlloc *allocMain,\r
+    ISzAlloc *allocTemp)\r
+{\r
+  UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];\r
+  SRes res = SZ_OK;\r
+  *offset = 0;\r
+  *outSizeProcessed = 0;\r
+  if (folderIndex == (UInt32)-1)\r
+  {\r
+    IAlloc_Free(allocMain, *outBuffer);\r
+    *blockIndex = folderIndex;\r
+    *outBuffer = 0;\r
+    *outBufferSize = 0;\r
+    return SZ_OK;\r
+  }\r
+\r
+  if (*outBuffer == 0 || *blockIndex != folderIndex)\r
+  {\r
+    CSzFolder *folder = p->db.Folders + folderIndex;\r
+    UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);\r
+    size_t unpackSize = (size_t)unpackSizeSpec;\r
+    UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);\r
+\r
+    if (unpackSize != unpackSizeSpec)\r
+      return SZ_ERROR_MEM;\r
+    *blockIndex = folderIndex;\r
+    IAlloc_Free(allocMain, *outBuffer);\r
+    *outBuffer = 0;\r
+    \r
+    RINOK(LookInStream_SeekTo(inStream, startOffset));\r
+    \r
+    if (res == SZ_OK)\r
+    {\r
+      *outBufferSize = unpackSize;\r
+      if (unpackSize != 0)\r
+      {\r
+        *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);\r
+        if (*outBuffer == 0)\r
+          res = SZ_ERROR_MEM;\r
+      }\r
+      if (res == SZ_OK)\r
+      {\r
+        res = SzFolder_Decode(folder,\r
+          p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],\r
+          inStream, startOffset,\r
+          *outBuffer, unpackSize, allocTemp);\r
+        if (res == SZ_OK)\r
+        {\r
+          if (folder->UnpackCRCDefined)\r
+          {\r
+            if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)\r
+              res = SZ_ERROR_CRC;\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+  if (res == SZ_OK)\r
+  {\r
+    UInt32 i;\r
+    CSzFileItem *fileItem = p->db.Files + fileIndex;\r
+    *offset = 0;\r
+    for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)\r
+      *offset += (UInt32)p->db.Files[i].Size;\r
+    *outSizeProcessed = (size_t)fileItem->Size;\r
+    if (*offset + *outSizeProcessed > *outBufferSize)\r
+      return SZ_ERROR_FAIL;\r
+    if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc)\r
+      res = SZ_ERROR_CRC;\r
+  }\r
+  return res;\r
+}\r
diff --git a/C/7zStream.c b/C/7zStream.c
new file mode 100755 (executable)
index 0000000..f0959fb
--- /dev/null
@@ -0,0 +1,169 @@
+/* 7zStream.c -- 7z Stream functions\r
+2010-03-11 : Igor Pavlov : Public domain */\r
+\r
+#include <string.h>\r
+\r
+#include "Types.h"\r
+\r
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)\r
+{\r
+  while (size != 0)\r
+  {\r
+    size_t processed = size;\r
+    RINOK(stream->Read(stream, buf, &processed));\r
+    if (processed == 0)\r
+      return errorType;\r
+    buf = (void *)((Byte *)buf + processed);\r
+    size -= processed;\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)\r
+{\r
+  return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);\r
+}\r
+\r
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)\r
+{\r
+  size_t processed = 1;\r
+  RINOK(stream->Read(stream, buf, &processed));\r
+  return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;\r
+}\r
+\r
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)\r
+{\r
+  Int64 t = offset;\r
+  return stream->Seek(stream, &t, SZ_SEEK_SET);\r
+}\r
+\r
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)\r
+{\r
+  const void *lookBuf;\r
+  if (*size == 0)\r
+    return SZ_OK;\r
+  RINOK(stream->Look(stream, &lookBuf, size));\r
+  memcpy(buf, lookBuf, *size);\r
+  return stream->Skip(stream, *size);\r
+}\r
+\r
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)\r
+{\r
+  while (size != 0)\r
+  {\r
+    size_t processed = size;\r
+    RINOK(stream->Read(stream, buf, &processed));\r
+    if (processed == 0)\r
+      return errorType;\r
+    buf = (void *)((Byte *)buf + processed);\r
+    size -= processed;\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)\r
+{\r
+  return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);\r
+}\r
+\r
+static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)\r
+{\r
+  SRes res = SZ_OK;\r
+  CLookToRead *p = (CLookToRead *)pp;\r
+  size_t size2 = p->size - p->pos;\r
+  if (size2 == 0 && *size > 0)\r
+  {\r
+    p->pos = 0;\r
+    size2 = LookToRead_BUF_SIZE;\r
+    res = p->realStream->Read(p->realStream, p->buf, &size2);\r
+    p->size = size2;\r
+  }\r
+  if (size2 < *size)\r
+    *size = size2;\r
+  *buf = p->buf + p->pos;\r
+  return res;\r
+}\r
+\r
+static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)\r
+{\r
+  SRes res = SZ_OK;\r
+  CLookToRead *p = (CLookToRead *)pp;\r
+  size_t size2 = p->size - p->pos;\r
+  if (size2 == 0 && *size > 0)\r
+  {\r
+    p->pos = 0;\r
+    if (*size > LookToRead_BUF_SIZE)\r
+      *size = LookToRead_BUF_SIZE;\r
+    res = p->realStream->Read(p->realStream, p->buf, size);\r
+    size2 = p->size = *size;\r
+  }\r
+  if (size2 < *size)\r
+    *size = size2;\r
+  *buf = p->buf + p->pos;\r
+  return res;\r
+}\r
+\r
+static SRes LookToRead_Skip(void *pp, size_t offset)\r
+{\r
+  CLookToRead *p = (CLookToRead *)pp;\r
+  p->pos += offset;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes LookToRead_Read(void *pp, void *buf, size_t *size)\r
+{\r
+  CLookToRead *p = (CLookToRead *)pp;\r
+  size_t rem = p->size - p->pos;\r
+  if (rem == 0)\r
+    return p->realStream->Read(p->realStream, buf, size);\r
+  if (rem > *size)\r
+    rem = *size;\r
+  memcpy(buf, p->buf + p->pos, rem);\r
+  p->pos += rem;\r
+  *size = rem;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)\r
+{\r
+  CLookToRead *p = (CLookToRead *)pp;\r
+  p->pos = p->size = 0;\r
+  return p->realStream->Seek(p->realStream, pos, origin);\r
+}\r
+\r
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead)\r
+{\r
+  p->s.Look = lookahead ?\r
+      LookToRead_Look_Lookahead :\r
+      LookToRead_Look_Exact;\r
+  p->s.Skip = LookToRead_Skip;\r
+  p->s.Read = LookToRead_Read;\r
+  p->s.Seek = LookToRead_Seek;\r
+}\r
+\r
+void LookToRead_Init(CLookToRead *p)\r
+{\r
+  p->pos = p->size = 0;\r
+}\r
+\r
+static SRes SecToLook_Read(void *pp, void *buf, size_t *size)\r
+{\r
+  CSecToLook *p = (CSecToLook *)pp;\r
+  return LookInStream_LookRead(p->realStream, buf, size);\r
+}\r
+\r
+void SecToLook_CreateVTable(CSecToLook *p)\r
+{\r
+  p->s.Read = SecToLook_Read;\r
+}\r
+\r
+static SRes SecToRead_Read(void *pp, void *buf, size_t *size)\r
+{\r
+  CSecToRead *p = (CSecToRead *)pp;\r
+  return p->realStream->Read(p->realStream, buf, size);\r
+}\r
+\r
+void SecToRead_CreateVTable(CSecToRead *p)\r
+{\r
+  p->s.Read = SecToRead_Read;\r
+}\r
diff --git a/C/7zVersion.h b/C/7zVersion.h
new file mode 100755 (executable)
index 0000000..d4ac470
--- /dev/null
@@ -0,0 +1,7 @@
+#define MY_VER_MAJOR 9\r
+#define MY_VER_MINOR 20\r
+#define MY_VER_BUILD 0\r
+#define MY_VERSION "9.20"\r
+#define MY_DATE "2010-11-18"\r
+#define MY_COPYRIGHT ": Igor Pavlov : Public domain"\r
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE\r
diff --git a/C/Alloc.c b/C/Alloc.c
new file mode 100755 (executable)
index 0000000..bb24a77
--- /dev/null
+++ b/C/Alloc.c
@@ -0,0 +1,127 @@
+/* Alloc.c -- Memory allocation functions\r
+2008-09-24\r
+Igor Pavlov\r
+Public domain */\r
+\r
+#ifdef _WIN32\r
+#include <windows.h>\r
+#endif\r
+#include <stdlib.h>\r
+\r
+#include "Alloc.h"\r
+\r
+/* #define _SZ_ALLOC_DEBUG */\r
+\r
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */\r
+#ifdef _SZ_ALLOC_DEBUG\r
+#include <stdio.h>\r
+int g_allocCount = 0;\r
+int g_allocCountMid = 0;\r
+int g_allocCountBig = 0;\r
+#endif\r
+\r
+void *MyAlloc(size_t size)\r
+{\r
+  if (size == 0)\r
+    return 0;\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  {\r
+    void *p = malloc(size);\r
+    fprintf(stderr, "\nAlloc %10d bytes, count = %10d,  addr = %8X", size, g_allocCount++, (unsigned)p);\r
+    return p;\r
+  }\r
+  #else\r
+  return malloc(size);\r
+  #endif\r
+}\r
+\r
+void MyFree(void *address)\r
+{\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  if (address != 0)\r
+    fprintf(stderr, "\nFree; count = %10d,  addr = %8X", --g_allocCount, (unsigned)address);\r
+  #endif\r
+  free(address);\r
+}\r
+\r
+#ifdef _WIN32\r
+\r
+void *MidAlloc(size_t size)\r
+{\r
+  if (size == 0)\r
+    return 0;\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  fprintf(stderr, "\nAlloc_Mid %10d bytes;  count = %10d", size, g_allocCountMid++);\r
+  #endif\r
+  return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);\r
+}\r
+\r
+void MidFree(void *address)\r
+{\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  if (address != 0)\r
+    fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);\r
+  #endif\r
+  if (address == 0)\r
+    return;\r
+  VirtualFree(address, 0, MEM_RELEASE);\r
+}\r
+\r
+#ifndef MEM_LARGE_PAGES\r
+#undef _7ZIP_LARGE_PAGES\r
+#endif\r
+\r
+#ifdef _7ZIP_LARGE_PAGES\r
+SIZE_T g_LargePageSize = 0;\r
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();\r
+#endif\r
+\r
+void SetLargePageSize()\r
+{\r
+  #ifdef _7ZIP_LARGE_PAGES\r
+  SIZE_T size = 0;\r
+  GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)\r
+        GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");\r
+  if (largePageMinimum == 0)\r
+    return;\r
+  size = largePageMinimum();\r
+  if (size == 0 || (size & (size - 1)) != 0)\r
+    return;\r
+  g_LargePageSize = size;\r
+  #endif\r
+}\r
+\r
+\r
+void *BigAlloc(size_t size)\r
+{\r
+  if (size == 0)\r
+    return 0;\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  fprintf(stderr, "\nAlloc_Big %10d bytes;  count = %10d", size, g_allocCountBig++);\r
+  #endif\r
+  \r
+  #ifdef _7ZIP_LARGE_PAGES\r
+  if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))\r
+  {\r
+    void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),\r
+        MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);\r
+    if (res != 0)\r
+      return res;\r
+  }\r
+  #endif\r
+  return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);\r
+}\r
+\r
+void BigFree(void *address)\r
+{\r
+  #ifdef _SZ_ALLOC_DEBUG\r
+  if (address != 0)\r
+    fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);\r
+  #endif\r
+  \r
+  if (address == 0)\r
+    return;\r
+  VirtualFree(address, 0, MEM_RELEASE);\r
+}\r
+\r
+#endif\r
diff --git a/C/Alloc.h b/C/Alloc.h
new file mode 100755 (executable)
index 0000000..6b3f034
--- /dev/null
+++ b/C/Alloc.h
@@ -0,0 +1,38 @@
+/* Alloc.h -- Memory allocation functions\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __COMMON_ALLOC_H\r
+#define __COMMON_ALLOC_H\r
+\r
+#include <stddef.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+void *MyAlloc(size_t size);\r
+void MyFree(void *address);\r
+\r
+#ifdef _WIN32\r
+\r
+void SetLargePageSize();\r
+\r
+void *MidAlloc(size_t size);\r
+void MidFree(void *address);\r
+void *BigAlloc(size_t size);\r
+void BigFree(void *address);\r
+\r
+#else\r
+\r
+#define MidAlloc(size) MyAlloc(size)\r
+#define MidFree(address) MyFree(address)\r
+#define BigAlloc(size) MyAlloc(size)\r
+#define BigFree(address) MyFree(address)\r
+\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/Bcj2.c b/C/Bcj2.c
new file mode 100755 (executable)
index 0000000..474bdd4
--- /dev/null
+++ b/C/Bcj2.c
@@ -0,0 +1,132 @@
+/* Bcj2.c -- Converter for x86 code (BCJ2)\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#include "Bcj2.h"\r
+\r
+#ifdef _LZMA_PROB32\r
+#define CProb UInt32\r
+#else\r
+#define CProb UInt16\r
+#endif\r
+\r
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)\r
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))\r
+\r
+#define kNumTopBits 24\r
+#define kTopValue ((UInt32)1 << kNumTopBits)\r
+\r
+#define kNumBitModelTotalBits 11\r
+#define kBitModelTotal (1 << kNumBitModelTotalBits)\r
+#define kNumMoveBits 5\r
+\r
+#define RC_READ_BYTE (*buffer++)\r
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }\r
+#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \\r
+  { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}\r
+\r
+#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }\r
+\r
+#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)\r
+#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;\r
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;\r
+\r
+int Bcj2_Decode(\r
+    const Byte *buf0, SizeT size0,\r
+    const Byte *buf1, SizeT size1,\r
+    const Byte *buf2, SizeT size2,\r
+    const Byte *buf3, SizeT size3,\r
+    Byte *outBuf, SizeT outSize)\r
+{\r
+  CProb p[256 + 2];\r
+  SizeT inPos = 0, outPos = 0;\r
+\r
+  const Byte *buffer, *bufferLim;\r
+  UInt32 range, code;\r
+  Byte prevByte = 0;\r
+\r
+  unsigned int i;\r
+  for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)\r
+    p[i] = kBitModelTotal >> 1;\r
+\r
+  buffer = buf3;\r
+  bufferLim = buffer + size3;\r
+  RC_INIT2\r
+\r
+  if (outSize == 0)\r
+    return SZ_OK;\r
+\r
+  for (;;)\r
+  {\r
+    Byte b;\r
+    CProb *prob;\r
+    UInt32 bound;\r
+    UInt32 ttt;\r
+\r
+    SizeT limit = size0 - inPos;\r
+    if (outSize - outPos < limit)\r
+      limit = outSize - outPos;\r
+    while (limit != 0)\r
+    {\r
+      Byte b = buf0[inPos];\r
+      outBuf[outPos++] = b;\r
+      if (IsJ(prevByte, b))\r
+        break;\r
+      inPos++;\r
+      prevByte = b;\r
+      limit--;\r
+    }\r
+\r
+    if (limit == 0 || outPos == outSize)\r
+      break;\r
+\r
+    b = buf0[inPos++];\r
+\r
+    if (b == 0xE8)\r
+      prob = p + prevByte;\r
+    else if (b == 0xE9)\r
+      prob = p + 256;\r
+    else\r
+      prob = p + 257;\r
+\r
+    IF_BIT_0(prob)\r
+    {\r
+      UPDATE_0(prob)\r
+      prevByte = b;\r
+    }\r
+    else\r
+    {\r
+      UInt32 dest;\r
+      const Byte *v;\r
+      UPDATE_1(prob)\r
+      if (b == 0xE8)\r
+      {\r
+        v = buf1;\r
+        if (size1 < 4)\r
+          return SZ_ERROR_DATA;\r
+        buf1 += 4;\r
+        size1 -= 4;\r
+      }\r
+      else\r
+      {\r
+        v = buf2;\r
+        if (size2 < 4)\r
+          return SZ_ERROR_DATA;\r
+        buf2 += 4;\r
+        size2 -= 4;\r
+      }\r
+      dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |\r
+          ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);\r
+      outBuf[outPos++] = (Byte)dest;\r
+      if (outPos == outSize)\r
+        break;\r
+      outBuf[outPos++] = (Byte)(dest >> 8);\r
+      if (outPos == outSize)\r
+        break;\r
+      outBuf[outPos++] = (Byte)(dest >> 16);\r
+      if (outPos == outSize)\r
+        break;\r
+      outBuf[outPos++] = prevByte = (Byte)(dest >> 24);\r
+    }\r
+  }\r
+  return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;\r
+}\r
diff --git a/C/Bcj2.h b/C/Bcj2.h
new file mode 100755 (executable)
index 0000000..d9d857b
--- /dev/null
+++ b/C/Bcj2.h
@@ -0,0 +1,38 @@
+/* Bcj2.h -- Converter for x86 code (BCJ2)\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __BCJ2_H\r
+#define __BCJ2_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*\r
+Conditions:\r
+  outSize <= FullOutputSize,\r
+  where FullOutputSize is full size of output stream of x86_2 filter.\r
+\r
+If buf0 overlaps outBuf, there are two required conditions:\r
+  1) (buf0 >= outBuf)\r
+  2) (buf0 + size0 >= outBuf + FullOutputSize).\r
+\r
+Returns:\r
+  SZ_OK\r
+  SZ_ERROR_DATA - Data error\r
+*/\r
+\r
+int Bcj2_Decode(\r
+    const Byte *buf0, SizeT size0,\r
+    const Byte *buf1, SizeT size1,\r
+    const Byte *buf2, SizeT size2,\r
+    const Byte *buf3, SizeT size3,\r
+    Byte *outBuf, SizeT outSize);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/Bra.c b/C/Bra.c
new file mode 100755 (executable)
index 0000000..2a0f147
--- /dev/null
+++ b/C/Bra.c
@@ -0,0 +1,133 @@
+/* Bra.c -- Converters for RISC code\r
+2010-04-16 : Igor Pavlov : Public domain */\r
+\r
+#include "Bra.h"\r
+\r
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)\r
+{\r
+  SizeT i;\r
+  if (size < 4)\r
+    return 0;\r
+  size -= 4;\r
+  ip += 8;\r
+  for (i = 0; i <= size; i += 4)\r
+  {\r
+    if (data[i + 3] == 0xEB)\r
+    {\r
+      UInt32 dest;\r
+      UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);\r
+      src <<= 2;\r
+      if (encoding)\r
+        dest = ip + (UInt32)i + src;\r
+      else\r
+        dest = src - (ip + (UInt32)i);\r
+      dest >>= 2;\r
+      data[i + 2] = (Byte)(dest >> 16);\r
+      data[i + 1] = (Byte)(dest >> 8);\r
+      data[i + 0] = (Byte)dest;\r
+    }\r
+  }\r
+  return i;\r
+}\r
+\r
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)\r
+{\r
+  SizeT i;\r
+  if (size < 4)\r
+    return 0;\r
+  size -= 4;\r
+  ip += 4;\r
+  for (i = 0; i <= size; i += 2)\r
+  {\r
+    if ((data[i + 1] & 0xF8) == 0xF0 &&\r
+        (data[i + 3] & 0xF8) == 0xF8)\r
+    {\r
+      UInt32 dest;\r
+      UInt32 src =\r
+        (((UInt32)data[i + 1] & 0x7) << 19) |\r
+        ((UInt32)data[i + 0] << 11) |\r
+        (((UInt32)data[i + 3] & 0x7) << 8) |\r
+        (data[i + 2]);\r
+      \r
+      src <<= 1;\r
+      if (encoding)\r
+        dest = ip + (UInt32)i + src;\r
+      else\r
+        dest = src - (ip + (UInt32)i);\r
+      dest >>= 1;\r
+      \r
+      data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));\r
+      data[i + 0] = (Byte)(dest >> 11);\r
+      data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));\r
+      data[i + 2] = (Byte)dest;\r
+      i += 2;\r
+    }\r
+  }\r
+  return i;\r
+}\r
+\r
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)\r
+{\r
+  SizeT i;\r
+  if (size < 4)\r
+    return 0;\r
+  size -= 4;\r
+  for (i = 0; i <= size; i += 4)\r
+  {\r
+    if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)\r
+    {\r
+      UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |\r
+        ((UInt32)data[i + 1] << 16) |\r
+        ((UInt32)data[i + 2] << 8) |\r
+        ((UInt32)data[i + 3] & (~3));\r
+      \r
+      UInt32 dest;\r
+      if (encoding)\r
+        dest = ip + (UInt32)i + src;\r
+      else\r
+        dest = src - (ip + (UInt32)i);\r
+      data[i + 0] = (Byte)(0x48 | ((dest >> 24) &  0x3));\r
+      data[i + 1] = (Byte)(dest >> 16);\r
+      data[i + 2] = (Byte)(dest >> 8);\r
+      data[i + 3] &= 0x3;\r
+      data[i + 3] |= dest;\r
+    }\r
+  }\r
+  return i;\r
+}\r
+\r
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)\r
+{\r
+  UInt32 i;\r
+  if (size < 4)\r
+    return 0;\r
+  size -= 4;\r
+  for (i = 0; i <= size; i += 4)\r
+  {\r
+    if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||\r
+        (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))\r
+    {\r
+      UInt32 src =\r
+        ((UInt32)data[i + 0] << 24) |\r
+        ((UInt32)data[i + 1] << 16) |\r
+        ((UInt32)data[i + 2] << 8) |\r
+        ((UInt32)data[i + 3]);\r
+      UInt32 dest;\r
+      \r
+      src <<= 2;\r
+      if (encoding)\r
+        dest = ip + i + src;\r
+      else\r
+        dest = src - (ip + i);\r
+      dest >>= 2;\r
+      \r
+      dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;\r
+\r
+      data[i + 0] = (Byte)(dest >> 24);\r
+      data[i + 1] = (Byte)(dest >> 16);\r
+      data[i + 2] = (Byte)(dest >> 8);\r
+      data[i + 3] = (Byte)dest;\r
+    }\r
+  }\r
+  return i;\r
+}\r
diff --git a/C/Bra.h b/C/Bra.h
new file mode 100755 (executable)
index 0000000..9c91e33
--- /dev/null
+++ b/C/Bra.h
@@ -0,0 +1,68 @@
+/* Bra.h -- Branch converters for executables\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __BRA_H\r
+#define __BRA_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*\r
+These functions convert relative addresses to absolute addresses\r
+in CALL instructions to increase the compression ratio.\r
+  \r
+  In:\r
+    data     - data buffer\r
+    size     - size of data\r
+    ip       - current virtual Instruction Pinter (IP) value\r
+    state    - state variable for x86 converter\r
+    encoding - 0 (for decoding), 1 (for encoding)\r
+  \r
+  Out:\r
+    state    - state variable for x86 converter\r
+\r
+  Returns:\r
+    The number of processed bytes. If you call these functions with multiple calls,\r
+    you must start next call with first byte after block of processed bytes.\r
+  \r
+  Type   Endian  Alignment  LookAhead\r
+  \r
+  x86    little      1          4\r
+  ARMT   little      2          2\r
+  ARM    little      4          0\r
+  PPC     big        4          0\r
+  SPARC   big        4          0\r
+  IA64   little     16          0\r
+\r
+  size must be >= Alignment + LookAhead, if it's not last block.\r
+  If (size < Alignment + LookAhead), converter returns 0.\r
+\r
+  Example:\r
+\r
+    UInt32 ip = 0;\r
+    for ()\r
+    {\r
+      ; size must be >= Alignment + LookAhead, if it's not last block\r
+      SizeT processed = Convert(data, size, ip, 1);\r
+      data += processed;\r
+      size -= processed;\r
+      ip += processed;\r
+    }\r
+*/\r
+\r
+#define x86_Convert_Init(state) { state = 0; }\r
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);\r
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/Bra86.c b/C/Bra86.c
new file mode 100755 (executable)
index 0000000..93566cb
--- /dev/null
+++ b/C/Bra86.c
@@ -0,0 +1,85 @@
+/* Bra86.c -- Converter for x86 code (BCJ)\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#include "Bra.h"\r
+\r
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)\r
+\r
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};\r
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};\r
+\r
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)\r
+{\r
+  SizeT bufferPos = 0, prevPosT;\r
+  UInt32 prevMask = *state & 0x7;\r
+  if (size < 5)\r
+    return 0;\r
+  ip += 5;\r
+  prevPosT = (SizeT)0 - 1;\r
+\r
+  for (;;)\r
+  {\r
+    Byte *p = data + bufferPos;\r
+    Byte *limit = data + size - 4;\r
+    for (; p < limit; p++)\r
+      if ((*p & 0xFE) == 0xE8)\r
+        break;\r
+    bufferPos = (SizeT)(p - data);\r
+    if (p >= limit)\r
+      break;\r
+    prevPosT = bufferPos - prevPosT;\r
+    if (prevPosT > 3)\r
+      prevMask = 0;\r
+    else\r
+    {\r
+      prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;\r
+      if (prevMask != 0)\r
+      {\r
+        Byte b = p[4 - kMaskToBitNumber[prevMask]];\r
+        if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))\r
+        {\r
+          prevPosT = bufferPos;\r
+          prevMask = ((prevMask << 1) & 0x7) | 1;\r
+          bufferPos++;\r
+          continue;\r
+        }\r
+      }\r
+    }\r
+    prevPosT = bufferPos;\r
+\r
+    if (Test86MSByte(p[4]))\r
+    {\r
+      UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);\r
+      UInt32 dest;\r
+      for (;;)\r
+      {\r
+        Byte b;\r
+        int index;\r
+        if (encoding)\r
+          dest = (ip + (UInt32)bufferPos) + src;\r
+        else\r
+          dest = src - (ip + (UInt32)bufferPos);\r
+        if (prevMask == 0)\r
+          break;\r
+        index = kMaskToBitNumber[prevMask] * 8;\r
+        b = (Byte)(dest >> (24 - index));\r
+        if (!Test86MSByte(b))\r
+          break;\r
+        src = dest ^ ((1 << (32 - index)) - 1);\r
+      }\r
+      p[4] = (Byte)(~(((dest >> 24) & 1) - 1));\r
+      p[3] = (Byte)(dest >> 16);\r
+      p[2] = (Byte)(dest >> 8);\r
+      p[1] = (Byte)dest;\r
+      bufferPos += 5;\r
+    }\r
+    else\r
+    {\r
+      prevMask = ((prevMask << 1) & 0x7) | 1;\r
+      bufferPos++;\r
+    }\r
+  }\r
+  prevPosT = bufferPos - prevPosT;\r
+  *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));\r
+  return bufferPos;\r
+}\r
diff --git a/C/BraIA64.c b/C/BraIA64.c
new file mode 100755 (executable)
index 0000000..f359f16
--- /dev/null
@@ -0,0 +1,67 @@
+/* BraIA64.c -- Converter for IA-64 code\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#include "Bra.h"\r
+\r
+static const Byte kBranchTable[32] =\r
+{\r
+  0, 0, 0, 0, 0, 0, 0, 0,\r
+  0, 0, 0, 0, 0, 0, 0, 0,\r
+  4, 4, 6, 6, 0, 0, 7, 7,\r
+  4, 4, 0, 0, 4, 4, 0, 0\r
+};\r
+\r
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)\r
+{\r
+  SizeT i;\r
+  if (size < 16)\r
+    return 0;\r
+  size -= 16;\r
+  for (i = 0; i <= size; i += 16)\r
+  {\r
+    UInt32 instrTemplate = data[i] & 0x1F;\r
+    UInt32 mask = kBranchTable[instrTemplate];\r
+    UInt32 bitPos = 5;\r
+    int slot;\r
+    for (slot = 0; slot < 3; slot++, bitPos += 41)\r
+    {\r
+      UInt32 bytePos, bitRes;\r
+      UInt64 instruction, instNorm;\r
+      int j;\r
+      if (((mask >> slot) & 1) == 0)\r
+        continue;\r
+      bytePos = (bitPos >> 3);\r
+      bitRes = bitPos & 0x7;\r
+      instruction = 0;\r
+      for (j = 0; j < 6; j++)\r
+        instruction += (UInt64)data[i + j + bytePos] << (8 * j);\r
+\r
+      instNorm = instruction >> bitRes;\r
+      if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)\r
+      {\r
+        UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);\r
+        UInt32 dest;\r
+        src |= ((UInt32)(instNorm >> 36) & 1) << 20;\r
+        \r
+        src <<= 4;\r
+        \r
+        if (encoding)\r
+          dest = ip + (UInt32)i + src;\r
+        else\r
+          dest = src - (ip + (UInt32)i);\r
+        \r
+        dest >>= 4;\r
+        \r
+        instNorm &= ~((UInt64)(0x8FFFFF) << 13);\r
+        instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);\r
+        instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));\r
+        \r
+        instruction &= (1 << bitRes) - 1;\r
+        instruction |= (instNorm << bitRes);\r
+        for (j = 0; j < 6; j++)\r
+          data[i + j + bytePos] = (Byte)(instruction >> (8 * j));\r
+      }\r
+    }\r
+  }\r
+  return i;\r
+}\r
diff --git a/C/CpuArch.c b/C/CpuArch.c
new file mode 100755 (executable)
index 0000000..36e7680
--- /dev/null
@@ -0,0 +1,168 @@
+/* CpuArch.c -- CPU specific code\r
+2010-10-26: Igor Pavlov : Public domain */\r
+\r
+#include "CpuArch.h"\r
+\r
+#ifdef MY_CPU_X86_OR_AMD64\r
+\r
+#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)\r
+#define USE_ASM\r
+#endif\r
+\r
+#if defined(USE_ASM) && !defined(MY_CPU_AMD64)\r
+static UInt32 CheckFlag(UInt32 flag)\r
+{\r
+  #ifdef _MSC_VER\r
+  __asm pushfd;\r
+  __asm pop EAX;\r
+  __asm mov EDX, EAX;\r
+  __asm xor EAX, flag;\r
+  __asm push EAX;\r
+  __asm popfd;\r
+  __asm pushfd;\r
+  __asm pop EAX;\r
+  __asm xor EAX, EDX;\r
+  __asm push EDX;\r
+  __asm popfd;\r
+  __asm and flag, EAX;\r
+  #else\r
+  __asm__ __volatile__ (\r
+    "pushf\n\t"\r
+    "pop  %%EAX\n\t"\r
+    "movl %%EAX,%%EDX\n\t"\r
+    "xorl %0,%%EAX\n\t"\r
+    "push %%EAX\n\t"\r
+    "popf\n\t"\r
+    "pushf\n\t"\r
+    "pop  %%EAX\n\t"\r
+    "xorl %%EDX,%%EAX\n\t"\r
+    "push %%EDX\n\t"\r
+    "popf\n\t"\r
+    "andl %%EAX, %0\n\t":\r
+    "=c" (flag) : "c" (flag));\r
+  #endif\r
+  return flag;\r
+}\r
+#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;\r
+#else\r
+#define CHECK_CPUID_IS_SUPPORTED\r
+#endif\r
+\r
+static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)\r
+{\r
+  #ifdef USE_ASM\r
+\r
+  #ifdef _MSC_VER\r
+\r
+  UInt32 a2, b2, c2, d2;\r
+  __asm xor EBX, EBX;\r
+  __asm xor ECX, ECX;\r
+  __asm xor EDX, EDX;\r
+  __asm mov EAX, function;\r
+  __asm cpuid;\r
+  __asm mov a2, EAX;\r
+  __asm mov b2, EBX;\r
+  __asm mov c2, ECX;\r
+  __asm mov d2, EDX;\r
+\r
+  *a = a2;\r
+  *b = b2;\r
+  *c = c2;\r
+  *d = d2;\r
+\r
+  #else\r
+\r
+  __asm__ __volatile__ (\r
+    "cpuid"\r
+    : "=a" (*a) ,\r
+      "=b" (*b) ,\r
+      "=c" (*c) ,\r
+      "=d" (*d)\r
+    : "0" (function)) ;\r
+\r
+  #endif\r
+  \r
+  #else\r
+\r
+  int CPUInfo[4];\r
+  __cpuid(CPUInfo, function);\r
+  *a = CPUInfo[0];\r
+  *b = CPUInfo[1];\r
+  *c = CPUInfo[2];\r
+  *d = CPUInfo[3];\r
+\r
+  #endif\r
+}\r
+\r
+Bool x86cpuid_CheckAndRead(Cx86cpuid *p)\r
+{\r
+  CHECK_CPUID_IS_SUPPORTED\r
+  MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);\r
+  MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);\r
+  return True;\r
+}\r
+\r
+static UInt32 kVendors[][3] =\r
+{\r
+  { 0x756E6547, 0x49656E69, 0x6C65746E},\r
+  { 0x68747541, 0x69746E65, 0x444D4163},\r
+  { 0x746E6543, 0x48727561, 0x736C7561}\r
+};\r
+\r
+int x86cpuid_GetFirm(const Cx86cpuid *p)\r
+{\r
+  unsigned i;\r
+  for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)\r
+  {\r
+    const UInt32 *v = kVendors[i];\r
+    if (v[0] == p->vendor[0] &&\r
+        v[1] == p->vendor[1] &&\r
+        v[2] == p->vendor[2])\r
+      return (int)i;\r
+  }\r
+  return -1;\r
+}\r
+\r
+Bool CPU_Is_InOrder()\r
+{\r
+  Cx86cpuid p;\r
+  int firm;\r
+  UInt32 family, model;\r
+  if (!x86cpuid_CheckAndRead(&p))\r
+    return True;\r
+  family = x86cpuid_GetFamily(&p);\r
+  model = x86cpuid_GetModel(&p);\r
+  firm = x86cpuid_GetFirm(&p);\r
+  switch (firm)\r
+  {\r
+    case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));\r
+    case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));\r
+    case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));\r
+  }\r
+  return True;\r
+}\r
+\r
+#if !defined(MY_CPU_AMD64) && defined(_WIN32)\r
+static Bool CPU_Sys_Is_SSE_Supported()\r
+{\r
+  OSVERSIONINFO vi;\r
+  vi.dwOSVersionInfoSize = sizeof(vi);\r
+  if (!GetVersionEx(&vi))\r
+    return False;\r
+  return (vi.dwMajorVersion >= 5);\r
+}\r
+#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;\r
+#else\r
+#define CHECK_SYS_SSE_SUPPORT\r
+#endif\r
+\r
+Bool CPU_Is_Aes_Supported()\r
+{\r
+  Cx86cpuid p;\r
+  CHECK_SYS_SSE_SUPPORT\r
+  if (!x86cpuid_CheckAndRead(&p))\r
+    return False;\r
+  return (p.c >> 25) & 1;\r
+}\r
+\r
+#endif\r
diff --git a/C/CpuArch.h b/C/CpuArch.h
new file mode 100755 (executable)
index 0000000..0a709bb
--- /dev/null
@@ -0,0 +1,155 @@
+/* CpuArch.h -- CPU specific code\r
+2010-10-26: Igor Pavlov : Public domain */\r
+\r
+#ifndef __CPU_ARCH_H\r
+#define __CPU_ARCH_H\r
+\r
+#include "Types.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+/*\r
+MY_CPU_LE means that CPU is LITTLE ENDIAN.\r
+If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).\r
+\r
+MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.\r
+If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.\r
+*/\r
+\r
+#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)\r
+#define MY_CPU_AMD64\r
+#endif\r
+\r
+#if defined(MY_CPU_AMD64) || defined(_M_IA64)\r
+#define MY_CPU_64BIT\r
+#endif\r
+\r
+#if defined(_M_IX86) || defined(__i386__)\r
+#define MY_CPU_X86\r
+#endif\r
+\r
+#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)\r
+#define MY_CPU_X86_OR_AMD64\r
+#endif\r
+\r
+#if defined(MY_CPU_X86) || defined(_M_ARM)\r
+#define MY_CPU_32BIT\r
+#endif\r
+\r
+#if defined(_WIN32) && defined(_M_ARM)\r
+#define MY_CPU_ARM_LE\r
+#endif\r
+\r
+#if defined(_WIN32) && defined(_M_IA64)\r
+#define MY_CPU_IA64_LE\r
+#endif\r
+\r
+#if defined(MY_CPU_X86_OR_AMD64)\r
+#define MY_CPU_LE_UNALIGN\r
+#endif\r
+\r
+#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE)  || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)\r
+#define MY_CPU_LE\r
+#endif\r
+\r
+#if defined(__BIG_ENDIAN__)\r
+#define MY_CPU_BE\r
+#endif\r
+\r
+#if defined(MY_CPU_LE) && defined(MY_CPU_BE)\r
+Stop_Compiling_Bad_Endian\r
+#endif\r
+\r
+#ifdef MY_CPU_LE_UNALIGN\r
+\r
+#define GetUi16(p) (*(const UInt16 *)(p))\r
+#define GetUi32(p) (*(const UInt32 *)(p))\r
+#define GetUi64(p) (*(const UInt64 *)(p))\r
+#define SetUi16(p, d) *(UInt16 *)(p) = (d);\r
+#define SetUi32(p, d) *(UInt32 *)(p) = (d);\r
+#define SetUi64(p, d) *(UInt64 *)(p) = (d);\r
+\r
+#else\r
+\r
+#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))\r
+\r
+#define GetUi32(p) ( \\r
+             ((const Byte *)(p))[0]        | \\r
+    ((UInt32)((const Byte *)(p))[1] <<  8) | \\r
+    ((UInt32)((const Byte *)(p))[2] << 16) | \\r
+    ((UInt32)((const Byte *)(p))[3] << 24))\r
+\r
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))\r
+\r
+#define SetUi16(p, d) { UInt32 _x_ = (d); \\r
+    ((Byte *)(p))[0] = (Byte)_x_; \\r
+    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); }\r
+\r
+#define SetUi32(p, d) { UInt32 _x_ = (d); \\r
+    ((Byte *)(p))[0] = (Byte)_x_; \\r
+    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \\r
+    ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \\r
+    ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }\r
+\r
+#define SetUi64(p, d) { UInt64 _x64_ = (d); \\r
+    SetUi32(p, (UInt32)_x64_); \\r
+    SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }\r
+\r
+#endif\r
+\r
+#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)\r
+\r
+#pragma intrinsic(_byteswap_ulong)\r
+#pragma intrinsic(_byteswap_uint64)\r
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))\r
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))\r
+\r
+#else\r
+\r
+#define GetBe32(p) ( \\r
+    ((UInt32)((const Byte *)(p))[0] << 24) | \\r
+    ((UInt32)((const Byte *)(p))[1] << 16) | \\r
+    ((UInt32)((const Byte *)(p))[2] <<  8) | \\r
+             ((const Byte *)(p))[3] )\r
+\r
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))\r
+\r
+#endif\r
+\r
+#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])\r
+\r
+\r
+#ifdef MY_CPU_X86_OR_AMD64\r
+\r
+typedef struct\r
+{\r
+  UInt32 maxFunc;\r
+  UInt32 vendor[3];\r
+  UInt32 ver;\r
+  UInt32 b;\r
+  UInt32 c;\r
+  UInt32 d;\r
+} Cx86cpuid;\r
+\r
+enum\r
+{\r
+  CPU_FIRM_INTEL,\r
+  CPU_FIRM_AMD,\r
+  CPU_FIRM_VIA\r
+};\r
+\r
+Bool x86cpuid_CheckAndRead(Cx86cpuid *p);\r
+int x86cpuid_GetFirm(const Cx86cpuid *p);\r
+\r
+#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)\r
+#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)\r
+#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)\r
+\r
+Bool CPU_Is_InOrder();\r
+Bool CPU_Is_Aes_Supported();\r
+\r
+#endif\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/Delta.c b/C/Delta.c
new file mode 100755 (executable)
index 0000000..93c93a1
--- /dev/null
+++ b/C/Delta.c
@@ -0,0 +1,62 @@
+/* Delta.c -- Delta converter\r
+2009-05-26 : Igor Pavlov : Public domain */\r
+\r
+#include "Delta.h"\r
+\r
+void Delta_Init(Byte *state)\r
+{\r
+  unsigned i;\r
+  for (i = 0; i < DELTA_STATE_SIZE; i++)\r
+    state[i] = 0;\r
+}\r
+\r
+static void MyMemCpy(Byte *dest, const Byte *src, unsigned size)\r
+{\r
+  unsigned i;\r
+  for (i = 0; i < size; i++)\r
+    dest[i] = src[i];\r
+}\r
+\r
+void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size)\r
+{\r
+  Byte buf[DELTA_STATE_SIZE];\r
+  unsigned j = 0;\r
+  MyMemCpy(buf, state, delta);\r
+  {\r
+    SizeT i;\r
+    for (i = 0; i < size;)\r
+    {\r
+      for (j = 0; j < delta && i < size; i++, j++)\r
+      {\r
+        Byte b = data[i];\r
+        data[i] = (Byte)(b - buf[j]);\r
+        buf[j] = b;\r
+      }\r
+    }\r
+  }\r
+  if (j == delta)\r
+    j = 0;\r
+  MyMemCpy(state, buf + j, delta - j);\r
+  MyMemCpy(state + delta - j, buf, j);\r
+}\r
+\r
+void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)\r
+{\r
+  Byte buf[DELTA_STATE_SIZE];\r
+  unsigned j = 0;\r
+  MyMemCpy(buf, state, delta);\r
+  {\r
+    SizeT i;\r
+    for (i = 0; i < size;)\r
+    {\r
+      for (j = 0; j < delta && i < size; i++, j++)\r
+      {\r
+        buf[j] = data[i] = (Byte)(buf[j] + data[i]);\r
+      }\r
+    }\r
+  }\r
+  if (j == delta)\r
+    j = 0;\r
+  MyMemCpy(state, buf + j, delta - j);\r
+  MyMemCpy(state + delta - j, buf, j);\r
+}\r
diff --git a/C/Delta.h b/C/Delta.h
new file mode 100755 (executable)
index 0000000..776cd45
--- /dev/null
+++ b/C/Delta.h
@@ -0,0 +1,23 @@
+/* Delta.h -- Delta converter\r
+2009-04-15 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __DELTA_H\r
+#define __DELTA_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define DELTA_STATE_SIZE 256\r
+\r
+void Delta_Init(Byte *state);\r
+void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);\r
+void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/LzFind.c b/C/LzFind.c
new file mode 100755 (executable)
index 0000000..f6c9e66
--- /dev/null
@@ -0,0 +1,761 @@
+/* LzFind.c -- Match finder for LZ algorithms\r
+2009-04-22 : Igor Pavlov : Public domain */\r
+\r
+#include <string.h>\r
+\r
+#include "LzFind.h"\r
+#include "LzHash.h"\r
+\r
+#define kEmptyHashValue 0\r
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)\r
+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */\r
+#define kNormalizeMask (~(kNormalizeStepMin - 1))\r
+#define kMaxHistorySize ((UInt32)3 << 30)\r
+\r
+#define kStartMaxLen 3\r
+\r
+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)\r
+{\r
+  if (!p->directInput)\r
+  {\r
+    alloc->Free(alloc, p->bufferBase);\r
+    p->bufferBase = 0;\r
+  }\r
+}\r
+\r
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */\r
+\r
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)\r
+{\r
+  UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;\r
+  if (p->directInput)\r
+  {\r
+    p->blockSize = blockSize;\r
+    return 1;\r
+  }\r
+  if (p->bufferBase == 0 || p->blockSize != blockSize)\r
+  {\r
+    LzInWindow_Free(p, alloc);\r
+    p->blockSize = blockSize;\r
+    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);\r
+  }\r
+  return (p->bufferBase != 0);\r
+}\r
+\r
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }\r
+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }\r
+\r
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }\r
+\r
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)\r
+{\r
+  p->posLimit -= subValue;\r
+  p->pos -= subValue;\r
+  p->streamPos -= subValue;\r
+}\r
+\r
+static void MatchFinder_ReadBlock(CMatchFinder *p)\r
+{\r
+  if (p->streamEndWasReached || p->result != SZ_OK)\r
+    return;\r
+  if (p->directInput)\r
+  {\r
+    UInt32 curSize = 0xFFFFFFFF - p->streamPos;\r
+    if (curSize > p->directInputRem)\r
+      curSize = (UInt32)p->directInputRem;\r
+    p->directInputRem -= curSize;\r
+    p->streamPos += curSize;\r
+    if (p->directInputRem == 0)\r
+      p->streamEndWasReached = 1;\r
+    return;\r
+  }\r
+  for (;;)\r
+  {\r
+    Byte *dest = p->buffer + (p->streamPos - p->pos);\r
+    size_t size = (p->bufferBase + p->blockSize - dest);\r
+    if (size == 0)\r
+      return;\r
+    p->result = p->stream->Read(p->stream, dest, &size);\r
+    if (p->result != SZ_OK)\r
+      return;\r
+    if (size == 0)\r
+    {\r
+      p->streamEndWasReached = 1;\r
+      return;\r
+    }\r
+    p->streamPos += (UInt32)size;\r
+    if (p->streamPos - p->pos > p->keepSizeAfter)\r
+      return;\r
+  }\r
+}\r
+\r
+void MatchFinder_MoveBlock(CMatchFinder *p)\r
+{\r
+  memmove(p->bufferBase,\r
+    p->buffer - p->keepSizeBefore,\r
+    (size_t)(p->streamPos - p->pos + p->keepSizeBefore));\r
+  p->buffer = p->bufferBase + p->keepSizeBefore;\r
+}\r
+\r
+int MatchFinder_NeedMove(CMatchFinder *p)\r
+{\r
+  if (p->directInput)\r
+    return 0;\r
+  /* if (p->streamEndWasReached) return 0; */\r
+  return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);\r
+}\r
+\r
+void MatchFinder_ReadIfRequired(CMatchFinder *p)\r
+{\r
+  if (p->streamEndWasReached)\r
+    return;\r
+  if (p->keepSizeAfter >= p->streamPos - p->pos)\r
+    MatchFinder_ReadBlock(p);\r
+}\r
+\r
+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)\r
+{\r
+  if (MatchFinder_NeedMove(p))\r
+    MatchFinder_MoveBlock(p);\r
+  MatchFinder_ReadBlock(p);\r
+}\r
+\r
+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)\r
+{\r
+  p->cutValue = 32;\r
+  p->btMode = 1;\r
+  p->numHashBytes = 4;\r
+  p->bigHash = 0;\r
+}\r
+\r
+#define kCrcPoly 0xEDB88320\r
+\r
+void MatchFinder_Construct(CMatchFinder *p)\r
+{\r
+  UInt32 i;\r
+  p->bufferBase = 0;\r
+  p->directInput = 0;\r
+  p->hash = 0;\r
+  MatchFinder_SetDefaultSettings(p);\r
+\r
+  for (i = 0; i < 256; i++)\r
+  {\r
+    UInt32 r = i;\r
+    int j;\r
+    for (j = 0; j < 8; j++)\r
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));\r
+    p->crc[i] = r;\r
+  }\r
+}\r
+\r
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->hash);\r
+  p->hash = 0;\r
+}\r
+\r
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)\r
+{\r
+  MatchFinder_FreeThisClassMemory(p, alloc);\r
+  LzInWindow_Free(p, alloc);\r
+}\r
+\r
+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)\r
+{\r
+  size_t sizeInBytes = (size_t)num * sizeof(CLzRef);\r
+  if (sizeInBytes / sizeof(CLzRef) != num)\r
+    return 0;\r
+  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);\r
+}\r
+\r
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,\r
+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,\r
+    ISzAlloc *alloc)\r
+{\r
+  UInt32 sizeReserv;\r
+  if (historySize > kMaxHistorySize)\r
+  {\r
+    MatchFinder_Free(p, alloc);\r
+    return 0;\r
+  }\r
+  sizeReserv = historySize >> 1;\r
+  if (historySize > ((UInt32)2 << 30))\r
+    sizeReserv = historySize >> 2;\r
+  sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);\r
+\r
+  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;\r
+  p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;\r
+  /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */\r
+  if (LzInWindow_Create(p, sizeReserv, alloc))\r
+  {\r
+    UInt32 newCyclicBufferSize = historySize + 1;\r
+    UInt32 hs;\r
+    p->matchMaxLen = matchMaxLen;\r
+    {\r
+      p->fixedHashSize = 0;\r
+      if (p->numHashBytes == 2)\r
+        hs = (1 << 16) - 1;\r
+      else\r
+      {\r
+        hs = historySize - 1;\r
+        hs |= (hs >> 1);\r
+        hs |= (hs >> 2);\r
+        hs |= (hs >> 4);\r
+        hs |= (hs >> 8);\r
+        hs >>= 1;\r
+        hs |= 0xFFFF; /* don't change it! It's required for Deflate */\r
+        if (hs > (1 << 24))\r
+        {\r
+          if (p->numHashBytes == 3)\r
+            hs = (1 << 24) - 1;\r
+          else\r
+            hs >>= 1;\r
+        }\r
+      }\r
+      p->hashMask = hs;\r
+      hs++;\r
+      if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;\r
+      if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;\r
+      if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;\r
+      hs += p->fixedHashSize;\r
+    }\r
+\r
+    {\r
+      UInt32 prevSize = p->hashSizeSum + p->numSons;\r
+      UInt32 newSize;\r
+      p->historySize = historySize;\r
+      p->hashSizeSum = hs;\r
+      p->cyclicBufferSize = newCyclicBufferSize;\r
+      p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);\r
+      newSize = p->hashSizeSum + p->numSons;\r
+      if (p->hash != 0 && prevSize == newSize)\r
+        return 1;\r
+      MatchFinder_FreeThisClassMemory(p, alloc);\r
+      p->hash = AllocRefs(newSize, alloc);\r
+      if (p->hash != 0)\r
+      {\r
+        p->son = p->hash + p->hashSizeSum;\r
+        return 1;\r
+      }\r
+    }\r
+  }\r
+  MatchFinder_Free(p, alloc);\r
+  return 0;\r
+}\r
+\r
+static void MatchFinder_SetLimits(CMatchFinder *p)\r
+{\r
+  UInt32 limit = kMaxValForNormalize - p->pos;\r
+  UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;\r
+  if (limit2 < limit)\r
+    limit = limit2;\r
+  limit2 = p->streamPos - p->pos;\r
+  if (limit2 <= p->keepSizeAfter)\r
+  {\r
+    if (limit2 > 0)\r
+      limit2 = 1;\r
+  }\r
+  else\r
+    limit2 -= p->keepSizeAfter;\r
+  if (limit2 < limit)\r
+    limit = limit2;\r
+  {\r
+    UInt32 lenLimit = p->streamPos - p->pos;\r
+    if (lenLimit > p->matchMaxLen)\r
+      lenLimit = p->matchMaxLen;\r
+    p->lenLimit = lenLimit;\r
+  }\r
+  p->posLimit = p->pos + limit;\r
+}\r
+\r
+void MatchFinder_Init(CMatchFinder *p)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < p->hashSizeSum; i++)\r
+    p->hash[i] = kEmptyHashValue;\r
+  p->cyclicBufferPos = 0;\r
+  p->buffer = p->bufferBase;\r
+  p->pos = p->streamPos = p->cyclicBufferSize;\r
+  p->result = SZ_OK;\r
+  p->streamEndWasReached = 0;\r
+  MatchFinder_ReadBlock(p);\r
+  MatchFinder_SetLimits(p);\r
+}\r
+\r
+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)\r
+{\r
+  return (p->pos - p->historySize - 1) & kNormalizeMask;\r
+}\r
+\r
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < numItems; i++)\r
+  {\r
+    UInt32 value = items[i];\r
+    if (value <= subValue)\r
+      value = kEmptyHashValue;\r
+    else\r
+      value -= subValue;\r
+    items[i] = value;\r
+  }\r
+}\r
+\r
+static void MatchFinder_Normalize(CMatchFinder *p)\r
+{\r
+  UInt32 subValue = MatchFinder_GetSubValue(p);\r
+  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);\r
+  MatchFinder_ReduceOffsets(p, subValue);\r
+}\r
+\r
+static void MatchFinder_CheckLimits(CMatchFinder *p)\r
+{\r
+  if (p->pos == kMaxValForNormalize)\r
+    MatchFinder_Normalize(p);\r
+  if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)\r
+    MatchFinder_CheckAndMoveAndRead(p);\r
+  if (p->cyclicBufferPos == p->cyclicBufferSize)\r
+    p->cyclicBufferPos = 0;\r
+  MatchFinder_SetLimits(p);\r
+}\r
+\r
+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,\r
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,\r
+    UInt32 *distances, UInt32 maxLen)\r
+{\r
+  son[_cyclicBufferPos] = curMatch;\r
+  for (;;)\r
+  {\r
+    UInt32 delta = pos - curMatch;\r
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)\r
+      return distances;\r
+    {\r
+      const Byte *pb = cur - delta;\r
+      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];\r
+      if (pb[maxLen] == cur[maxLen] && *pb == *cur)\r
+      {\r
+        UInt32 len = 0;\r
+        while (++len != lenLimit)\r
+          if (pb[len] != cur[len])\r
+            break;\r
+        if (maxLen < len)\r
+        {\r
+          *distances++ = maxLen = len;\r
+          *distances++ = delta - 1;\r
+          if (len == lenLimit)\r
+            return distances;\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,\r
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,\r
+    UInt32 *distances, UInt32 maxLen)\r
+{\r
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;\r
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);\r
+  UInt32 len0 = 0, len1 = 0;\r
+  for (;;)\r
+  {\r
+    UInt32 delta = pos - curMatch;\r
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)\r
+    {\r
+      *ptr0 = *ptr1 = kEmptyHashValue;\r
+      return distances;\r
+    }\r
+    {\r
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);\r
+      const Byte *pb = cur - delta;\r
+      UInt32 len = (len0 < len1 ? len0 : len1);\r
+      if (pb[len] == cur[len])\r
+      {\r
+        if (++len != lenLimit && pb[len] == cur[len])\r
+          while (++len != lenLimit)\r
+            if (pb[len] != cur[len])\r
+              break;\r
+        if (maxLen < len)\r
+        {\r
+          *distances++ = maxLen = len;\r
+          *distances++ = delta - 1;\r
+          if (len == lenLimit)\r
+          {\r
+            *ptr1 = pair[0];\r
+            *ptr0 = pair[1];\r
+            return distances;\r
+          }\r
+        }\r
+      }\r
+      if (pb[len] < cur[len])\r
+      {\r
+        *ptr1 = curMatch;\r
+        ptr1 = pair + 1;\r
+        curMatch = *ptr1;\r
+        len1 = len;\r
+      }\r
+      else\r
+      {\r
+        *ptr0 = curMatch;\r
+        ptr0 = pair;\r
+        curMatch = *ptr0;\r
+        len0 = len;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,\r
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)\r
+{\r
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;\r
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);\r
+  UInt32 len0 = 0, len1 = 0;\r
+  for (;;)\r
+  {\r
+    UInt32 delta = pos - curMatch;\r
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)\r
+    {\r
+      *ptr0 = *ptr1 = kEmptyHashValue;\r
+      return;\r
+    }\r
+    {\r
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);\r
+      const Byte *pb = cur - delta;\r
+      UInt32 len = (len0 < len1 ? len0 : len1);\r
+      if (pb[len] == cur[len])\r
+      {\r
+        while (++len != lenLimit)\r
+          if (pb[len] != cur[len])\r
+            break;\r
+        {\r
+          if (len == lenLimit)\r
+          {\r
+            *ptr1 = pair[0];\r
+            *ptr0 = pair[1];\r
+            return;\r
+          }\r
+        }\r
+      }\r
+      if (pb[len] < cur[len])\r
+      {\r
+        *ptr1 = curMatch;\r
+        ptr1 = pair + 1;\r
+        curMatch = *ptr1;\r
+        len1 = len;\r
+      }\r
+      else\r
+      {\r
+        *ptr0 = curMatch;\r
+        ptr0 = pair;\r
+        curMatch = *ptr0;\r
+        len0 = len;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+#define MOVE_POS \\r
+  ++p->cyclicBufferPos; \\r
+  p->buffer++; \\r
+  if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);\r
+\r
+#define MOVE_POS_RET MOVE_POS return offset;\r
+\r
+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }\r
+\r
+#define GET_MATCHES_HEADER2(minLen, ret_op) \\r
+  UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \\r
+  lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \\r
+  cur = p->buffer;\r
+\r
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)\r
+#define SKIP_HEADER(minLen)        GET_MATCHES_HEADER2(minLen, continue)\r
+\r
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue\r
+\r
+#define GET_MATCHES_FOOTER(offset, maxLen) \\r
+  offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \\r
+  distances + offset, maxLen) - distances); MOVE_POS_RET;\r
+\r
+#define SKIP_FOOTER \\r
+  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;\r
+\r
+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+  UInt32 offset;\r
+  GET_MATCHES_HEADER(2)\r
+  HASH2_CALC;\r
+  curMatch = p->hash[hashValue];\r
+  p->hash[hashValue] = p->pos;\r
+  offset = 0;\r
+  GET_MATCHES_FOOTER(offset, 1)\r
+}\r
+\r
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+  UInt32 offset;\r
+  GET_MATCHES_HEADER(3)\r
+  HASH_ZIP_CALC;\r
+  curMatch = p->hash[hashValue];\r
+  p->hash[hashValue] = p->pos;\r
+  offset = 0;\r
+  GET_MATCHES_FOOTER(offset, 2)\r
+}\r
+\r
+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+  UInt32 hash2Value, delta2, maxLen, offset;\r
+  GET_MATCHES_HEADER(3)\r
+\r
+  HASH3_CALC;\r
+\r
+  delta2 = p->pos - p->hash[hash2Value];\r
+  curMatch = p->hash[kFix3HashSize + hashValue];\r
+  \r
+  p->hash[hash2Value] =\r
+  p->hash[kFix3HashSize + hashValue] = p->pos;\r
+\r
+\r
+  maxLen = 2;\r
+  offset = 0;\r
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)\r
+  {\r
+    for (; maxLen != lenLimit; maxLen++)\r
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])\r
+        break;\r
+    distances[0] = maxLen;\r
+    distances[1] = delta2 - 1;\r
+    offset = 2;\r
+    if (maxLen == lenLimit)\r
+    {\r
+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));\r
+      MOVE_POS_RET;\r
+    }\r
+  }\r
+  GET_MATCHES_FOOTER(offset, maxLen)\r
+}\r
+\r
+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;\r
+  GET_MATCHES_HEADER(4)\r
+\r
+  HASH4_CALC;\r
+\r
+  delta2 = p->pos - p->hash[                hash2Value];\r
+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];\r
+  curMatch = p->hash[kFix4HashSize + hashValue];\r
+  \r
+  p->hash[                hash2Value] =\r
+  p->hash[kFix3HashSize + hash3Value] =\r
+  p->hash[kFix4HashSize + hashValue] = p->pos;\r
+\r
+  maxLen = 1;\r
+  offset = 0;\r
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)\r
+  {\r
+    distances[0] = maxLen = 2;\r
+    distances[1] = delta2 - 1;\r
+    offset = 2;\r
+  }\r
+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)\r
+  {\r
+    maxLen = 3;\r
+    distances[offset + 1] = delta3 - 1;\r
+    offset += 2;\r
+    delta2 = delta3;\r
+  }\r
+  if (offset != 0)\r
+  {\r
+    for (; maxLen != lenLimit; maxLen++)\r
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])\r
+        break;\r
+    distances[offset - 2] = maxLen;\r
+    if (maxLen == lenLimit)\r
+    {\r
+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));\r
+      MOVE_POS_RET;\r
+    }\r
+  }\r
+  if (maxLen < 3)\r
+    maxLen = 3;\r
+  GET_MATCHES_FOOTER(offset, maxLen)\r
+}\r
+\r
+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;\r
+  GET_MATCHES_HEADER(4)\r
+\r
+  HASH4_CALC;\r
+\r
+  delta2 = p->pos - p->hash[                hash2Value];\r
+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];\r
+  curMatch = p->hash[kFix4HashSize + hashValue];\r
+\r
+  p->hash[                hash2Value] =\r
+  p->hash[kFix3HashSize + hash3Value] =\r
+  p->hash[kFix4HashSize + hashValue] = p->pos;\r
+\r
+  maxLen = 1;\r
+  offset = 0;\r
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)\r
+  {\r
+    distances[0] = maxLen = 2;\r
+    distances[1] = delta2 - 1;\r
+    offset = 2;\r
+  }\r
+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)\r
+  {\r
+    maxLen = 3;\r
+    distances[offset + 1] = delta3 - 1;\r
+    offset += 2;\r
+    delta2 = delta3;\r
+  }\r
+  if (offset != 0)\r
+  {\r
+    for (; maxLen != lenLimit; maxLen++)\r
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])\r
+        break;\r
+    distances[offset - 2] = maxLen;\r
+    if (maxLen == lenLimit)\r
+    {\r
+      p->son[p->cyclicBufferPos] = curMatch;\r
+      MOVE_POS_RET;\r
+    }\r
+  }\r
+  if (maxLen < 3)\r
+    maxLen = 3;\r
+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),\r
+    distances + offset, maxLen) - (distances));\r
+  MOVE_POS_RET\r
+}\r
+\r
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+  UInt32 offset;\r
+  GET_MATCHES_HEADER(3)\r
+  HASH_ZIP_CALC;\r
+  curMatch = p->hash[hashValue];\r
+  p->hash[hashValue] = p->pos;\r
+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),\r
+    distances, 2) - (distances));\r
+  MOVE_POS_RET\r
+}\r
+\r
+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+  do\r
+  {\r
+    SKIP_HEADER(2)\r
+    HASH2_CALC;\r
+    curMatch = p->hash[hashValue];\r
+    p->hash[hashValue] = p->pos;\r
+    SKIP_FOOTER\r
+  }\r
+  while (--num != 0);\r
+}\r
+\r
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+  do\r
+  {\r
+    SKIP_HEADER(3)\r
+    HASH_ZIP_CALC;\r
+    curMatch = p->hash[hashValue];\r
+    p->hash[hashValue] = p->pos;\r
+    SKIP_FOOTER\r
+  }\r
+  while (--num != 0);\r
+}\r
+\r
+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+  do\r
+  {\r
+    UInt32 hash2Value;\r
+    SKIP_HEADER(3)\r
+    HASH3_CALC;\r
+    curMatch = p->hash[kFix3HashSize + hashValue];\r
+    p->hash[hash2Value] =\r
+    p->hash[kFix3HashSize + hashValue] = p->pos;\r
+    SKIP_FOOTER\r
+  }\r
+  while (--num != 0);\r
+}\r
+\r
+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+  do\r
+  {\r
+    UInt32 hash2Value, hash3Value;\r
+    SKIP_HEADER(4)\r
+    HASH4_CALC;\r
+    curMatch = p->hash[kFix4HashSize + hashValue];\r
+    p->hash[                hash2Value] =\r
+    p->hash[kFix3HashSize + hash3Value] = p->pos;\r
+    p->hash[kFix4HashSize + hashValue] = p->pos;\r
+    SKIP_FOOTER\r
+  }\r
+  while (--num != 0);\r
+}\r
+\r
+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+  do\r
+  {\r
+    UInt32 hash2Value, hash3Value;\r
+    SKIP_HEADER(4)\r
+    HASH4_CALC;\r
+    curMatch = p->hash[kFix4HashSize + hashValue];\r
+    p->hash[                hash2Value] =\r
+    p->hash[kFix3HashSize + hash3Value] =\r
+    p->hash[kFix4HashSize + hashValue] = p->pos;\r
+    p->son[p->cyclicBufferPos] = curMatch;\r
+    MOVE_POS\r
+  }\r
+  while (--num != 0);\r
+}\r
+\r
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+  do\r
+  {\r
+    SKIP_HEADER(3)\r
+    HASH_ZIP_CALC;\r
+    curMatch = p->hash[hashValue];\r
+    p->hash[hashValue] = p->pos;\r
+    p->son[p->cyclicBufferPos] = curMatch;\r
+    MOVE_POS\r
+  }\r
+  while (--num != 0);\r
+}\r
+\r
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)\r
+{\r
+  vTable->Init = (Mf_Init_Func)MatchFinder_Init;\r
+  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;\r
+  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;\r
+  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;\r
+  if (!p->btMode)\r
+  {\r
+    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;\r
+    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;\r
+  }\r
+  else if (p->numHashBytes == 2)\r
+  {\r
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;\r
+    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;\r
+  }\r
+  else if (p->numHashBytes == 3)\r
+  {\r
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;\r
+    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;\r
+  }\r
+  else\r
+  {\r
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;\r
+    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;\r
+  }\r
+}\r
diff --git a/C/LzFind.h b/C/LzFind.h
new file mode 100755 (executable)
index 0000000..7ebdfa4
--- /dev/null
@@ -0,0 +1,115 @@
+/* LzFind.h -- Match finder for LZ algorithms\r
+2009-04-22 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZ_FIND_H\r
+#define __LZ_FIND_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef UInt32 CLzRef;\r
+\r
+typedef struct _CMatchFinder\r
+{\r
+  Byte *buffer;\r
+  UInt32 pos;\r
+  UInt32 posLimit;\r
+  UInt32 streamPos;\r
+  UInt32 lenLimit;\r
+\r
+  UInt32 cyclicBufferPos;\r
+  UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */\r
+\r
+  UInt32 matchMaxLen;\r
+  CLzRef *hash;\r
+  CLzRef *son;\r
+  UInt32 hashMask;\r
+  UInt32 cutValue;\r
+\r
+  Byte *bufferBase;\r
+  ISeqInStream *stream;\r
+  int streamEndWasReached;\r
+\r
+  UInt32 blockSize;\r
+  UInt32 keepSizeBefore;\r
+  UInt32 keepSizeAfter;\r
+\r
+  UInt32 numHashBytes;\r
+  int directInput;\r
+  size_t directInputRem;\r
+  int btMode;\r
+  int bigHash;\r
+  UInt32 historySize;\r
+  UInt32 fixedHashSize;\r
+  UInt32 hashSizeSum;\r
+  UInt32 numSons;\r
+  SRes result;\r
+  UInt32 crc[256];\r
+} CMatchFinder;\r
+\r
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)\r
+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])\r
+\r
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)\r
+\r
+int MatchFinder_NeedMove(CMatchFinder *p);\r
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);\r
+void MatchFinder_MoveBlock(CMatchFinder *p);\r
+void MatchFinder_ReadIfRequired(CMatchFinder *p);\r
+\r
+void MatchFinder_Construct(CMatchFinder *p);\r
+\r
+/* Conditions:\r
+     historySize <= 3 GB\r
+     keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB\r
+*/\r
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,\r
+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,\r
+    ISzAlloc *alloc);\r
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);\r
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);\r
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);\r
+\r
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,\r
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,\r
+    UInt32 *distances, UInt32 maxLen);\r
+\r
+/*\r
+Conditions:\r
+  Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.\r
+  Mf_GetPointerToCurrentPos_Func's result must be used only before any other function\r
+*/\r
+\r
+typedef void (*Mf_Init_Func)(void *object);\r
+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);\r
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);\r
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);\r
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);\r
+typedef void (*Mf_Skip_Func)(void *object, UInt32);\r
+\r
+typedef struct _IMatchFinder\r
+{\r
+  Mf_Init_Func Init;\r
+  Mf_GetIndexByte_Func GetIndexByte;\r
+  Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;\r
+  Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;\r
+  Mf_GetMatches_Func GetMatches;\r
+  Mf_Skip_Func Skip;\r
+} IMatchFinder;\r
+\r
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);\r
+\r
+void MatchFinder_Init(CMatchFinder *p);\r
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);\r
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);\r
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);\r
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/LzFindMt.c b/C/LzFindMt.c
new file mode 100755 (executable)
index 0000000..db95590
--- /dev/null
@@ -0,0 +1,793 @@
+/* LzFindMt.c -- multithreaded Match finder for LZ algorithms\r
+2009-09-20 : Igor Pavlov : Public domain */\r
+\r
+#include "LzHash.h"\r
+\r
+#include "LzFindMt.h"\r
+\r
+void MtSync_Construct(CMtSync *p)\r
+{\r
+  p->wasCreated = False;\r
+  p->csWasInitialized = False;\r
+  p->csWasEntered = False;\r
+  Thread_Construct(&p->thread);\r
+  Event_Construct(&p->canStart);\r
+  Event_Construct(&p->wasStarted);\r
+  Event_Construct(&p->wasStopped);\r
+  Semaphore_Construct(&p->freeSemaphore);\r
+  Semaphore_Construct(&p->filledSemaphore);\r
+}\r
+\r
+void MtSync_GetNextBlock(CMtSync *p)\r
+{\r
+  if (p->needStart)\r
+  {\r
+    p->numProcessedBlocks = 1;\r
+    p->needStart = False;\r
+    p->stopWriting = False;\r
+    p->exit = False;\r
+    Event_Reset(&p->wasStarted);\r
+    Event_Reset(&p->wasStopped);\r
+\r
+    Event_Set(&p->canStart);\r
+    Event_Wait(&p->wasStarted);\r
+  }\r
+  else\r
+  {\r
+    CriticalSection_Leave(&p->cs);\r
+    p->csWasEntered = False;\r
+    p->numProcessedBlocks++;\r
+    Semaphore_Release1(&p->freeSemaphore);\r
+  }\r
+  Semaphore_Wait(&p->filledSemaphore);\r
+  CriticalSection_Enter(&p->cs);\r
+  p->csWasEntered = True;\r
+}\r
+\r
+/* MtSync_StopWriting must be called if Writing was started */\r
+\r
+void MtSync_StopWriting(CMtSync *p)\r
+{\r
+  UInt32 myNumBlocks = p->numProcessedBlocks;\r
+  if (!Thread_WasCreated(&p->thread) || p->needStart)\r
+    return;\r
+  p->stopWriting = True;\r
+  if (p->csWasEntered)\r
+  {\r
+    CriticalSection_Leave(&p->cs);\r
+    p->csWasEntered = False;\r
+  }\r
+  Semaphore_Release1(&p->freeSemaphore);\r
\r
+  Event_Wait(&p->wasStopped);\r
+\r
+  while (myNumBlocks++ != p->numProcessedBlocks)\r
+  {\r
+    Semaphore_Wait(&p->filledSemaphore);\r
+    Semaphore_Release1(&p->freeSemaphore);\r
+  }\r
+  p->needStart = True;\r
+}\r
+\r
+void MtSync_Destruct(CMtSync *p)\r
+{\r
+  if (Thread_WasCreated(&p->thread))\r
+  {\r
+    MtSync_StopWriting(p);\r
+    p->exit = True;\r
+    if (p->needStart)\r
+      Event_Set(&p->canStart);\r
+    Thread_Wait(&p->thread);\r
+    Thread_Close(&p->thread);\r
+  }\r
+  if (p->csWasInitialized)\r
+  {\r
+    CriticalSection_Delete(&p->cs);\r
+    p->csWasInitialized = False;\r
+  }\r
+\r
+  Event_Close(&p->canStart);\r
+  Event_Close(&p->wasStarted);\r
+  Event_Close(&p->wasStopped);\r
+  Semaphore_Close(&p->freeSemaphore);\r
+  Semaphore_Close(&p->filledSemaphore);\r
+\r
+  p->wasCreated = False;\r
+}\r
+\r
+#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }\r
+\r
+static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)\r
+{\r
+  if (p->wasCreated)\r
+    return SZ_OK;\r
+\r
+  RINOK_THREAD(CriticalSection_Init(&p->cs));\r
+  p->csWasInitialized = True;\r
+\r
+  RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));\r
+  RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));\r
+  RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));\r
+  \r
+  RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));\r
+  RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));\r
+\r
+  p->needStart = True;\r
+  \r
+  RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));\r
+  p->wasCreated = True;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)\r
+{\r
+  SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);\r
+  if (res != SZ_OK)\r
+    MtSync_Destruct(p);\r
+  return res;\r
+}\r
+\r
+void MtSync_Init(CMtSync *p) { p->needStart = True; }\r
+\r
+#define kMtMaxValForNormalize 0xFFFFFFFF\r
+\r
+#define DEF_GetHeads2(name, v, action) \\r
+static void GetHeads ## name(const Byte *p, UInt32 pos, \\r
+UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \\r
+{ action; for (; numHeads != 0; numHeads--) { \\r
+const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++;  } }\r
+\r
+#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)\r
+\r
+DEF_GetHeads2(2,  (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )\r
+DEF_GetHeads(3,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)\r
+DEF_GetHeads(4,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)\r
+DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)\r
+/* DEF_GetHeads(5,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */\r
+\r
+void HashThreadFunc(CMatchFinderMt *mt)\r
+{\r
+  CMtSync *p = &mt->hashSync;\r
+  for (;;)\r
+  {\r
+    UInt32 numProcessedBlocks = 0;\r
+    Event_Wait(&p->canStart);\r
+    Event_Set(&p->wasStarted);\r
+    for (;;)\r
+    {\r
+      if (p->exit)\r
+        return;\r
+      if (p->stopWriting)\r
+      {\r
+        p->numProcessedBlocks = numProcessedBlocks;\r
+        Event_Set(&p->wasStopped);\r
+        break;\r
+      }\r
+\r
+      {\r
+        CMatchFinder *mf = mt->MatchFinder;\r
+        if (MatchFinder_NeedMove(mf))\r
+        {\r
+          CriticalSection_Enter(&mt->btSync.cs);\r
+          CriticalSection_Enter(&mt->hashSync.cs);\r
+          {\r
+            const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);\r
+            const Byte *afterPtr;\r
+            MatchFinder_MoveBlock(mf);\r
+            afterPtr = MatchFinder_GetPointerToCurrentPos(mf);\r
+            mt->pointerToCurPos -= beforePtr - afterPtr;\r
+            mt->buffer -= beforePtr - afterPtr;\r
+          }\r
+          CriticalSection_Leave(&mt->btSync.cs);\r
+          CriticalSection_Leave(&mt->hashSync.cs);\r
+          continue;\r
+        }\r
+\r
+        Semaphore_Wait(&p->freeSemaphore);\r
+\r
+        MatchFinder_ReadIfRequired(mf);\r
+        if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))\r
+        {\r
+          UInt32 subValue = (mf->pos - mf->historySize - 1);\r
+          MatchFinder_ReduceOffsets(mf, subValue);\r
+          MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);\r
+        }\r
+        {\r
+          UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;\r
+          UInt32 num = mf->streamPos - mf->pos;\r
+          heads[0] = 2;\r
+          heads[1] = num;\r
+          if (num >= mf->numHashBytes)\r
+          {\r
+            num = num - mf->numHashBytes + 1;\r
+            if (num > kMtHashBlockSize - 2)\r
+              num = kMtHashBlockSize - 2;\r
+            mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);\r
+            heads[0] += num;\r
+          }\r
+          mf->pos += num;\r
+          mf->buffer += num;\r
+        }\r
+      }\r
+\r
+      Semaphore_Release1(&p->filledSemaphore);\r
+    }\r
+  }\r
+}\r
+\r
+void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)\r
+{\r
+  MtSync_GetNextBlock(&p->hashSync);\r
+  p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;\r
+  p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];\r
+  p->hashNumAvail = p->hashBuf[p->hashBufPos++];\r
+}\r
+\r
+#define kEmptyHashValue 0\r
+\r
+/* #define MFMT_GM_INLINE */\r
+\r
+#ifdef MFMT_GM_INLINE\r
+\r
+#define NO_INLINE MY_FAST_CALL\r
+\r
+Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,\r
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,\r
+    UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)\r
+{\r
+  do\r
+  {\r
+  UInt32 *distances = _distances + 1;\r
+  UInt32 curMatch = pos - *hash++;\r
+\r
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;\r
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);\r
+  UInt32 len0 = 0, len1 = 0;\r
+  UInt32 cutValue = _cutValue;\r
+  UInt32 maxLen = _maxLen;\r
+  for (;;)\r
+  {\r
+    UInt32 delta = pos - curMatch;\r
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)\r
+    {\r
+      *ptr0 = *ptr1 = kEmptyHashValue;\r
+      break;\r
+    }\r
+    {\r
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);\r
+      const Byte *pb = cur - delta;\r
+      UInt32 len = (len0 < len1 ? len0 : len1);\r
+      if (pb[len] == cur[len])\r
+      {\r
+        if (++len != lenLimit && pb[len] == cur[len])\r
+          while (++len != lenLimit)\r
+            if (pb[len] != cur[len])\r
+              break;\r
+        if (maxLen < len)\r
+        {\r
+          *distances++ = maxLen = len;\r
+          *distances++ = delta - 1;\r
+          if (len == lenLimit)\r
+          {\r
+            *ptr1 = pair[0];\r
+            *ptr0 = pair[1];\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      if (pb[len] < cur[len])\r
+      {\r
+        *ptr1 = curMatch;\r
+        ptr1 = pair + 1;\r
+        curMatch = *ptr1;\r
+        len1 = len;\r
+      }\r
+      else\r
+      {\r
+        *ptr0 = curMatch;\r
+        ptr0 = pair;\r
+        curMatch = *ptr0;\r
+        len0 = len;\r
+      }\r
+    }\r
+  }\r
+  pos++;\r
+  _cyclicBufferPos++;\r
+  cur++;\r
+  {\r
+    UInt32 num = (UInt32)(distances - _distances);\r
+    *_distances = num - 1;\r
+    _distances += num;\r
+    limit -= num;\r
+  }\r
+  }\r
+  while (limit > 0 && --size != 0);\r
+  *posRes = pos;\r
+  return limit;\r
+}\r
+\r
+#endif\r
+\r
+void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)\r
+{\r
+  UInt32 numProcessed = 0;\r
+  UInt32 curPos = 2;\r
+  UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);\r
+  distances[1] = p->hashNumAvail;\r
+  while (curPos < limit)\r
+  {\r
+    if (p->hashBufPos == p->hashBufPosLimit)\r
+    {\r
+      MatchFinderMt_GetNextBlock_Hash(p);\r
+      distances[1] = numProcessed + p->hashNumAvail;\r
+      if (p->hashNumAvail >= p->numHashBytes)\r
+        continue;\r
+      for (; p->hashNumAvail != 0; p->hashNumAvail--)\r
+        distances[curPos++] = 0;\r
+      break;\r
+    }\r
+    {\r
+      UInt32 size = p->hashBufPosLimit - p->hashBufPos;\r
+      UInt32 lenLimit = p->matchMaxLen;\r
+      UInt32 pos = p->pos;\r
+      UInt32 cyclicBufferPos = p->cyclicBufferPos;\r
+      if (lenLimit >= p->hashNumAvail)\r
+        lenLimit = p->hashNumAvail;\r
+      {\r
+        UInt32 size2 = p->hashNumAvail - lenLimit + 1;\r
+        if (size2 < size)\r
+          size = size2;\r
+        size2 = p->cyclicBufferSize - cyclicBufferPos;\r
+        if (size2 < size)\r
+          size = size2;\r
+      }\r
+      #ifndef MFMT_GM_INLINE\r
+      while (curPos < limit && size-- != 0)\r
+      {\r
+        UInt32 *startDistances = distances + curPos;\r
+        UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],\r
+          pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,\r
+          startDistances + 1, p->numHashBytes - 1) - startDistances);\r
+        *startDistances = num - 1;\r
+        curPos += num;\r
+        cyclicBufferPos++;\r
+        pos++;\r
+        p->buffer++;\r
+      }\r
+      #else\r
+      {\r
+        UInt32 posRes;\r
+        curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,\r
+          distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);\r
+        p->hashBufPos += posRes - pos;\r
+        cyclicBufferPos += posRes - pos;\r
+        p->buffer += posRes - pos;\r
+        pos = posRes;\r
+      }\r
+      #endif\r
+\r
+      numProcessed += pos - p->pos;\r
+      p->hashNumAvail -= pos - p->pos;\r
+      p->pos = pos;\r
+      if (cyclicBufferPos == p->cyclicBufferSize)\r
+        cyclicBufferPos = 0;\r
+      p->cyclicBufferPos = cyclicBufferPos;\r
+    }\r
+  }\r
+  distances[0] = curPos;\r
+}\r
+\r
+void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)\r
+{\r
+  CMtSync *sync = &p->hashSync;\r
+  if (!sync->needStart)\r
+  {\r
+    CriticalSection_Enter(&sync->cs);\r
+    sync->csWasEntered = True;\r
+  }\r
+  \r
+  BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);\r
+\r
+  if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)\r
+  {\r
+    UInt32 subValue = p->pos - p->cyclicBufferSize;\r
+    MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);\r
+    p->pos -= subValue;\r
+  }\r
+\r
+  if (!sync->needStart)\r
+  {\r
+    CriticalSection_Leave(&sync->cs);\r
+    sync->csWasEntered = False;\r
+  }\r
+}\r
+\r
+void BtThreadFunc(CMatchFinderMt *mt)\r
+{\r
+  CMtSync *p = &mt->btSync;\r
+  for (;;)\r
+  {\r
+    UInt32 blockIndex = 0;\r
+    Event_Wait(&p->canStart);\r
+    Event_Set(&p->wasStarted);\r
+    for (;;)\r
+    {\r
+      if (p->exit)\r
+        return;\r
+      if (p->stopWriting)\r
+      {\r
+        p->numProcessedBlocks = blockIndex;\r
+        MtSync_StopWriting(&mt->hashSync);\r
+        Event_Set(&p->wasStopped);\r
+        break;\r
+      }\r
+      Semaphore_Wait(&p->freeSemaphore);\r
+      BtFillBlock(mt, blockIndex++);\r
+      Semaphore_Release1(&p->filledSemaphore);\r
+    }\r
+  }\r
+}\r
+\r
+void MatchFinderMt_Construct(CMatchFinderMt *p)\r
+{\r
+  p->hashBuf = 0;\r
+  MtSync_Construct(&p->hashSync);\r
+  MtSync_Construct(&p->btSync);\r
+}\r
+\r
+void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->hashBuf);\r
+  p->hashBuf = 0;\r
+}\r
+\r
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)\r
+{\r
+  MtSync_Destruct(&p->hashSync);\r
+  MtSync_Destruct(&p->btSync);\r
+  MatchFinderMt_FreeMem(p, alloc);\r
+}\r
+\r
+#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)\r
+#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)\r
+\r
+static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p);  return 0; }\r
+static unsigned MY_STD_CALL BtThreadFunc2(void *p)\r
+{\r
+  Byte allocaDummy[0x180];\r
+  int i = 0;\r
+  for (i = 0; i < 16; i++)\r
+    allocaDummy[i] = (Byte)i;\r
+  BtThreadFunc((CMatchFinderMt *)p);\r
+  return 0;\r
+}\r
+\r
+SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,\r
+    UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)\r
+{\r
+  CMatchFinder *mf = p->MatchFinder;\r
+  p->historySize = historySize;\r
+  if (kMtBtBlockSize <= matchMaxLen * 4)\r
+    return SZ_ERROR_PARAM;\r
+  if (p->hashBuf == 0)\r
+  {\r
+    p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));\r
+    if (p->hashBuf == 0)\r
+      return SZ_ERROR_MEM;\r
+    p->btBuf = p->hashBuf + kHashBufferSize;\r
+  }\r
+  keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);\r
+  keepAddBufferAfter += kMtHashBlockSize;\r
+  if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))\r
+    return SZ_ERROR_MEM;\r
+\r
+  RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));\r
+  RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));\r
+  return SZ_OK;\r
+}\r
+\r
+/* Call it after ReleaseStream / SetStream */\r
+void MatchFinderMt_Init(CMatchFinderMt *p)\r
+{\r
+  CMatchFinder *mf = p->MatchFinder;\r
+  p->btBufPos = p->btBufPosLimit = 0;\r
+  p->hashBufPos = p->hashBufPosLimit = 0;\r
+  MatchFinder_Init(mf);\r
+  p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);\r
+  p->btNumAvailBytes = 0;\r
+  p->lzPos = p->historySize + 1;\r
+\r
+  p->hash = mf->hash;\r
+  p->fixedHashSize = mf->fixedHashSize;\r
+  p->crc = mf->crc;\r
+\r
+  p->son = mf->son;\r
+  p->matchMaxLen = mf->matchMaxLen;\r
+  p->numHashBytes = mf->numHashBytes;\r
+  p->pos = mf->pos;\r
+  p->buffer = mf->buffer;\r
+  p->cyclicBufferPos = mf->cyclicBufferPos;\r
+  p->cyclicBufferSize = mf->cyclicBufferSize;\r
+  p->cutValue = mf->cutValue;\r
+}\r
+\r
+/* ReleaseStream is required to finish multithreading */\r
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)\r
+{\r
+  MtSync_StopWriting(&p->btSync);\r
+  /* p->MatchFinder->ReleaseStream(); */\r
+}\r
+\r
+void MatchFinderMt_Normalize(CMatchFinderMt *p)\r
+{\r
+  MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);\r
+  p->lzPos = p->historySize + 1;\r
+}\r
+\r
+void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)\r
+{\r
+  UInt32 blockIndex;\r
+  MtSync_GetNextBlock(&p->btSync);\r
+  blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);\r
+  p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;\r
+  p->btBufPosLimit += p->btBuf[p->btBufPos++];\r
+  p->btNumAvailBytes = p->btBuf[p->btBufPos++];\r
+  if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)\r
+    MatchFinderMt_Normalize(p);\r
+}\r
+\r
+const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)\r
+{\r
+  return p->pointerToCurPos;\r
+}\r
+\r
+#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);\r
+\r
+UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)\r
+{\r
+  GET_NEXT_BLOCK_IF_REQUIRED;\r
+  return p->btNumAvailBytes;\r
+}\r
+\r
+Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)\r
+{\r
+  return p->pointerToCurPos[index];\r
+}\r
+\r
+UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)\r
+{\r
+  UInt32 hash2Value, curMatch2;\r
+  UInt32 *hash = p->hash;\r
+  const Byte *cur = p->pointerToCurPos;\r
+  UInt32 lzPos = p->lzPos;\r
+  MT_HASH2_CALC\r
+      \r
+  curMatch2 = hash[hash2Value];\r
+  hash[hash2Value] = lzPos;\r
+\r
+  if (curMatch2 >= matchMinPos)\r
+    if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])\r
+    {\r
+      *distances++ = 2;\r
+      *distances++ = lzPos - curMatch2 - 1;\r
+    }\r
+  return distances;\r
+}\r
+\r
+UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)\r
+{\r
+  UInt32 hash2Value, hash3Value, curMatch2, curMatch3;\r
+  UInt32 *hash = p->hash;\r
+  const Byte *cur = p->pointerToCurPos;\r
+  UInt32 lzPos = p->lzPos;\r
+  MT_HASH3_CALC\r
+\r
+  curMatch2 = hash[                hash2Value];\r
+  curMatch3 = hash[kFix3HashSize + hash3Value];\r
+  \r
+  hash[                hash2Value] =\r
+  hash[kFix3HashSize + hash3Value] =\r
+    lzPos;\r
+\r
+  if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])\r
+  {\r
+    distances[1] = lzPos - curMatch2 - 1;\r
+    if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])\r
+    {\r
+      distances[0] = 3;\r
+      return distances + 2;\r
+    }\r
+    distances[0] = 2;\r
+    distances += 2;\r
+  }\r
+  if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])\r
+  {\r
+    *distances++ = 3;\r
+    *distances++ = lzPos - curMatch3 - 1;\r
+  }\r
+  return distances;\r
+}\r
+\r
+/*\r
+UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)\r
+{\r
+  UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;\r
+  UInt32 *hash = p->hash;\r
+  const Byte *cur = p->pointerToCurPos;\r
+  UInt32 lzPos = p->lzPos;\r
+  MT_HASH4_CALC\r
+      \r
+  curMatch2 = hash[                hash2Value];\r
+  curMatch3 = hash[kFix3HashSize + hash3Value];\r
+  curMatch4 = hash[kFix4HashSize + hash4Value];\r
+  \r
+  hash[                hash2Value] =\r
+  hash[kFix3HashSize + hash3Value] =\r
+  hash[kFix4HashSize + hash4Value] =\r
+    lzPos;\r
+\r
+  if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])\r
+  {\r
+    distances[1] = lzPos - curMatch2 - 1;\r
+    if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])\r
+    {\r
+      distances[0] =  (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;\r
+      return distances + 2;\r
+    }\r
+    distances[0] = 2;\r
+    distances += 2;\r
+  }\r
+  if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])\r
+  {\r
+    distances[1] = lzPos - curMatch3 - 1;\r
+    if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])\r
+    {\r
+      distances[0] = 4;\r
+      return distances + 2;\r
+    }\r
+    distances[0] = 3;\r
+    distances += 2;\r
+  }\r
+\r
+  if (curMatch4 >= matchMinPos)\r
+    if (\r
+      cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&\r
+      cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]\r
+      )\r
+    {\r
+      *distances++ = 4;\r
+      *distances++ = lzPos - curMatch4 - 1;\r
+    }\r
+  return distances;\r
+}\r
+*/\r
+\r
+#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;\r
+\r
+UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)\r
+{\r
+  const UInt32 *btBuf = p->btBuf + p->btBufPos;\r
+  UInt32 len = *btBuf++;\r
+  p->btBufPos += 1 + len;\r
+  p->btNumAvailBytes--;\r
+  {\r
+    UInt32 i;\r
+    for (i = 0; i < len; i += 2)\r
+    {\r
+      *distances++ = *btBuf++;\r
+      *distances++ = *btBuf++;\r
+    }\r
+  }\r
+  INCREASE_LZ_POS\r
+  return len;\r
+}\r
+\r
+UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)\r
+{\r
+  const UInt32 *btBuf = p->btBuf + p->btBufPos;\r
+  UInt32 len = *btBuf++;\r
+  p->btBufPos += 1 + len;\r
+\r
+  if (len == 0)\r
+  {\r
+    if (p->btNumAvailBytes-- >= 4)\r
+      len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));\r
+  }\r
+  else\r
+  {\r
+    /* Condition: there are matches in btBuf with length < p->numHashBytes */\r
+    UInt32 *distances2;\r
+    p->btNumAvailBytes--;\r
+    distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);\r
+    do\r
+    {\r
+      *distances2++ = *btBuf++;\r
+      *distances2++ = *btBuf++;\r
+    }\r
+    while ((len -= 2) != 0);\r
+    len  = (UInt32)(distances2 - (distances));\r
+  }\r
+  INCREASE_LZ_POS\r
+  return len;\r
+}\r
+\r
+#define SKIP_HEADER2_MT  do { GET_NEXT_BLOCK_IF_REQUIRED\r
+#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;\r
+#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);\r
+\r
+void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)\r
+{\r
+  SKIP_HEADER2_MT { p->btNumAvailBytes--;\r
+  SKIP_FOOTER_MT\r
+}\r
+\r
+void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)\r
+{\r
+  SKIP_HEADER_MT(2)\r
+      UInt32 hash2Value;\r
+      MT_HASH2_CALC\r
+      hash[hash2Value] = p->lzPos;\r
+  SKIP_FOOTER_MT\r
+}\r
+\r
+void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)\r
+{\r
+  SKIP_HEADER_MT(3)\r
+      UInt32 hash2Value, hash3Value;\r
+      MT_HASH3_CALC\r
+      hash[kFix3HashSize + hash3Value] =\r
+      hash[                hash2Value] =\r
+        p->lzPos;\r
+  SKIP_FOOTER_MT\r
+}\r
+\r
+/*\r
+void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)\r
+{\r
+  SKIP_HEADER_MT(4)\r
+      UInt32 hash2Value, hash3Value, hash4Value;\r
+      MT_HASH4_CALC\r
+      hash[kFix4HashSize + hash4Value] =\r
+      hash[kFix3HashSize + hash3Value] =\r
+      hash[                hash2Value] =\r
+        p->lzPos;\r
+  SKIP_FOOTER_MT\r
+}\r
+*/\r
+\r
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)\r
+{\r
+  vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;\r
+  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;\r
+  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;\r
+  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;\r
+  vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;\r
+  switch(p->MatchFinder->numHashBytes)\r
+  {\r
+    case 2:\r
+      p->GetHeadsFunc = GetHeads2;\r
+      p->MixMatchesFunc = (Mf_Mix_Matches)0;\r
+      vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;\r
+      vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;\r
+      break;\r
+    case 3:\r
+      p->GetHeadsFunc = GetHeads3;\r
+      p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;\r
+      vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;\r
+      break;\r
+    default:\r
+    /* case 4: */\r
+      p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;\r
+      /* p->GetHeadsFunc = GetHeads4; */\r
+      p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;\r
+      vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;\r
+      break;\r
+    /*\r
+    default:\r
+      p->GetHeadsFunc = GetHeads5;\r
+      p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;\r
+      vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;\r
+      break;\r
+    */\r
+  }\r
+}\r
diff --git a/C/LzFindMt.h b/C/LzFindMt.h
new file mode 100755 (executable)
index 0000000..17ed237
--- /dev/null
@@ -0,0 +1,105 @@
+/* LzFindMt.h -- multithreaded Match finder for LZ algorithms\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZ_FIND_MT_H\r
+#define __LZ_FIND_MT_H\r
+\r
+#include "LzFind.h"\r
+#include "Threads.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define kMtHashBlockSize (1 << 13)\r
+#define kMtHashNumBlocks (1 << 3)\r
+#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)\r
+\r
+#define kMtBtBlockSize (1 << 14)\r
+#define kMtBtNumBlocks (1 << 6)\r
+#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)\r
+\r
+typedef struct _CMtSync\r
+{\r
+  Bool wasCreated;\r
+  Bool needStart;\r
+  Bool exit;\r
+  Bool stopWriting;\r
+\r
+  CThread thread;\r
+  CAutoResetEvent canStart;\r
+  CAutoResetEvent wasStarted;\r
+  CAutoResetEvent wasStopped;\r
+  CSemaphore freeSemaphore;\r
+  CSemaphore filledSemaphore;\r
+  Bool csWasInitialized;\r
+  Bool csWasEntered;\r
+  CCriticalSection cs;\r
+  UInt32 numProcessedBlocks;\r
+} CMtSync;\r
+\r
+typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);\r
+\r
+/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */\r
+#define kMtCacheLineDummy 128\r
+\r
+typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,\r
+  UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);\r
+\r
+typedef struct _CMatchFinderMt\r
+{\r
+  /* LZ */\r
+  const Byte *pointerToCurPos;\r
+  UInt32 *btBuf;\r
+  UInt32 btBufPos;\r
+  UInt32 btBufPosLimit;\r
+  UInt32 lzPos;\r
+  UInt32 btNumAvailBytes;\r
+\r
+  UInt32 *hash;\r
+  UInt32 fixedHashSize;\r
+  UInt32 historySize;\r
+  const UInt32 *crc;\r
+\r
+  Mf_Mix_Matches MixMatchesFunc;\r
+  \r
+  /* LZ + BT */\r
+  CMtSync btSync;\r
+  Byte btDummy[kMtCacheLineDummy];\r
+\r
+  /* BT */\r
+  UInt32 *hashBuf;\r
+  UInt32 hashBufPos;\r
+  UInt32 hashBufPosLimit;\r
+  UInt32 hashNumAvail;\r
+\r
+  CLzRef *son;\r
+  UInt32 matchMaxLen;\r
+  UInt32 numHashBytes;\r
+  UInt32 pos;\r
+  Byte *buffer;\r
+  UInt32 cyclicBufferPos;\r
+  UInt32 cyclicBufferSize; /* it must be historySize + 1 */\r
+  UInt32 cutValue;\r
+\r
+  /* BT + Hash */\r
+  CMtSync hashSync;\r
+  /* Byte hashDummy[kMtCacheLineDummy]; */\r
+  \r
+  /* Hash */\r
+  Mf_GetHeads GetHeadsFunc;\r
+  CMatchFinder *MatchFinder;\r
+} CMatchFinderMt;\r
+\r
+void MatchFinderMt_Construct(CMatchFinderMt *p);\r
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);\r
+SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,\r
+    UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);\r
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);\r
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/LzHash.h b/C/LzHash.h
new file mode 100755 (executable)
index 0000000..b2f0e3c
--- /dev/null
@@ -0,0 +1,54 @@
+/* LzHash.h -- HASH functions for LZ algorithms\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZ_HASH_H\r
+#define __LZ_HASH_H\r
+\r
+#define kHash2Size (1 << 10)\r
+#define kHash3Size (1 << 16)\r
+#define kHash4Size (1 << 20)\r
+\r
+#define kFix3HashSize (kHash2Size)\r
+#define kFix4HashSize (kHash2Size + kHash3Size)\r
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)\r
+\r
+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);\r
+\r
+#define HASH3_CALC { \\r
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+  hash2Value = temp & (kHash2Size - 1); \\r
+  hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }\r
+\r
+#define HASH4_CALC { \\r
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+  hash2Value = temp & (kHash2Size - 1); \\r
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \\r
+  hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }\r
+\r
+#define HASH5_CALC { \\r
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+  hash2Value = temp & (kHash2Size - 1); \\r
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \\r
+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \\r
+  hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \\r
+  hash4Value &= (kHash4Size - 1); }\r
+\r
+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */\r
+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;\r
+\r
+\r
+#define MT_HASH2_CALC \\r
+  hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);\r
+\r
+#define MT_HASH3_CALC { \\r
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+  hash2Value = temp & (kHash2Size - 1); \\r
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }\r
+\r
+#define MT_HASH4_CALC { \\r
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+  hash2Value = temp & (kHash2Size - 1); \\r
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \\r
+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }\r
+\r
+#endif\r
diff --git a/C/Lzma2Dec.c b/C/Lzma2Dec.c
new file mode 100755 (executable)
index 0000000..8f24067
--- /dev/null
@@ -0,0 +1,356 @@
+/* Lzma2Dec.c -- LZMA2 Decoder\r
+2009-05-03 : Igor Pavlov : Public domain */\r
+\r
+/* #define SHOW_DEBUG_INFO */\r
+\r
+#ifdef SHOW_DEBUG_INFO\r
+#include <stdio.h>\r
+#endif\r
+\r
+#include <string.h>\r
+\r
+#include "Lzma2Dec.h"\r
+\r
+/*\r
+00000000  -  EOS\r
+00000001 U U  -  Uncompressed Reset Dic\r
+00000010 U U  -  Uncompressed No Reset\r
+100uuuuu U U P P  -  LZMA no reset\r
+101uuuuu U U P P  -  LZMA reset state\r
+110uuuuu U U P P S  -  LZMA reset state + new prop\r
+111uuuuu U U P P S  -  LZMA reset state + new prop + reset dic\r
+\r
+  u, U - Unpack Size\r
+  P - Pack Size\r
+  S - Props\r
+*/\r
+\r
+#define LZMA2_CONTROL_LZMA (1 << 7)\r
+#define LZMA2_CONTROL_COPY_NO_RESET 2\r
+#define LZMA2_CONTROL_COPY_RESET_DIC 1\r
+#define LZMA2_CONTROL_EOF 0\r
+\r
+#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)\r
+\r
+#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)\r
+#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)\r
+\r
+#define LZMA2_LCLP_MAX 4\r
+#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))\r
+\r
+#ifdef SHOW_DEBUG_INFO\r
+#define PRF(x) x\r
+#else\r
+#define PRF(x)\r
+#endif\r
+\r
+typedef enum\r
+{\r
+  LZMA2_STATE_CONTROL,\r
+  LZMA2_STATE_UNPACK0,\r
+  LZMA2_STATE_UNPACK1,\r
+  LZMA2_STATE_PACK0,\r
+  LZMA2_STATE_PACK1,\r
+  LZMA2_STATE_PROP,\r
+  LZMA2_STATE_DATA,\r
+  LZMA2_STATE_DATA_CONT,\r
+  LZMA2_STATE_FINISHED,\r
+  LZMA2_STATE_ERROR\r
+} ELzma2State;\r
+\r
+static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)\r
+{\r
+  UInt32 dicSize;\r
+  if (prop > 40)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);\r
+  props[0] = (Byte)LZMA2_LCLP_MAX;\r
+  props[1] = (Byte)(dicSize);\r
+  props[2] = (Byte)(dicSize >> 8);\r
+  props[3] = (Byte)(dicSize >> 16);\r
+  props[4] = (Byte)(dicSize >> 24);\r
+  return SZ_OK;\r
+}\r
+\r
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)\r
+{\r
+  Byte props[LZMA_PROPS_SIZE];\r
+  RINOK(Lzma2Dec_GetOldProps(prop, props));\r
+  return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);\r
+}\r
+\r
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)\r
+{\r
+  Byte props[LZMA_PROPS_SIZE];\r
+  RINOK(Lzma2Dec_GetOldProps(prop, props));\r
+  return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);\r
+}\r
+\r
+void Lzma2Dec_Init(CLzma2Dec *p)\r
+{\r
+  p->state = LZMA2_STATE_CONTROL;\r
+  p->needInitDic = True;\r
+  p->needInitState = True;\r
+  p->needInitProp = True;\r
+  LzmaDec_Init(&p->decoder);\r
+}\r
+\r
+static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)\r
+{\r
+  switch(p->state)\r
+  {\r
+    case LZMA2_STATE_CONTROL:\r
+      p->control = b;\r
+      PRF(printf("\n %4X ", p->decoder.dicPos));\r
+      PRF(printf(" %2X", b));\r
+      if (p->control == 0)\r
+        return LZMA2_STATE_FINISHED;\r
+      if (LZMA2_IS_UNCOMPRESSED_STATE(p))\r
+      {\r
+        if ((p->control & 0x7F) > 2)\r
+          return LZMA2_STATE_ERROR;\r
+        p->unpackSize = 0;\r
+      }\r
+      else\r
+        p->unpackSize = (UInt32)(p->control & 0x1F) << 16;\r
+      return LZMA2_STATE_UNPACK0;\r
+    \r
+    case LZMA2_STATE_UNPACK0:\r
+      p->unpackSize |= (UInt32)b << 8;\r
+      return LZMA2_STATE_UNPACK1;\r
+    \r
+    case LZMA2_STATE_UNPACK1:\r
+      p->unpackSize |= (UInt32)b;\r
+      p->unpackSize++;\r
+      PRF(printf(" %8d", p->unpackSize));\r
+      return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;\r
+    \r
+    case LZMA2_STATE_PACK0:\r
+      p->packSize = (UInt32)b << 8;\r
+      return LZMA2_STATE_PACK1;\r
+\r
+    case LZMA2_STATE_PACK1:\r
+      p->packSize |= (UInt32)b;\r
+      p->packSize++;\r
+      PRF(printf(" %8d", p->packSize));\r
+      return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:\r
+        (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);\r
+\r
+    case LZMA2_STATE_PROP:\r
+    {\r
+      int lc, lp;\r
+      if (b >= (9 * 5 * 5))\r
+        return LZMA2_STATE_ERROR;\r
+      lc = b % 9;\r
+      b /= 9;\r
+      p->decoder.prop.pb = b / 5;\r
+      lp = b % 5;\r
+      if (lc + lp > LZMA2_LCLP_MAX)\r
+        return LZMA2_STATE_ERROR;\r
+      p->decoder.prop.lc = lc;\r
+      p->decoder.prop.lp = lp;\r
+      p->needInitProp = False;\r
+      return LZMA2_STATE_DATA;\r
+    }\r
+  }\r
+  return LZMA2_STATE_ERROR;\r
+}\r
+\r
+static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)\r
+{\r
+  memcpy(p->dic + p->dicPos, src, size);\r
+  p->dicPos += size;\r
+  if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)\r
+    p->checkDicSize = p->prop.dicSize;\r
+  p->processedPos += (UInt32)size;\r
+}\r
+\r
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);\r
+\r
+SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,\r
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)\r
+{\r
+  SizeT inSize = *srcLen;\r
+  *srcLen = 0;\r
+  *status = LZMA_STATUS_NOT_SPECIFIED;\r
+\r
+  while (p->state != LZMA2_STATE_FINISHED)\r
+  {\r
+    SizeT dicPos = p->decoder.dicPos;\r
+    if (p->state == LZMA2_STATE_ERROR)\r
+      return SZ_ERROR_DATA;\r
+    if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)\r
+    {\r
+      *status = LZMA_STATUS_NOT_FINISHED;\r
+      return SZ_OK;\r
+    }\r
+    if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)\r
+    {\r
+      if (*srcLen == inSize)\r
+      {\r
+        *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+        return SZ_OK;\r
+      }\r
+      (*srcLen)++;\r
+      p->state = Lzma2Dec_UpdateState(p, *src++);\r
+      continue;\r
+    }\r
+    {\r
+      SizeT destSizeCur = dicLimit - dicPos;\r
+      SizeT srcSizeCur = inSize - *srcLen;\r
+      ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;\r
+      \r
+      if (p->unpackSize <= destSizeCur)\r
+      {\r
+        destSizeCur = (SizeT)p->unpackSize;\r
+        curFinishMode = LZMA_FINISH_END;\r
+      }\r
+\r
+      if (LZMA2_IS_UNCOMPRESSED_STATE(p))\r
+      {\r
+        if (*srcLen == inSize)\r
+        {\r
+          *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+          return SZ_OK;\r
+        }\r
+\r
+        if (p->state == LZMA2_STATE_DATA)\r
+        {\r
+          Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);\r
+          if (initDic)\r
+            p->needInitProp = p->needInitState = True;\r
+          else if (p->needInitDic)\r
+            return SZ_ERROR_DATA;\r
+          p->needInitDic = False;\r
+          LzmaDec_InitDicAndState(&p->decoder, initDic, False);\r
+        }\r
+\r
+        if (srcSizeCur > destSizeCur)\r
+          srcSizeCur = destSizeCur;\r
+\r
+        if (srcSizeCur == 0)\r
+          return SZ_ERROR_DATA;\r
+\r
+        LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);\r
+\r
+        src += srcSizeCur;\r
+        *srcLen += srcSizeCur;\r
+        p->unpackSize -= (UInt32)srcSizeCur;\r
+        p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;\r
+      }\r
+      else\r
+      {\r
+        SizeT outSizeProcessed;\r
+        SRes res;\r
+\r
+        if (p->state == LZMA2_STATE_DATA)\r
+        {\r
+          int mode = LZMA2_GET_LZMA_MODE(p);\r
+          Bool initDic = (mode == 3);\r
+          Bool initState = (mode > 0);\r
+          if ((!initDic && p->needInitDic) || (!initState && p->needInitState))\r
+            return SZ_ERROR_DATA;\r
+          \r
+          LzmaDec_InitDicAndState(&p->decoder, initDic, initState);\r
+          p->needInitDic = False;\r
+          p->needInitState = False;\r
+          p->state = LZMA2_STATE_DATA_CONT;\r
+        }\r
+        if (srcSizeCur > p->packSize)\r
+          srcSizeCur = (SizeT)p->packSize;\r
+          \r
+        res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);\r
+        \r
+        src += srcSizeCur;\r
+        *srcLen += srcSizeCur;\r
+        p->packSize -= (UInt32)srcSizeCur;\r
+\r
+        outSizeProcessed = p->decoder.dicPos - dicPos;\r
+        p->unpackSize -= (UInt32)outSizeProcessed;\r
+\r
+        RINOK(res);\r
+        if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)\r
+          return res;\r
+\r
+        if (srcSizeCur == 0 && outSizeProcessed == 0)\r
+        {\r
+          if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||\r
+              p->unpackSize != 0 || p->packSize != 0)\r
+            return SZ_ERROR_DATA;\r
+          p->state = LZMA2_STATE_CONTROL;\r
+        }\r
+        if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)\r
+          *status = LZMA_STATUS_NOT_FINISHED;\r
+      }\r
+    }\r
+  }\r
+  *status = LZMA_STATUS_FINISHED_WITH_MARK;\r
+  return SZ_OK;\r
+}\r
+\r
+SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)\r
+{\r
+  SizeT outSize = *destLen, inSize = *srcLen;\r
+  *srcLen = *destLen = 0;\r
+  for (;;)\r
+  {\r
+    SizeT srcSizeCur = inSize, outSizeCur, dicPos;\r
+    ELzmaFinishMode curFinishMode;\r
+    SRes res;\r
+    if (p->decoder.dicPos == p->decoder.dicBufSize)\r
+      p->decoder.dicPos = 0;\r
+    dicPos = p->decoder.dicPos;\r
+    if (outSize > p->decoder.dicBufSize - dicPos)\r
+    {\r
+      outSizeCur = p->decoder.dicBufSize;\r
+      curFinishMode = LZMA_FINISH_ANY;\r
+    }\r
+    else\r
+    {\r
+      outSizeCur = dicPos + outSize;\r
+      curFinishMode = finishMode;\r
+    }\r
+\r
+    res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);\r
+    src += srcSizeCur;\r
+    inSize -= srcSizeCur;\r
+    *srcLen += srcSizeCur;\r
+    outSizeCur = p->decoder.dicPos - dicPos;\r
+    memcpy(dest, p->decoder.dic + dicPos, outSizeCur);\r
+    dest += outSizeCur;\r
+    outSize -= outSizeCur;\r
+    *destLen += outSizeCur;\r
+    if (res != 0)\r
+      return res;\r
+    if (outSizeCur == 0 || outSize == 0)\r
+      return SZ_OK;\r
+  }\r
+}\r
+\r
+SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)\r
+{\r
+  CLzma2Dec decoder;\r
+  SRes res;\r
+  SizeT outSize = *destLen, inSize = *srcLen;\r
+  Byte props[LZMA_PROPS_SIZE];\r
+\r
+  Lzma2Dec_Construct(&decoder);\r
+\r
+  *destLen = *srcLen = 0;\r
+  *status = LZMA_STATUS_NOT_SPECIFIED;\r
+  decoder.decoder.dic = dest;\r
+  decoder.decoder.dicBufSize = outSize;\r
+\r
+  RINOK(Lzma2Dec_GetOldProps(prop, props));\r
+  RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));\r
+  \r
+  *srcLen = inSize;\r
+  res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);\r
+  *destLen = decoder.decoder.dicPos;\r
+  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)\r
+    res = SZ_ERROR_INPUT_EOF;\r
+\r
+  LzmaDec_FreeProbs(&decoder.decoder, alloc);\r
+  return res;\r
+}\r
diff --git a/C/Lzma2Dec.h b/C/Lzma2Dec.h
new file mode 100755 (executable)
index 0000000..827698d
--- /dev/null
@@ -0,0 +1,84 @@
+/* Lzma2Dec.h -- LZMA2 Decoder\r
+2009-05-03 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZMA2_DEC_H\r
+#define __LZMA2_DEC_H\r
+\r
+#include "LzmaDec.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/* ---------- State Interface ---------- */\r
+\r
+typedef struct\r
+{\r
+  CLzmaDec decoder;\r
+  UInt32 packSize;\r
+  UInt32 unpackSize;\r
+  int state;\r
+  Byte control;\r
+  Bool needInitDic;\r
+  Bool needInitState;\r
+  Bool needInitProp;\r
+} CLzma2Dec;\r
+\r
+#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)\r
+#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);\r
+#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);\r
+\r
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);\r
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);\r
+void Lzma2Dec_Init(CLzma2Dec *p);\r
+\r
+\r
+/*\r
+finishMode:\r
+  It has meaning only if the decoding reaches output limit (*destLen or dicLimit).\r
+  LZMA_FINISH_ANY - use smallest number of input bytes\r
+  LZMA_FINISH_END - read EndOfStream marker after decoding\r
+\r
+Returns:\r
+  SZ_OK\r
+    status:\r
+      LZMA_STATUS_FINISHED_WITH_MARK\r
+      LZMA_STATUS_NOT_FINISHED\r
+      LZMA_STATUS_NEEDS_MORE_INPUT\r
+  SZ_ERROR_DATA - Data error\r
+*/\r
+\r
+SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,\r
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);\r
+\r
+SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,\r
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);\r
+\r
+\r
+/* ---------- One Call Interface ---------- */\r
+\r
+/*\r
+finishMode:\r
+  It has meaning only if the decoding reaches output limit (*destLen).\r
+  LZMA_FINISH_ANY - use smallest number of input bytes\r
+  LZMA_FINISH_END - read EndOfStream marker after decoding\r
+\r
+Returns:\r
+  SZ_OK\r
+    status:\r
+      LZMA_STATUS_FINISHED_WITH_MARK\r
+      LZMA_STATUS_NOT_FINISHED\r
+  SZ_ERROR_DATA - Data error\r
+  SZ_ERROR_MEM  - Memory allocation error\r
+  SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).\r
+*/\r
+\r
+SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/Lzma2Enc.c b/C/Lzma2Enc.c
new file mode 100755 (executable)
index 0000000..35f6ed7
--- /dev/null
@@ -0,0 +1,477 @@
+/* Lzma2Enc.c -- LZMA2 Encoder\r
+2010-09-24 : Igor Pavlov : Public domain */\r
+\r
+/* #include <stdio.h> */\r
+#include <string.h>\r
+\r
+/* #define _7ZIP_ST */\r
+\r
+#include "Lzma2Enc.h"\r
+\r
+#ifndef _7ZIP_ST\r
+#include "MtCoder.h"\r
+#else\r
+#define NUM_MT_CODER_THREADS_MAX 1\r
+#endif\r
+\r
+#define LZMA2_CONTROL_LZMA (1 << 7)\r
+#define LZMA2_CONTROL_COPY_NO_RESET 2\r
+#define LZMA2_CONTROL_COPY_RESET_DIC 1\r
+#define LZMA2_CONTROL_EOF 0\r
+\r
+#define LZMA2_LCLP_MAX 4\r
+\r
+#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))\r
+\r
+#define LZMA2_PACK_SIZE_MAX (1 << 16)\r
+#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX\r
+#define LZMA2_UNPACK_SIZE_MAX (1 << 21)\r
+#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX\r
+\r
+#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16)\r
+\r
+\r
+#define PRF(x) /* x */\r
+\r
+/* ---------- CLzma2EncInt ---------- */\r
+\r
+typedef struct\r
+{\r
+  CLzmaEncHandle enc;\r
+  UInt64 srcPos;\r
+  Byte props;\r
+  Bool needInitState;\r
+  Bool needInitProp;\r
+} CLzma2EncInt;\r
+\r
+static SRes Lzma2EncInt_Init(CLzma2EncInt *p, const CLzma2EncProps *props)\r
+{\r
+  Byte propsEncoded[LZMA_PROPS_SIZE];\r
+  SizeT propsSize = LZMA_PROPS_SIZE;\r
+  RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps));\r
+  RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize));\r
+  p->srcPos = 0;\r
+  p->props = propsEncoded[0];\r
+  p->needInitState = True;\r
+  p->needInitProp = True;\r
+  return SZ_OK;\r
+}\r
+\r
+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,\r
+    ISzAlloc *alloc, ISzAlloc *allocBig);\r
+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,\r
+    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig);\r
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,\r
+    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);\r
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);\r
+void LzmaEnc_Finish(CLzmaEncHandle pp);\r
+void LzmaEnc_SaveState(CLzmaEncHandle pp);\r
+void LzmaEnc_RestoreState(CLzmaEncHandle pp);\r
+\r
+\r
+static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,\r
+    size_t *packSizeRes, ISeqOutStream *outStream)\r
+{\r
+  size_t packSizeLimit = *packSizeRes;\r
+  size_t packSize = packSizeLimit;\r
+  UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX;\r
+  unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0);\r
+  Bool useCopyBlock;\r
+  SRes res;\r
+\r
+  *packSizeRes = 0;\r
+  if (packSize < lzHeaderSize)\r
+    return SZ_ERROR_OUTPUT_EOF;\r
+  packSize -= lzHeaderSize;\r
+  \r
+  LzmaEnc_SaveState(p->enc);\r
+  res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState,\r
+      outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize);\r
+  \r
+  PRF(printf("\npackSize = %7d unpackSize = %7d  ", packSize, unpackSize));\r
+\r
+  if (unpackSize == 0)\r
+    return res;\r
+\r
+  if (res == SZ_OK)\r
+    useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16));\r
+  else\r
+  {\r
+    if (res != SZ_ERROR_OUTPUT_EOF)\r
+      return res;\r
+    res = SZ_OK;\r
+    useCopyBlock = True;\r
+  }\r
+\r
+  if (useCopyBlock)\r
+  {\r
+    size_t destPos = 0;\r
+    PRF(printf("################# COPY           "));\r
+    while (unpackSize > 0)\r
+    {\r
+      UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;\r
+      if (packSizeLimit - destPos < u + 3)\r
+        return SZ_ERROR_OUTPUT_EOF;\r
+      outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET);\r
+      outBuf[destPos++] = (Byte)((u - 1) >> 8);\r
+      outBuf[destPos++] = (Byte)(u - 1);\r
+      memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u);\r
+      unpackSize -= u;\r
+      destPos += u;\r
+      p->srcPos += u;\r
+      if (outStream)\r
+      {\r
+        *packSizeRes += destPos;\r
+        if (outStream->Write(outStream, outBuf, destPos) != destPos)\r
+          return SZ_ERROR_WRITE;\r
+        destPos = 0;\r
+      }\r
+      else\r
+        *packSizeRes = destPos;\r
+      /* needInitState = True; */\r
+    }\r
+    LzmaEnc_RestoreState(p->enc);\r
+    return SZ_OK;\r
+  }\r
+  {\r
+    size_t destPos = 0;\r
+    UInt32 u = unpackSize - 1;\r
+    UInt32 pm = (UInt32)(packSize - 1);\r
+    unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0);\r
+\r
+    PRF(printf("               "));\r
+\r
+    outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F));\r
+    outBuf[destPos++] = (Byte)(u >> 8);\r
+    outBuf[destPos++] = (Byte)u;\r
+    outBuf[destPos++] = (Byte)(pm >> 8);\r
+    outBuf[destPos++] = (Byte)pm;\r
+    \r
+    if (p->needInitProp)\r
+      outBuf[destPos++] = p->props;\r
+    \r
+    p->needInitProp = False;\r
+    p->needInitState = False;\r
+    destPos += packSize;\r
+    p->srcPos += unpackSize;\r
+\r
+    if (outStream)\r
+      if (outStream->Write(outStream, outBuf, destPos) != destPos)\r
+        return SZ_ERROR_WRITE;\r
+    *packSizeRes = destPos;\r
+    return SZ_OK;\r
+  }\r
+}\r
+\r
+/* ---------- Lzma2 Props ---------- */\r
+\r
+void Lzma2EncProps_Init(CLzma2EncProps *p)\r
+{\r
+  LzmaEncProps_Init(&p->lzmaProps);\r
+  p->numTotalThreads = -1;\r
+  p->numBlockThreads = -1;\r
+  p->blockSize = 0;\r
+}\r
+\r
+void Lzma2EncProps_Normalize(CLzma2EncProps *p)\r
+{\r
+  int t1, t1n, t2, t3;\r
+  {\r
+    CLzmaEncProps lzmaProps = p->lzmaProps;\r
+    LzmaEncProps_Normalize(&lzmaProps);\r
+    t1n = lzmaProps.numThreads;\r
+  }\r
+\r
+  t1 = p->lzmaProps.numThreads;\r
+  t2 = p->numBlockThreads;\r
+  t3 = p->numTotalThreads;\r
+\r
+  if (t2 > NUM_MT_CODER_THREADS_MAX)\r
+    t2 = NUM_MT_CODER_THREADS_MAX;\r
+\r
+  if (t3 <= 0)\r
+  {\r
+    if (t2 <= 0)\r
+      t2 = 1;\r
+    t3 = t1n * t2;\r
+  }\r
+  else if (t2 <= 0)\r
+  {\r
+    t2 = t3 / t1n;\r
+    if (t2 == 0)\r
+    {\r
+      t1 = 1;\r
+      t2 = t3;\r
+    }\r
+    if (t2 > NUM_MT_CODER_THREADS_MAX)\r
+      t2 = NUM_MT_CODER_THREADS_MAX;\r
+  }\r
+  else if (t1 <= 0)\r
+  {\r
+    t1 = t3 / t2;\r
+    if (t1 == 0)\r
+      t1 = 1;\r
+  }\r
+  else\r
+    t3 = t1n * t2;\r
+\r
+  p->lzmaProps.numThreads = t1;\r
+  p->numBlockThreads = t2;\r
+  p->numTotalThreads = t3;\r
+  LzmaEncProps_Normalize(&p->lzmaProps);\r
+\r
+  if (p->blockSize == 0)\r
+  {\r
+    UInt32 dictSize = p->lzmaProps.dictSize;\r
+    UInt64 blockSize = (UInt64)dictSize << 2;\r
+    const UInt32 kMinSize = (UInt32)1 << 20;\r
+    const UInt32 kMaxSize = (UInt32)1 << 28;\r
+    if (blockSize < kMinSize) blockSize = kMinSize;\r
+    if (blockSize > kMaxSize) blockSize = kMaxSize;\r
+    if (blockSize < dictSize) blockSize = dictSize;\r
+    p->blockSize = (size_t)blockSize;\r
+  }\r
+}\r
+\r
+static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)\r
+{\r
+  return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;\r
+}\r
+\r
+/* ---------- Lzma2 ---------- */\r
+\r
+typedef struct\r
+{\r
+  Byte propEncoded;\r
+  CLzma2EncProps props;\r
+  \r
+  Byte *outBuf;\r
+\r
+  ISzAlloc *alloc;\r
+  ISzAlloc *allocBig;\r
+\r
+  CLzma2EncInt coders[NUM_MT_CODER_THREADS_MAX];\r
+\r
+  #ifndef _7ZIP_ST\r
+  CMtCoder mtCoder;\r
+  #endif\r
+\r
+} CLzma2Enc;\r
+\r
+\r
+/* ---------- Lzma2EncThread ---------- */\r
+\r
+static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,\r
+  ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)\r
+{\r
+  UInt64 packTotal = 0;\r
+  SRes res = SZ_OK;\r
+\r
+  if (mainEncoder->outBuf == 0)\r
+  {\r
+    mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);\r
+    if (mainEncoder->outBuf == 0)\r
+      return SZ_ERROR_MEM;\r
+  }\r
+  RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));\r
+  RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,\r
+      mainEncoder->alloc, mainEncoder->allocBig));\r
+  for (;;)\r
+  {\r
+    size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;\r
+    res = Lzma2EncInt_EncodeSubblock(p, mainEncoder->outBuf, &packSize, outStream);\r
+    if (res != SZ_OK)\r
+      break;\r
+    packTotal += packSize;\r
+    res = Progress(progress, p->srcPos, packTotal);\r
+    if (res != SZ_OK)\r
+      break;\r
+    if (packSize == 0)\r
+      break;\r
+  }\r
+  LzmaEnc_Finish(p->enc);\r
+  if (res == SZ_OK)\r
+  {\r
+    Byte b = 0;\r
+    if (outStream->Write(outStream, &b, 1) != 1)\r
+      return SZ_ERROR_WRITE;\r
+  }\r
+  return res;\r
+}\r
+\r
+#ifndef _7ZIP_ST\r
+\r
+typedef struct\r
+{\r
+  IMtCoderCallback funcTable;\r
+  CLzma2Enc *lzma2Enc;\r
+} CMtCallbackImp;\r
+\r
+static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *destSize,\r
+      const Byte *src, size_t srcSize, int finished)\r
+{\r
+  CMtCallbackImp *imp = (CMtCallbackImp *)pp;\r
+  CLzma2Enc *mainEncoder = imp->lzma2Enc;\r
+  CLzma2EncInt *p = &mainEncoder->coders[index];\r
+\r
+  SRes res = SZ_OK;\r
+  {\r
+    size_t destLim = *destSize;\r
+    *destSize = 0;\r
+\r
+    if (srcSize != 0)\r
+    {\r
+      RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));\r
+     \r
+      RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE,\r
+          mainEncoder->alloc, mainEncoder->allocBig));\r
+     \r
+      while (p->srcPos < srcSize)\r
+      {\r
+        size_t packSize = destLim - *destSize;\r
+        res = Lzma2EncInt_EncodeSubblock(p, dest + *destSize, &packSize, NULL);\r
+        if (res != SZ_OK)\r
+          break;\r
+        *destSize += packSize;\r
+\r
+        if (packSize == 0)\r
+        {\r
+          res = SZ_ERROR_FAIL;\r
+          break;\r
+        }\r
+\r
+        if (MtProgress_Set(&mainEncoder->mtCoder.mtProgress, index, p->srcPos, *destSize) != SZ_OK)\r
+        {\r
+          res = SZ_ERROR_PROGRESS;\r
+          break;\r
+        }\r
+      }\r
+      LzmaEnc_Finish(p->enc);\r
+      if (res != SZ_OK)\r
+        return res;\r
+    }\r
+    if (finished)\r
+    {\r
+      if (*destSize == destLim)\r
+        return SZ_ERROR_OUTPUT_EOF;\r
+      dest[(*destSize)++] = 0;\r
+    }\r
+  }\r
+  return res;\r
+}\r
+\r
+#endif\r
+\r
+/* ---------- Lzma2Enc ---------- */\r
+\r
+CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));\r
+  if (p == 0)\r
+    return NULL;\r
+  Lzma2EncProps_Init(&p->props);\r
+  Lzma2EncProps_Normalize(&p->props);\r
+  p->outBuf = 0;\r
+  p->alloc = alloc;\r
+  p->allocBig = allocBig;\r
+  {\r
+    unsigned i;\r
+    for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)\r
+      p->coders[i].enc = 0;\r
+  }\r
+  #ifndef _7ZIP_ST\r
+  MtCoder_Construct(&p->mtCoder);\r
+  #endif\r
+\r
+  return p;\r
+}\r
+\r
+void Lzma2Enc_Destroy(CLzma2EncHandle pp)\r
+{\r
+  CLzma2Enc *p = (CLzma2Enc *)pp;\r
+  unsigned i;\r
+  for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)\r
+  {\r
+    CLzma2EncInt *t = &p->coders[i];\r
+    if (t->enc)\r
+    {\r
+      LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig);\r
+      t->enc = 0;\r
+    }\r
+  }\r
+\r
+  #ifndef _7ZIP_ST\r
+  MtCoder_Destruct(&p->mtCoder);\r
+  #endif\r
+\r
+  IAlloc_Free(p->alloc, p->outBuf);\r
+  IAlloc_Free(p->alloc, pp);\r
+}\r
+\r
+SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)\r
+{\r
+  CLzma2Enc *p = (CLzma2Enc *)pp;\r
+  CLzmaEncProps lzmaProps = props->lzmaProps;\r
+  LzmaEncProps_Normalize(&lzmaProps);\r
+  if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX)\r
+    return SZ_ERROR_PARAM;\r
+  p->props = *props;\r
+  Lzma2EncProps_Normalize(&p->props);\r
+  return SZ_OK;\r
+}\r
+\r
+Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)\r
+{\r
+  CLzma2Enc *p = (CLzma2Enc *)pp;\r
+  unsigned i;\r
+  UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps);\r
+  for (i = 0; i < 40; i++)\r
+    if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i))\r
+      break;\r
+  return (Byte)i;\r
+}\r
+\r
+SRes Lzma2Enc_Encode(CLzma2EncHandle pp,\r
+    ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)\r
+{\r
+  CLzma2Enc *p = (CLzma2Enc *)pp;\r
+  int i;\r
+\r
+  for (i = 0; i < p->props.numBlockThreads; i++)\r
+  {\r
+    CLzma2EncInt *t = &p->coders[i];\r
+    if (t->enc == NULL)\r
+    {\r
+      t->enc = LzmaEnc_Create(p->alloc);\r
+      if (t->enc == NULL)\r
+        return SZ_ERROR_MEM;\r
+    }\r
+  }\r
+\r
+  #ifndef _7ZIP_ST\r
+  if (p->props.numBlockThreads <= 1)\r
+  #endif\r
+    return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);\r
+\r
+  #ifndef _7ZIP_ST\r
+\r
+  {\r
+    CMtCallbackImp mtCallback;\r
+\r
+    mtCallback.funcTable.Code = MtCallbackImp_Code;\r
+    mtCallback.lzma2Enc = p;\r
+    \r
+    p->mtCoder.progress = progress;\r
+    p->mtCoder.inStream = inStream;\r
+    p->mtCoder.outStream = outStream;\r
+    p->mtCoder.alloc = p->alloc;\r
+    p->mtCoder.mtCallback = &mtCallback.funcTable;\r
+\r
+    p->mtCoder.blockSize = p->props.blockSize;\r
+    p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;\r
+    p->mtCoder.numThreads = p->props.numBlockThreads;\r
+    \r
+    return MtCoder_Code(&p->mtCoder);\r
+  }\r
+  #endif\r
+}\r
diff --git a/C/Lzma2Enc.h b/C/Lzma2Enc.h
new file mode 100755 (executable)
index 0000000..38830e5
--- /dev/null
@@ -0,0 +1,66 @@
+/* Lzma2Enc.h -- LZMA2 Encoder\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZMA2_ENC_H\r
+#define __LZMA2_ENC_H\r
+\r
+#include "LzmaEnc.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef struct\r
+{\r
+  CLzmaEncProps lzmaProps;\r
+  size_t blockSize;\r
+  int numBlockThreads;\r
+  int numTotalThreads;\r
+} CLzma2EncProps;\r
+\r
+void Lzma2EncProps_Init(CLzma2EncProps *p);\r
+void Lzma2EncProps_Normalize(CLzma2EncProps *p);\r
+\r
+/* ---------- CLzmaEnc2Handle Interface ---------- */\r
+\r
+/* Lzma2Enc_* functions can return the following exit codes:\r
+Returns:\r
+  SZ_OK           - OK\r
+  SZ_ERROR_MEM    - Memory allocation error\r
+  SZ_ERROR_PARAM  - Incorrect paramater in props\r
+  SZ_ERROR_WRITE  - Write callback error\r
+  SZ_ERROR_PROGRESS - some break from progress callback\r
+  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)\r
+*/\r
+\r
+typedef void * CLzma2EncHandle;\r
+\r
+CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig);\r
+void Lzma2Enc_Destroy(CLzma2EncHandle p);\r
+SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);\r
+Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);\r
+SRes Lzma2Enc_Encode(CLzma2EncHandle p,\r
+    ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress);\r
+\r
+/* ---------- One Call Interface ---------- */\r
+\r
+/* Lzma2Encode\r
+Return code:\r
+  SZ_OK               - OK\r
+  SZ_ERROR_MEM        - Memory allocation error\r
+  SZ_ERROR_PARAM      - Incorrect paramater\r
+  SZ_ERROR_OUTPUT_EOF - output buffer overflow\r
+  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)\r
+*/\r
+\r
+/*\r
+SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
+    const CLzmaEncProps *props, Byte *propsEncoded, int writeEndMark,\r
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);\r
+*/\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/Lzma86.h b/C/Lzma86.h
new file mode 100755 (executable)
index 0000000..6425bb8
--- /dev/null
@@ -0,0 +1,111 @@
+/* Lzma86.h -- LZMA + x86 (BCJ) Filter\r
+2009-08-14 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZMA86_H\r
+#define __LZMA86_H\r
+\r
+#include "Types.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+#define LZMA86_SIZE_OFFSET (1 + 5)\r
+#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)\r
+\r
+/*\r
+It's an example for LZMA + x86 Filter use.\r
+You can use .lzma86 extension, if you write that stream to file.\r
+.lzma86 header adds one additional byte to standard .lzma header.\r
+.lzma86 header (14 bytes):\r
+  Offset Size  Description\r
+    0     1    = 0 - no filter, pure LZMA\r
+               = 1 - x86 filter + LZMA\r
+    1     1    lc, lp and pb in encoded form\r
+    2     4    dictSize (little endian)\r
+    6     8    uncompressed size (little endian)\r
+\r
+\r
+Lzma86_Encode\r
+-------------\r
+level - compression level: 0 <= level <= 9, the default value for "level" is 5.\r
+\r
+dictSize - The dictionary size in bytes. The maximum value is\r
+        128 MB = (1 << 27) bytes for 32-bit version\r
+          1 GB = (1 << 30) bytes for 64-bit version\r
+     The default value is 16 MB = (1 << 24) bytes, for level = 5.\r
+     It's recommended to use the dictionary that is larger than 4 KB and\r
+     that can be calculated as (1 << N) or (3 << N) sizes.\r
+     For better compression ratio dictSize must be >= inSize.\r
+\r
+filterMode:\r
+    SZ_FILTER_NO   - no Filter\r
+    SZ_FILTER_YES  - x86 Filter\r
+    SZ_FILTER_AUTO - it tries both alternatives to select best.\r
+              Encoder will use 2 or 3 passes:\r
+              2 passes when FILTER_NO provides better compression.\r
+              3 passes when FILTER_YES provides better compression.\r
+\r
+Lzma86Encode allocates Data with MyAlloc functions.\r
+RAM Requirements for compressing:\r
+  RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize\r
+      filterMode     FilterBlockSize\r
+     SZ_FILTER_NO         0\r
+     SZ_FILTER_YES      inSize\r
+     SZ_FILTER_AUTO     inSize\r
+\r
+\r
+Return code:\r
+  SZ_OK               - OK\r
+  SZ_ERROR_MEM        - Memory allocation error\r
+  SZ_ERROR_PARAM      - Incorrect paramater\r
+  SZ_ERROR_OUTPUT_EOF - output buffer overflow\r
+  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)\r
+*/\r
+\r
+enum ESzFilterMode\r
+{\r
+  SZ_FILTER_NO,\r
+  SZ_FILTER_YES,\r
+  SZ_FILTER_AUTO\r
+};\r
+\r
+SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,\r
+    int level, UInt32 dictSize, int filterMode);\r
+\r
+\r
+/*\r
+Lzma86_GetUnpackSize:\r
+  In:\r
+    src      - input data\r
+    srcLen   - input data size\r
+  Out:\r
+    unpackSize - size of uncompressed stream\r
+  Return code:\r
+    SZ_OK               - OK\r
+    SZ_ERROR_INPUT_EOF  - Error in headers\r
+*/\r
+\r
+SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);\r
+\r
+/*\r
+Lzma86_Decode:\r
+  In:\r
+    dest     - output data\r
+    destLen  - output data size\r
+    src      - input data\r
+    srcLen   - input data size\r
+  Out:\r
+    destLen  - processed output size\r
+    srcLen   - processed input size\r
+  Return code:\r
+    SZ_OK           - OK\r
+    SZ_ERROR_DATA  - Data error\r
+    SZ_ERROR_MEM   - Memory allocation error\r
+    SZ_ERROR_UNSUPPORTED - unsupported file\r
+    SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer\r
+*/\r
+\r
+SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/Lzma86Dec.c b/C/Lzma86Dec.c
new file mode 100755 (executable)
index 0000000..760a447
--- /dev/null
@@ -0,0 +1,56 @@
+/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder\r
+2009-08-14 : Igor Pavlov : Public domain */\r
+\r
+#include "Lzma86.h"\r
+\r
+#include "Alloc.h"\r
+#include "Bra.h"\r
+#include "LzmaDec.h"\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
+\r
+SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)\r
+{\r
+  unsigned i;\r
+  if (srcLen < LZMA86_HEADER_SIZE)\r
+    return SZ_ERROR_INPUT_EOF;\r
+  *unpackSize = 0;\r
+  for (i = 0; i < sizeof(UInt64); i++)\r
+    *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i);\r
+  return SZ_OK;\r
+}\r
+\r
+SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)\r
+{\r
+  ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+  SRes res;\r
+  int useFilter;\r
+  SizeT inSizePure;\r
+  ELzmaStatus status;\r
+\r
+  if (*srcLen < LZMA86_HEADER_SIZE)\r
+    return SZ_ERROR_INPUT_EOF;\r
+\r
+  useFilter = src[0];\r
+\r
+  if (useFilter > 1)\r
+  {\r
+    *destLen = 0;\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  }\r
+\r
+  inSizePure = *srcLen - LZMA86_HEADER_SIZE;\r
+  res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure,\r
+      src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc);\r
+  *srcLen = inSizePure + LZMA86_HEADER_SIZE;\r
+  if (res != SZ_OK)\r
+    return res;\r
+  if (useFilter == 1)\r
+  {\r
+    UInt32 x86State;\r
+    x86_Convert_Init(x86State);\r
+    x86_Convert(dest, *destLen, 0, &x86State, 0);\r
+  }\r
+  return SZ_OK;\r
+}\r
diff --git a/C/Lzma86Enc.c b/C/Lzma86Enc.c
new file mode 100755 (executable)
index 0000000..a29c605
--- /dev/null
@@ -0,0 +1,108 @@
+/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder\r
+2009-08-14 : Igor Pavlov : Public domain */\r
+\r
+#include <string.h>\r
+\r
+#include "Lzma86.h"\r
+\r
+#include "Alloc.h"\r
+#include "Bra.h"\r
+#include "LzmaEnc.h"\r
+\r
+#define SZE_OUT_OVERFLOW SZE_DATA_ERROR\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
+\r
+int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,\r
+    int level, UInt32 dictSize, int filterMode)\r
+{\r
+  ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+  size_t outSize2 = *destLen;\r
+  Byte *filteredStream;\r
+  Bool useFilter;\r
+  int mainResult = SZ_ERROR_OUTPUT_EOF;\r
+  CLzmaEncProps props;\r
+  LzmaEncProps_Init(&props);\r
+  props.level = level;\r
+  props.dictSize = dictSize;\r
+  \r
+  *destLen = 0;\r
+  if (outSize2 < LZMA86_HEADER_SIZE)\r
+    return SZ_ERROR_OUTPUT_EOF;\r
+\r
+  {\r
+    int i;\r
+    UInt64 t = srcLen;\r
+    for (i = 0; i < 8; i++, t >>= 8)\r
+      dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;\r
+  }\r
+\r
+  filteredStream = 0;\r
+  useFilter = (filterMode != SZ_FILTER_NO);\r
+  if (useFilter)\r
+  {\r
+    if (srcLen != 0)\r
+    {\r
+      filteredStream = (Byte *)MyAlloc(srcLen);\r
+      if (filteredStream == 0)\r
+        return SZ_ERROR_MEM;\r
+      memcpy(filteredStream, src, srcLen);\r
+    }\r
+    {\r
+      UInt32 x86State;\r
+      x86_Convert_Init(x86State);\r
+      x86_Convert(filteredStream, srcLen, 0, &x86State, 1);\r
+    }\r
+  }\r
+\r
+  {\r
+    size_t minSize = 0;\r
+    Bool bestIsFiltered = False;\r
+\r
+    /* passes for SZ_FILTER_AUTO:\r
+        0 - BCJ + LZMA\r
+        1 - LZMA\r
+        2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.\r
+    */\r
+    int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;\r
+\r
+    int i;\r
+    for (i = 0; i < numPasses; i++)\r
+    {\r
+      size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;\r
+      size_t outPropsSize = 5;\r
+      SRes curRes;\r
+      Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);\r
+      if (curModeIsFiltered && !bestIsFiltered)\r
+        break;\r
+      if (useFilter && i == 0)\r
+        curModeIsFiltered = True;\r
+      \r
+      curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,\r
+          curModeIsFiltered ? filteredStream : src, srcLen,\r
+          &props, dest + 1, &outPropsSize, 0,\r
+          NULL, &g_Alloc, &g_Alloc);\r
+      \r
+      if (curRes != SZ_ERROR_OUTPUT_EOF)\r
+      {\r
+        if (curRes != SZ_OK)\r
+        {\r
+          mainResult = curRes;\r
+          break;\r
+        }\r
+        if (outSizeProcessed <= minSize || mainResult != SZ_OK)\r
+        {\r
+          minSize = outSizeProcessed;\r
+          bestIsFiltered = curModeIsFiltered;\r
+          mainResult = SZ_OK;\r
+        }\r
+      }\r
+    }\r
+    dest[0] = (bestIsFiltered ? 1 : 0);\r
+    *destLen = LZMA86_HEADER_SIZE + minSize;\r
+  }\r
+  if (useFilter)\r
+    MyFree(filteredStream);\r
+  return mainResult;\r
+}\r
diff --git a/C/LzmaDec.c b/C/LzmaDec.c
new file mode 100755 (executable)
index 0000000..4fdc11d
--- /dev/null
@@ -0,0 +1,999 @@
+/* LzmaDec.c -- LZMA Decoder\r
+2009-09-20 : Igor Pavlov : Public domain */\r
+\r
+#include "LzmaDec.h"\r
+\r
+#include <string.h>\r
+\r
+#define kNumTopBits 24\r
+#define kTopValue ((UInt32)1 << kNumTopBits)\r
+\r
+#define kNumBitModelTotalBits 11\r
+#define kBitModelTotal (1 << kNumBitModelTotalBits)\r
+#define kNumMoveBits 5\r
+\r
+#define RC_INIT_SIZE 5\r
+\r
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }\r
+\r
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)\r
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));\r
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));\r
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \\r
+  { UPDATE_0(p); i = (i + i); A0; } else \\r
+  { UPDATE_1(p); i = (i + i) + 1; A1; }\r
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)\r
+\r
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }\r
+#define TREE_DECODE(probs, limit, i) \\r
+  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }\r
+\r
+/* #define _LZMA_SIZE_OPT */\r
+\r
+#ifdef _LZMA_SIZE_OPT\r
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)\r
+#else\r
+#define TREE_6_DECODE(probs, i) \\r
+  { i = 1; \\r
+  TREE_GET_BIT(probs, i); \\r
+  TREE_GET_BIT(probs, i); \\r
+  TREE_GET_BIT(probs, i); \\r
+  TREE_GET_BIT(probs, i); \\r
+  TREE_GET_BIT(probs, i); \\r
+  TREE_GET_BIT(probs, i); \\r
+  i -= 0x40; }\r
+#endif\r
+\r
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }\r
+\r
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)\r
+#define UPDATE_0_CHECK range = bound;\r
+#define UPDATE_1_CHECK range -= bound; code -= bound;\r
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \\r
+  { UPDATE_0_CHECK; i = (i + i); A0; } else \\r
+  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }\r
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)\r
+#define TREE_DECODE_CHECK(probs, limit, i) \\r
+  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }\r
+\r
+\r
+#define kNumPosBitsMax 4\r
+#define kNumPosStatesMax (1 << kNumPosBitsMax)\r
+\r
+#define kLenNumLowBits 3\r
+#define kLenNumLowSymbols (1 << kLenNumLowBits)\r
+#define kLenNumMidBits 3\r
+#define kLenNumMidSymbols (1 << kLenNumMidBits)\r
+#define kLenNumHighBits 8\r
+#define kLenNumHighSymbols (1 << kLenNumHighBits)\r
+\r
+#define LenChoice 0\r
+#define LenChoice2 (LenChoice + 1)\r
+#define LenLow (LenChoice2 + 1)\r
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))\r
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))\r
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)\r
+\r
+\r
+#define kNumStates 12\r
+#define kNumLitStates 7\r
+\r
+#define kStartPosModelIndex 4\r
+#define kEndPosModelIndex 14\r
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))\r
+\r
+#define kNumPosSlotBits 6\r
+#define kNumLenToPosStates 4\r
+\r
+#define kNumAlignBits 4\r
+#define kAlignTableSize (1 << kNumAlignBits)\r
+\r
+#define kMatchMinLen 2\r
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)\r
+\r
+#define IsMatch 0\r
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))\r
+#define IsRepG0 (IsRep + kNumStates)\r
+#define IsRepG1 (IsRepG0 + kNumStates)\r
+#define IsRepG2 (IsRepG1 + kNumStates)\r
+#define IsRep0Long (IsRepG2 + kNumStates)\r
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))\r
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))\r
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)\r
+#define LenCoder (Align + kAlignTableSize)\r
+#define RepLenCoder (LenCoder + kNumLenProbs)\r
+#define Literal (RepLenCoder + kNumLenProbs)\r
+\r
+#define LZMA_BASE_SIZE 1846\r
+#define LZMA_LIT_SIZE 768\r
+\r
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
+\r
+#if Literal != LZMA_BASE_SIZE\r
+StopCompilingDueBUG\r
+#endif\r
+\r
+#define LZMA_DIC_MIN (1 << 12)\r
+\r
+/* First LZMA-symbol is always decoded.\r
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization\r
+Out:\r
+  Result:\r
+    SZ_OK - OK\r
+    SZ_ERROR_DATA - Error\r
+  p->remainLen:\r
+    < kMatchSpecLenStart : normal remain\r
+    = kMatchSpecLenStart : finished\r
+    = kMatchSpecLenStart + 1 : Flush marker\r
+    = kMatchSpecLenStart + 2 : State Init Marker\r
+*/\r
+\r
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
+{\r
+  CLzmaProb *probs = p->probs;\r
+\r
+  unsigned state = p->state;\r
+  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];\r
+  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;\r
+  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;\r
+  unsigned lc = p->prop.lc;\r
+\r
+  Byte *dic = p->dic;\r
+  SizeT dicBufSize = p->dicBufSize;\r
+  SizeT dicPos = p->dicPos;\r
+  \r
+  UInt32 processedPos = p->processedPos;\r
+  UInt32 checkDicSize = p->checkDicSize;\r
+  unsigned len = 0;\r
+\r
+  const Byte *buf = p->buf;\r
+  UInt32 range = p->range;\r
+  UInt32 code = p->code;\r
+\r
+  do\r
+  {\r
+    CLzmaProb *prob;\r
+    UInt32 bound;\r
+    unsigned ttt;\r
+    unsigned posState = processedPos & pbMask;\r
+\r
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;\r
+    IF_BIT_0(prob)\r
+    {\r
+      unsigned symbol;\r
+      UPDATE_0(prob);\r
+      prob = probs + Literal;\r
+      if (checkDicSize != 0 || processedPos != 0)\r
+        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +\r
+        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));\r
+\r
+      if (state < kNumLitStates)\r
+      {\r
+        state -= (state < 4) ? state : 3;\r
+        symbol = 1;\r
+        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);\r
+      }\r
+      else\r
+      {\r
+        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+        unsigned offs = 0x100;\r
+        state -= (state < 10) ? 3 : 6;\r
+        symbol = 1;\r
+        do\r
+        {\r
+          unsigned bit;\r
+          CLzmaProb *probLit;\r
+          matchByte <<= 1;\r
+          bit = (matchByte & offs);\r
+          probLit = prob + offs + bit + symbol;\r
+          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)\r
+        }\r
+        while (symbol < 0x100);\r
+      }\r
+      dic[dicPos++] = (Byte)symbol;\r
+      processedPos++;\r
+      continue;\r
+    }\r
+    else\r
+    {\r
+      UPDATE_1(prob);\r
+      prob = probs + IsRep + state;\r
+      IF_BIT_0(prob)\r
+      {\r
+        UPDATE_0(prob);\r
+        state += kNumStates;\r
+        prob = probs + LenCoder;\r
+      }\r
+      else\r
+      {\r
+        UPDATE_1(prob);\r
+        if (checkDicSize == 0 && processedPos == 0)\r
+          return SZ_ERROR_DATA;\r
+        prob = probs + IsRepG0 + state;\r
+        IF_BIT_0(prob)\r
+        {\r
+          UPDATE_0(prob);\r
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;\r
+          IF_BIT_0(prob)\r
+          {\r
+            UPDATE_0(prob);\r
+            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+            dicPos++;\r
+            processedPos++;\r
+            state = state < kNumLitStates ? 9 : 11;\r
+            continue;\r
+          }\r
+          UPDATE_1(prob);\r
+        }\r
+        else\r
+        {\r
+          UInt32 distance;\r
+          UPDATE_1(prob);\r
+          prob = probs + IsRepG1 + state;\r
+          IF_BIT_0(prob)\r
+          {\r
+            UPDATE_0(prob);\r
+            distance = rep1;\r
+          }\r
+          else\r
+          {\r
+            UPDATE_1(prob);\r
+            prob = probs + IsRepG2 + state;\r
+            IF_BIT_0(prob)\r
+            {\r
+              UPDATE_0(prob);\r
+              distance = rep2;\r
+            }\r
+            else\r
+            {\r
+              UPDATE_1(prob);\r
+              distance = rep3;\r
+              rep3 = rep2;\r
+            }\r
+            rep2 = rep1;\r
+          }\r
+          rep1 = rep0;\r
+          rep0 = distance;\r
+        }\r
+        state = state < kNumLitStates ? 8 : 11;\r
+        prob = probs + RepLenCoder;\r
+      }\r
+      {\r
+        unsigned limit, offset;\r
+        CLzmaProb *probLen = prob + LenChoice;\r
+        IF_BIT_0(probLen)\r
+        {\r
+          UPDATE_0(probLen);\r
+          probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+          offset = 0;\r
+          limit = (1 << kLenNumLowBits);\r
+        }\r
+        else\r
+        {\r
+          UPDATE_1(probLen);\r
+          probLen = prob + LenChoice2;\r
+          IF_BIT_0(probLen)\r
+          {\r
+            UPDATE_0(probLen);\r
+            probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+            offset = kLenNumLowSymbols;\r
+            limit = (1 << kLenNumMidBits);\r
+          }\r
+          else\r
+          {\r
+            UPDATE_1(probLen);\r
+            probLen = prob + LenHigh;\r
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;\r
+            limit = (1 << kLenNumHighBits);\r
+          }\r
+        }\r
+        TREE_DECODE(probLen, limit, len);\r
+        len += offset;\r
+      }\r
+\r
+      if (state >= kNumStates)\r
+      {\r
+        UInt32 distance;\r
+        prob = probs + PosSlot +\r
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);\r
+        TREE_6_DECODE(prob, distance);\r
+        if (distance >= kStartPosModelIndex)\r
+        {\r
+          unsigned posSlot = (unsigned)distance;\r
+          int numDirectBits = (int)(((distance >> 1) - 1));\r
+          distance = (2 | (distance & 1));\r
+          if (posSlot < kEndPosModelIndex)\r
+          {\r
+            distance <<= numDirectBits;\r
+            prob = probs + SpecPos + distance - posSlot - 1;\r
+            {\r
+              UInt32 mask = 1;\r
+              unsigned i = 1;\r
+              do\r
+              {\r
+                GET_BIT2(prob + i, i, ; , distance |= mask);\r
+                mask <<= 1;\r
+              }\r
+              while (--numDirectBits != 0);\r
+            }\r
+          }\r
+          else\r
+          {\r
+            numDirectBits -= kNumAlignBits;\r
+            do\r
+            {\r
+              NORMALIZE\r
+              range >>= 1;\r
+              \r
+              {\r
+                UInt32 t;\r
+                code -= range;\r
+                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */\r
+                distance = (distance << 1) + (t + 1);\r
+                code += range & t;\r
+              }\r
+              /*\r
+              distance <<= 1;\r
+              if (code >= range)\r
+              {\r
+                code -= range;\r
+                distance |= 1;\r
+              }\r
+              */\r
+            }\r
+            while (--numDirectBits != 0);\r
+            prob = probs + Align;\r
+            distance <<= kNumAlignBits;\r
+            {\r
+              unsigned i = 1;\r
+              GET_BIT2(prob + i, i, ; , distance |= 1);\r
+              GET_BIT2(prob + i, i, ; , distance |= 2);\r
+              GET_BIT2(prob + i, i, ; , distance |= 4);\r
+              GET_BIT2(prob + i, i, ; , distance |= 8);\r
+            }\r
+            if (distance == (UInt32)0xFFFFFFFF)\r
+            {\r
+              len += kMatchSpecLenStart;\r
+              state -= kNumStates;\r
+              break;\r
+            }\r
+          }\r
+        }\r
+        rep3 = rep2;\r
+        rep2 = rep1;\r
+        rep1 = rep0;\r
+        rep0 = distance + 1;\r
+        if (checkDicSize == 0)\r
+        {\r
+          if (distance >= processedPos)\r
+            return SZ_ERROR_DATA;\r
+        }\r
+        else if (distance >= checkDicSize)\r
+          return SZ_ERROR_DATA;\r
+        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;\r
+      }\r
+\r
+      len += kMatchMinLen;\r
+\r
+      if (limit == dicPos)\r
+        return SZ_ERROR_DATA;\r
+      {\r
+        SizeT rem = limit - dicPos;\r
+        unsigned curLen = ((rem < len) ? (unsigned)rem : len);\r
+        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);\r
+\r
+        processedPos += curLen;\r
+\r
+        len -= curLen;\r
+        if (pos + curLen <= dicBufSize)\r
+        {\r
+          Byte *dest = dic + dicPos;\r
+          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;\r
+          const Byte *lim = dest + curLen;\r
+          dicPos += curLen;\r
+          do\r
+            *(dest) = (Byte)*(dest + src);\r
+          while (++dest != lim);\r
+        }\r
+        else\r
+        {\r
+          do\r
+          {\r
+            dic[dicPos++] = dic[pos];\r
+            if (++pos == dicBufSize)\r
+              pos = 0;\r
+          }\r
+          while (--curLen != 0);\r
+        }\r
+      }\r
+    }\r
+  }\r
+  while (dicPos < limit && buf < bufLimit);\r
+  NORMALIZE;\r
+  p->buf = buf;\r
+  p->range = range;\r
+  p->code = code;\r
+  p->remainLen = len;\r
+  p->dicPos = dicPos;\r
+  p->processedPos = processedPos;\r
+  p->reps[0] = rep0;\r
+  p->reps[1] = rep1;\r
+  p->reps[2] = rep2;\r
+  p->reps[3] = rep3;\r
+  p->state = state;\r
+\r
+  return SZ_OK;\r
+}\r
+\r
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)\r
+{\r
+  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)\r
+  {\r
+    Byte *dic = p->dic;\r
+    SizeT dicPos = p->dicPos;\r
+    SizeT dicBufSize = p->dicBufSize;\r
+    unsigned len = p->remainLen;\r
+    UInt32 rep0 = p->reps[0];\r
+    if (limit - dicPos < len)\r
+      len = (unsigned)(limit - dicPos);\r
+\r
+    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)\r
+      p->checkDicSize = p->prop.dicSize;\r
+\r
+    p->processedPos += len;\r
+    p->remainLen -= len;\r
+    while (len-- != 0)\r
+    {\r
+      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+      dicPos++;\r
+    }\r
+    p->dicPos = dicPos;\r
+  }\r
+}\r
+\r
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
+{\r
+  do\r
+  {\r
+    SizeT limit2 = limit;\r
+    if (p->checkDicSize == 0)\r
+    {\r
+      UInt32 rem = p->prop.dicSize - p->processedPos;\r
+      if (limit - p->dicPos > rem)\r
+        limit2 = p->dicPos + rem;\r
+    }\r
+    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));\r
+    if (p->processedPos >= p->prop.dicSize)\r
+      p->checkDicSize = p->prop.dicSize;\r
+    LzmaDec_WriteRem(p, limit);\r
+  }\r
+  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);\r
+\r
+  if (p->remainLen > kMatchSpecLenStart)\r
+  {\r
+    p->remainLen = kMatchSpecLenStart;\r
+  }\r
+  return 0;\r
+}\r
+\r
+typedef enum\r
+{\r
+  DUMMY_ERROR, /* unexpected end of input stream */\r
+  DUMMY_LIT,\r
+  DUMMY_MATCH,\r
+  DUMMY_REP\r
+} ELzmaDummy;\r
+\r
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)\r
+{\r
+  UInt32 range = p->range;\r
+  UInt32 code = p->code;\r
+  const Byte *bufLimit = buf + inSize;\r
+  CLzmaProb *probs = p->probs;\r
+  unsigned state = p->state;\r
+  ELzmaDummy res;\r
+\r
+  {\r
+    CLzmaProb *prob;\r
+    UInt32 bound;\r
+    unsigned ttt;\r
+    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);\r
+\r
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;\r
+    IF_BIT_0_CHECK(prob)\r
+    {\r
+      UPDATE_0_CHECK\r
+\r
+      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */\r
+\r
+      prob = probs + Literal;\r
+      if (p->checkDicSize != 0 || p->processedPos != 0)\r
+        prob += (LZMA_LIT_SIZE *\r
+          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +\r
+          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));\r
+\r
+      if (state < kNumLitStates)\r
+      {\r
+        unsigned symbol = 1;\r
+        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);\r
+      }\r
+      else\r
+      {\r
+        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +\r
+            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];\r
+        unsigned offs = 0x100;\r
+        unsigned symbol = 1;\r
+        do\r
+        {\r
+          unsigned bit;\r
+          CLzmaProb *probLit;\r
+          matchByte <<= 1;\r
+          bit = (matchByte & offs);\r
+          probLit = prob + offs + bit + symbol;\r
+          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)\r
+        }\r
+        while (symbol < 0x100);\r
+      }\r
+      res = DUMMY_LIT;\r
+    }\r
+    else\r
+    {\r
+      unsigned len;\r
+      UPDATE_1_CHECK;\r
+\r
+      prob = probs + IsRep + state;\r
+      IF_BIT_0_CHECK(prob)\r
+      {\r
+        UPDATE_0_CHECK;\r
+        state = 0;\r
+        prob = probs + LenCoder;\r
+        res = DUMMY_MATCH;\r
+      }\r
+      else\r
+      {\r
+        UPDATE_1_CHECK;\r
+        res = DUMMY_REP;\r
+        prob = probs + IsRepG0 + state;\r
+        IF_BIT_0_CHECK(prob)\r
+        {\r
+          UPDATE_0_CHECK;\r
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;\r
+          IF_BIT_0_CHECK(prob)\r
+          {\r
+            UPDATE_0_CHECK;\r
+            NORMALIZE_CHECK;\r
+            return DUMMY_REP;\r
+          }\r
+          else\r
+          {\r
+            UPDATE_1_CHECK;\r
+          }\r
+        }\r
+        else\r
+        {\r
+          UPDATE_1_CHECK;\r
+          prob = probs + IsRepG1 + state;\r
+          IF_BIT_0_CHECK(prob)\r
+          {\r
+            UPDATE_0_CHECK;\r
+          }\r
+          else\r
+          {\r
+            UPDATE_1_CHECK;\r
+            prob = probs + IsRepG2 + state;\r
+            IF_BIT_0_CHECK(prob)\r
+            {\r
+              UPDATE_0_CHECK;\r
+            }\r
+            else\r
+            {\r
+              UPDATE_1_CHECK;\r
+            }\r
+          }\r
+        }\r
+        state = kNumStates;\r
+        prob = probs + RepLenCoder;\r
+      }\r
+      {\r
+        unsigned limit, offset;\r
+        CLzmaProb *probLen = prob + LenChoice;\r
+        IF_BIT_0_CHECK(probLen)\r
+        {\r
+          UPDATE_0_CHECK;\r
+          probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+          offset = 0;\r
+          limit = 1 << kLenNumLowBits;\r
+        }\r
+        else\r
+        {\r
+          UPDATE_1_CHECK;\r
+          probLen = prob + LenChoice2;\r
+          IF_BIT_0_CHECK(probLen)\r
+          {\r
+            UPDATE_0_CHECK;\r
+            probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+            offset = kLenNumLowSymbols;\r
+            limit = 1 << kLenNumMidBits;\r
+          }\r
+          else\r
+          {\r
+            UPDATE_1_CHECK;\r
+            probLen = prob + LenHigh;\r
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;\r
+            limit = 1 << kLenNumHighBits;\r
+          }\r
+        }\r
+        TREE_DECODE_CHECK(probLen, limit, len);\r
+        len += offset;\r
+      }\r
+\r
+      if (state < 4)\r
+      {\r
+        unsigned posSlot;\r
+        prob = probs + PosSlot +\r
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<\r
+            kNumPosSlotBits);\r
+        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);\r
+        if (posSlot >= kStartPosModelIndex)\r
+        {\r
+          int numDirectBits = ((posSlot >> 1) - 1);\r
+\r
+          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */\r
+\r
+          if (posSlot < kEndPosModelIndex)\r
+          {\r
+            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;\r
+          }\r
+          else\r
+          {\r
+            numDirectBits -= kNumAlignBits;\r
+            do\r
+            {\r
+              NORMALIZE_CHECK\r
+              range >>= 1;\r
+              code -= range & (((code - range) >> 31) - 1);\r
+              /* if (code >= range) code -= range; */\r
+            }\r
+            while (--numDirectBits != 0);\r
+            prob = probs + Align;\r
+            numDirectBits = kNumAlignBits;\r
+          }\r
+          {\r
+            unsigned i = 1;\r
+            do\r
+            {\r
+              GET_BIT_CHECK(prob + i, i);\r
+            }\r
+            while (--numDirectBits != 0);\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+  NORMALIZE_CHECK;\r
+  return res;\r
+}\r
+\r
+\r
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)\r
+{\r
+  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);\r
+  p->range = 0xFFFFFFFF;\r
+  p->needFlush = 0;\r
+}\r
+\r
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)\r
+{\r
+  p->needFlush = 1;\r
+  p->remainLen = 0;\r
+  p->tempBufSize = 0;\r
+\r
+  if (initDic)\r
+  {\r
+    p->processedPos = 0;\r
+    p->checkDicSize = 0;\r
+    p->needInitState = 1;\r
+  }\r
+  if (initState)\r
+    p->needInitState = 1;\r
+}\r
+\r
+void LzmaDec_Init(CLzmaDec *p)\r
+{\r
+  p->dicPos = 0;\r
+  LzmaDec_InitDicAndState(p, True, True);\r
+}\r
+\r
+static void LzmaDec_InitStateReal(CLzmaDec *p)\r
+{\r
+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));\r
+  UInt32 i;\r
+  CLzmaProb *probs = p->probs;\r
+  for (i = 0; i < numProbs; i++)\r
+    probs[i] = kBitModelTotal >> 1;\r
+  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;\r
+  p->state = 0;\r
+  p->needInitState = 0;\r
+}\r
+\r
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,\r
+    ELzmaFinishMode finishMode, ELzmaStatus *status)\r
+{\r
+  SizeT inSize = *srcLen;\r
+  (*srcLen) = 0;\r
+  LzmaDec_WriteRem(p, dicLimit);\r
+  \r
+  *status = LZMA_STATUS_NOT_SPECIFIED;\r
+\r
+  while (p->remainLen != kMatchSpecLenStart)\r
+  {\r
+      int checkEndMarkNow;\r
+\r
+      if (p->needFlush != 0)\r
+      {\r
+        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)\r
+          p->tempBuf[p->tempBufSize++] = *src++;\r
+        if (p->tempBufSize < RC_INIT_SIZE)\r
+        {\r
+          *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+          return SZ_OK;\r
+        }\r
+        if (p->tempBuf[0] != 0)\r
+          return SZ_ERROR_DATA;\r
+\r
+        LzmaDec_InitRc(p, p->tempBuf);\r
+        p->tempBufSize = 0;\r
+      }\r
+\r
+      checkEndMarkNow = 0;\r
+      if (p->dicPos >= dicLimit)\r
+      {\r
+        if (p->remainLen == 0 && p->code == 0)\r
+        {\r
+          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;\r
+          return SZ_OK;\r
+        }\r
+        if (finishMode == LZMA_FINISH_ANY)\r
+        {\r
+          *status = LZMA_STATUS_NOT_FINISHED;\r
+          return SZ_OK;\r
+        }\r
+        if (p->remainLen != 0)\r
+        {\r
+          *status = LZMA_STATUS_NOT_FINISHED;\r
+          return SZ_ERROR_DATA;\r
+        }\r
+        checkEndMarkNow = 1;\r
+      }\r
+\r
+      if (p->needInitState)\r
+        LzmaDec_InitStateReal(p);\r
+  \r
+      if (p->tempBufSize == 0)\r
+      {\r
+        SizeT processed;\r
+        const Byte *bufLimit;\r
+        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)\r
+        {\r
+          int dummyRes = LzmaDec_TryDummy(p, src, inSize);\r
+          if (dummyRes == DUMMY_ERROR)\r
+          {\r
+            memcpy(p->tempBuf, src, inSize);\r
+            p->tempBufSize = (unsigned)inSize;\r
+            (*srcLen) += inSize;\r
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+            return SZ_OK;\r
+          }\r
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)\r
+          {\r
+            *status = LZMA_STATUS_NOT_FINISHED;\r
+            return SZ_ERROR_DATA;\r
+          }\r
+          bufLimit = src;\r
+        }\r
+        else\r
+          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;\r
+        p->buf = src;\r
+        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)\r
+          return SZ_ERROR_DATA;\r
+        processed = (SizeT)(p->buf - src);\r
+        (*srcLen) += processed;\r
+        src += processed;\r
+        inSize -= processed;\r
+      }\r
+      else\r
+      {\r
+        unsigned rem = p->tempBufSize, lookAhead = 0;\r
+        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)\r
+          p->tempBuf[rem++] = src[lookAhead++];\r
+        p->tempBufSize = rem;\r
+        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)\r
+        {\r
+          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);\r
+          if (dummyRes == DUMMY_ERROR)\r
+          {\r
+            (*srcLen) += lookAhead;\r
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+            return SZ_OK;\r
+          }\r
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)\r
+          {\r
+            *status = LZMA_STATUS_NOT_FINISHED;\r
+            return SZ_ERROR_DATA;\r
+          }\r
+        }\r
+        p->buf = p->tempBuf;\r
+        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)\r
+          return SZ_ERROR_DATA;\r
+        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));\r
+        (*srcLen) += lookAhead;\r
+        src += lookAhead;\r
+        inSize -= lookAhead;\r
+        p->tempBufSize = 0;\r
+      }\r
+  }\r
+  if (p->code == 0)\r
+    *status = LZMA_STATUS_FINISHED_WITH_MARK;\r
+  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;\r
+}\r
+\r
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)\r
+{\r
+  SizeT outSize = *destLen;\r
+  SizeT inSize = *srcLen;\r
+  *srcLen = *destLen = 0;\r
+  for (;;)\r
+  {\r
+    SizeT inSizeCur = inSize, outSizeCur, dicPos;\r
+    ELzmaFinishMode curFinishMode;\r
+    SRes res;\r
+    if (p->dicPos == p->dicBufSize)\r
+      p->dicPos = 0;\r
+    dicPos = p->dicPos;\r
+    if (outSize > p->dicBufSize - dicPos)\r
+    {\r
+      outSizeCur = p->dicBufSize;\r
+      curFinishMode = LZMA_FINISH_ANY;\r
+    }\r
+    else\r
+    {\r
+      outSizeCur = dicPos + outSize;\r
+      curFinishMode = finishMode;\r
+    }\r
+\r
+    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);\r
+    src += inSizeCur;\r
+    inSize -= inSizeCur;\r
+    *srcLen += inSizeCur;\r
+    outSizeCur = p->dicPos - dicPos;\r
+    memcpy(dest, p->dic + dicPos, outSizeCur);\r
+    dest += outSizeCur;\r
+    outSize -= outSizeCur;\r
+    *destLen += outSizeCur;\r
+    if (res != 0)\r
+      return res;\r
+    if (outSizeCur == 0 || outSize == 0)\r
+      return SZ_OK;\r
+  }\r
+}\r
+\r
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->probs);\r
+  p->probs = 0;\r
+}\r
+\r
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->dic);\r
+  p->dic = 0;\r
+}\r
+\r
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)\r
+{\r
+  LzmaDec_FreeProbs(p, alloc);\r
+  LzmaDec_FreeDict(p, alloc);\r
+}\r
+\r
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)\r
+{\r
+  UInt32 dicSize;\r
+  Byte d;\r
+  \r
+  if (size < LZMA_PROPS_SIZE)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  else\r
+    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);\r
\r
+  if (dicSize < LZMA_DIC_MIN)\r
+    dicSize = LZMA_DIC_MIN;\r
+  p->dicSize = dicSize;\r
+\r
+  d = data[0];\r
+  if (d >= (9 * 5 * 5))\r
+    return SZ_ERROR_UNSUPPORTED;\r
+\r
+  p->lc = d % 9;\r
+  d /= 9;\r
+  p->pb = d / 5;\r
+  p->lp = d % 5;\r
+\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)\r
+{\r
+  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);\r
+  if (p->probs == 0 || numProbs != p->numProbs)\r
+  {\r
+    LzmaDec_FreeProbs(p, alloc);\r
+    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));\r
+    p->numProbs = numProbs;\r
+    if (p->probs == 0)\r
+      return SZ_ERROR_MEM;\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)\r
+{\r
+  CLzmaProps propNew;\r
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));\r
+  p->prop = propNew;\r
+  return SZ_OK;\r
+}\r
+\r
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)\r
+{\r
+  CLzmaProps propNew;\r
+  SizeT dicBufSize;\r
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));\r
+  dicBufSize = propNew.dicSize;\r
+  if (p->dic == 0 || dicBufSize != p->dicBufSize)\r
+  {\r
+    LzmaDec_FreeDict(p, alloc);\r
+    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);\r
+    if (p->dic == 0)\r
+    {\r
+      LzmaDec_FreeProbs(p, alloc);\r
+      return SZ_ERROR_MEM;\r
+    }\r
+  }\r
+  p->dicBufSize = dicBufSize;\r
+  p->prop = propNew;\r
+  return SZ_OK;\r
+}\r
+\r
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,\r
+    ELzmaStatus *status, ISzAlloc *alloc)\r
+{\r
+  CLzmaDec p;\r
+  SRes res;\r
+  SizeT inSize = *srcLen;\r
+  SizeT outSize = *destLen;\r
+  *srcLen = *destLen = 0;\r
+  if (inSize < RC_INIT_SIZE)\r
+    return SZ_ERROR_INPUT_EOF;\r
+\r
+  LzmaDec_Construct(&p);\r
+  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);\r
+  if (res != 0)\r
+    return res;\r
+  p.dic = dest;\r
+  p.dicBufSize = outSize;\r
+\r
+  LzmaDec_Init(&p);\r
+  \r
+  *srcLen = inSize;\r
+  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);\r
+\r
+  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)\r
+    res = SZ_ERROR_INPUT_EOF;\r
+\r
+  (*destLen) = p.dicPos;\r
+  LzmaDec_FreeProbs(&p, alloc);\r
+  return res;\r
+}\r
diff --git a/C/LzmaDec.h b/C/LzmaDec.h
new file mode 100755 (executable)
index 0000000..6741a64
--- /dev/null
@@ -0,0 +1,231 @@
+/* LzmaDec.h -- LZMA Decoder\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZMA_DEC_H\r
+#define __LZMA_DEC_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/* #define _LZMA_PROB32 */\r
+/* _LZMA_PROB32 can increase the speed on some CPUs,\r
+   but memory usage for CLzmaDec::probs will be doubled in that case */\r
+\r
+#ifdef _LZMA_PROB32\r
+#define CLzmaProb UInt32\r
+#else\r
+#define CLzmaProb UInt16\r
+#endif\r
+\r
+\r
+/* ---------- LZMA Properties ---------- */\r
+\r
+#define LZMA_PROPS_SIZE 5\r
+\r
+typedef struct _CLzmaProps\r
+{\r
+  unsigned lc, lp, pb;\r
+  UInt32 dicSize;\r
+} CLzmaProps;\r
+\r
+/* LzmaProps_Decode - decodes properties\r
+Returns:\r
+  SZ_OK\r
+  SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+*/\r
+\r
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);\r
+\r
+\r
+/* ---------- LZMA Decoder state ---------- */\r
+\r
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.\r
+   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */\r
+\r
+#define LZMA_REQUIRED_INPUT_MAX 20\r
+\r
+typedef struct\r
+{\r
+  CLzmaProps prop;\r
+  CLzmaProb *probs;\r
+  Byte *dic;\r
+  const Byte *buf;\r
+  UInt32 range, code;\r
+  SizeT dicPos;\r
+  SizeT dicBufSize;\r
+  UInt32 processedPos;\r
+  UInt32 checkDicSize;\r
+  unsigned state;\r
+  UInt32 reps[4];\r
+  unsigned remainLen;\r
+  int needFlush;\r
+  int needInitState;\r
+  UInt32 numProbs;\r
+  unsigned tempBufSize;\r
+  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];\r
+} CLzmaDec;\r
+\r
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }\r
+\r
+void LzmaDec_Init(CLzmaDec *p);\r
+\r
+/* There are two types of LZMA streams:\r
+     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.\r
+     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */\r
+\r
+typedef enum\r
+{\r
+  LZMA_FINISH_ANY,   /* finish at any point */\r
+  LZMA_FINISH_END    /* block must be finished at the end */\r
+} ELzmaFinishMode;\r
+\r
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!\r
+\r
+   You must use LZMA_FINISH_END, when you know that current output buffer\r
+   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.\r
+\r
+   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,\r
+   and output value of destLen will be less than output buffer size limit.\r
+   You can check status result also.\r
+\r
+   You can use multiple checks to test data integrity after full decompression:\r
+     1) Check Result and "status" variable.\r
+     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.\r
+     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.\r
+        You must use correct finish mode in that case. */\r
+\r
+typedef enum\r
+{\r
+  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */\r
+  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */\r
+  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */\r
+  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */\r
+  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */\r
+} ELzmaStatus;\r
+\r
+/* ELzmaStatus is used only as output value for function call */\r
+\r
+\r
+/* ---------- Interfaces ---------- */\r
+\r
+/* There are 3 levels of interfaces:\r
+     1) Dictionary Interface\r
+     2) Buffer Interface\r
+     3) One Call Interface\r
+   You can select any of these interfaces, but don't mix functions from different\r
+   groups for same object. */\r
+\r
+\r
+/* There are two variants to allocate state for Dictionary Interface:\r
+     1) LzmaDec_Allocate / LzmaDec_Free\r
+     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs\r
+   You can use variant 2, if you set dictionary buffer manually.\r
+   For Buffer Interface you must always use variant 1.\r
+\r
+LzmaDec_Allocate* can return:\r
+  SZ_OK\r
+  SZ_ERROR_MEM         - Memory allocation error\r
+  SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+*/\r
+   \r
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);\r
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);\r
+\r
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);\r
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);\r
+\r
+/* ---------- Dictionary Interface ---------- */\r
+\r
+/* You can use it, if you want to eliminate the overhead for data copying from\r
+   dictionary to some other external buffer.\r
+   You must work with CLzmaDec variables directly in this interface.\r
+\r
+   STEPS:\r
+     LzmaDec_Constr()\r
+     LzmaDec_Allocate()\r
+     for (each new stream)\r
+     {\r
+       LzmaDec_Init()\r
+       while (it needs more decompression)\r
+       {\r
+         LzmaDec_DecodeToDic()\r
+         use data from CLzmaDec::dic and update CLzmaDec::dicPos\r
+       }\r
+     }\r
+     LzmaDec_Free()\r
+*/\r
+\r
+/* LzmaDec_DecodeToDic\r
+   \r
+   The decoding to internal dictionary buffer (CLzmaDec::dic).\r
+   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!\r
+\r
+finishMode:\r
+  It has meaning only if the decoding reaches output limit (dicLimit).\r
+  LZMA_FINISH_ANY - Decode just dicLimit bytes.\r
+  LZMA_FINISH_END - Stream must be finished after dicLimit.\r
+\r
+Returns:\r
+  SZ_OK\r
+    status:\r
+      LZMA_STATUS_FINISHED_WITH_MARK\r
+      LZMA_STATUS_NOT_FINISHED\r
+      LZMA_STATUS_NEEDS_MORE_INPUT\r
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK\r
+  SZ_ERROR_DATA - Data error\r
+*/\r
+\r
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,\r
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);\r
+\r
+\r
+/* ---------- Buffer Interface ---------- */\r
+\r
+/* It's zlib-like interface.\r
+   See LzmaDec_DecodeToDic description for information about STEPS and return results,\r
+   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need\r
+   to work with CLzmaDec variables manually.\r
+\r
+finishMode:\r
+  It has meaning only if the decoding reaches output limit (*destLen).\r
+  LZMA_FINISH_ANY - Decode just destLen bytes.\r
+  LZMA_FINISH_END - Stream must be finished after (*destLen).\r
+*/\r
+\r
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,\r
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);\r
+\r
+\r
+/* ---------- One Call Interface ---------- */\r
+\r
+/* LzmaDecode\r
+\r
+finishMode:\r
+  It has meaning only if the decoding reaches output limit (*destLen).\r
+  LZMA_FINISH_ANY - Decode just destLen bytes.\r
+  LZMA_FINISH_END - Stream must be finished after (*destLen).\r
+\r
+Returns:\r
+  SZ_OK\r
+    status:\r
+      LZMA_STATUS_FINISHED_WITH_MARK\r
+      LZMA_STATUS_NOT_FINISHED\r
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK\r
+  SZ_ERROR_DATA - Data error\r
+  SZ_ERROR_MEM  - Memory allocation error\r
+  SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).\r
+*/\r
+\r
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,\r
+    ELzmaStatus *status, ISzAlloc *alloc);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c
new file mode 100755 (executable)
index 0000000..9e6dbdb
--- /dev/null
@@ -0,0 +1,2268 @@
+/* LzmaEnc.c -- LZMA Encoder\r
+2010-04-16 : Igor Pavlov : Public domain */\r
+\r
+#include <string.h>\r
+\r
+/* #define SHOW_STAT */\r
+/* #define SHOW_STAT2 */\r
+\r
+#if defined(SHOW_STAT) || defined(SHOW_STAT2)\r
+#include <stdio.h>\r
+#endif\r
+\r
+#include "LzmaEnc.h"\r
+\r
+#include "LzFind.h"\r
+#ifndef _7ZIP_ST\r
+#include "LzFindMt.h"\r
+#endif\r
+\r
+#ifdef SHOW_STAT\r
+static int ttt = 0;\r
+#endif\r
+\r
+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)\r
+\r
+#define kBlockSize (9 << 10)\r
+#define kUnpackBlockSize (1 << 18)\r
+#define kMatchArraySize (1 << 21)\r
+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)\r
+\r
+#define kNumMaxDirectBits (31)\r
+\r
+#define kNumTopBits 24\r
+#define kTopValue ((UInt32)1 << kNumTopBits)\r
+\r
+#define kNumBitModelTotalBits 11\r
+#define kBitModelTotal (1 << kNumBitModelTotalBits)\r
+#define kNumMoveBits 5\r
+#define kProbInitValue (kBitModelTotal >> 1)\r
+\r
+#define kNumMoveReducingBits 4\r
+#define kNumBitPriceShiftBits 4\r
+#define kBitPrice (1 << kNumBitPriceShiftBits)\r
+\r
+void LzmaEncProps_Init(CLzmaEncProps *p)\r
+{\r
+  p->level = 5;\r
+  p->dictSize = p->mc = 0;\r
+  p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;\r
+  p->writeEndMark = 0;\r
+}\r
+\r
+void LzmaEncProps_Normalize(CLzmaEncProps *p)\r
+{\r
+  int level = p->level;\r
+  if (level < 0) level = 5;\r
+  p->level = level;\r
+  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));\r
+  if (p->lc < 0) p->lc = 3;\r
+  if (p->lp < 0) p->lp = 0;\r
+  if (p->pb < 0) p->pb = 2;\r
+  if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);\r
+  if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);\r
+  if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);\r
+  if (p->numHashBytes < 0) p->numHashBytes = 4;\r
+  if (p->mc == 0)  p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);\r
+  if (p->numThreads < 0)\r
+    p->numThreads =\r
+      #ifndef _7ZIP_ST\r
+      ((p->btMode && p->algo) ? 2 : 1);\r
+      #else\r
+      1;\r
+      #endif\r
+}\r
+\r
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)\r
+{\r
+  CLzmaEncProps props = *props2;\r
+  LzmaEncProps_Normalize(&props);\r
+  return props.dictSize;\r
+}\r
+\r
+/* #define LZMA_LOG_BSR */\r
+/* Define it for Intel's CPU */\r
+\r
+\r
+#ifdef LZMA_LOG_BSR\r
+\r
+#define kDicLogSizeMaxCompress 30\r
+\r
+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }\r
+\r
+UInt32 GetPosSlot1(UInt32 pos)\r
+{\r
+  UInt32 res;\r
+  BSR2_RET(pos, res);\r
+  return res;\r
+}\r
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }\r
+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }\r
+\r
+#else\r
+\r
+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)\r
+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)\r
+\r
+void LzmaEnc_FastPosInit(Byte *g_FastPos)\r
+{\r
+  int c = 2, slotFast;\r
+  g_FastPos[0] = 0;\r
+  g_FastPos[1] = 1;\r
+  \r
+  for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)\r
+  {\r
+    UInt32 k = (1 << ((slotFast >> 1) - 1));\r
+    UInt32 j;\r
+    for (j = 0; j < k; j++, c++)\r
+      g_FastPos[c] = (Byte)slotFast;\r
+  }\r
+}\r
+\r
+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \\r
+  (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \\r
+  res = p->g_FastPos[pos >> i] + (i * 2); }\r
+/*\r
+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \\r
+  p->g_FastPos[pos >> 6] + 12 : \\r
+  p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }\r
+*/\r
+\r
+#define GetPosSlot1(pos) p->g_FastPos[pos]\r
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }\r
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }\r
+\r
+#endif\r
+\r
+\r
+#define LZMA_NUM_REPS 4\r
+\r
+typedef unsigned CState;\r
+\r
+typedef struct\r
+{\r
+  UInt32 price;\r
+\r
+  CState state;\r
+  int prev1IsChar;\r
+  int prev2;\r
+\r
+  UInt32 posPrev2;\r
+  UInt32 backPrev2;\r
+\r
+  UInt32 posPrev;\r
+  UInt32 backPrev;\r
+  UInt32 backs[LZMA_NUM_REPS];\r
+} COptimal;\r
+\r
+#define kNumOpts (1 << 12)\r
+\r
+#define kNumLenToPosStates 4\r
+#define kNumPosSlotBits 6\r
+#define kDicLogSizeMin 0\r
+#define kDicLogSizeMax 32\r
+#define kDistTableSizeMax (kDicLogSizeMax * 2)\r
+\r
+\r
+#define kNumAlignBits 4\r
+#define kAlignTableSize (1 << kNumAlignBits)\r
+#define kAlignMask (kAlignTableSize - 1)\r
+\r
+#define kStartPosModelIndex 4\r
+#define kEndPosModelIndex 14\r
+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)\r
+\r
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))\r
+\r
+#ifdef _LZMA_PROB32\r
+#define CLzmaProb UInt32\r
+#else\r
+#define CLzmaProb UInt16\r
+#endif\r
+\r
+#define LZMA_PB_MAX 4\r
+#define LZMA_LC_MAX 8\r
+#define LZMA_LP_MAX 4\r
+\r
+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)\r
+\r
+\r
+#define kLenNumLowBits 3\r
+#define kLenNumLowSymbols (1 << kLenNumLowBits)\r
+#define kLenNumMidBits 3\r
+#define kLenNumMidSymbols (1 << kLenNumMidBits)\r
+#define kLenNumHighBits 8\r
+#define kLenNumHighSymbols (1 << kLenNumHighBits)\r
+\r
+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)\r
+\r
+#define LZMA_MATCH_LEN_MIN 2\r
+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)\r
+\r
+#define kNumStates 12\r
+\r
+typedef struct\r
+{\r
+  CLzmaProb choice;\r
+  CLzmaProb choice2;\r
+  CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];\r
+  CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];\r
+  CLzmaProb high[kLenNumHighSymbols];\r
+} CLenEnc;\r
+\r
+typedef struct\r
+{\r
+  CLenEnc p;\r
+  UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];\r
+  UInt32 tableSize;\r
+  UInt32 counters[LZMA_NUM_PB_STATES_MAX];\r
+} CLenPriceEnc;\r
+\r
+typedef struct\r
+{\r
+  UInt32 range;\r
+  Byte cache;\r
+  UInt64 low;\r
+  UInt64 cacheSize;\r
+  Byte *buf;\r
+  Byte *bufLim;\r
+  Byte *bufBase;\r
+  ISeqOutStream *outStream;\r
+  UInt64 processed;\r
+  SRes res;\r
+} CRangeEnc;\r
+\r
+typedef struct\r
+{\r
+  CLzmaProb *litProbs;\r
+\r
+  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
+  CLzmaProb isRep[kNumStates];\r
+  CLzmaProb isRepG0[kNumStates];\r
+  CLzmaProb isRepG1[kNumStates];\r
+  CLzmaProb isRepG2[kNumStates];\r
+  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
+\r
+  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];\r
+  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];\r
+  CLzmaProb posAlignEncoder[1 << kNumAlignBits];\r
+  \r
+  CLenPriceEnc lenEnc;\r
+  CLenPriceEnc repLenEnc;\r
+\r
+  UInt32 reps[LZMA_NUM_REPS];\r
+  UInt32 state;\r
+} CSaveState;\r
+\r
+typedef struct\r
+{\r
+  IMatchFinder matchFinder;\r
+  void *matchFinderObj;\r
+\r
+  #ifndef _7ZIP_ST\r
+  Bool mtMode;\r
+  CMatchFinderMt matchFinderMt;\r
+  #endif\r
+\r
+  CMatchFinder matchFinderBase;\r
+\r
+  #ifndef _7ZIP_ST\r
+  Byte pad[128];\r
+  #endif\r
+  \r
+  UInt32 optimumEndIndex;\r
+  UInt32 optimumCurrentIndex;\r
+\r
+  UInt32 longestMatchLength;\r
+  UInt32 numPairs;\r
+  UInt32 numAvail;\r
+  COptimal opt[kNumOpts];\r
+  \r
+  #ifndef LZMA_LOG_BSR\r
+  Byte g_FastPos[1 << kNumLogBits];\r
+  #endif\r
+\r
+  UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];\r
+  UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];\r
+  UInt32 numFastBytes;\r
+  UInt32 additionalOffset;\r
+  UInt32 reps[LZMA_NUM_REPS];\r
+  UInt32 state;\r
+\r
+  UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];\r
+  UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];\r
+  UInt32 alignPrices[kAlignTableSize];\r
+  UInt32 alignPriceCount;\r
+\r
+  UInt32 distTableSize;\r
+\r
+  unsigned lc, lp, pb;\r
+  unsigned lpMask, pbMask;\r
+\r
+  CLzmaProb *litProbs;\r
+\r
+  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
+  CLzmaProb isRep[kNumStates];\r
+  CLzmaProb isRepG0[kNumStates];\r
+  CLzmaProb isRepG1[kNumStates];\r
+  CLzmaProb isRepG2[kNumStates];\r
+  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];\r
+\r
+  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];\r
+  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];\r
+  CLzmaProb posAlignEncoder[1 << kNumAlignBits];\r
+  \r
+  CLenPriceEnc lenEnc;\r
+  CLenPriceEnc repLenEnc;\r
+\r
+  unsigned lclp;\r
+\r
+  Bool fastMode;\r
+  \r
+  CRangeEnc rc;\r
+\r
+  Bool writeEndMark;\r
+  UInt64 nowPos64;\r
+  UInt32 matchPriceCount;\r
+  Bool finished;\r
+  Bool multiThread;\r
+\r
+  SRes result;\r
+  UInt32 dictSize;\r
+  UInt32 matchFinderCycles;\r
+\r
+  int needInit;\r
+\r
+  CSaveState saveState;\r
+} CLzmaEnc;\r
+\r
+void LzmaEnc_SaveState(CLzmaEncHandle pp)\r
+{\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  CSaveState *dest = &p->saveState;\r
+  int i;\r
+  dest->lenEnc = p->lenEnc;\r
+  dest->repLenEnc = p->repLenEnc;\r
+  dest->state = p->state;\r
+\r
+  for (i = 0; i < kNumStates; i++)\r
+  {\r
+    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));\r
+    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));\r
+  }\r
+  for (i = 0; i < kNumLenToPosStates; i++)\r
+    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));\r
+  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));\r
+  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));\r
+  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));\r
+  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));\r
+  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));\r
+  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));\r
+  memcpy(dest->reps, p->reps, sizeof(p->reps));\r
+  memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));\r
+}\r
+\r
+void LzmaEnc_RestoreState(CLzmaEncHandle pp)\r
+{\r
+  CLzmaEnc *dest = (CLzmaEnc *)pp;\r
+  const CSaveState *p = &dest->saveState;\r
+  int i;\r
+  dest->lenEnc = p->lenEnc;\r
+  dest->repLenEnc = p->repLenEnc;\r
+  dest->state = p->state;\r
+\r
+  for (i = 0; i < kNumStates; i++)\r
+  {\r
+    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));\r
+    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));\r
+  }\r
+  for (i = 0; i < kNumLenToPosStates; i++)\r
+    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));\r
+  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));\r
+  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));\r
+  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));\r
+  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));\r
+  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));\r
+  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));\r
+  memcpy(dest->reps, p->reps, sizeof(p->reps));\r
+  memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));\r
+}\r
+\r
+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)\r
+{\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  CLzmaEncProps props = *props2;\r
+  LzmaEncProps_Normalize(&props);\r
+\r
+  if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||\r
+      props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))\r
+    return SZ_ERROR_PARAM;\r
+  p->dictSize = props.dictSize;\r
+  p->matchFinderCycles = props.mc;\r
+  {\r
+    unsigned fb = props.fb;\r
+    if (fb < 5)\r
+      fb = 5;\r
+    if (fb > LZMA_MATCH_LEN_MAX)\r
+      fb = LZMA_MATCH_LEN_MAX;\r
+    p->numFastBytes = fb;\r
+  }\r
+  p->lc = props.lc;\r
+  p->lp = props.lp;\r
+  p->pb = props.pb;\r
+  p->fastMode = (props.algo == 0);\r
+  p->matchFinderBase.btMode = props.btMode;\r
+  {\r
+    UInt32 numHashBytes = 4;\r
+    if (props.btMode)\r
+    {\r
+      if (props.numHashBytes < 2)\r
+        numHashBytes = 2;\r
+      else if (props.numHashBytes < 4)\r
+        numHashBytes = props.numHashBytes;\r
+    }\r
+    p->matchFinderBase.numHashBytes = numHashBytes;\r
+  }\r
+\r
+  p->matchFinderBase.cutValue = props.mc;\r
+\r
+  p->writeEndMark = props.writeEndMark;\r
+\r
+  #ifndef _7ZIP_ST\r
+  /*\r
+  if (newMultiThread != _multiThread)\r
+  {\r
+    ReleaseMatchFinder();\r
+    _multiThread = newMultiThread;\r
+  }\r
+  */\r
+  p->multiThread = (props.numThreads > 1);\r
+  #endif\r
+\r
+  return SZ_OK;\r
+}\r
+\r
+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};\r
+static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};\r
+static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};\r
+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};\r
+\r
+#define IsCharState(s) ((s) < 7)\r
+\r
+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)\r
+\r
+#define kInfinityPrice (1 << 30)\r
+\r
+static void RangeEnc_Construct(CRangeEnc *p)\r
+{\r
+  p->outStream = 0;\r
+  p->bufBase = 0;\r
+}\r
+\r
+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)\r
+\r
+#define RC_BUF_SIZE (1 << 16)\r
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)\r
+{\r
+  if (p->bufBase == 0)\r
+  {\r
+    p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);\r
+    if (p->bufBase == 0)\r
+      return 0;\r
+    p->bufLim = p->bufBase + RC_BUF_SIZE;\r
+  }\r
+  return 1;\r
+}\r
+\r
+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->bufBase);\r
+  p->bufBase = 0;\r
+}\r
+\r
+static void RangeEnc_Init(CRangeEnc *p)\r
+{\r
+  /* Stream.Init(); */\r
+  p->low = 0;\r
+  p->range = 0xFFFFFFFF;\r
+  p->cacheSize = 1;\r
+  p->cache = 0;\r
+\r
+  p->buf = p->bufBase;\r
+\r
+  p->processed = 0;\r
+  p->res = SZ_OK;\r
+}\r
+\r
+static void RangeEnc_FlushStream(CRangeEnc *p)\r
+{\r
+  size_t num;\r
+  if (p->res != SZ_OK)\r
+    return;\r
+  num = p->buf - p->bufBase;\r
+  if (num != p->outStream->Write(p->outStream, p->bufBase, num))\r
+    p->res = SZ_ERROR_WRITE;\r
+  p->processed += num;\r
+  p->buf = p->bufBase;\r
+}\r
+\r
+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)\r
+{\r
+  if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)\r
+  {\r
+    Byte temp = p->cache;\r
+    do\r
+    {\r
+      Byte *buf = p->buf;\r
+      *buf++ = (Byte)(temp + (Byte)(p->low >> 32));\r
+      p->buf = buf;\r
+      if (buf == p->bufLim)\r
+        RangeEnc_FlushStream(p);\r
+      temp = 0xFF;\r
+    }\r
+    while (--p->cacheSize != 0);\r
+    p->cache = (Byte)((UInt32)p->low >> 24);\r
+  }\r
+  p->cacheSize++;\r
+  p->low = (UInt32)p->low << 8;\r
+}\r
+\r
+static void RangeEnc_FlushData(CRangeEnc *p)\r
+{\r
+  int i;\r
+  for (i = 0; i < 5; i++)\r
+    RangeEnc_ShiftLow(p);\r
+}\r
+\r
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)\r
+{\r
+  do\r
+  {\r
+    p->range >>= 1;\r
+    p->low += p->range & (0 - ((value >> --numBits) & 1));\r
+    if (p->range < kTopValue)\r
+    {\r
+      p->range <<= 8;\r
+      RangeEnc_ShiftLow(p);\r
+    }\r
+  }\r
+  while (numBits != 0);\r
+}\r
+\r
+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)\r
+{\r
+  UInt32 ttt = *prob;\r
+  UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;\r
+  if (symbol == 0)\r
+  {\r
+    p->range = newBound;\r
+    ttt += (kBitModelTotal - ttt) >> kNumMoveBits;\r
+  }\r
+  else\r
+  {\r
+    p->low += newBound;\r
+    p->range -= newBound;\r
+    ttt -= ttt >> kNumMoveBits;\r
+  }\r
+  *prob = (CLzmaProb)ttt;\r
+  if (p->range < kTopValue)\r
+  {\r
+    p->range <<= 8;\r
+    RangeEnc_ShiftLow(p);\r
+  }\r
+}\r
+\r
+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)\r
+{\r
+  symbol |= 0x100;\r
+  do\r
+  {\r
+    RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);\r
+    symbol <<= 1;\r
+  }\r
+  while (symbol < 0x10000);\r
+}\r
+\r
+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)\r
+{\r
+  UInt32 offs = 0x100;\r
+  symbol |= 0x100;\r
+  do\r
+  {\r
+    matchByte <<= 1;\r
+    RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);\r
+    symbol <<= 1;\r
+    offs &= ~(matchByte ^ symbol);\r
+  }\r
+  while (symbol < 0x10000);\r
+}\r
+\r
+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)\r
+{\r
+  UInt32 i;\r
+  for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))\r
+  {\r
+    const int kCyclesBits = kNumBitPriceShiftBits;\r
+    UInt32 w = i;\r
+    UInt32 bitCount = 0;\r
+    int j;\r
+    for (j = 0; j < kCyclesBits; j++)\r
+    {\r
+      w = w * w;\r
+      bitCount <<= 1;\r
+      while (w >= ((UInt32)1 << 16))\r
+      {\r
+        w >>= 1;\r
+        bitCount++;\r
+      }\r
+    }\r
+    ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);\r
+  }\r
+}\r
+\r
+\r
+#define GET_PRICE(prob, symbol) \\r
+  p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];\r
+\r
+#define GET_PRICEa(prob, symbol) \\r
+  ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];\r
+\r
+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]\r
+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]\r
+\r
+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]\r
+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]\r
+\r
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)\r
+{\r
+  UInt32 price = 0;\r
+  symbol |= 0x100;\r
+  do\r
+  {\r
+    price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);\r
+    symbol <<= 1;\r
+  }\r
+  while (symbol < 0x10000);\r
+  return price;\r
+}\r
+\r
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)\r
+{\r
+  UInt32 price = 0;\r
+  UInt32 offs = 0x100;\r
+  symbol |= 0x100;\r
+  do\r
+  {\r
+    matchByte <<= 1;\r
+    price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);\r
+    symbol <<= 1;\r
+    offs &= ~(matchByte ^ symbol);\r
+  }\r
+  while (symbol < 0x10000);\r
+  return price;\r
+}\r
+\r
+\r
+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)\r
+{\r
+  UInt32 m = 1;\r
+  int i;\r
+  for (i = numBitLevels; i != 0;)\r
+  {\r
+    UInt32 bit;\r
+    i--;\r
+    bit = (symbol >> i) & 1;\r
+    RangeEnc_EncodeBit(rc, probs + m, bit);\r
+    m = (m << 1) | bit;\r
+  }\r
+}\r
+\r
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)\r
+{\r
+  UInt32 m = 1;\r
+  int i;\r
+  for (i = 0; i < numBitLevels; i++)\r
+  {\r
+    UInt32 bit = symbol & 1;\r
+    RangeEnc_EncodeBit(rc, probs + m, bit);\r
+    m = (m << 1) | bit;\r
+    symbol >>= 1;\r
+  }\r
+}\r
+\r
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)\r
+{\r
+  UInt32 price = 0;\r
+  symbol |= (1 << numBitLevels);\r
+  while (symbol != 1)\r
+  {\r
+    price += GET_PRICEa(probs[symbol >> 1], symbol & 1);\r
+    symbol >>= 1;\r
+  }\r
+  return price;\r
+}\r
+\r
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)\r
+{\r
+  UInt32 price = 0;\r
+  UInt32 m = 1;\r
+  int i;\r
+  for (i = numBitLevels; i != 0; i--)\r
+  {\r
+    UInt32 bit = symbol & 1;\r
+    symbol >>= 1;\r
+    price += GET_PRICEa(probs[m], bit);\r
+    m = (m << 1) | bit;\r
+  }\r
+  return price;\r
+}\r
+\r
+\r
+static void LenEnc_Init(CLenEnc *p)\r
+{\r
+  unsigned i;\r
+  p->choice = p->choice2 = kProbInitValue;\r
+  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)\r
+    p->low[i] = kProbInitValue;\r
+  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)\r
+    p->mid[i] = kProbInitValue;\r
+  for (i = 0; i < kLenNumHighSymbols; i++)\r
+    p->high[i] = kProbInitValue;\r
+}\r
+\r
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)\r
+{\r
+  if (symbol < kLenNumLowSymbols)\r
+  {\r
+    RangeEnc_EncodeBit(rc, &p->choice, 0);\r
+    RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);\r
+  }\r
+  else\r
+  {\r
+    RangeEnc_EncodeBit(rc, &p->choice, 1);\r
+    if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)\r
+    {\r
+      RangeEnc_EncodeBit(rc, &p->choice2, 0);\r
+      RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);\r
+    }\r
+    else\r
+    {\r
+      RangeEnc_EncodeBit(rc, &p->choice2, 1);\r
+      RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);\r
+    }\r
+  }\r
+}\r
+\r
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)\r
+{\r
+  UInt32 a0 = GET_PRICE_0a(p->choice);\r
+  UInt32 a1 = GET_PRICE_1a(p->choice);\r
+  UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);\r
+  UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);\r
+  UInt32 i = 0;\r
+  for (i = 0; i < kLenNumLowSymbols; i++)\r
+  {\r
+    if (i >= numSymbols)\r
+      return;\r
+    prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);\r
+  }\r
+  for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)\r
+  {\r
+    if (i >= numSymbols)\r
+      return;\r
+    prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);\r
+  }\r
+  for (; i < numSymbols; i++)\r
+    prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);\r
+}\r
+\r
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)\r
+{\r
+  LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);\r
+  p->counters[posState] = p->tableSize;\r
+}\r
+\r
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)\r
+{\r
+  UInt32 posState;\r
+  for (posState = 0; posState < numPosStates; posState++)\r
+    LenPriceEnc_UpdateTable(p, posState, ProbPrices);\r
+}\r
+\r
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)\r
+{\r
+  LenEnc_Encode(&p->p, rc, symbol, posState);\r
+  if (updatePrice)\r
+    if (--p->counters[posState] == 0)\r
+      LenPriceEnc_UpdateTable(p, posState, ProbPrices);\r
+}\r
+\r
+\r
+\r
+\r
+static void MovePos(CLzmaEnc *p, UInt32 num)\r
+{\r
+  #ifdef SHOW_STAT\r
+  ttt += num;\r
+  printf("\n MovePos %d", num);\r
+  #endif\r
+  if (num != 0)\r
+  {\r
+    p->additionalOffset += num;\r
+    p->matchFinder.Skip(p->matchFinderObj, num);\r
+  }\r
+}\r
+\r
+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)\r
+{\r
+  UInt32 lenRes = 0, numPairs;\r
+  p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);\r
+  numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);\r
+  #ifdef SHOW_STAT\r
+  printf("\n i = %d numPairs = %d    ", ttt, numPairs / 2);\r
+  ttt++;\r
+  {\r
+    UInt32 i;\r
+    for (i = 0; i < numPairs; i += 2)\r
+      printf("%2d %6d   | ", p->matches[i], p->matches[i + 1]);\r
+  }\r
+  #endif\r
+  if (numPairs > 0)\r
+  {\r
+    lenRes = p->matches[numPairs - 2];\r
+    if (lenRes == p->numFastBytes)\r
+    {\r
+      const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
+      UInt32 distance = p->matches[numPairs - 1] + 1;\r
+      UInt32 numAvail = p->numAvail;\r
+      if (numAvail > LZMA_MATCH_LEN_MAX)\r
+        numAvail = LZMA_MATCH_LEN_MAX;\r
+      {\r
+        const Byte *pby2 = pby - distance;\r
+        for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);\r
+      }\r
+    }\r
+  }\r
+  p->additionalOffset++;\r
+  *numDistancePairsRes = numPairs;\r
+  return lenRes;\r
+}\r
+\r
+\r
+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;\r
+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;\r
+#define IsShortRep(p) ((p)->backPrev == 0)\r
+\r
+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)\r
+{\r
+  return\r
+    GET_PRICE_0(p->isRepG0[state]) +\r
+    GET_PRICE_0(p->isRep0Long[state][posState]);\r
+}\r
+\r
+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)\r
+{\r
+  UInt32 price;\r
+  if (repIndex == 0)\r
+  {\r
+    price = GET_PRICE_0(p->isRepG0[state]);\r
+    price += GET_PRICE_1(p->isRep0Long[state][posState]);\r
+  }\r
+  else\r
+  {\r
+    price = GET_PRICE_1(p->isRepG0[state]);\r
+    if (repIndex == 1)\r
+      price += GET_PRICE_0(p->isRepG1[state]);\r
+    else\r
+    {\r
+      price += GET_PRICE_1(p->isRepG1[state]);\r
+      price += GET_PRICE(p->isRepG2[state], repIndex - 2);\r
+    }\r
+  }\r
+  return price;\r
+}\r
+\r
+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)\r
+{\r
+  return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +\r
+    GetPureRepPrice(p, repIndex, state, posState);\r
+}\r
+\r
+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)\r
+{\r
+  UInt32 posMem = p->opt[cur].posPrev;\r
+  UInt32 backMem = p->opt[cur].backPrev;\r
+  p->optimumEndIndex = cur;\r
+  do\r
+  {\r
+    if (p->opt[cur].prev1IsChar)\r
+    {\r
+      MakeAsChar(&p->opt[posMem])\r
+      p->opt[posMem].posPrev = posMem - 1;\r
+      if (p->opt[cur].prev2)\r
+      {\r
+        p->opt[posMem - 1].prev1IsChar = False;\r
+        p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;\r
+        p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;\r
+      }\r
+    }\r
+    {\r
+      UInt32 posPrev = posMem;\r
+      UInt32 backCur = backMem;\r
+      \r
+      backMem = p->opt[posPrev].backPrev;\r
+      posMem = p->opt[posPrev].posPrev;\r
+      \r
+      p->opt[posPrev].backPrev = backCur;\r
+      p->opt[posPrev].posPrev = cur;\r
+      cur = posPrev;\r
+    }\r
+  }\r
+  while (cur != 0);\r
+  *backRes = p->opt[0].backPrev;\r
+  p->optimumCurrentIndex  = p->opt[0].posPrev;\r
+  return p->optimumCurrentIndex;\r
+}\r
+\r
+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)\r
+\r
+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)\r
+{\r
+  UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;\r
+  UInt32 matchPrice, repMatchPrice, normalMatchPrice;\r
+  UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];\r
+  UInt32 *matches;\r
+  const Byte *data;\r
+  Byte curByte, matchByte;\r
+  if (p->optimumEndIndex != p->optimumCurrentIndex)\r
+  {\r
+    const COptimal *opt = &p->opt[p->optimumCurrentIndex];\r
+    UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;\r
+    *backRes = opt->backPrev;\r
+    p->optimumCurrentIndex = opt->posPrev;\r
+    return lenRes;\r
+  }\r
+  p->optimumCurrentIndex = p->optimumEndIndex = 0;\r
+  \r
+  if (p->additionalOffset == 0)\r
+    mainLen = ReadMatchDistances(p, &numPairs);\r
+  else\r
+  {\r
+    mainLen = p->longestMatchLength;\r
+    numPairs = p->numPairs;\r
+  }\r
+\r
+  numAvail = p->numAvail;\r
+  if (numAvail < 2)\r
+  {\r
+    *backRes = (UInt32)(-1);\r
+    return 1;\r
+  }\r
+  if (numAvail > LZMA_MATCH_LEN_MAX)\r
+    numAvail = LZMA_MATCH_LEN_MAX;\r
+\r
+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
+  repMaxIndex = 0;\r
+  for (i = 0; i < LZMA_NUM_REPS; i++)\r
+  {\r
+    UInt32 lenTest;\r
+    const Byte *data2;\r
+    reps[i] = p->reps[i];\r
+    data2 = data - (reps[i] + 1);\r
+    if (data[0] != data2[0] || data[1] != data2[1])\r
+    {\r
+      repLens[i] = 0;\r
+      continue;\r
+    }\r
+    for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);\r
+    repLens[i] = lenTest;\r
+    if (lenTest > repLens[repMaxIndex])\r
+      repMaxIndex = i;\r
+  }\r
+  if (repLens[repMaxIndex] >= p->numFastBytes)\r
+  {\r
+    UInt32 lenRes;\r
+    *backRes = repMaxIndex;\r
+    lenRes = repLens[repMaxIndex];\r
+    MovePos(p, lenRes - 1);\r
+    return lenRes;\r
+  }\r
+\r
+  matches = p->matches;\r
+  if (mainLen >= p->numFastBytes)\r
+  {\r
+    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;\r
+    MovePos(p, mainLen - 1);\r
+    return mainLen;\r
+  }\r
+  curByte = *data;\r
+  matchByte = *(data - (reps[0] + 1));\r
+\r
+  if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)\r
+  {\r
+    *backRes = (UInt32)-1;\r
+    return 1;\r
+  }\r
+\r
+  p->opt[0].state = (CState)p->state;\r
+\r
+  posState = (position & p->pbMask);\r
+\r
+  {\r
+    const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));\r
+    p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +\r
+        (!IsCharState(p->state) ?\r
+          LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :\r
+          LitEnc_GetPrice(probs, curByte, p->ProbPrices));\r
+  }\r
+\r
+  MakeAsChar(&p->opt[1]);\r
+\r
+  matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);\r
+  repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);\r
+\r
+  if (matchByte == curByte)\r
+  {\r
+    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);\r
+    if (shortRepPrice < p->opt[1].price)\r
+    {\r
+      p->opt[1].price = shortRepPrice;\r
+      MakeAsShortRep(&p->opt[1]);\r
+    }\r
+  }\r
+  lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);\r
+\r
+  if (lenEnd < 2)\r
+  {\r
+    *backRes = p->opt[1].backPrev;\r
+    return 1;\r
+  }\r
+\r
+  p->opt[1].posPrev = 0;\r
+  for (i = 0; i < LZMA_NUM_REPS; i++)\r
+    p->opt[0].backs[i] = reps[i];\r
+\r
+  len = lenEnd;\r
+  do\r
+    p->opt[len--].price = kInfinityPrice;\r
+  while (len >= 2);\r
+\r
+  for (i = 0; i < LZMA_NUM_REPS; i++)\r
+  {\r
+    UInt32 repLen = repLens[i];\r
+    UInt32 price;\r
+    if (repLen < 2)\r
+      continue;\r
+    price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);\r
+    do\r
+    {\r
+      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];\r
+      COptimal *opt = &p->opt[repLen];\r
+      if (curAndLenPrice < opt->price)\r
+      {\r
+        opt->price = curAndLenPrice;\r
+        opt->posPrev = 0;\r
+        opt->backPrev = i;\r
+        opt->prev1IsChar = False;\r
+      }\r
+    }\r
+    while (--repLen >= 2);\r
+  }\r
+\r
+  normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);\r
+\r
+  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);\r
+  if (len <= mainLen)\r
+  {\r
+    UInt32 offs = 0;\r
+    while (len > matches[offs])\r
+      offs += 2;\r
+    for (; ; len++)\r
+    {\r
+      COptimal *opt;\r
+      UInt32 distance = matches[offs + 1];\r
+\r
+      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];\r
+      UInt32 lenToPosState = GetLenToPosState(len);\r
+      if (distance < kNumFullDistances)\r
+        curAndLenPrice += p->distancesPrices[lenToPosState][distance];\r
+      else\r
+      {\r
+        UInt32 slot;\r
+        GetPosSlot2(distance, slot);\r
+        curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];\r
+      }\r
+      opt = &p->opt[len];\r
+      if (curAndLenPrice < opt->price)\r
+      {\r
+        opt->price = curAndLenPrice;\r
+        opt->posPrev = 0;\r
+        opt->backPrev = distance + LZMA_NUM_REPS;\r
+        opt->prev1IsChar = False;\r
+      }\r
+      if (len == matches[offs])\r
+      {\r
+        offs += 2;\r
+        if (offs == numPairs)\r
+          break;\r
+      }\r
+    }\r
+  }\r
+\r
+  cur = 0;\r
+\r
+    #ifdef SHOW_STAT2\r
+    if (position >= 0)\r
+    {\r
+      unsigned i;\r
+      printf("\n pos = %4X", position);\r
+      for (i = cur; i <= lenEnd; i++)\r
+      printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);\r
+    }\r
+    #endif\r
+\r
+  for (;;)\r
+  {\r
+    UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;\r
+    UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;\r
+    Bool nextIsChar;\r
+    Byte curByte, matchByte;\r
+    const Byte *data;\r
+    COptimal *curOpt;\r
+    COptimal *nextOpt;\r
+\r
+    cur++;\r
+    if (cur == lenEnd)\r
+      return Backward(p, backRes, cur);\r
+\r
+    newLen = ReadMatchDistances(p, &numPairs);\r
+    if (newLen >= p->numFastBytes)\r
+    {\r
+      p->numPairs = numPairs;\r
+      p->longestMatchLength = newLen;\r
+      return Backward(p, backRes, cur);\r
+    }\r
+    position++;\r
+    curOpt = &p->opt[cur];\r
+    posPrev = curOpt->posPrev;\r
+    if (curOpt->prev1IsChar)\r
+    {\r
+      posPrev--;\r
+      if (curOpt->prev2)\r
+      {\r
+        state = p->opt[curOpt->posPrev2].state;\r
+        if (curOpt->backPrev2 < LZMA_NUM_REPS)\r
+          state = kRepNextStates[state];\r
+        else\r
+          state = kMatchNextStates[state];\r
+      }\r
+      else\r
+        state = p->opt[posPrev].state;\r
+      state = kLiteralNextStates[state];\r
+    }\r
+    else\r
+      state = p->opt[posPrev].state;\r
+    if (posPrev == cur - 1)\r
+    {\r
+      if (IsShortRep(curOpt))\r
+        state = kShortRepNextStates[state];\r
+      else\r
+        state = kLiteralNextStates[state];\r
+    }\r
+    else\r
+    {\r
+      UInt32 pos;\r
+      const COptimal *prevOpt;\r
+      if (curOpt->prev1IsChar && curOpt->prev2)\r
+      {\r
+        posPrev = curOpt->posPrev2;\r
+        pos = curOpt->backPrev2;\r
+        state = kRepNextStates[state];\r
+      }\r
+      else\r
+      {\r
+        pos = curOpt->backPrev;\r
+        if (pos < LZMA_NUM_REPS)\r
+          state = kRepNextStates[state];\r
+        else\r
+          state = kMatchNextStates[state];\r
+      }\r
+      prevOpt = &p->opt[posPrev];\r
+      if (pos < LZMA_NUM_REPS)\r
+      {\r
+        UInt32 i;\r
+        reps[0] = prevOpt->backs[pos];\r
+        for (i = 1; i <= pos; i++)\r
+          reps[i] = prevOpt->backs[i - 1];\r
+        for (; i < LZMA_NUM_REPS; i++)\r
+          reps[i] = prevOpt->backs[i];\r
+      }\r
+      else\r
+      {\r
+        UInt32 i;\r
+        reps[0] = (pos - LZMA_NUM_REPS);\r
+        for (i = 1; i < LZMA_NUM_REPS; i++)\r
+          reps[i] = prevOpt->backs[i - 1];\r
+      }\r
+    }\r
+    curOpt->state = (CState)state;\r
+\r
+    curOpt->backs[0] = reps[0];\r
+    curOpt->backs[1] = reps[1];\r
+    curOpt->backs[2] = reps[2];\r
+    curOpt->backs[3] = reps[3];\r
+\r
+    curPrice = curOpt->price;\r
+    nextIsChar = False;\r
+    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
+    curByte = *data;\r
+    matchByte = *(data - (reps[0] + 1));\r
+\r
+    posState = (position & p->pbMask);\r
+\r
+    curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);\r
+    {\r
+      const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));\r
+      curAnd1Price +=\r
+        (!IsCharState(state) ?\r
+          LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :\r
+          LitEnc_GetPrice(probs, curByte, p->ProbPrices));\r
+    }\r
+\r
+    nextOpt = &p->opt[cur + 1];\r
+\r
+    if (curAnd1Price < nextOpt->price)\r
+    {\r
+      nextOpt->price = curAnd1Price;\r
+      nextOpt->posPrev = cur;\r
+      MakeAsChar(nextOpt);\r
+      nextIsChar = True;\r
+    }\r
+\r
+    matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);\r
+    repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);\r
+    \r
+    if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))\r
+    {\r
+      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);\r
+      if (shortRepPrice <= nextOpt->price)\r
+      {\r
+        nextOpt->price = shortRepPrice;\r
+        nextOpt->posPrev = cur;\r
+        MakeAsShortRep(nextOpt);\r
+        nextIsChar = True;\r
+      }\r
+    }\r
+    numAvailFull = p->numAvail;\r
+    {\r
+      UInt32 temp = kNumOpts - 1 - cur;\r
+      if (temp < numAvailFull)\r
+        numAvailFull = temp;\r
+    }\r
+\r
+    if (numAvailFull < 2)\r
+      continue;\r
+    numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);\r
+\r
+    if (!nextIsChar && matchByte != curByte) /* speed optimization */\r
+    {\r
+      /* try Literal + rep0 */\r
+      UInt32 temp;\r
+      UInt32 lenTest2;\r
+      const Byte *data2 = data - (reps[0] + 1);\r
+      UInt32 limit = p->numFastBytes + 1;\r
+      if (limit > numAvailFull)\r
+        limit = numAvailFull;\r
+\r
+      for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);\r
+      lenTest2 = temp - 1;\r
+      if (lenTest2 >= 2)\r
+      {\r
+        UInt32 state2 = kLiteralNextStates[state];\r
+        UInt32 posStateNext = (position + 1) & p->pbMask;\r
+        UInt32 nextRepMatchPrice = curAnd1Price +\r
+            GET_PRICE_1(p->isMatch[state2][posStateNext]) +\r
+            GET_PRICE_1(p->isRep[state2]);\r
+        /* for (; lenTest2 >= 2; lenTest2--) */\r
+        {\r
+          UInt32 curAndLenPrice;\r
+          COptimal *opt;\r
+          UInt32 offset = cur + 1 + lenTest2;\r
+          while (lenEnd < offset)\r
+            p->opt[++lenEnd].price = kInfinityPrice;\r
+          curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);\r
+          opt = &p->opt[offset];\r
+          if (curAndLenPrice < opt->price)\r
+          {\r
+            opt->price = curAndLenPrice;\r
+            opt->posPrev = cur + 1;\r
+            opt->backPrev = 0;\r
+            opt->prev1IsChar = True;\r
+            opt->prev2 = False;\r
+          }\r
+        }\r
+      }\r
+    }\r
+    \r
+    startLen = 2; /* speed optimization */\r
+    {\r
+    UInt32 repIndex;\r
+    for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)\r
+    {\r
+      UInt32 lenTest;\r
+      UInt32 lenTestTemp;\r
+      UInt32 price;\r
+      const Byte *data2 = data - (reps[repIndex] + 1);\r
+      if (data[0] != data2[0] || data[1] != data2[1])\r
+        continue;\r
+      for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);\r
+      while (lenEnd < cur + lenTest)\r
+        p->opt[++lenEnd].price = kInfinityPrice;\r
+      lenTestTemp = lenTest;\r
+      price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);\r
+      do\r
+      {\r
+        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];\r
+        COptimal *opt = &p->opt[cur + lenTest];\r
+        if (curAndLenPrice < opt->price)\r
+        {\r
+          opt->price = curAndLenPrice;\r
+          opt->posPrev = cur;\r
+          opt->backPrev = repIndex;\r
+          opt->prev1IsChar = False;\r
+        }\r
+      }\r
+      while (--lenTest >= 2);\r
+      lenTest = lenTestTemp;\r
+      \r
+      if (repIndex == 0)\r
+        startLen = lenTest + 1;\r
+        \r
+      /* if (_maxMode) */\r
+        {\r
+          UInt32 lenTest2 = lenTest + 1;\r
+          UInt32 limit = lenTest2 + p->numFastBytes;\r
+          UInt32 nextRepMatchPrice;\r
+          if (limit > numAvailFull)\r
+            limit = numAvailFull;\r
+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);\r
+          lenTest2 -= lenTest + 1;\r
+          if (lenTest2 >= 2)\r
+          {\r
+            UInt32 state2 = kRepNextStates[state];\r
+            UInt32 posStateNext = (position + lenTest) & p->pbMask;\r
+            UInt32 curAndLenCharPrice =\r
+                price + p->repLenEnc.prices[posState][lenTest - 2] +\r
+                GET_PRICE_0(p->isMatch[state2][posStateNext]) +\r
+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),\r
+                    data[lenTest], data2[lenTest], p->ProbPrices);\r
+            state2 = kLiteralNextStates[state2];\r
+            posStateNext = (position + lenTest + 1) & p->pbMask;\r
+            nextRepMatchPrice = curAndLenCharPrice +\r
+                GET_PRICE_1(p->isMatch[state2][posStateNext]) +\r
+                GET_PRICE_1(p->isRep[state2]);\r
+            \r
+            /* for (; lenTest2 >= 2; lenTest2--) */\r
+            {\r
+              UInt32 curAndLenPrice;\r
+              COptimal *opt;\r
+              UInt32 offset = cur + lenTest + 1 + lenTest2;\r
+              while (lenEnd < offset)\r
+                p->opt[++lenEnd].price = kInfinityPrice;\r
+              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);\r
+              opt = &p->opt[offset];\r
+              if (curAndLenPrice < opt->price)\r
+              {\r
+                opt->price = curAndLenPrice;\r
+                opt->posPrev = cur + lenTest + 1;\r
+                opt->backPrev = 0;\r
+                opt->prev1IsChar = True;\r
+                opt->prev2 = True;\r
+                opt->posPrev2 = cur;\r
+                opt->backPrev2 = repIndex;\r
+              }\r
+            }\r
+          }\r
+        }\r
+    }\r
+    }\r
+    /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */\r
+    if (newLen > numAvail)\r
+    {\r
+      newLen = numAvail;\r
+      for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);\r
+      matches[numPairs] = newLen;\r
+      numPairs += 2;\r
+    }\r
+    if (newLen >= startLen)\r
+    {\r
+      UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);\r
+      UInt32 offs, curBack, posSlot;\r
+      UInt32 lenTest;\r
+      while (lenEnd < cur + newLen)\r
+        p->opt[++lenEnd].price = kInfinityPrice;\r
+\r
+      offs = 0;\r
+      while (startLen > matches[offs])\r
+        offs += 2;\r
+      curBack = matches[offs + 1];\r
+      GetPosSlot2(curBack, posSlot);\r
+      for (lenTest = /*2*/ startLen; ; lenTest++)\r
+      {\r
+        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];\r
+        UInt32 lenToPosState = GetLenToPosState(lenTest);\r
+        COptimal *opt;\r
+        if (curBack < kNumFullDistances)\r
+          curAndLenPrice += p->distancesPrices[lenToPosState][curBack];\r
+        else\r
+          curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];\r
+        \r
+        opt = &p->opt[cur + lenTest];\r
+        if (curAndLenPrice < opt->price)\r
+        {\r
+          opt->price = curAndLenPrice;\r
+          opt->posPrev = cur;\r
+          opt->backPrev = curBack + LZMA_NUM_REPS;\r
+          opt->prev1IsChar = False;\r
+        }\r
+\r
+        if (/*_maxMode && */lenTest == matches[offs])\r
+        {\r
+          /* Try Match + Literal + Rep0 */\r
+          const Byte *data2 = data - (curBack + 1);\r
+          UInt32 lenTest2 = lenTest + 1;\r
+          UInt32 limit = lenTest2 + p->numFastBytes;\r
+          UInt32 nextRepMatchPrice;\r
+          if (limit > numAvailFull)\r
+            limit = numAvailFull;\r
+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);\r
+          lenTest2 -= lenTest + 1;\r
+          if (lenTest2 >= 2)\r
+          {\r
+            UInt32 state2 = kMatchNextStates[state];\r
+            UInt32 posStateNext = (position + lenTest) & p->pbMask;\r
+            UInt32 curAndLenCharPrice = curAndLenPrice +\r
+                GET_PRICE_0(p->isMatch[state2][posStateNext]) +\r
+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),\r
+                    data[lenTest], data2[lenTest], p->ProbPrices);\r
+            state2 = kLiteralNextStates[state2];\r
+            posStateNext = (posStateNext + 1) & p->pbMask;\r
+            nextRepMatchPrice = curAndLenCharPrice +\r
+                GET_PRICE_1(p->isMatch[state2][posStateNext]) +\r
+                GET_PRICE_1(p->isRep[state2]);\r
+            \r
+            /* for (; lenTest2 >= 2; lenTest2--) */\r
+            {\r
+              UInt32 offset = cur + lenTest + 1 + lenTest2;\r
+              UInt32 curAndLenPrice;\r
+              COptimal *opt;\r
+              while (lenEnd < offset)\r
+                p->opt[++lenEnd].price = kInfinityPrice;\r
+              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);\r
+              opt = &p->opt[offset];\r
+              if (curAndLenPrice < opt->price)\r
+              {\r
+                opt->price = curAndLenPrice;\r
+                opt->posPrev = cur + lenTest + 1;\r
+                opt->backPrev = 0;\r
+                opt->prev1IsChar = True;\r
+                opt->prev2 = True;\r
+                opt->posPrev2 = cur;\r
+                opt->backPrev2 = curBack + LZMA_NUM_REPS;\r
+              }\r
+            }\r
+          }\r
+          offs += 2;\r
+          if (offs == numPairs)\r
+            break;\r
+          curBack = matches[offs + 1];\r
+          if (curBack >= kNumFullDistances)\r
+            GetPosSlot2(curBack, posSlot);\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))\r
+\r
+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)\r
+{\r
+  UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;\r
+  const Byte *data;\r
+  const UInt32 *matches;\r
+\r
+  if (p->additionalOffset == 0)\r
+    mainLen = ReadMatchDistances(p, &numPairs);\r
+  else\r
+  {\r
+    mainLen = p->longestMatchLength;\r
+    numPairs = p->numPairs;\r
+  }\r
+\r
+  numAvail = p->numAvail;\r
+  *backRes = (UInt32)-1;\r
+  if (numAvail < 2)\r
+    return 1;\r
+  if (numAvail > LZMA_MATCH_LEN_MAX)\r
+    numAvail = LZMA_MATCH_LEN_MAX;\r
+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
+\r
+  repLen = repIndex = 0;\r
+  for (i = 0; i < LZMA_NUM_REPS; i++)\r
+  {\r
+    UInt32 len;\r
+    const Byte *data2 = data - (p->reps[i] + 1);\r
+    if (data[0] != data2[0] || data[1] != data2[1])\r
+      continue;\r
+    for (len = 2; len < numAvail && data[len] == data2[len]; len++);\r
+    if (len >= p->numFastBytes)\r
+    {\r
+      *backRes = i;\r
+      MovePos(p, len - 1);\r
+      return len;\r
+    }\r
+    if (len > repLen)\r
+    {\r
+      repIndex = i;\r
+      repLen = len;\r
+    }\r
+  }\r
+\r
+  matches = p->matches;\r
+  if (mainLen >= p->numFastBytes)\r
+  {\r
+    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;\r
+    MovePos(p, mainLen - 1);\r
+    return mainLen;\r
+  }\r
+\r
+  mainDist = 0; /* for GCC */\r
+  if (mainLen >= 2)\r
+  {\r
+    mainDist = matches[numPairs - 1];\r
+    while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)\r
+    {\r
+      if (!ChangePair(matches[numPairs - 3], mainDist))\r
+        break;\r
+      numPairs -= 2;\r
+      mainLen = matches[numPairs - 2];\r
+      mainDist = matches[numPairs - 1];\r
+    }\r
+    if (mainLen == 2 && mainDist >= 0x80)\r
+      mainLen = 1;\r
+  }\r
+\r
+  if (repLen >= 2 && (\r
+        (repLen + 1 >= mainLen) ||\r
+        (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||\r
+        (repLen + 3 >= mainLen && mainDist >= (1 << 15))))\r
+  {\r
+    *backRes = repIndex;\r
+    MovePos(p, repLen - 1);\r
+    return repLen;\r
+  }\r
+  \r
+  if (mainLen < 2 || numAvail <= 2)\r
+    return 1;\r
+\r
+  p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);\r
+  if (p->longestMatchLength >= 2)\r
+  {\r
+    UInt32 newDistance = matches[p->numPairs - 1];\r
+    if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||\r
+        (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||\r
+        (p->longestMatchLength > mainLen + 1) ||\r
+        (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))\r
+      return 1;\r
+  }\r
+  \r
+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;\r
+  for (i = 0; i < LZMA_NUM_REPS; i++)\r
+  {\r
+    UInt32 len, limit;\r
+    const Byte *data2 = data - (p->reps[i] + 1);\r
+    if (data[0] != data2[0] || data[1] != data2[1])\r
+      continue;\r
+    limit = mainLen - 1;\r
+    for (len = 2; len < limit && data[len] == data2[len]; len++);\r
+    if (len >= limit)\r
+      return 1;\r
+  }\r
+  *backRes = mainDist + LZMA_NUM_REPS;\r
+  MovePos(p, mainLen - 2);\r
+  return mainLen;\r
+}\r
+\r
+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)\r
+{\r
+  UInt32 len;\r
+  RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);\r
+  RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);\r
+  p->state = kMatchNextStates[p->state];\r
+  len = LZMA_MATCH_LEN_MIN;\r
+  LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);\r
+  RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);\r
+  RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);\r
+  RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);\r
+}\r
+\r
+static SRes CheckErrors(CLzmaEnc *p)\r
+{\r
+  if (p->result != SZ_OK)\r
+    return p->result;\r
+  if (p->rc.res != SZ_OK)\r
+    p->result = SZ_ERROR_WRITE;\r
+  if (p->matchFinderBase.result != SZ_OK)\r
+    p->result = SZ_ERROR_READ;\r
+  if (p->result != SZ_OK)\r
+    p->finished = True;\r
+  return p->result;\r
+}\r
+\r
+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)\r
+{\r
+  /* ReleaseMFStream(); */\r
+  p->finished = True;\r
+  if (p->writeEndMark)\r
+    WriteEndMarker(p, nowPos & p->pbMask);\r
+  RangeEnc_FlushData(&p->rc);\r
+  RangeEnc_FlushStream(&p->rc);\r
+  return CheckErrors(p);\r
+}\r
+\r
+static void FillAlignPrices(CLzmaEnc *p)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < kAlignTableSize; i++)\r
+    p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);\r
+  p->alignPriceCount = 0;\r
+}\r
+\r
+static void FillDistancesPrices(CLzmaEnc *p)\r
+{\r
+  UInt32 tempPrices[kNumFullDistances];\r
+  UInt32 i, lenToPosState;\r
+  for (i = kStartPosModelIndex; i < kNumFullDistances; i++)\r
+  {\r
+    UInt32 posSlot = GetPosSlot1(i);\r
+    UInt32 footerBits = ((posSlot >> 1) - 1);\r
+    UInt32 base = ((2 | (posSlot & 1)) << footerBits);\r
+    tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);\r
+  }\r
+\r
+  for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)\r
+  {\r
+    UInt32 posSlot;\r
+    const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];\r
+    UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];\r
+    for (posSlot = 0; posSlot < p->distTableSize; posSlot++)\r
+      posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);\r
+    for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)\r
+      posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);\r
+\r
+    {\r
+      UInt32 *distancesPrices = p->distancesPrices[lenToPosState];\r
+      UInt32 i;\r
+      for (i = 0; i < kStartPosModelIndex; i++)\r
+        distancesPrices[i] = posSlotPrices[i];\r
+      for (; i < kNumFullDistances; i++)\r
+        distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];\r
+    }\r
+  }\r
+  p->matchPriceCount = 0;\r
+}\r
+\r
+void LzmaEnc_Construct(CLzmaEnc *p)\r
+{\r
+  RangeEnc_Construct(&p->rc);\r
+  MatchFinder_Construct(&p->matchFinderBase);\r
+  #ifndef _7ZIP_ST\r
+  MatchFinderMt_Construct(&p->matchFinderMt);\r
+  p->matchFinderMt.MatchFinder = &p->matchFinderBase;\r
+  #endif\r
+\r
+  {\r
+    CLzmaEncProps props;\r
+    LzmaEncProps_Init(&props);\r
+    LzmaEnc_SetProps(p, &props);\r
+  }\r
+\r
+  #ifndef LZMA_LOG_BSR\r
+  LzmaEnc_FastPosInit(p->g_FastPos);\r
+  #endif\r
+\r
+  LzmaEnc_InitPriceTables(p->ProbPrices);\r
+  p->litProbs = 0;\r
+  p->saveState.litProbs = 0;\r
+}\r
+\r
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)\r
+{\r
+  void *p;\r
+  p = alloc->Alloc(alloc, sizeof(CLzmaEnc));\r
+  if (p != 0)\r
+    LzmaEnc_Construct((CLzmaEnc *)p);\r
+  return p;\r
+}\r
+\r
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->litProbs);\r
+  alloc->Free(alloc, p->saveState.litProbs);\r
+  p->litProbs = 0;\r
+  p->saveState.litProbs = 0;\r
+}\r
+\r
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  #ifndef _7ZIP_ST\r
+  MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);\r
+  #endif\r
+  MatchFinder_Free(&p->matchFinderBase, allocBig);\r
+  LzmaEnc_FreeLits(p, alloc);\r
+  RangeEnc_Free(&p->rc, alloc);\r
+}\r
+\r
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);\r
+  alloc->Free(alloc, p);\r
+}\r
+\r
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)\r
+{\r
+  UInt32 nowPos32, startPos32;\r
+  if (p->needInit)\r
+  {\r
+    p->matchFinder.Init(p->matchFinderObj);\r
+    p->needInit = 0;\r
+  }\r
+\r
+  if (p->finished)\r
+    return p->result;\r
+  RINOK(CheckErrors(p));\r
+\r
+  nowPos32 = (UInt32)p->nowPos64;\r
+  startPos32 = nowPos32;\r
+\r
+  if (p->nowPos64 == 0)\r
+  {\r
+    UInt32 numPairs;\r
+    Byte curByte;\r
+    if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)\r
+      return Flush(p, nowPos32);\r
+    ReadMatchDistances(p, &numPairs);\r
+    RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);\r
+    p->state = kLiteralNextStates[p->state];\r
+    curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);\r
+    LitEnc_Encode(&p->rc, p->litProbs, curByte);\r
+    p->additionalOffset--;\r
+    nowPos32++;\r
+  }\r
+\r
+  if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)\r
+  for (;;)\r
+  {\r
+    UInt32 pos, len, posState;\r
+\r
+    if (p->fastMode)\r
+      len = GetOptimumFast(p, &pos);\r
+    else\r
+      len = GetOptimum(p, nowPos32, &pos);\r
+\r
+    #ifdef SHOW_STAT2\r
+    printf("\n pos = %4X,   len = %d   pos = %d", nowPos32, len, pos);\r
+    #endif\r
+\r
+    posState = nowPos32 & p->pbMask;\r
+    if (len == 1 && pos == (UInt32)-1)\r
+    {\r
+      Byte curByte;\r
+      CLzmaProb *probs;\r
+      const Byte *data;\r
+\r
+      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);\r
+      data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;\r
+      curByte = *data;\r
+      probs = LIT_PROBS(nowPos32, *(data - 1));\r
+      if (IsCharState(p->state))\r
+        LitEnc_Encode(&p->rc, probs, curByte);\r
+      else\r
+        LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));\r
+      p->state = kLiteralNextStates[p->state];\r
+    }\r
+    else\r
+    {\r
+      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);\r
+      if (pos < LZMA_NUM_REPS)\r
+      {\r
+        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);\r
+        if (pos == 0)\r
+        {\r
+          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);\r
+          RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));\r
+        }\r
+        else\r
+        {\r
+          UInt32 distance = p->reps[pos];\r
+          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);\r
+          if (pos == 1)\r
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);\r
+          else\r
+          {\r
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);\r
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);\r
+            if (pos == 3)\r
+              p->reps[3] = p->reps[2];\r
+            p->reps[2] = p->reps[1];\r
+          }\r
+          p->reps[1] = p->reps[0];\r
+          p->reps[0] = distance;\r
+        }\r
+        if (len == 1)\r
+          p->state = kShortRepNextStates[p->state];\r
+        else\r
+        {\r
+          LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);\r
+          p->state = kRepNextStates[p->state];\r
+        }\r
+      }\r
+      else\r
+      {\r
+        UInt32 posSlot;\r
+        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);\r
+        p->state = kMatchNextStates[p->state];\r
+        LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);\r
+        pos -= LZMA_NUM_REPS;\r
+        GetPosSlot(pos, posSlot);\r
+        RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);\r
+        \r
+        if (posSlot >= kStartPosModelIndex)\r
+        {\r
+          UInt32 footerBits = ((posSlot >> 1) - 1);\r
+          UInt32 base = ((2 | (posSlot & 1)) << footerBits);\r
+          UInt32 posReduced = pos - base;\r
+\r
+          if (posSlot < kEndPosModelIndex)\r
+            RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);\r
+          else\r
+          {\r
+            RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);\r
+            RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);\r
+            p->alignPriceCount++;\r
+          }\r
+        }\r
+        p->reps[3] = p->reps[2];\r
+        p->reps[2] = p->reps[1];\r
+        p->reps[1] = p->reps[0];\r
+        p->reps[0] = pos;\r
+        p->matchPriceCount++;\r
+      }\r
+    }\r
+    p->additionalOffset -= len;\r
+    nowPos32 += len;\r
+    if (p->additionalOffset == 0)\r
+    {\r
+      UInt32 processed;\r
+      if (!p->fastMode)\r
+      {\r
+        if (p->matchPriceCount >= (1 << 7))\r
+          FillDistancesPrices(p);\r
+        if (p->alignPriceCount >= kAlignTableSize)\r
+          FillAlignPrices(p);\r
+      }\r
+      if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)\r
+        break;\r
+      processed = nowPos32 - startPos32;\r
+      if (useLimits)\r
+      {\r
+        if (processed + kNumOpts + 300 >= maxUnpackSize ||\r
+            RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)\r
+          break;\r
+      }\r
+      else if (processed >= (1 << 15))\r
+      {\r
+        p->nowPos64 += nowPos32 - startPos32;\r
+        return CheckErrors(p);\r
+      }\r
+    }\r
+  }\r
+  p->nowPos64 += nowPos32 - startPos32;\r
+  return Flush(p, nowPos32);\r
+}\r
+\r
+#define kBigHashDicLimit ((UInt32)1 << 24)\r
+\r
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  UInt32 beforeSize = kNumOpts;\r
+  Bool btMode;\r
+  if (!RangeEnc_Alloc(&p->rc, alloc))\r
+    return SZ_ERROR_MEM;\r
+  btMode = (p->matchFinderBase.btMode != 0);\r
+  #ifndef _7ZIP_ST\r
+  p->mtMode = (p->multiThread && !p->fastMode && btMode);\r
+  #endif\r
+\r
+  {\r
+    unsigned lclp = p->lc + p->lp;\r
+    if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)\r
+    {\r
+      LzmaEnc_FreeLits(p, alloc);\r
+      p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));\r
+      p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));\r
+      if (p->litProbs == 0 || p->saveState.litProbs == 0)\r
+      {\r
+        LzmaEnc_FreeLits(p, alloc);\r
+        return SZ_ERROR_MEM;\r
+      }\r
+      p->lclp = lclp;\r
+    }\r
+  }\r
+\r
+  p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);\r
+\r
+  if (beforeSize + p->dictSize < keepWindowSize)\r
+    beforeSize = keepWindowSize - p->dictSize;\r
+\r
+  #ifndef _7ZIP_ST\r
+  if (p->mtMode)\r
+  {\r
+    RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));\r
+    p->matchFinderObj = &p->matchFinderMt;\r
+    MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);\r
+  }\r
+  else\r
+  #endif\r
+  {\r
+    if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))\r
+      return SZ_ERROR_MEM;\r
+    p->matchFinderObj = &p->matchFinderBase;\r
+    MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+void LzmaEnc_Init(CLzmaEnc *p)\r
+{\r
+  UInt32 i;\r
+  p->state = 0;\r
+  for (i = 0 ; i < LZMA_NUM_REPS; i++)\r
+    p->reps[i] = 0;\r
+\r
+  RangeEnc_Init(&p->rc);\r
+\r
+\r
+  for (i = 0; i < kNumStates; i++)\r
+  {\r
+    UInt32 j;\r
+    for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)\r
+    {\r
+      p->isMatch[i][j] = kProbInitValue;\r
+      p->isRep0Long[i][j] = kProbInitValue;\r
+    }\r
+    p->isRep[i] = kProbInitValue;\r
+    p->isRepG0[i] = kProbInitValue;\r
+    p->isRepG1[i] = kProbInitValue;\r
+    p->isRepG2[i] = kProbInitValue;\r
+  }\r
+\r
+  {\r
+    UInt32 num = 0x300 << (p->lp + p->lc);\r
+    for (i = 0; i < num; i++)\r
+      p->litProbs[i] = kProbInitValue;\r
+  }\r
+\r
+  {\r
+    for (i = 0; i < kNumLenToPosStates; i++)\r
+    {\r
+      CLzmaProb *probs = p->posSlotEncoder[i];\r
+      UInt32 j;\r
+      for (j = 0; j < (1 << kNumPosSlotBits); j++)\r
+        probs[j] = kProbInitValue;\r
+    }\r
+  }\r
+  {\r
+    for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)\r
+      p->posEncoders[i] = kProbInitValue;\r
+  }\r
+\r
+  LenEnc_Init(&p->lenEnc.p);\r
+  LenEnc_Init(&p->repLenEnc.p);\r
+\r
+  for (i = 0; i < (1 << kNumAlignBits); i++)\r
+    p->posAlignEncoder[i] = kProbInitValue;\r
+\r
+  p->optimumEndIndex = 0;\r
+  p->optimumCurrentIndex = 0;\r
+  p->additionalOffset = 0;\r
+\r
+  p->pbMask = (1 << p->pb) - 1;\r
+  p->lpMask = (1 << p->lp) - 1;\r
+}\r
+\r
+void LzmaEnc_InitPrices(CLzmaEnc *p)\r
+{\r
+  if (!p->fastMode)\r
+  {\r
+    FillDistancesPrices(p);\r
+    FillAlignPrices(p);\r
+  }\r
+\r
+  p->lenEnc.tableSize =\r
+  p->repLenEnc.tableSize =\r
+      p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;\r
+  LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);\r
+  LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);\r
+}\r
+\r
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)\r
+    if (p->dictSize <= ((UInt32)1 << i))\r
+      break;\r
+  p->distTableSize = i * 2;\r
+\r
+  p->finished = False;\r
+  p->result = SZ_OK;\r
+  RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));\r
+  LzmaEnc_Init(p);\r
+  LzmaEnc_InitPrices(p);\r
+  p->nowPos64 = 0;\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,\r
+    ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  p->matchFinderBase.stream = inStream;\r
+  p->needInit = 1;\r
+  p->rc.outStream = outStream;\r
+  return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);\r
+}\r
+\r
+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,\r
+    ISeqInStream *inStream, UInt32 keepWindowSize,\r
+    ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  p->matchFinderBase.stream = inStream;\r
+  p->needInit = 1;\r
+  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);\r
+}\r
+\r
+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)\r
+{\r
+  p->matchFinderBase.directInput = 1;\r
+  p->matchFinderBase.bufferBase = (Byte *)src;\r
+  p->matchFinderBase.directInputRem = srcLen;\r
+}\r
+\r
+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,\r
+    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  LzmaEnc_SetInputBuf(p, src, srcLen);\r
+  p->needInit = 1;\r
+\r
+  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);\r
+}\r
+\r
+void LzmaEnc_Finish(CLzmaEncHandle pp)\r
+{\r
+  #ifndef _7ZIP_ST\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  if (p->mtMode)\r
+    MatchFinderMt_ReleaseStream(&p->matchFinderMt);\r
+  #else\r
+  pp = pp;\r
+  #endif\r
+}\r
+\r
+typedef struct\r
+{\r
+  ISeqOutStream funcTable;\r
+  Byte *data;\r
+  SizeT rem;\r
+  Bool overflow;\r
+} CSeqOutStreamBuf;\r
+\r
+static size_t MyWrite(void *pp, const void *data, size_t size)\r
+{\r
+  CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;\r
+  if (p->rem < size)\r
+  {\r
+    size = p->rem;\r
+    p->overflow = True;\r
+  }\r
+  memcpy(p->data, data, size);\r
+  p->rem -= size;\r
+  p->data += size;\r
+  return size;\r
+}\r
+\r
+\r
+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)\r
+{\r
+  const CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);\r
+}\r
+\r
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)\r
+{\r
+  const CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;\r
+}\r
+\r
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,\r
+    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)\r
+{\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  UInt64 nowPos64;\r
+  SRes res;\r
+  CSeqOutStreamBuf outStream;\r
+\r
+  outStream.funcTable.Write = MyWrite;\r
+  outStream.data = dest;\r
+  outStream.rem = *destLen;\r
+  outStream.overflow = False;\r
+\r
+  p->writeEndMark = False;\r
+  p->finished = False;\r
+  p->result = SZ_OK;\r
+\r
+  if (reInit)\r
+    LzmaEnc_Init(p);\r
+  LzmaEnc_InitPrices(p);\r
+  nowPos64 = p->nowPos64;\r
+  RangeEnc_Init(&p->rc);\r
+  p->rc.outStream = &outStream.funcTable;\r
+\r
+  res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);\r
+  \r
+  *unpackSize = (UInt32)(p->nowPos64 - nowPos64);\r
+  *destLen -= outStream.rem;\r
+  if (outStream.overflow)\r
+    return SZ_ERROR_OUTPUT_EOF;\r
+\r
+  return res;\r
+}\r
+\r
+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)\r
+{\r
+  SRes res = SZ_OK;\r
+\r
+  #ifndef _7ZIP_ST\r
+  Byte allocaDummy[0x300];\r
+  int i = 0;\r
+  for (i = 0; i < 16; i++)\r
+    allocaDummy[i] = (Byte)i;\r
+  #endif\r
+\r
+  for (;;)\r
+  {\r
+    res = LzmaEnc_CodeOneBlock(p, False, 0, 0);\r
+    if (res != SZ_OK || p->finished != 0)\r
+      break;\r
+    if (progress != 0)\r
+    {\r
+      res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));\r
+      if (res != SZ_OK)\r
+      {\r
+        res = SZ_ERROR_PROGRESS;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  LzmaEnc_Finish(p);\r
+  return res;\r
+}\r
+\r
+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,\r
+    ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));\r
+  return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);\r
+}\r
+\r
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)\r
+{\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+  int i;\r
+  UInt32 dictSize = p->dictSize;\r
+  if (*size < LZMA_PROPS_SIZE)\r
+    return SZ_ERROR_PARAM;\r
+  *size = LZMA_PROPS_SIZE;\r
+  props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);\r
+\r
+  for (i = 11; i <= 30; i++)\r
+  {\r
+    if (dictSize <= ((UInt32)2 << i))\r
+    {\r
+      dictSize = (2 << i);\r
+      break;\r
+    }\r
+    if (dictSize <= ((UInt32)3 << i))\r
+    {\r
+      dictSize = (3 << i);\r
+      break;\r
+    }\r
+  }\r
+\r
+  for (i = 0; i < 4; i++)\r
+    props[1 + i] = (Byte)(dictSize >> (8 * i));\r
+  return SZ_OK;\r
+}\r
+\r
+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
+    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  SRes res;\r
+  CLzmaEnc *p = (CLzmaEnc *)pp;\r
+\r
+  CSeqOutStreamBuf outStream;\r
+\r
+  LzmaEnc_SetInputBuf(p, src, srcLen);\r
+\r
+  outStream.funcTable.Write = MyWrite;\r
+  outStream.data = dest;\r
+  outStream.rem = *destLen;\r
+  outStream.overflow = False;\r
+\r
+  p->writeEndMark = writeEndMark;\r
+\r
+  p->rc.outStream = &outStream.funcTable;\r
+  res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);\r
+  if (res == SZ_OK)\r
+    res = LzmaEnc_Encode2(p, progress);\r
+\r
+  *destLen -= outStream.rem;\r
+  if (outStream.overflow)\r
+    return SZ_ERROR_OUTPUT_EOF;\r
+  return res;\r
+}\r
+\r
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
+    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,\r
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)\r
+{\r
+  CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);\r
+  SRes res;\r
+  if (p == 0)\r
+    return SZ_ERROR_MEM;\r
+\r
+  res = LzmaEnc_SetProps(p, props);\r
+  if (res == SZ_OK)\r
+  {\r
+    res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);\r
+    if (res == SZ_OK)\r
+      res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,\r
+          writeEndMark, progress, alloc, allocBig);\r
+  }\r
+\r
+  LzmaEnc_Destroy(p, alloc, allocBig);\r
+  return res;\r
+}\r
diff --git a/C/LzmaEnc.h b/C/LzmaEnc.h
new file mode 100755 (executable)
index 0000000..999f5af
--- /dev/null
@@ -0,0 +1,80 @@
+/*  LzmaEnc.h -- LZMA Encoder\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZMA_ENC_H\r
+#define __LZMA_ENC_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define LZMA_PROPS_SIZE 5\r
+\r
+typedef struct _CLzmaEncProps\r
+{\r
+  int level;       /*  0 <= level <= 9 */\r
+  UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version\r
+                      (1 << 12) <= dictSize <= (1 << 30) for 64-bit version\r
+                       default = (1 << 24) */\r
+  int lc;          /* 0 <= lc <= 8, default = 3 */\r
+  int lp;          /* 0 <= lp <= 4, default = 0 */\r
+  int pb;          /* 0 <= pb <= 4, default = 2 */\r
+  int algo;        /* 0 - fast, 1 - normal, default = 1 */\r
+  int fb;          /* 5 <= fb <= 273, default = 32 */\r
+  int btMode;      /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */\r
+  int numHashBytes; /* 2, 3 or 4, default = 4 */\r
+  UInt32 mc;        /* 1 <= mc <= (1 << 30), default = 32 */\r
+  unsigned writeEndMark;  /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */\r
+  int numThreads;  /* 1 or 2, default = 2 */\r
+} CLzmaEncProps;\r
+\r
+void LzmaEncProps_Init(CLzmaEncProps *p);\r
+void LzmaEncProps_Normalize(CLzmaEncProps *p);\r
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);\r
+\r
+\r
+/* ---------- CLzmaEncHandle Interface ---------- */\r
+\r
+/* LzmaEnc_* functions can return the following exit codes:\r
+Returns:\r
+  SZ_OK           - OK\r
+  SZ_ERROR_MEM    - Memory allocation error\r
+  SZ_ERROR_PARAM  - Incorrect paramater in props\r
+  SZ_ERROR_WRITE  - Write callback error.\r
+  SZ_ERROR_PROGRESS - some break from progress callback\r
+  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)\r
+*/\r
+\r
+typedef void * CLzmaEncHandle;\r
+\r
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);\r
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);\r
+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);\r
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);\r
+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,\r
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);\r
+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
+    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);\r
+\r
+/* ---------- One Call Interface ---------- */\r
+\r
+/* LzmaEncode\r
+Return code:\r
+  SZ_OK               - OK\r
+  SZ_ERROR_MEM        - Memory allocation error\r
+  SZ_ERROR_PARAM      - Incorrect paramater\r
+  SZ_ERROR_OUTPUT_EOF - output buffer overflow\r
+  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)\r
+*/\r
+\r
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
+    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,\r
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/LzmaLib.c b/C/LzmaLib.c
new file mode 100755 (executable)
index 0000000..3e3cf40
--- /dev/null
@@ -0,0 +1,46 @@
+/* LzmaLib.c -- LZMA library wrapper\r
+2008-08-05\r
+Igor Pavlov\r
+Public domain */\r
+\r
+#include "LzmaEnc.h"\r
+#include "LzmaDec.h"\r
+#include "Alloc.h"\r
+#include "LzmaLib.h"\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+MY_STDAPI LzmaCompress(unsigned char *dest, size_t  *destLen, const unsigned char *src, size_t  srcLen,\r
+  unsigned char *outProps, size_t *outPropsSize,\r
+  int level, /* 0 <= level <= 9, default = 5 */\r
+  unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */\r
+  int lc, /* 0 <= lc <= 8, default = 3  */\r
+  int lp, /* 0 <= lp <= 4, default = 0  */\r
+  int pb, /* 0 <= pb <= 4, default = 2  */\r
+  int fb,  /* 5 <= fb <= 273, default = 32 */\r
+  int numThreads /* 1 or 2, default = 2 */\r
+)\r
+{\r
+  CLzmaEncProps props;\r
+  LzmaEncProps_Init(&props);\r
+  props.level = level;\r
+  props.dictSize = dictSize;\r
+  props.lc = lc;\r
+  props.lp = lp;\r
+  props.pb = pb;\r
+  props.fb = fb;\r
+  props.numThreads = numThreads;\r
+\r
+  return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,\r
+      NULL, &g_Alloc, &g_Alloc);\r
+}\r
+\r
+\r
+MY_STDAPI LzmaUncompress(unsigned char *dest, size_t  *destLen, const unsigned char *src, size_t  *srcLen,\r
+  const unsigned char *props, size_t propsSize)\r
+{\r
+  ELzmaStatus status;\r
+  return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);\r
+}\r
diff --git a/C/LzmaLib.h b/C/LzmaLib.h
new file mode 100755 (executable)
index 0000000..55e1e11
--- /dev/null
@@ -0,0 +1,135 @@
+/* LzmaLib.h -- LZMA library interface\r
+2009-04-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZMA_LIB_H\r
+#define __LZMA_LIB_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define MY_STDAPI int MY_STD_CALL\r
+\r
+#define LZMA_PROPS_SIZE 5\r
+\r
+/*\r
+RAM requirements for LZMA:\r
+  for compression:   (dictSize * 11.5 + 6 MB) + state_size\r
+  for decompression: dictSize + state_size\r
+    state_size = (4 + (1.5 << (lc + lp))) KB\r
+    by default (lc=3, lp=0), state_size = 16 KB.\r
+\r
+LZMA properties (5 bytes) format\r
+    Offset Size  Description\r
+      0     1    lc, lp and pb in encoded form.\r
+      1     4    dictSize (little endian).\r
+*/\r
+\r
+/*\r
+LzmaCompress\r
+------------\r
+\r
+outPropsSize -\r
+     In:  the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.\r
+     Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.\r
+\r
+  LZMA Encoder will use defult values for any parameter, if it is\r
+  -1  for any from: level, loc, lp, pb, fb, numThreads\r
+   0  for dictSize\r
+  \r
+level - compression level: 0 <= level <= 9;\r
+\r
+  level dictSize algo  fb\r
+    0:    16 KB   0    32\r
+    1:    64 KB   0    32\r
+    2:   256 KB   0    32\r
+    3:     1 MB   0    32\r
+    4:     4 MB   0    32\r
+    5:    16 MB   1    32\r
+    6:    32 MB   1    32\r
+    7+:   64 MB   1    64\r
\r
+  The default value for "level" is 5.\r
+\r
+  algo = 0 means fast method\r
+  algo = 1 means normal method\r
+\r
+dictSize - The dictionary size in bytes. The maximum value is\r
+        128 MB = (1 << 27) bytes for 32-bit version\r
+          1 GB = (1 << 30) bytes for 64-bit version\r
+     The default value is 16 MB = (1 << 24) bytes.\r
+     It's recommended to use the dictionary that is larger than 4 KB and\r
+     that can be calculated as (1 << N) or (3 << N) sizes.\r
+\r
+lc - The number of literal context bits (high bits of previous literal).\r
+     It can be in the range from 0 to 8. The default value is 3.\r
+     Sometimes lc=4 gives the gain for big files.\r
+\r
+lp - The number of literal pos bits (low bits of current position for literals).\r
+     It can be in the range from 0 to 4. The default value is 0.\r
+     The lp switch is intended for periodical data when the period is equal to 2^lp.\r
+     For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's\r
+     better to set lc=0, if you change lp switch.\r
+\r
+pb - The number of pos bits (low bits of current position).\r
+     It can be in the range from 0 to 4. The default value is 2.\r
+     The pb switch is intended for periodical data when the period is equal 2^pb.\r
+\r
+fb - Word size (the number of fast bytes).\r
+     It can be in the range from 5 to 273. The default value is 32.\r
+     Usually, a big number gives a little bit better compression ratio and\r
+     slower compression process.\r
+\r
+numThreads - The number of thereads. 1 or 2. The default value is 2.\r
+     Fast mode (algo = 0) can use only 1 thread.\r
+\r
+Out:\r
+  destLen  - processed output size\r
+Returns:\r
+  SZ_OK               - OK\r
+  SZ_ERROR_MEM        - Memory allocation error\r
+  SZ_ERROR_PARAM      - Incorrect paramater\r
+  SZ_ERROR_OUTPUT_EOF - output buffer overflow\r
+  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)\r
+*/\r
+\r
+MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,\r
+  unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */\r
+  int level,      /* 0 <= level <= 9, default = 5 */\r
+  unsigned dictSize,  /* default = (1 << 24) */\r
+  int lc,        /* 0 <= lc <= 8, default = 3  */\r
+  int lp,        /* 0 <= lp <= 4, default = 0  */\r
+  int pb,        /* 0 <= pb <= 4, default = 2  */\r
+  int fb,        /* 5 <= fb <= 273, default = 32 */\r
+  int numThreads /* 1 or 2, default = 2 */\r
+  );\r
+\r
+/*\r
+LzmaUncompress\r
+--------------\r
+In:\r
+  dest     - output data\r
+  destLen  - output data size\r
+  src      - input data\r
+  srcLen   - input data size\r
+Out:\r
+  destLen  - processed output size\r
+  srcLen   - processed input size\r
+Returns:\r
+  SZ_OK                - OK\r
+  SZ_ERROR_DATA        - Data error\r
+  SZ_ERROR_MEM         - Memory allocation arror\r
+  SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+  SZ_ERROR_INPUT_EOF   - it needs more bytes in input buffer (src)\r
+*/\r
+\r
+MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,\r
+  const unsigned char *props, size_t propsSize);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/MtCoder.c b/C/MtCoder.c
new file mode 100755 (executable)
index 0000000..9f0d268
--- /dev/null
@@ -0,0 +1,327 @@
+/* MtCoder.c -- Multi-thread Coder\r
+2010-09-24 : Igor Pavlov : Public domain */\r
+\r
+#include <stdio.h>\r
+\r
+#include "MtCoder.h"\r
+\r
+void LoopThread_Construct(CLoopThread *p)\r
+{\r
+  Thread_Construct(&p->thread);\r
+  Event_Construct(&p->startEvent);\r
+  Event_Construct(&p->finishedEvent);\r
+}\r
+\r
+void LoopThread_Close(CLoopThread *p)\r
+{\r
+  Thread_Close(&p->thread);\r
+  Event_Close(&p->startEvent);\r
+  Event_Close(&p->finishedEvent);\r
+}\r
+\r
+static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE LoopThreadFunc(void *pp)\r
+{\r
+  CLoopThread *p = (CLoopThread *)pp;\r
+  for (;;)\r
+  {\r
+    if (Event_Wait(&p->startEvent) != 0)\r
+      return SZ_ERROR_THREAD;\r
+    if (p->stop)\r
+      return 0;\r
+    p->res = p->func(p->param);\r
+    if (Event_Set(&p->finishedEvent) != 0)\r
+      return SZ_ERROR_THREAD;\r
+  }\r
+}\r
+\r
+WRes LoopThread_Create(CLoopThread *p)\r
+{\r
+  p->stop = 0;\r
+  RINOK(AutoResetEvent_CreateNotSignaled(&p->startEvent));\r
+  RINOK(AutoResetEvent_CreateNotSignaled(&p->finishedEvent));\r
+  return Thread_Create(&p->thread, LoopThreadFunc, p);\r
+}\r
+\r
+WRes LoopThread_StopAndWait(CLoopThread *p)\r
+{\r
+  p->stop = 1;\r
+  if (Event_Set(&p->startEvent) != 0)\r
+    return SZ_ERROR_THREAD;\r
+  return Thread_Wait(&p->thread);\r
+}\r
+\r
+WRes LoopThread_StartSubThread(CLoopThread *p) { return Event_Set(&p->startEvent); }\r
+WRes LoopThread_WaitSubThread(CLoopThread *p) { return Event_Wait(&p->finishedEvent); }\r
+\r
+static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)\r
+{\r
+  return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;\r
+}\r
+\r
+static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress)\r
+{\r
+  unsigned i;\r
+  for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)\r
+    p->inSizes[i] = p->outSizes[i] = 0;\r
+  p->totalInSize = p->totalOutSize = 0;\r
+  p->progress = progress;\r
+  p->res = SZ_OK;\r
+}\r
+\r
+static void MtProgress_Reinit(CMtProgress *p, unsigned index)\r
+{\r
+  p->inSizes[index] = 0;\r
+  p->outSizes[index] = 0;\r
+}\r
+\r
+#define UPDATE_PROGRESS(size, prev, total) \\r
+  if (size != (UInt64)(Int64)-1) { total += size - prev; prev = size; }\r
+\r
+SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize)\r
+{\r
+  SRes res;\r
+  CriticalSection_Enter(&p->cs);\r
+  UPDATE_PROGRESS(inSize, p->inSizes[index], p->totalInSize)\r
+  UPDATE_PROGRESS(outSize, p->outSizes[index], p->totalOutSize)\r
+  if (p->res == SZ_OK)\r
+    p->res = Progress(p->progress, p->totalInSize, p->totalOutSize);\r
+  res = p->res;\r
+  CriticalSection_Leave(&p->cs);\r
+  return res;\r
+}\r
+\r
+static void MtProgress_SetError(CMtProgress *p, SRes res)\r
+{\r
+  CriticalSection_Enter(&p->cs);\r
+  if (p->res == SZ_OK)\r
+    p->res = res;\r
+  CriticalSection_Leave(&p->cs);\r
+}\r
+\r
+static void MtCoder_SetError(CMtCoder* p, SRes res)\r
+{\r
+  CriticalSection_Enter(&p->cs);\r
+  if (p->res == SZ_OK)\r
+    p->res = res;\r
+  CriticalSection_Leave(&p->cs);\r
+}\r
+\r
+/* ---------- MtThread ---------- */\r
+\r
+void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)\r
+{\r
+  p->mtCoder = mtCoder;\r
+  p->outBuf = 0;\r
+  p->inBuf = 0;\r
+  Event_Construct(&p->canRead);\r
+  Event_Construct(&p->canWrite);\r
+  LoopThread_Construct(&p->thread);\r
+}\r
+\r
+#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; }\r
+\r
+static void CMtThread_CloseEvents(CMtThread *p)\r
+{\r
+  Event_Close(&p->canRead);\r
+  Event_Close(&p->canWrite);\r
+}\r
+\r
+static void CMtThread_Destruct(CMtThread *p)\r
+{\r
+  CMtThread_CloseEvents(p);\r
+\r
+  if (Thread_WasCreated(&p->thread.thread))\r
+  {\r
+    LoopThread_StopAndWait(&p->thread);\r
+    LoopThread_Close(&p->thread);\r
+  }\r
+\r
+  if (p->mtCoder->alloc)\r
+    IAlloc_Free(p->mtCoder->alloc, p->outBuf);\r
+  p->outBuf = 0;\r
+\r
+  if (p->mtCoder->alloc)\r
+    IAlloc_Free(p->mtCoder->alloc, p->inBuf);\r
+  p->inBuf = 0;\r
+}\r
+\r
+#define MY_BUF_ALLOC(buf, size, newSize) \\r
+  if (buf == 0 || size != newSize) \\r
+  { IAlloc_Free(p->mtCoder->alloc, buf); \\r
+    size = newSize; buf = (Byte *)IAlloc_Alloc(p->mtCoder->alloc, size); \\r
+    if (buf == 0) return SZ_ERROR_MEM; }\r
+\r
+static SRes CMtThread_Prepare(CMtThread *p)\r
+{\r
+  MY_BUF_ALLOC(p->inBuf, p->inBufSize, p->mtCoder->blockSize)\r
+  MY_BUF_ALLOC(p->outBuf, p->outBufSize, p->mtCoder->destBlockSize)\r
+\r
+  p->stopReading = False;\r
+  p->stopWriting = False;\r
+  RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canRead));\r
+  RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canWrite));\r
+\r
+  return SZ_OK;\r
+}\r
+\r
+static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)\r
+{\r
+  size_t size = *processedSize;\r
+  *processedSize = 0;\r
+  while (size != 0)\r
+  {\r
+    size_t curSize = size;\r
+    SRes res = stream->Read(stream, data, &curSize);\r
+    *processedSize += curSize;\r
+    data += curSize;\r
+    size -= curSize;\r
+    RINOK(res);\r
+    if (curSize == 0)\r
+      return SZ_OK;\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+#define GET_NEXT_THREAD(p) &p->mtCoder->threads[p->index == p->mtCoder->numThreads  - 1 ? 0 : p->index + 1]\r
+\r
+static SRes MtThread_Process(CMtThread *p, Bool *stop)\r
+{\r
+  CMtThread *next;\r
+  *stop = True;\r
+  if (Event_Wait(&p->canRead) != 0)\r
+    return SZ_ERROR_THREAD;\r
+  \r
+  next = GET_NEXT_THREAD(p);\r
+  \r
+  if (p->stopReading)\r
+  {\r
+    next->stopReading = True;\r
+    return Event_Set(&next->canRead) == 0 ? SZ_OK : SZ_ERROR_THREAD;\r
+  }\r
+\r
+  {\r
+    size_t size = p->mtCoder->blockSize;\r
+    size_t destSize = p->outBufSize;\r
+\r
+    RINOK(FullRead(p->mtCoder->inStream, p->inBuf, &size));\r
+    next->stopReading = *stop = (size != p->mtCoder->blockSize);\r
+    if (Event_Set(&next->canRead) != 0)\r
+      return SZ_ERROR_THREAD;\r
+\r
+    RINOK(p->mtCoder->mtCallback->Code(p->mtCoder->mtCallback, p->index,\r
+        p->outBuf, &destSize, p->inBuf, size, *stop));\r
+\r
+    MtProgress_Reinit(&p->mtCoder->mtProgress, p->index);\r
+\r
+    if (Event_Wait(&p->canWrite) != 0)\r
+      return SZ_ERROR_THREAD;\r
+    if (p->stopWriting)\r
+      return SZ_ERROR_FAIL;\r
+    if (p->mtCoder->outStream->Write(p->mtCoder->outStream, p->outBuf, destSize) != destSize)\r
+      return SZ_ERROR_WRITE;\r
+    return Event_Set(&next->canWrite) == 0 ? SZ_OK : SZ_ERROR_THREAD;\r
+  }\r
+}\r
+\r
+static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp)\r
+{\r
+  CMtThread *p = (CMtThread *)pp;\r
+  for (;;)\r
+  {\r
+    Bool stop;\r
+    CMtThread *next = GET_NEXT_THREAD(p);\r
+    SRes res = MtThread_Process(p, &stop);\r
+    if (res != SZ_OK)\r
+    {\r
+      MtCoder_SetError(p->mtCoder, res);\r
+      MtProgress_SetError(&p->mtCoder->mtProgress, res);\r
+      next->stopReading = True;\r
+      next->stopWriting = True;\r
+      Event_Set(&next->canRead);\r
+      Event_Set(&next->canWrite);\r
+      return res;\r
+    }\r
+    if (stop)\r
+      return 0;\r
+  }\r
+}\r
+\r
+void MtCoder_Construct(CMtCoder* p)\r
+{\r
+  unsigned i;\r
+  p->alloc = 0;\r
+  for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)\r
+  {\r
+    CMtThread *t = &p->threads[i];\r
+    t->index = i;\r
+    CMtThread_Construct(t, p);\r
+  }\r
+  CriticalSection_Init(&p->cs);\r
+  CriticalSection_Init(&p->mtProgress.cs);\r
+}\r
+\r
+void MtCoder_Destruct(CMtCoder* p)\r
+{\r
+  unsigned i;\r
+  for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)\r
+    CMtThread_Destruct(&p->threads[i]);\r
+  CriticalSection_Delete(&p->cs);\r
+  CriticalSection_Delete(&p->mtProgress.cs);\r
+}\r
+\r
+SRes MtCoder_Code(CMtCoder *p)\r
+{\r
+  unsigned i, numThreads = p->numThreads;\r
+  SRes res = SZ_OK;\r
+  p->res = SZ_OK;\r
+\r
+  MtProgress_Init(&p->mtProgress, p->progress);\r
+\r
+  for (i = 0; i < numThreads; i++)\r
+  {\r
+    RINOK(CMtThread_Prepare(&p->threads[i]));\r
+  }\r
+\r
+  for (i = 0; i < numThreads; i++)\r
+  {\r
+    CMtThread *t = &p->threads[i];\r
+    CLoopThread *lt = &t->thread;\r
+\r
+    if (!Thread_WasCreated(&lt->thread))\r
+    {\r
+      lt->func = ThreadFunc;\r
+      lt->param = t;\r
+\r
+      if (LoopThread_Create(lt) != SZ_OK)\r
+      {\r
+        res = SZ_ERROR_THREAD;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (res == SZ_OK)\r
+  {\r
+    unsigned j;\r
+    for (i = 0; i < numThreads; i++)\r
+    {\r
+      CMtThread *t = &p->threads[i];\r
+      if (LoopThread_StartSubThread(&t->thread) != SZ_OK)\r
+      {\r
+        res = SZ_ERROR_THREAD;\r
+        p->threads[0].stopReading = True;\r
+        break;\r
+      }\r
+    }\r
+\r
+    Event_Set(&p->threads[0].canWrite);\r
+    Event_Set(&p->threads[0].canRead);\r
+\r
+    for (j = 0; j < i; j++)\r
+      LoopThread_WaitSubThread(&p->threads[j].thread);\r
+  }\r
+\r
+  for (i = 0; i < numThreads; i++)\r
+    CMtThread_CloseEvents(&p->threads[i]);\r
+  return (res == SZ_OK) ? p->res : res;\r
+}\r
diff --git a/C/MtCoder.h b/C/MtCoder.h
new file mode 100755 (executable)
index 0000000..705208e
--- /dev/null
@@ -0,0 +1,98 @@
+/* MtCoder.h -- Multi-thread Coder\r
+2009-11-19 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __MT_CODER_H\r
+#define __MT_CODER_H\r
+\r
+#include "Threads.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+typedef struct\r
+{\r
+  CThread thread;\r
+  CAutoResetEvent startEvent;\r
+  CAutoResetEvent finishedEvent;\r
+  int stop;\r
+  \r
+  THREAD_FUNC_TYPE func;\r
+  LPVOID param;\r
+  THREAD_FUNC_RET_TYPE res;\r
+} CLoopThread;\r
+\r
+void LoopThread_Construct(CLoopThread *p);\r
+void LoopThread_Close(CLoopThread *p);\r
+WRes LoopThread_Create(CLoopThread *p);\r
+WRes LoopThread_StopAndWait(CLoopThread *p);\r
+WRes LoopThread_StartSubThread(CLoopThread *p);\r
+WRes LoopThread_WaitSubThread(CLoopThread *p);\r
+\r
+#ifndef _7ZIP_ST\r
+#define NUM_MT_CODER_THREADS_MAX 32\r
+#else\r
+#define NUM_MT_CODER_THREADS_MAX 1\r
+#endif\r
+\r
+typedef struct\r
+{\r
+  UInt64 totalInSize;\r
+  UInt64 totalOutSize;\r
+  ICompressProgress *progress;\r
+  SRes res;\r
+  CCriticalSection cs;\r
+  UInt64 inSizes[NUM_MT_CODER_THREADS_MAX];\r
+  UInt64 outSizes[NUM_MT_CODER_THREADS_MAX];\r
+} CMtProgress;\r
+\r
+SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize);\r
+\r
+struct _CMtCoder;\r
+\r
+typedef struct\r
+{\r
+  struct _CMtCoder *mtCoder;\r
+  Byte *outBuf;\r
+  size_t outBufSize;\r
+  Byte *inBuf;\r
+  size_t inBufSize;\r
+  unsigned index;\r
+  CLoopThread thread;\r
+\r
+  Bool stopReading;\r
+  Bool stopWriting;\r
+  CAutoResetEvent canRead;\r
+  CAutoResetEvent canWrite;\r
+} CMtThread;\r
+\r
+typedef struct\r
+{\r
+  SRes (*Code)(void *p, unsigned index, Byte *dest, size_t *destSize,\r
+      const Byte *src, size_t srcSize, int finished);\r
+} IMtCoderCallback;\r
+\r
+typedef struct _CMtCoder\r
+{\r
+  size_t blockSize;\r
+  size_t destBlockSize;\r
+  unsigned numThreads;\r
+  \r
+  ISeqInStream *inStream;\r
+  ISeqOutStream *outStream;\r
+  ICompressProgress *progress;\r
+  ISzAlloc *alloc;\r
+\r
+  IMtCoderCallback *mtCallback;\r
+  CCriticalSection cs;\r
+  SRes res;\r
+\r
+  CMtProgress mtProgress;\r
+  CMtThread threads[NUM_MT_CODER_THREADS_MAX];\r
+} CMtCoder;\r
+\r
+void MtCoder_Construct(CMtCoder* p);\r
+void MtCoder_Destruct(CMtCoder* p);\r
+SRes MtCoder_Code(CMtCoder *p);\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/Ppmd.h b/C/Ppmd.h
new file mode 100755 (executable)
index 0000000..14344a7
--- /dev/null
+++ b/C/Ppmd.h
@@ -0,0 +1,81 @@
+/* Ppmd.h -- PPMD codec common code\r
+2010-03-12 : Igor Pavlov : Public domain\r
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */\r
+\r
+#ifndef __PPMD_H\r
+#define __PPMD_H\r
+\r
+#include "Types.h"\r
+#include "CpuArch.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+#ifdef MY_CPU_32BIT\r
+  #define PPMD_32BIT\r
+#endif\r
+\r
+#define PPMD_INT_BITS 7\r
+#define PPMD_PERIOD_BITS 7\r
+#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))\r
+\r
+#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))\r
+#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)\r
+#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))\r
+#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))\r
+\r
+#define PPMD_N1 4\r
+#define PPMD_N2 4\r
+#define PPMD_N3 4\r
+#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)\r
+#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)\r
+\r
+/* SEE-contexts for PPM-contexts with masked symbols */\r
+typedef struct\r
+{\r
+  UInt16 Summ; /* Freq */\r
+  Byte Shift;  /* Speed of Freq change; low Shift is for fast change */\r
+  Byte Count;  /* Count to next change of Shift */\r
+} CPpmd_See;\r
+\r
+#define Ppmd_See_Update(p)  if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \\r
+    { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }\r
+\r
+typedef struct\r
+{\r
+  Byte Symbol;\r
+  Byte Freq;\r
+  UInt16 SuccessorLow;\r
+  UInt16 SuccessorHigh;\r
+} CPpmd_State;\r
+\r
+typedef\r
+  #ifdef PPMD_32BIT\r
+    CPpmd_State *\r
+  #else\r
+    UInt32\r
+  #endif\r
+  CPpmd_State_Ref;\r
+\r
+typedef\r
+  #ifdef PPMD_32BIT\r
+    void *\r
+  #else\r
+    UInt32\r
+  #endif\r
+  CPpmd_Void_Ref;\r
+\r
+typedef\r
+  #ifdef PPMD_32BIT\r
+    Byte *\r
+  #else\r
+    UInt32\r
+  #endif\r
+  CPpmd_Byte_Ref;\r
+\r
+#define PPMD_SetAllBitsIn256Bytes(p) \\r
+  { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \\r
+  p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}\r
+\r
+EXTERN_C_END\r
\r
+#endif\r
diff --git a/C/Ppmd7.c b/C/Ppmd7.c
new file mode 100755 (executable)
index 0000000..4b160cf
--- /dev/null
+++ b/C/Ppmd7.c
@@ -0,0 +1,708 @@
+/* Ppmd7.c -- PPMdH codec\r
+2010-03-12 : Igor Pavlov : Public domain\r
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */\r
+\r
+#include <memory.h>\r
+\r
+#include "Ppmd7.h"\r
+\r
+const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };\r
+static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};\r
+\r
+#define MAX_FREQ 124\r
+#define UNIT_SIZE 12\r
+\r
+#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)\r
+#define U2I(nu) (p->Units2Indx[(nu) - 1])\r
+#define I2U(indx) (p->Indx2Units[indx])\r
+\r
+#ifdef PPMD_32BIT\r
+  #define REF(ptr) (ptr)\r
+#else\r
+  #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))\r
+#endif\r
+\r
+#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))\r
+\r
+#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))\r
+#define STATS(ctx) Ppmd7_GetStats(p, ctx)\r
+#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)\r
+#define SUFFIX(ctx) CTX((ctx)->Suffix)\r
+\r
+typedef CPpmd7_Context * CTX_PTR;\r
+\r
+struct CPpmd7_Node_;\r
+\r
+typedef\r
+  #ifdef PPMD_32BIT\r
+    struct CPpmd7_Node_ *\r
+  #else\r
+    UInt32\r
+  #endif\r
+  CPpmd7_Node_Ref;\r
+\r
+typedef struct CPpmd7_Node_\r
+{\r
+  UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */\r
+  UInt16 NU;\r
+  CPpmd7_Node_Ref Next; /* must be at offset >= 4 */\r
+  CPpmd7_Node_Ref Prev;\r
+} CPpmd7_Node;\r
+\r
+#ifdef PPMD_32BIT\r
+  #define NODE(ptr) (ptr)\r
+#else\r
+  #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))\r
+#endif\r
+\r
+void Ppmd7_Construct(CPpmd7 *p)\r
+{\r
+  unsigned i, k, m;\r
+\r
+  p->Base = 0;\r
+\r
+  for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)\r
+  {\r
+    unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);\r
+    do { p->Units2Indx[k++] = (Byte)i; } while(--step);\r
+    p->Indx2Units[i] = (Byte)k;\r
+  }\r
+\r
+  p->NS2BSIndx[0] = (0 << 1);\r
+  p->NS2BSIndx[1] = (1 << 1);\r
+  memset(p->NS2BSIndx + 2, (2 << 1), 9);\r
+  memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);\r
+\r
+  for (i = 0; i < 3; i++)\r
+    p->NS2Indx[i] = (Byte)i;\r
+  for (m = i, k = 1; i < 256; i++)\r
+  {\r
+    p->NS2Indx[i] = (Byte)m;\r
+    if (--k == 0)\r
+      k = (++m) - 2;\r
+  }\r
+\r
+  memset(p->HB2Flag, 0, 0x40);\r
+  memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);\r
+}\r
+\r
+void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->Base);\r
+  p->Size = 0;\r
+  p->Base = 0;\r
+}\r
+\r
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)\r
+{\r
+  if (p->Base == 0 || p->Size != size)\r
+  {\r
+    Ppmd7_Free(p, alloc);\r
+    p->AlignOffset =\r
+      #ifdef PPMD_32BIT\r
+        (4 - size) & 3;\r
+      #else\r
+        4 - (size & 3);\r
+      #endif\r
+    if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size\r
+        #ifndef PPMD_32BIT\r
+        + UNIT_SIZE\r
+        #endif\r
+        )) == 0)\r
+      return False;\r
+    p->Size = size;\r
+  }\r
+  return True;\r
+}\r
+\r
+static void InsertNode(CPpmd7 *p, void *node, unsigned indx)\r
+{\r
+  *((CPpmd_Void_Ref *)node) = p->FreeList[indx];\r
+  p->FreeList[indx] = REF(node);\r
+}\r
+\r
+static void *RemoveNode(CPpmd7 *p, unsigned indx)\r
+{\r
+  CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);\r
+  p->FreeList[indx] = *node;\r
+  return node;\r
+}\r
+\r
+static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)\r
+{\r
+  unsigned i, nu = I2U(oldIndx) - I2U(newIndx);\r
+  ptr = (Byte *)ptr + U2B(I2U(newIndx));\r
+  if (I2U(i = U2I(nu)) != nu)\r
+  {\r
+    unsigned k = I2U(--i);\r
+    InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);\r
+  }\r
+  InsertNode(p, ptr, i);\r
+}\r
+\r
+static void GlueFreeBlocks(CPpmd7 *p)\r
+{\r
+  #ifdef PPMD_32BIT\r
+  CPpmd7_Node headItem;\r
+  CPpmd7_Node_Ref head = &headItem;\r
+  #else\r
+  CPpmd7_Node_Ref head = p->AlignOffset + p->Size;\r
+  #endif\r
+  \r
+  CPpmd7_Node_Ref n = head;\r
+  unsigned i;\r
+\r
+  p->GlueCount = 255;\r
+\r
+  /* create doubly-linked list of free blocks */\r
+  for (i = 0; i < PPMD_NUM_INDEXES; i++)\r
+  {\r
+    UInt16 nu = I2U(i);\r
+    CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];\r
+    p->FreeList[i] = 0;\r
+    while (next != 0)\r
+    {\r
+      CPpmd7_Node *node = NODE(next);\r
+      node->Next = n;\r
+      n = NODE(n)->Prev = next;\r
+      next = *(const CPpmd7_Node_Ref *)node;\r
+      node->Stamp = 0;\r
+      node->NU = (UInt16)nu;\r
+    }\r
+  }\r
+  NODE(head)->Stamp = 1;\r
+  NODE(head)->Next = n;\r
+  NODE(n)->Prev = head;\r
+  if (p->LoUnit != p->HiUnit)\r
+    ((CPpmd7_Node *)p->LoUnit)->Stamp = 1;\r
+  \r
+  /* Glue free blocks */\r
+  while (n != head)\r
+  {\r
+    CPpmd7_Node *node = NODE(n);\r
+    UInt32 nu = (UInt32)node->NU;\r
+    for (;;)\r
+    {\r
+      CPpmd7_Node *node2 = NODE(n) + nu;\r
+      nu += node2->NU;\r
+      if (node2->Stamp != 0 || nu >= 0x10000)\r
+        break;\r
+      NODE(node2->Prev)->Next = node2->Next;\r
+      NODE(node2->Next)->Prev = node2->Prev;\r
+      node->NU = (UInt16)nu;\r
+    }\r
+    n = node->Next;\r
+  }\r
+  \r
+  /* Fill lists of free blocks */\r
+  for (n = NODE(head)->Next; n != head;)\r
+  {\r
+    CPpmd7_Node *node = NODE(n);\r
+    unsigned nu;\r
+    CPpmd7_Node_Ref next = node->Next;\r
+    for (nu = node->NU; nu > 128; nu -= 128, node += 128)\r
+      InsertNode(p, node, PPMD_NUM_INDEXES - 1);\r
+    if (I2U(i = U2I(nu)) != nu)\r
+    {\r
+      unsigned k = I2U(--i);\r
+      InsertNode(p, node + k, nu - k - 1);\r
+    }\r
+    InsertNode(p, node, i);\r
+    n = next;\r
+  }\r
+}\r
+\r
+static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)\r
+{\r
+  unsigned i;\r
+  void *retVal;\r
+  if (p->GlueCount == 0)\r
+  {\r
+    GlueFreeBlocks(p);\r
+    if (p->FreeList[indx] != 0)\r
+      return RemoveNode(p, indx);\r
+  }\r
+  i = indx;\r
+  do\r
+  {\r
+    if (++i == PPMD_NUM_INDEXES)\r
+    {\r
+      UInt32 numBytes = U2B(I2U(indx));\r
+      p->GlueCount--;\r
+      return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);\r
+    }\r
+  }\r
+  while (p->FreeList[i] == 0);\r
+  retVal = RemoveNode(p, i);\r
+  SplitBlock(p, retVal, i, indx);\r
+  return retVal;\r
+}\r
+\r
+static void *AllocUnits(CPpmd7 *p, unsigned indx)\r
+{\r
+  UInt32 numBytes;\r
+  if (p->FreeList[indx] != 0)\r
+    return RemoveNode(p, indx);\r
+  numBytes = U2B(I2U(indx));\r
+  if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))\r
+  {\r
+    void *retVal = p->LoUnit;\r
+    p->LoUnit += numBytes;\r
+    return retVal;\r
+  }\r
+  return AllocUnitsRare(p, indx);\r
+}\r
+\r
+#define MyMem12Cpy(dest, src, num) \\r
+  { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \\r
+    do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }\r
+\r
+static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)\r
+{\r
+  unsigned i0 = U2I(oldNU);\r
+  unsigned i1 = U2I(newNU);\r
+  if (i0 == i1)\r
+    return oldPtr;\r
+  if (p->FreeList[i1] != 0)\r
+  {\r
+    void *ptr = RemoveNode(p, i1);\r
+    MyMem12Cpy(ptr, oldPtr, newNU);\r
+    InsertNode(p, oldPtr, i0);\r
+    return ptr;\r
+  }\r
+  SplitBlock(p, oldPtr, i0, i1);\r
+  return oldPtr;\r
+}\r
+\r
+#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))\r
+\r
+static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)\r
+{\r
+  (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);\r
+  (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);\r
+}\r
+\r
+static void RestartModel(CPpmd7 *p)\r
+{\r
+  unsigned i, k, m;\r
+\r
+  memset(p->FreeList, 0, sizeof(p->FreeList));\r
+  p->Text = p->Base + p->AlignOffset;\r
+  p->HiUnit = p->Text + p->Size;\r
+  p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;\r
+  p->GlueCount = 0;\r
+\r
+  p->OrderFall = p->MaxOrder;\r
+  p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;\r
+  p->PrevSuccess = 0;\r
+\r
+  p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */\r
+  p->MinContext->Suffix = 0;\r
+  p->MinContext->NumStats = 256;\r
+  p->MinContext->SummFreq = 256 + 1;\r
+  p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */\r
+  p->LoUnit += U2B(256 / 2);\r
+  p->MinContext->Stats = REF(p->FoundState);\r
+  for (i = 0; i < 256; i++)\r
+  {\r
+    CPpmd_State *s = &p->FoundState[i];\r
+    s->Symbol = (Byte)i;\r
+    s->Freq = 1;\r
+    SetSuccessor(s, 0);\r
+  }\r
+\r
+  for (i = 0; i < 128; i++)\r
+    for (k = 0; k < 8; k++)\r
+    {\r
+      UInt16 *dest = p->BinSumm[i] + k;\r
+      UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));\r
+      for (m = 0; m < 64; m += 8)\r
+        dest[m] = val;\r
+    }\r
+  \r
+  for (i = 0; i < 25; i++)\r
+    for (k = 0; k < 16; k++)\r
+    {\r
+      CPpmd_See *s = &p->See[i][k];\r
+      s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));\r
+      s->Count = 4;\r
+    }\r
+}\r
+\r
+void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)\r
+{\r
+  p->MaxOrder = maxOrder;\r
+  RestartModel(p);\r
+  p->DummySee.Shift = PPMD_PERIOD_BITS;\r
+  p->DummySee.Summ = 0; /* unused */\r
+  p->DummySee.Count = 64; /* unused */\r
+}\r
+\r
+static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)\r
+{\r
+  CPpmd_State upState;\r
+  CTX_PTR c = p->MinContext;\r
+  CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);\r
+  CPpmd_State *ps[PPMD7_MAX_ORDER];\r
+  unsigned numPs = 0;\r
+  \r
+  if (!skip)\r
+    ps[numPs++] = p->FoundState;\r
+  \r
+  while (c->Suffix)\r
+  {\r
+    CPpmd_Void_Ref successor;\r
+    CPpmd_State *s;\r
+    c = SUFFIX(c);\r
+    if (c->NumStats != 1)\r
+    {\r
+      for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);\r
+    }\r
+    else\r
+      s = ONE_STATE(c);\r
+    successor = SUCCESSOR(s);\r
+    if (successor != upBranch)\r
+    {\r
+      c = CTX(successor);\r
+      if (numPs == 0)\r
+        return c;\r
+      break;\r
+    }\r
+    ps[numPs++] = s;\r
+  }\r
+  \r
+  upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);\r
+  SetSuccessor(&upState, upBranch + 1);\r
+  \r
+  if (c->NumStats == 1)\r
+    upState.Freq = ONE_STATE(c)->Freq;\r
+  else\r
+  {\r
+    UInt32 cf, s0;\r
+    CPpmd_State *s;\r
+    for (s = STATS(c); s->Symbol != upState.Symbol; s++);\r
+    cf = s->Freq - 1;\r
+    s0 = c->SummFreq - c->NumStats - cf;\r
+    upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));\r
+  }\r
+\r
+  do\r
+  {\r
+    /* Create Child */\r
+    CTX_PTR c1; /* = AllocContext(p); */\r
+    if (p->HiUnit != p->LoUnit)\r
+      c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);\r
+    else if (p->FreeList[0] != 0)\r
+      c1 = (CTX_PTR)RemoveNode(p, 0);\r
+    else\r
+    {\r
+      c1 = (CTX_PTR)AllocUnitsRare(p, 0);\r
+      if (!c1)\r
+        return NULL;\r
+    }\r
+    c1->NumStats = 1;\r
+    *ONE_STATE(c1) = upState;\r
+    c1->Suffix = REF(c);\r
+    SetSuccessor(ps[--numPs], REF(c1));\r
+    c = c1;\r
+  }\r
+  while (numPs != 0);\r
+  \r
+  return c;\r
+}\r
+\r
+static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)\r
+{\r
+  CPpmd_State tmp = *t1;\r
+  *t1 = *t2;\r
+  *t2 = tmp;\r
+}\r
+\r
+static void UpdateModel(CPpmd7 *p)\r
+{\r
+  CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);\r
+  CTX_PTR c;\r
+  unsigned s0, ns;\r
+  \r
+  if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)\r
+  {\r
+    c = SUFFIX(p->MinContext);\r
+    \r
+    if (c->NumStats == 1)\r
+    {\r
+      CPpmd_State *s = ONE_STATE(c);\r
+      if (s->Freq < 32)\r
+        s->Freq++;\r
+    }\r
+    else\r
+    {\r
+      CPpmd_State *s = STATS(c);\r
+      if (s->Symbol != p->FoundState->Symbol)\r
+      {\r
+        do { s++; } while (s->Symbol != p->FoundState->Symbol);\r
+        if (s[0].Freq >= s[-1].Freq)\r
+        {\r
+          SwapStates(&s[0], &s[-1]);\r
+          s--;\r
+        }\r
+      }\r
+      if (s->Freq < MAX_FREQ - 9)\r
+      {\r
+        s->Freq += 2;\r
+        c->SummFreq += 2;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (p->OrderFall == 0)\r
+  {\r
+    p->MinContext = p->MaxContext = CreateSuccessors(p, True);\r
+    if (p->MinContext == 0)\r
+    {\r
+      RestartModel(p);\r
+      return;\r
+    }\r
+    SetSuccessor(p->FoundState, REF(p->MinContext));\r
+    return;\r
+  }\r
+  \r
+  *p->Text++ = p->FoundState->Symbol;\r
+  successor = REF(p->Text);\r
+  if (p->Text >= p->UnitsStart)\r
+  {\r
+    RestartModel(p);\r
+    return;\r
+  }\r
+  \r
+  if (fSuccessor)\r
+  {\r
+    if (fSuccessor <= successor)\r
+    {\r
+      CTX_PTR cs = CreateSuccessors(p, False);\r
+      if (cs == NULL)\r
+      {\r
+        RestartModel(p);\r
+        return;\r
+      }\r
+      fSuccessor = REF(cs);\r
+    }\r
+    if (--p->OrderFall == 0)\r
+    {\r
+      successor = fSuccessor;\r
+      p->Text -= (p->MaxContext != p->MinContext);\r
+    }\r
+  }\r
+  else\r
+  {\r
+    SetSuccessor(p->FoundState, successor);\r
+    fSuccessor = REF(p->MinContext);\r
+  }\r
+  \r
+  s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);\r
+  \r
+  for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))\r
+  {\r
+    unsigned ns1;\r
+    UInt32 cf, sf;\r
+    if ((ns1 = c->NumStats) != 1)\r
+    {\r
+      if ((ns1 & 1) == 0)\r
+      {\r
+        /* Expand for one UNIT */\r
+        unsigned oldNU = ns1 >> 1;\r
+        unsigned i = U2I(oldNU);\r
+        if (i != U2I(oldNU + 1))\r
+        {\r
+          void *ptr = AllocUnits(p, i + 1);\r
+          void *oldPtr;\r
+          if (!ptr)\r
+          {\r
+            RestartModel(p);\r
+            return;\r
+          }\r
+          oldPtr = STATS(c);\r
+          MyMem12Cpy(ptr, oldPtr, oldNU);\r
+          InsertNode(p, oldPtr, i);\r
+          c->Stats = STATS_REF(ptr);\r
+        }\r
+      }\r
+      c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));\r
+    }\r
+    else\r
+    {\r
+      CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);\r
+      if (!s)\r
+      {\r
+        RestartModel(p);\r
+        return;\r
+      }\r
+      *s = *ONE_STATE(c);\r
+      c->Stats = REF(s);\r
+      if (s->Freq < MAX_FREQ / 4 - 1)\r
+        s->Freq <<= 1;\r
+      else\r
+        s->Freq = MAX_FREQ - 4;\r
+      c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));\r
+    }\r
+    cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);\r
+    sf = (UInt32)s0 + c->SummFreq;\r
+    if (cf < 6 * sf)\r
+    {\r
+      cf = 1 + (cf > sf) + (cf >= 4 * sf);\r
+      c->SummFreq += 3;\r
+    }\r
+    else\r
+    {\r
+      cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);\r
+      c->SummFreq = (UInt16)(c->SummFreq + cf);\r
+    }\r
+    {\r
+      CPpmd_State *s = STATS(c) + ns1;\r
+      SetSuccessor(s, successor);\r
+      s->Symbol = p->FoundState->Symbol;\r
+      s->Freq = (Byte)cf;\r
+      c->NumStats = (UInt16)(ns1 + 1);\r
+    }\r
+  }\r
+  p->MaxContext = p->MinContext = CTX(fSuccessor);\r
+}\r
+  \r
+static void Rescale(CPpmd7 *p)\r
+{\r
+  unsigned i, adder, sumFreq, escFreq;\r
+  CPpmd_State *stats = STATS(p->MinContext);\r
+  CPpmd_State *s = p->FoundState;\r
+  {\r
+    CPpmd_State tmp = *s;\r
+    for (; s != stats; s--)\r
+      s[0] = s[-1];\r
+    *s = tmp;\r
+  }\r
+  escFreq = p->MinContext->SummFreq - s->Freq;\r
+  s->Freq += 4;\r
+  adder = (p->OrderFall != 0);\r
+  s->Freq = (Byte)((s->Freq + adder) >> 1);\r
+  sumFreq = s->Freq;\r
+  \r
+  i = p->MinContext->NumStats - 1;\r
+  do\r
+  {\r
+    escFreq -= (++s)->Freq;\r
+    s->Freq = (Byte)((s->Freq + adder) >> 1);\r
+    sumFreq += s->Freq;\r
+    if (s[0].Freq > s[-1].Freq)\r
+    {\r
+      CPpmd_State *s1 = s;\r
+      CPpmd_State tmp = *s1;\r
+      do\r
+        s1[0] = s1[-1];\r
+      while (--s1 != stats && tmp.Freq > s1[-1].Freq);\r
+      *s1 = tmp;\r
+    }\r
+  }\r
+  while (--i);\r
+  \r
+  if (s->Freq == 0)\r
+  {\r
+    unsigned numStats = p->MinContext->NumStats;\r
+    unsigned n0, n1;\r
+    do { i++; } while ((--s)->Freq == 0);\r
+    escFreq += i;\r
+    p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);\r
+    if (p->MinContext->NumStats == 1)\r
+    {\r
+      CPpmd_State tmp = *stats;\r
+      do\r
+      {\r
+        tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));\r
+        escFreq >>= 1;\r
+      }\r
+      while (escFreq > 1);\r
+      InsertNode(p, stats, U2I(((numStats + 1) >> 1)));\r
+      *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;\r
+      return;\r
+    }\r
+    n0 = (numStats + 1) >> 1;\r
+    n1 = (p->MinContext->NumStats + 1) >> 1;\r
+    if (n0 != n1)\r
+      p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));\r
+  }\r
+  p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));\r
+  p->FoundState = STATS(p->MinContext);\r
+}\r
+\r
+CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)\r
+{\r
+  CPpmd_See *see;\r
+  unsigned nonMasked = p->MinContext->NumStats - numMasked;\r
+  if (p->MinContext->NumStats != 256)\r
+  {\r
+    see = p->See[p->NS2Indx[nonMasked - 1]] +\r
+        (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +\r
+        2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +\r
+        4 * (numMasked > nonMasked) +\r
+        p->HiBitsFlag;\r
+    {\r
+      unsigned r = (see->Summ >> see->Shift);\r
+      see->Summ = (UInt16)(see->Summ - r);\r
+      *escFreq = r + (r == 0);\r
+    }\r
+  }\r
+  else\r
+  {\r
+    see = &p->DummySee;\r
+    *escFreq = 1;\r
+  }\r
+  return see;\r
+}\r
+\r
+static void NextContext(CPpmd7 *p)\r
+{\r
+  CTX_PTR c = CTX(SUCCESSOR(p->FoundState));\r
+  if (p->OrderFall == 0 && (Byte *)c > p->Text)\r
+    p->MinContext = p->MaxContext = c;\r
+  else\r
+    UpdateModel(p);\r
+}\r
+\r
+void Ppmd7_Update1(CPpmd7 *p)\r
+{\r
+  CPpmd_State *s = p->FoundState;\r
+  s->Freq += 4;\r
+  p->MinContext->SummFreq += 4;\r
+  if (s[0].Freq > s[-1].Freq)\r
+  {\r
+    SwapStates(&s[0], &s[-1]);\r
+    p->FoundState = --s;\r
+    if (s->Freq > MAX_FREQ)\r
+      Rescale(p);\r
+  }\r
+  NextContext(p);\r
+}\r
+\r
+void Ppmd7_Update1_0(CPpmd7 *p)\r
+{\r
+  p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);\r
+  p->RunLength += p->PrevSuccess;\r
+  p->MinContext->SummFreq += 4;\r
+  if ((p->FoundState->Freq += 4) > MAX_FREQ)\r
+    Rescale(p);\r
+  NextContext(p);\r
+}\r
+\r
+void Ppmd7_UpdateBin(CPpmd7 *p)\r
+{\r
+  p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));\r
+  p->PrevSuccess = 1;\r
+  p->RunLength++;\r
+  NextContext(p);\r
+}\r
+\r
+void Ppmd7_Update2(CPpmd7 *p)\r
+{\r
+  p->MinContext->SummFreq += 4;\r
+  if ((p->FoundState->Freq += 4) > MAX_FREQ)\r
+    Rescale(p);\r
+  p->RunLength = p->InitRL;\r
+  UpdateModel(p);\r
+}\r
diff --git a/C/Ppmd7.h b/C/Ppmd7.h
new file mode 100755 (executable)
index 0000000..56e81eb
--- /dev/null
+++ b/C/Ppmd7.h
@@ -0,0 +1,140 @@
+/* Ppmd7.h -- PPMdH compression codec\r
+2010-03-12 : Igor Pavlov : Public domain\r
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */\r
+\r
+/* This code supports virtual RangeDecoder and includes the implementation\r
+of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.\r
+If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */\r
+\r
+#ifndef __PPMD7_H\r
+#define __PPMD7_H\r
+\r
+#include "Ppmd.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+#define PPMD7_MIN_ORDER 2\r
+#define PPMD7_MAX_ORDER 64\r
+\r
+#define PPMD7_MIN_MEM_SIZE (1 << 11)\r
+#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)\r
+\r
+struct CPpmd7_Context_;\r
+\r
+typedef\r
+  #ifdef PPMD_32BIT\r
+    struct CPpmd7_Context_ *\r
+  #else\r
+    UInt32\r
+  #endif\r
+  CPpmd7_Context_Ref;\r
+\r
+typedef struct CPpmd7_Context_\r
+{\r
+  UInt16 NumStats;\r
+  UInt16 SummFreq;\r
+  CPpmd_State_Ref Stats;\r
+  CPpmd7_Context_Ref Suffix;\r
+} CPpmd7_Context;\r
+\r
+#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)\r
+\r
+typedef struct\r
+{\r
+  CPpmd7_Context *MinContext, *MaxContext;\r
+  CPpmd_State *FoundState;\r
+  unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;\r
+  Int32 RunLength, InitRL; /* must be 32-bit at least */\r
+\r
+  UInt32 Size;\r
+  UInt32 GlueCount;\r
+  Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;\r
+  UInt32 AlignOffset;\r
+\r
+  Byte Indx2Units[PPMD_NUM_INDEXES];\r
+  Byte Units2Indx[128];\r
+  CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];\r
+  Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];\r
+  CPpmd_See DummySee, See[25][16];\r
+  UInt16 BinSumm[128][64];\r
+} CPpmd7;\r
+\r
+void Ppmd7_Construct(CPpmd7 *p);\r
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);\r
+void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);\r
+void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);\r
+#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)\r
+\r
+\r
+/* ---------- Internal Functions ---------- */\r
+\r
+extern const Byte PPMD7_kExpEscape[16];\r
+\r
+#ifdef PPMD_32BIT\r
+  #define Ppmd7_GetPtr(p, ptr) (ptr)\r
+  #define Ppmd7_GetContext(p, ptr) (ptr)\r
+  #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)\r
+#else\r
+  #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))\r
+  #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))\r
+  #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))\r
+#endif\r
+\r
+void Ppmd7_Update1(CPpmd7 *p);\r
+void Ppmd7_Update1_0(CPpmd7 *p);\r
+void Ppmd7_Update2(CPpmd7 *p);\r
+void Ppmd7_UpdateBin(CPpmd7 *p);\r
+\r
+#define Ppmd7_GetBinSumm(p) \\r
+    &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \\r
+    p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \\r
+    (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \\r
+    2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \\r
+    ((p->RunLength >> 26) & 0x20)]\r
+\r
+CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);\r
+\r
+\r
+/* ---------- Decode ---------- */\r
+\r
+typedef struct\r
+{\r
+  UInt32 (*GetThreshold)(void *p, UInt32 total);\r
+  void (*Decode)(void *p, UInt32 start, UInt32 size);\r
+  UInt32 (*DecodeBit)(void *p, UInt32 size0);\r
+} IPpmd7_RangeDec;\r
+\r
+typedef struct\r
+{\r
+  IPpmd7_RangeDec p;\r
+  UInt32 Range;\r
+  UInt32 Code;\r
+  IByteIn *Stream;\r
+} CPpmd7z_RangeDec;\r
+\r
+void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);\r
+Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);\r
+#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)\r
+\r
+int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);\r
+\r
+\r
+/* ---------- Encode ---------- */\r
+\r
+typedef struct\r
+{\r
+  UInt64 Low;\r
+  UInt32 Range;\r
+  Byte Cache;\r
+  UInt64 CacheSize;\r
+  IByteOut *Stream;\r
+} CPpmd7z_RangeEnc;\r
+\r
+void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);\r
+void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);\r
+\r
+void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);\r
+\r
+EXTERN_C_END\r
\r
+#endif\r
diff --git a/C/Ppmd7Dec.c b/C/Ppmd7Dec.c
new file mode 100755 (executable)
index 0000000..d6608e8
--- /dev/null
@@ -0,0 +1,187 @@
+/* Ppmd7Dec.c -- PPMdH Decoder\r
+2010-03-12 : Igor Pavlov : Public domain\r
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */\r
+\r
+#include "Ppmd7.h"\r
+\r
+#define kTopValue (1 << 24)\r
+\r
+Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)\r
+{\r
+  unsigned i;\r
+  p->Code = 0;\r
+  p->Range = 0xFFFFFFFF;\r
+  if (p->Stream->Read((void *)p->Stream) != 0)\r
+    return False;\r
+  for (i = 0; i < 4; i++)\r
+    p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);\r
+  return (p->Code < 0xFFFFFFFF);\r
+}\r
+\r
+static UInt32 Range_GetThreshold(void *pp, UInt32 total)\r
+{\r
+  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;\r
+  return (p->Code) / (p->Range /= total);\r
+}\r
+\r
+static void Range_Normalize(CPpmd7z_RangeDec *p)\r
+{\r
+  if (p->Range < kTopValue)\r
+  {\r
+    p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);\r
+    p->Range <<= 8;\r
+    if (p->Range < kTopValue)\r
+    {\r
+      p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);\r
+      p->Range <<= 8;\r
+    }\r
+  }\r
+}\r
+\r
+static void Range_Decode(void *pp, UInt32 start, UInt32 size)\r
+{\r
+  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;\r
+  p->Code -= start * p->Range;\r
+  p->Range *= size;\r
+  Range_Normalize(p);\r
+}\r
+\r
+static UInt32 Range_DecodeBit(void *pp, UInt32 size0)\r
+{\r
+  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;\r
+  UInt32 newBound = (p->Range >> 14) * size0;\r
+  UInt32 symbol;\r
+  if (p->Code < newBound)\r
+  {\r
+    symbol = 0;\r
+    p->Range = newBound;\r
+  }\r
+  else\r
+  {\r
+    symbol = 1;\r
+    p->Code -= newBound;\r
+    p->Range -= newBound;\r
+  }\r
+  Range_Normalize(p);\r
+  return symbol;\r
+}\r
+\r
+void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)\r
+{\r
+  p->p.GetThreshold = Range_GetThreshold;\r
+  p->p.Decode = Range_Decode;\r
+  p->p.DecodeBit = Range_DecodeBit;\r
+}\r
+\r
+\r
+#define MASK(sym) ((signed char *)charMask)[sym]\r
+\r
+int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)\r
+{\r
+  size_t charMask[256 / sizeof(size_t)];\r
+  if (p->MinContext->NumStats != 1)\r
+  {\r
+    CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);\r
+    unsigned i;\r
+    UInt32 count, hiCnt;\r
+    if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))\r
+    {\r
+      Byte symbol;\r
+      rc->Decode(rc, 0, s->Freq);\r
+      p->FoundState = s;\r
+      symbol = s->Symbol;\r
+      Ppmd7_Update1_0(p);\r
+      return symbol;\r
+    }\r
+    p->PrevSuccess = 0;\r
+    i = p->MinContext->NumStats - 1;\r
+    do\r
+    {\r
+      if ((hiCnt += (++s)->Freq) > count)\r
+      {\r
+        Byte symbol;\r
+        rc->Decode(rc, hiCnt - s->Freq, s->Freq);\r
+        p->FoundState = s;\r
+        symbol = s->Symbol;\r
+        Ppmd7_Update1(p);\r
+        return symbol;\r
+      }\r
+    }\r
+    while (--i);\r
+    if (count >= p->MinContext->SummFreq)\r
+      return -2;\r
+    p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];\r
+    rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);\r
+    PPMD_SetAllBitsIn256Bytes(charMask);\r
+    MASK(s->Symbol) = 0;\r
+    i = p->MinContext->NumStats - 1;\r
+    do { MASK((--s)->Symbol) = 0; } while (--i);\r
+  }\r
+  else\r
+  {\r
+    UInt16 *prob = Ppmd7_GetBinSumm(p);\r
+    if (rc->DecodeBit(rc, *prob) == 0)\r
+    {\r
+      Byte symbol;\r
+      *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);\r
+      symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;\r
+      Ppmd7_UpdateBin(p);\r
+      return symbol;\r
+    }\r
+    *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);\r
+    p->InitEsc = PPMD7_kExpEscape[*prob >> 10];\r
+    PPMD_SetAllBitsIn256Bytes(charMask);\r
+    MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;\r
+    p->PrevSuccess = 0;\r
+  }\r
+  for (;;)\r
+  {\r
+    CPpmd_State *ps[256], *s;\r
+    UInt32 freqSum, count, hiCnt;\r
+    CPpmd_See *see;\r
+    unsigned i, num, numMasked = p->MinContext->NumStats;\r
+    do\r
+    {\r
+      p->OrderFall++;\r
+      if (!p->MinContext->Suffix)\r
+        return -1;\r
+      p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);\r
+    }\r
+    while (p->MinContext->NumStats == numMasked);\r
+    hiCnt = 0;\r
+    s = Ppmd7_GetStats(p, p->MinContext);\r
+    i = 0;\r
+    num = p->MinContext->NumStats - numMasked;\r
+    do\r
+    {\r
+      int k = (int)(MASK(s->Symbol));\r
+      hiCnt += (s->Freq & k);\r
+      ps[i] = s++;\r
+      i -= k;\r
+    }\r
+    while (i != num);\r
+    \r
+    see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);\r
+    freqSum += hiCnt;\r
+    count = rc->GetThreshold(rc, freqSum);\r
+    \r
+    if (count < hiCnt)\r
+    {\r
+      Byte symbol;\r
+      CPpmd_State **pps = ps;\r
+      for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);\r
+      s = *pps;\r
+      rc->Decode(rc, hiCnt - s->Freq, s->Freq);\r
+      Ppmd_See_Update(see);\r
+      p->FoundState = s;\r
+      symbol = s->Symbol;\r
+      Ppmd7_Update2(p);\r
+      return symbol;\r
+    }\r
+    if (count >= freqSum)\r
+      return -2;\r
+    rc->Decode(rc, hiCnt, freqSum - hiCnt);\r
+    see->Summ = (UInt16)(see->Summ + freqSum);\r
+    do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);\r
+  }\r
+}\r
diff --git a/C/Ppmd7Enc.c b/C/Ppmd7Enc.c
new file mode 100755 (executable)
index 0000000..b1fecae
--- /dev/null
@@ -0,0 +1,185 @@
+/* Ppmd7Enc.c -- PPMdH Encoder\r
+2010-03-12 : Igor Pavlov : Public domain\r
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */\r
+\r
+#include "Ppmd7.h"\r
+\r
+#define kTopValue (1 << 24)\r
+\r
+void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p)\r
+{\r
+  p->Low = 0;\r
+  p->Range = 0xFFFFFFFF;\r
+  p->Cache = 0;\r
+  p->CacheSize = 1;\r
+}\r
+\r
+static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)\r
+{\r
+  if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0)\r
+  {\r
+    Byte temp = p->Cache;\r
+    do\r
+    {\r
+      p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));\r
+      temp = 0xFF;\r
+    }\r
+    while(--p->CacheSize != 0);\r
+    p->Cache = (Byte)((UInt32)p->Low >> 24);\r
+  }\r
+  p->CacheSize++;\r
+  p->Low = (UInt32)p->Low << 8;\r
+}\r
+\r
+static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)\r
+{\r
+  p->Low += start * (p->Range /= total);\r
+  p->Range *= size;\r
+  while (p->Range < kTopValue)\r
+  {\r
+    p->Range <<= 8;\r
+    RangeEnc_ShiftLow(p);\r
+  }\r
+}\r
+\r
+static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0)\r
+{\r
+  p->Range = (p->Range >> 14) * size0;\r
+  while (p->Range < kTopValue)\r
+  {\r
+    p->Range <<= 8;\r
+    RangeEnc_ShiftLow(p);\r
+  }\r
+}\r
+\r
+static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0)\r
+{\r
+  UInt32 newBound = (p->Range >> 14) * size0;\r
+  p->Low += newBound;\r
+  p->Range -= newBound;\r
+  while (p->Range < kTopValue)\r
+  {\r
+    p->Range <<= 8;\r
+    RangeEnc_ShiftLow(p);\r
+  }\r
+}\r
+\r
+void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p)\r
+{\r
+  unsigned i;\r
+  for (i = 0; i < 5; i++)\r
+    RangeEnc_ShiftLow(p);\r
+}\r
+\r
+\r
+#define MASK(sym) ((signed char *)charMask)[sym]\r
+\r
+void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol)\r
+{\r
+  size_t charMask[256 / sizeof(size_t)];\r
+  if (p->MinContext->NumStats != 1)\r
+  {\r
+    CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);\r
+    UInt32 sum;\r
+    unsigned i;\r
+    if (s->Symbol == symbol)\r
+    {\r
+      RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq);\r
+      p->FoundState = s;\r
+      Ppmd7_Update1_0(p);\r
+      return;\r
+    }\r
+    p->PrevSuccess = 0;\r
+    sum = s->Freq;\r
+    i = p->MinContext->NumStats - 1;\r
+    do\r
+    {\r
+      if ((++s)->Symbol == symbol)\r
+      {\r
+        RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq);\r
+        p->FoundState = s;\r
+        Ppmd7_Update1(p);\r
+        return;\r
+      }\r
+      sum += s->Freq;\r
+    }\r
+    while (--i);\r
+    \r
+    p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];\r
+    PPMD_SetAllBitsIn256Bytes(charMask);\r
+    MASK(s->Symbol) = 0;\r
+    i = p->MinContext->NumStats - 1;\r
+    do { MASK((--s)->Symbol) = 0; } while (--i);\r
+    RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);\r
+  }\r
+  else\r
+  {\r
+    UInt16 *prob = Ppmd7_GetBinSumm(p);\r
+    CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);\r
+    if (s->Symbol == symbol)\r
+    {\r
+      RangeEnc_EncodeBit_0(rc, *prob);\r
+      *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);\r
+      p->FoundState = s;\r
+      Ppmd7_UpdateBin(p);\r
+      return;\r
+    }\r
+    else\r
+    {\r
+      RangeEnc_EncodeBit_1(rc, *prob);\r
+      *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);\r
+      p->InitEsc = PPMD7_kExpEscape[*prob >> 10];\r
+      PPMD_SetAllBitsIn256Bytes(charMask);\r
+      MASK(s->Symbol) = 0;\r
+      p->PrevSuccess = 0;\r
+    }\r
+  }\r
+  for (;;)\r
+  {\r
+    UInt32 escFreq;\r
+    CPpmd_See *see;\r
+    CPpmd_State *s;\r
+    UInt32 sum;\r
+    unsigned i, numMasked = p->MinContext->NumStats;\r
+    do\r
+    {\r
+      p->OrderFall++;\r
+      if (!p->MinContext->Suffix)\r
+        return; /* EndMarker (symbol = -1) */\r
+      p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);\r
+    }\r
+    while (p->MinContext->NumStats == numMasked);\r
+    \r
+    see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);\r
+    s = Ppmd7_GetStats(p, p->MinContext);\r
+    sum = 0;\r
+    i = p->MinContext->NumStats;\r
+    do\r
+    {\r
+      int cur = s->Symbol;\r
+      if (cur == symbol)\r
+      {\r
+        UInt32 low = sum;\r
+        CPpmd_State *s1 = s;\r
+        do\r
+        {\r
+          sum += (s->Freq & (int)(MASK(s->Symbol)));\r
+          s++;\r
+        }\r
+        while (--i);\r
+        RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq);\r
+        Ppmd_See_Update(see);\r
+        p->FoundState = s1;\r
+        Ppmd7_Update2(p);\r
+        return;\r
+      }\r
+      sum += (s->Freq & (int)(MASK(cur)));\r
+      MASK(cur) = 0;\r
+      s++;\r
+    }\r
+    while (--i);\r
+    \r
+    RangeEnc_Encode(rc, sum, escFreq, sum + escFreq);\r
+    see->Summ = (UInt16)(see->Summ + sum + escFreq);\r
+  }\r
+}\r
diff --git a/C/RotateDefs.h b/C/RotateDefs.h
new file mode 100755 (executable)
index 0000000..ff9b722
--- /dev/null
@@ -0,0 +1,20 @@
+/* RotateDefs.h -- Rotate functions\r
+2009-02-07 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __ROTATE_DEFS_H\r
+#define __ROTATE_DEFS_H\r
+\r
+#ifdef _MSC_VER\r
+\r
+#include <stdlib.h>\r
+#define rotlFixed(x, n) _rotl((x), (n))\r
+#define rotrFixed(x, n) _rotr((x), (n))\r
+\r
+#else\r
+\r
+#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))\r
+#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))\r
+\r
+#endif\r
+\r
+#endif\r
diff --git a/C/Sha256.c b/C/Sha256.c
new file mode 100755 (executable)
index 0000000..cfb9eac
--- /dev/null
@@ -0,0 +1,204 @@
+/* Crypto/Sha256.c -- SHA-256 Hash\r
+2010-06-11 : Igor Pavlov : Public domain\r
+This code is based on public domain code from Wei Dai's Crypto++ library. */\r
+\r
+#include "RotateDefs.h"\r
+#include "Sha256.h"\r
+\r
+/* define it for speed optimization */\r
+/* #define _SHA256_UNROLL */\r
+/* #define _SHA256_UNROLL2 */\r
+\r
+void Sha256_Init(CSha256 *p)\r
+{\r
+  p->state[0] = 0x6a09e667;\r
+  p->state[1] = 0xbb67ae85;\r
+  p->state[2] = 0x3c6ef372;\r
+  p->state[3] = 0xa54ff53a;\r
+  p->state[4] = 0x510e527f;\r
+  p->state[5] = 0x9b05688c;\r
+  p->state[6] = 0x1f83d9ab;\r
+  p->state[7] = 0x5be0cd19;\r
+  p->count = 0;\r
+}\r
+\r
+#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))\r
+#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))\r
+#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))\r
+#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))\r
+\r
+#define blk0(i) (W[i] = data[i])\r
+#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))\r
+\r
+#define Ch(x,y,z) (z^(x&(y^z)))\r
+#define Maj(x,y,z) ((x&y)|(z&(x|y)))\r
+\r
+#define a(i) T[(0-(i))&7]\r
+#define b(i) T[(1-(i))&7]\r
+#define c(i) T[(2-(i))&7]\r
+#define d(i) T[(3-(i))&7]\r
+#define e(i) T[(4-(i))&7]\r
+#define f(i) T[(5-(i))&7]\r
+#define g(i) T[(6-(i))&7]\r
+#define h(i) T[(7-(i))&7]\r
+\r
+\r
+#ifdef _SHA256_UNROLL2\r
+\r
+#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\\r
+  d += h; h += S0(a) + Maj(a, b, c)\r
+\r
+#define RX_8(i) \\r
+  R(a,b,c,d,e,f,g,h, i); \\r
+  R(h,a,b,c,d,e,f,g, i+1); \\r
+  R(g,h,a,b,c,d,e,f, i+2); \\r
+  R(f,g,h,a,b,c,d,e, i+3); \\r
+  R(e,f,g,h,a,b,c,d, i+4); \\r
+  R(d,e,f,g,h,a,b,c, i+5); \\r
+  R(c,d,e,f,g,h,a,b, i+6); \\r
+  R(b,c,d,e,f,g,h,a, i+7)\r
+\r
+#else\r
+\r
+#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\\r
+  d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))\r
+\r
+#ifdef _SHA256_UNROLL\r
+\r
+#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);\r
+\r
+#endif\r
+\r
+#endif\r
+\r
+static const UInt32 K[64] = {\r
+  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\r
+  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\r
+  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\r
+  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\r
+  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\r
+  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\r
+  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\r
+  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\r
+  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\r
+  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\r
+  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\r
+  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\r
+  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\r
+  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\r
+  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\r
+  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\r
+};\r
+\r
+static void Sha256_Transform(UInt32 *state, const UInt32 *data)\r
+{\r
+  UInt32 W[16];\r
+  unsigned j;\r
+  #ifdef _SHA256_UNROLL2\r
+  UInt32 a,b,c,d,e,f,g,h;\r
+  a = state[0];\r
+  b = state[1];\r
+  c = state[2];\r
+  d = state[3];\r
+  e = state[4];\r
+  f = state[5];\r
+  g = state[6];\r
+  h = state[7];\r
+  #else\r
+  UInt32 T[8];\r
+  for (j = 0; j < 8; j++)\r
+    T[j] = state[j];\r
+  #endif\r
+\r
+  for (j = 0; j < 64; j += 16)\r
+  {\r
+    #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)\r
+    RX_8(0); RX_8(8);\r
+    #else\r
+    unsigned i;\r
+    for (i = 0; i < 16; i++) { R(i); }\r
+    #endif\r
+  }\r
+\r
+  #ifdef _SHA256_UNROLL2\r
+  state[0] += a;\r
+  state[1] += b;\r
+  state[2] += c;\r
+  state[3] += d;\r
+  state[4] += e;\r
+  state[5] += f;\r
+  state[6] += g;\r
+  state[7] += h;\r
+  #else\r
+  for (j = 0; j < 8; j++)\r
+    state[j] += T[j];\r
+  #endif\r
+  \r
+  /* Wipe variables */\r
+  /* memset(W, 0, sizeof(W)); */\r
+  /* memset(T, 0, sizeof(T)); */\r
+}\r
+\r
+#undef S0\r
+#undef S1\r
+#undef s0\r
+#undef s1\r
+\r
+static void Sha256_WriteByteBlock(CSha256 *p)\r
+{\r
+  UInt32 data32[16];\r
+  unsigned i;\r
+  for (i = 0; i < 16; i++)\r
+    data32[i] =\r
+      ((UInt32)(p->buffer[i * 4    ]) << 24) +\r
+      ((UInt32)(p->buffer[i * 4 + 1]) << 16) +\r
+      ((UInt32)(p->buffer[i * 4 + 2]) <<  8) +\r
+      ((UInt32)(p->buffer[i * 4 + 3]));\r
+  Sha256_Transform(p->state, data32);\r
+}\r
+\r
+void Sha256_Update(CSha256 *p, const Byte *data, size_t size)\r
+{\r
+  UInt32 curBufferPos = (UInt32)p->count & 0x3F;\r
+  while (size > 0)\r
+  {\r
+    p->buffer[curBufferPos++] = *data++;\r
+    p->count++;\r
+    size--;\r
+    if (curBufferPos == 64)\r
+    {\r
+      curBufferPos = 0;\r
+      Sha256_WriteByteBlock(p);\r
+    }\r
+  }\r
+}\r
+\r
+void Sha256_Final(CSha256 *p, Byte *digest)\r
+{\r
+  UInt64 lenInBits = (p->count << 3);\r
+  UInt32 curBufferPos = (UInt32)p->count & 0x3F;\r
+  unsigned i;\r
+  p->buffer[curBufferPos++] = 0x80;\r
+  while (curBufferPos != (64 - 8))\r
+  {\r
+    curBufferPos &= 0x3F;\r
+    if (curBufferPos == 0)\r
+      Sha256_WriteByteBlock(p);\r
+    p->buffer[curBufferPos++] = 0;\r
+  }\r
+  for (i = 0; i < 8; i++)\r
+  {\r
+    p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56);\r
+    lenInBits <<= 8;\r
+  }\r
+  Sha256_WriteByteBlock(p);\r
+\r
+  for (i = 0; i < 8; i++)\r
+  {\r
+    *digest++ = (Byte)(p->state[i] >> 24);\r
+    *digest++ = (Byte)(p->state[i] >> 16);\r
+    *digest++ = (Byte)(p->state[i] >> 8);\r
+    *digest++ = (Byte)(p->state[i]);\r
+  }\r
+  Sha256_Init(p);\r
+}\r
diff --git a/C/Sha256.h b/C/Sha256.h
new file mode 100755 (executable)
index 0000000..26d1e3a
--- /dev/null
@@ -0,0 +1,26 @@
+/* Sha256.h -- SHA-256 Hash\r
+2010-06-11 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __CRYPTO_SHA256_H\r
+#define __CRYPTO_SHA256_H\r
+\r
+#include "Types.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+#define SHA256_DIGEST_SIZE 32\r
+\r
+typedef struct\r
+{\r
+  UInt32 state[8];\r
+  UInt64 count;\r
+  Byte buffer[64];\r
+} CSha256;\r
+\r
+void Sha256_Init(CSha256 *p);\r
+void Sha256_Update(CSha256 *p, const Byte *data, size_t size);\r
+void Sha256_Final(CSha256 *p, Byte *digest);\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/Threads.c b/C/Threads.c
new file mode 100755 (executable)
index 0000000..4be44fb
--- /dev/null
@@ -0,0 +1,84 @@
+/* Threads.c -- multithreading library\r
+2009-09-20 : Igor Pavlov : Public domain */\r
+\r
+#ifndef _WIN32_WCE\r
+#include <process.h>\r
+#endif\r
+\r
+#include "Threads.h"\r
+\r
+static WRes GetError()\r
+{\r
+  DWORD res = GetLastError();\r
+  return (res) ? (WRes)(res) : 1;\r
+}\r
+\r
+WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }\r
+WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }\r
+\r
+WRes HandlePtr_Close(HANDLE *p)\r
+{\r
+  if (*p != NULL)\r
+    if (!CloseHandle(*p))\r
+      return GetError();\r
+  *p = NULL;\r
+  return 0;\r
+}\r
+\r
+WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); }\r
+\r
+WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)\r
+{\r
+  unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */\r
+  *p =\r
+    #ifdef UNDER_CE\r
+    CreateThread(0, 0, func, param, 0, &threadId);\r
+    #else\r
+    (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);\r
+    #endif\r
+    /* maybe we must use errno here, but probably GetLastError() is also OK. */\r
+  return HandleToWRes(*p);\r
+}\r
+\r
+WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)\r
+{\r
+  *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);\r
+  return HandleToWRes(*p);\r
+}\r
+\r
+WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); }\r
+WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); }\r
+\r
+WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); }\r
+WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); }\r
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); }\r
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); }\r
+\r
+\r
+WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)\r
+{\r
+  *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL);\r
+  return HandleToWRes(*p);\r
+}\r
+\r
+static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)\r
+  { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }\r
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num)\r
+  { return Semaphore_Release(p, (LONG)num, NULL); }\r
+WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); }\r
+\r
+WRes CriticalSection_Init(CCriticalSection *p)\r
+{\r
+  /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */\r
+  #ifdef _MSC_VER\r
+  __try\r
+  #endif\r
+  {\r
+    InitializeCriticalSection(p);\r
+    /* InitializeCriticalSectionAndSpinCount(p, 0); */\r
+  }\r
+  #ifdef _MSC_VER\r
+  __except (EXCEPTION_EXECUTE_HANDLER) { return 1; }\r
+  #endif\r
+  return 0;\r
+}\r
diff --git a/C/Threads.h b/C/Threads.h
new file mode 100755 (executable)
index 0000000..6a7afa8
--- /dev/null
@@ -0,0 +1,59 @@
+/* Threads.h -- multithreading library\r
+2009-03-27 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __7Z_THREADS_H\r
+#define __7Z_THREADS_H\r
+\r
+#include "Types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+WRes HandlePtr_Close(HANDLE *h);\r
+WRes Handle_WaitObject(HANDLE h);\r
+\r
+typedef HANDLE CThread;\r
+#define Thread_Construct(p) *(p) = NULL\r
+#define Thread_WasCreated(p) (*(p) != NULL)\r
+#define Thread_Close(p) HandlePtr_Close(p)\r
+#define Thread_Wait(p) Handle_WaitObject(*(p))\r
+typedef unsigned THREAD_FUNC_RET_TYPE;\r
+#define THREAD_FUNC_CALL_TYPE MY_STD_CALL\r
+#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE\r
+typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);\r
+WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);\r
+\r
+typedef HANDLE CEvent;\r
+typedef CEvent CAutoResetEvent;\r
+typedef CEvent CManualResetEvent;\r
+#define Event_Construct(p) *(p) = NULL\r
+#define Event_IsCreated(p) (*(p) != NULL)\r
+#define Event_Close(p) HandlePtr_Close(p)\r
+#define Event_Wait(p) Handle_WaitObject(*(p))\r
+WRes Event_Set(CEvent *p);\r
+WRes Event_Reset(CEvent *p);\r
+WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);\r
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);\r
+WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);\r
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);\r
+\r
+typedef HANDLE CSemaphore;\r
+#define Semaphore_Construct(p) (*p) = NULL\r
+#define Semaphore_Close(p) HandlePtr_Close(p)\r
+#define Semaphore_Wait(p) Handle_WaitObject(*(p))\r
+WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);\r
+WRes Semaphore_Release1(CSemaphore *p);\r
+\r
+typedef CRITICAL_SECTION CCriticalSection;\r
+WRes CriticalSection_Init(CCriticalSection *p);\r
+#define CriticalSection_Delete(p) DeleteCriticalSection(p)\r
+#define CriticalSection_Enter(p) EnterCriticalSection(p)\r
+#define CriticalSection_Leave(p) LeaveCriticalSection(p)\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/Types.h b/C/Types.h
new file mode 100755 (executable)
index 0000000..f193ce2
--- /dev/null
+++ b/C/Types.h
@@ -0,0 +1,254 @@
+/* Types.h -- Basic types\r
+2010-10-09 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __7Z_TYPES_H\r
+#define __7Z_TYPES_H\r
+\r
+#include <stddef.h>\r
+\r
+#ifdef _WIN32\r
+#include <windows.h>\r
+#endif\r
+\r
+#ifndef EXTERN_C_BEGIN\r
+#ifdef __cplusplus\r
+#define EXTERN_C_BEGIN extern "C" {\r
+#define EXTERN_C_END }\r
+#else\r
+#define EXTERN_C_BEGIN\r
+#define EXTERN_C_END\r
+#endif\r
+#endif\r
+\r
+EXTERN_C_BEGIN\r
+\r
+#define SZ_OK 0\r
+\r
+#define SZ_ERROR_DATA 1\r
+#define SZ_ERROR_MEM 2\r
+#define SZ_ERROR_CRC 3\r
+#define SZ_ERROR_UNSUPPORTED 4\r
+#define SZ_ERROR_PARAM 5\r
+#define SZ_ERROR_INPUT_EOF 6\r
+#define SZ_ERROR_OUTPUT_EOF 7\r
+#define SZ_ERROR_READ 8\r
+#define SZ_ERROR_WRITE 9\r
+#define SZ_ERROR_PROGRESS 10\r
+#define SZ_ERROR_FAIL 11\r
+#define SZ_ERROR_THREAD 12\r
+\r
+#define SZ_ERROR_ARCHIVE 16\r
+#define SZ_ERROR_NO_ARCHIVE 17\r
+\r
+typedef int SRes;\r
+\r
+#ifdef _WIN32\r
+typedef DWORD WRes;\r
+#else\r
+typedef int WRes;\r
+#endif\r
+\r
+#ifndef RINOK\r
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }\r
+#endif\r
+\r
+typedef unsigned char Byte;\r
+typedef short Int16;\r
+typedef unsigned short UInt16;\r
+\r
+#ifdef _LZMA_UINT32_IS_ULONG\r
+typedef long Int32;\r
+typedef unsigned long UInt32;\r
+#else\r
+typedef int Int32;\r
+typedef unsigned int UInt32;\r
+#endif\r
+\r
+#ifdef _SZ_NO_INT_64\r
+\r
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.\r
+   NOTES: Some code will work incorrectly in that case! */\r
+\r
+typedef long Int64;\r
+typedef unsigned long UInt64;\r
+\r
+#else\r
+\r
+#if defined(_MSC_VER) || defined(__BORLANDC__)\r
+typedef __int64 Int64;\r
+typedef unsigned __int64 UInt64;\r
+#define UINT64_CONST(n) n\r
+#else\r
+typedef long long int Int64;\r
+typedef unsigned long long int UInt64;\r
+#define UINT64_CONST(n) n ## ULL\r
+#endif\r
+\r
+#endif\r
+\r
+#ifdef _LZMA_NO_SYSTEM_SIZE_T\r
+typedef UInt32 SizeT;\r
+#else\r
+typedef size_t SizeT;\r
+#endif\r
+\r
+typedef int Bool;\r
+#define True 1\r
+#define False 0\r
+\r
+\r
+#ifdef _WIN32\r
+#define MY_STD_CALL __stdcall\r
+#else\r
+#define MY_STD_CALL\r
+#endif\r
+\r
+#ifdef _MSC_VER\r
+\r
+#if _MSC_VER >= 1300\r
+#define MY_NO_INLINE __declspec(noinline)\r
+#else\r
+#define MY_NO_INLINE\r
+#endif\r
+\r
+#define MY_CDECL __cdecl\r
+#define MY_FAST_CALL __fastcall\r
+\r
+#else\r
+\r
+#define MY_CDECL\r
+#define MY_FAST_CALL\r
+\r
+#endif\r
+\r
+\r
+/* The following interfaces use first parameter as pointer to structure */\r
+\r
+typedef struct\r
+{\r
+  Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */\r
+} IByteIn;\r
+\r
+typedef struct\r
+{\r
+  void (*Write)(void *p, Byte b);\r
+} IByteOut;\r
+\r
+typedef struct\r
+{\r
+  SRes (*Read)(void *p, void *buf, size_t *size);\r
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.\r
+       (output(*size) < input(*size)) is allowed */\r
+} ISeqInStream;\r
+\r
+/* it can return SZ_ERROR_INPUT_EOF */\r
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);\r
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);\r
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);\r
+\r
+typedef struct\r
+{\r
+  size_t (*Write)(void *p, const void *buf, size_t size);\r
+    /* Returns: result - the number of actually written bytes.\r
+       (result < size) means error */\r
+} ISeqOutStream;\r
+\r
+typedef enum\r
+{\r
+  SZ_SEEK_SET = 0,\r
+  SZ_SEEK_CUR = 1,\r
+  SZ_SEEK_END = 2\r
+} ESzSeek;\r
+\r
+typedef struct\r
+{\r
+  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */\r
+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);\r
+} ISeekInStream;\r
+\r
+typedef struct\r
+{\r
+  SRes (*Look)(void *p, const void **buf, size_t *size);\r
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.\r
+       (output(*size) > input(*size)) is not allowed\r
+       (output(*size) < input(*size)) is allowed */\r
+  SRes (*Skip)(void *p, size_t offset);\r
+    /* offset must be <= output(*size) of Look */\r
+\r
+  SRes (*Read)(void *p, void *buf, size_t *size);\r
+    /* reads directly (without buffer). It's same as ISeqInStream::Read */\r
+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);\r
+} ILookInStream;\r
+\r
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);\r
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);\r
+\r
+/* reads via ILookInStream::Read */\r
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);\r
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);\r
+\r
+#define LookToRead_BUF_SIZE (1 << 14)\r
+\r
+typedef struct\r
+{\r
+  ILookInStream s;\r
+  ISeekInStream *realStream;\r
+  size_t pos;\r
+  size_t size;\r
+  Byte buf[LookToRead_BUF_SIZE];\r
+} CLookToRead;\r
+\r
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);\r
+void LookToRead_Init(CLookToRead *p);\r
+\r
+typedef struct\r
+{\r
+  ISeqInStream s;\r
+  ILookInStream *realStream;\r
+} CSecToLook;\r
+\r
+void SecToLook_CreateVTable(CSecToLook *p);\r
+\r
+typedef struct\r
+{\r
+  ISeqInStream s;\r
+  ILookInStream *realStream;\r
+} CSecToRead;\r
+\r
+void SecToRead_CreateVTable(CSecToRead *p);\r
+\r
+typedef struct\r
+{\r
+  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);\r
+    /* Returns: result. (result != SZ_OK) means break.\r
+       Value (UInt64)(Int64)-1 for size means unknown value. */\r
+} ICompressProgress;\r
+\r
+typedef struct\r
+{\r
+  void *(*Alloc)(void *p, size_t size);\r
+  void (*Free)(void *p, void *address); /* address can be 0 */\r
+} ISzAlloc;\r
+\r
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)\r
+#define IAlloc_Free(p, a) (p)->Free((p), a)\r
+\r
+#ifdef _WIN32\r
+\r
+#define CHAR_PATH_SEPARATOR '\\'\r
+#define WCHAR_PATH_SEPARATOR L'\\'\r
+#define STRING_PATH_SEPARATOR "\\"\r
+#define WSTRING_PATH_SEPARATOR L"\\"\r
+\r
+#else\r
+\r
+#define CHAR_PATH_SEPARATOR '/'\r
+#define WCHAR_PATH_SEPARATOR L'/'\r
+#define STRING_PATH_SEPARATOR "/"\r
+#define WSTRING_PATH_SEPARATOR L"/"\r
+\r
+#endif\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/Util/7z/7z.dsp b/C/Util/7z/7z.dsp
new file mode 100755 (executable)
index 0000000..9f5806b
--- /dev/null
@@ -0,0 +1,214 @@
+# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=7z - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "7z.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "7z - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /YX /FD /c\r
+# ADD BASE RSC /l 0x419 /d "NDEBUG"\r
+# ADD RSC /l 0x419 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" /opt:NOWIN98\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ELSEIF  "$(CFG)" == "7z - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c\r
+# ADD BASE RSC /l 0x419 /d "_DEBUG"\r
+# ADD RSC /l 0x419 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "7z - Win32 Release"\r
+# Name "7z - Win32 Debug"\r
+# Begin Group "Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7z.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zAlloc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zAlloc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zBuf.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zBuf.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zCrc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zCrc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zCrcOpt.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zDec.c\r
+# ADD CPP /D "_7ZIP_PPMD_SUPPPORT"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zFile.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zFile.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zIn.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zStream.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bcj2.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bcj2.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bra.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bra.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bra86.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\CpuArch.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\CpuArch.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Lzma2Dec.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Lzma2Dec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaDec.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaDec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Ppmd.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Ppmd7.c\r
+# SUBTRACT CPP /YX\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Ppmd7.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Ppmd7Dec.c\r
+# SUBTRACT CPP /YX\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Types.h\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=.\7zMain.c\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/C/Util/7z/7z.dsw b/C/Util/7z/7z.dsw
new file mode 100755 (executable)
index 0000000..23089fb
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "7z"=.\7z.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/C/Util/7z/7zMain.c b/C/Util/7z/7zMain.c
new file mode 100755 (executable)
index 0000000..f217340
--- /dev/null
@@ -0,0 +1,501 @@
+/* 7zMain.c - Test application for 7z Decoder\r
+2010-10-28 : Igor Pavlov : Public domain */\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "../../7z.h"\r
+#include "../../7zAlloc.h"\r
+#include "../../7zCrc.h"\r
+#include "../../7zFile.h"\r
+#include "../../7zVersion.h"\r
+\r
+#ifndef USE_WINDOWS_FILE\r
+/* for mkdir */\r
+#ifdef _WIN32\r
+#include <direct.h>\r
+#else\r
+#include <sys/stat.h>\r
+#include <errno.h>\r
+#endif\r
+#endif\r
+\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+static int Buf_EnsureSize(CBuf *dest, size_t size)\r
+{\r
+  if (dest->size >= size)\r
+    return 1;\r
+  Buf_Free(dest, &g_Alloc);\r
+  return Buf_Create(dest, size, &g_Alloc);\r
+}\r
+\r
+#ifndef _WIN32\r
+\r
+static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };\r
+\r
+static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)\r
+{\r
+  size_t destPos = 0, srcPos = 0;\r
+  for (;;)\r
+  {\r
+    unsigned numAdds;\r
+    UInt32 value;\r
+    if (srcPos == srcLen)\r
+    {\r
+      *destLen = destPos;\r
+      return True;\r
+    }\r
+    value = src[srcPos++];\r
+    if (value < 0x80)\r
+    {\r
+      if (dest)\r
+        dest[destPos] = (char)value;\r
+      destPos++;\r
+      continue;\r
+    }\r
+    if (value >= 0xD800 && value < 0xE000)\r
+    {\r
+      UInt32 c2;\r
+      if (value >= 0xDC00 || srcPos == srcLen)\r
+        break;\r
+      c2 = src[srcPos++];\r
+      if (c2 < 0xDC00 || c2 >= 0xE000)\r
+        break;\r
+      value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;\r
+    }\r
+    for (numAdds = 1; numAdds < 5; numAdds++)\r
+      if (value < (((UInt32)1) << (numAdds * 5 + 6)))\r
+        break;\r
+    if (dest)\r
+      dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));\r
+    destPos++;\r
+    do\r
+    {\r
+      numAdds--;\r
+      if (dest)\r
+        dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));\r
+      destPos++;\r
+    }\r
+    while (numAdds != 0);\r
+  }\r
+  *destLen = destPos;\r
+  return False;\r
+}\r
+\r
+static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)\r
+{\r
+  size_t destLen = 0;\r
+  Bool res;\r
+  Utf16_To_Utf8(NULL, &destLen, src, srcLen);\r
+  destLen += 1;\r
+  if (!Buf_EnsureSize(dest, destLen))\r
+    return SZ_ERROR_MEM;\r
+  res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);\r
+  dest->data[destLen] = 0;\r
+  return res ? SZ_OK : SZ_ERROR_FAIL;\r
+}\r
+#endif\r
+\r
+static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)\r
+{\r
+  int len = 0;\r
+  for (len = 0; s[len] != '\0'; len++);\r
+\r
+  #ifdef _WIN32\r
+  {\r
+    int size = len * 3 + 100;\r
+    if (!Buf_EnsureSize(buf, size))\r
+      return SZ_ERROR_MEM;\r
+    {\r
+      char defaultChar = '_';\r
+      BOOL defUsed;\r
+      int numChars = WideCharToMultiByte(fileMode ?\r
+          (\r
+          #ifdef UNDER_CE\r
+          CP_ACP\r
+          #else\r
+          AreFileApisANSI() ? CP_ACP : CP_OEMCP\r
+          #endif\r
+          ) : CP_OEMCP,\r
+          0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);\r
+      if (numChars == 0 || numChars >= size)\r
+        return SZ_ERROR_FAIL;\r
+      buf->data[numChars] = 0;\r
+      return SZ_OK;\r
+    }\r
+  }\r
+  #else\r
+  fileMode = fileMode;\r
+  return Utf16_To_Utf8Buf(buf, s, len);\r
+  #endif\r
+}\r
+\r
+static WRes MyCreateDir(const UInt16 *name)\r
+{\r
+  #ifdef USE_WINDOWS_FILE\r
+  \r
+  return CreateDirectoryW(name, NULL) ? 0 : GetLastError();\r
+  \r
+  #else\r
+\r
+  CBuf buf;\r
+  WRes res;\r
+  Buf_Init(&buf);\r
+  RINOK(Utf16_To_Char(&buf, name, 1));\r
+\r
+  res =\r
+  #ifdef _WIN32\r
+  _mkdir((const char *)buf.data)\r
+  #else\r
+  mkdir((const char *)buf.data, 0777)\r
+  #endif\r
+  == 0 ? 0 : errno;\r
+  Buf_Free(&buf, &g_Alloc);\r
+  return res;\r
+  \r
+  #endif\r
+}\r
+\r
+static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)\r
+{\r
+  #ifdef USE_WINDOWS_FILE\r
+  return OutFile_OpenW(p, name);\r
+  #else\r
+  CBuf buf;\r
+  WRes res;\r
+  Buf_Init(&buf);\r
+  RINOK(Utf16_To_Char(&buf, name, 1));\r
+  res = OutFile_Open(p, (const char *)buf.data);\r
+  Buf_Free(&buf, &g_Alloc);\r
+  return res;\r
+  #endif\r
+}\r
+\r
+static SRes PrintString(const UInt16 *s)\r
+{\r
+  CBuf buf;\r
+  SRes res;\r
+  Buf_Init(&buf);\r
+  res = Utf16_To_Char(&buf, s, 0);\r
+  if (res == SZ_OK)\r
+    fputs((const char *)buf.data, stdout);\r
+  Buf_Free(&buf, &g_Alloc);\r
+  return res;\r
+}\r
+\r
+static void UInt64ToStr(UInt64 value, char *s)\r
+{\r
+  char temp[32];\r
+  int pos = 0;\r
+  do\r
+  {\r
+    temp[pos++] = (char)('0' + (unsigned)(value % 10));\r
+    value /= 10;\r
+  }\r
+  while (value != 0);\r
+  do\r
+    *s++ = temp[--pos];\r
+  while (pos);\r
+  *s = '\0';\r
+}\r
+\r
+static char *UIntToStr(char *s, unsigned value, int numDigits)\r
+{\r
+  char temp[16];\r
+  int pos = 0;\r
+  do\r
+    temp[pos++] = (char)('0' + (value % 10));\r
+  while (value /= 10);\r
+  for (numDigits -= pos; numDigits > 0; numDigits--)\r
+    *s++ = '0';\r
+  do\r
+    *s++ = temp[--pos];\r
+  while (pos);\r
+  *s = '\0';\r
+  return s;\r
+}\r
+\r
+#define PERIOD_4 (4 * 365 + 1)\r
+#define PERIOD_100 (PERIOD_4 * 25 - 1)\r
+#define PERIOD_400 (PERIOD_100 * 4 + 1)\r
+\r
+static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s)\r
+{\r
+  unsigned year, mon, day, hour, min, sec;\r
+  UInt64 v64 = (ft->Low | ((UInt64)ft->High << 32)) / 10000000;\r
+  Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
+  unsigned t;\r
+  UInt32 v;\r
+  sec = (unsigned)(v64 % 60); v64 /= 60;\r
+  min = (unsigned)(v64 % 60); v64 /= 60;\r
+  hour = (unsigned)(v64 % 24); v64 /= 24;\r
+\r
+  v = (UInt32)v64;\r
+\r
+  year = (unsigned)(1601 + v / PERIOD_400 * 400);\r
+  v %= PERIOD_400;\r
+\r
+  t = v / PERIOD_100; if (t ==  4) t =  3; year += t * 100; v -= t * PERIOD_100;\r
+  t = v / PERIOD_4;   if (t == 25) t = 24; year += t * 4;   v -= t * PERIOD_4;\r
+  t = v / 365;        if (t ==  4) t =  3; year += t;       v -= t * 365;\r
+\r
+  if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))\r
+    ms[1] = 29;\r
+  for (mon = 1; mon <= 12; mon++)\r
+  {\r
+    unsigned s = ms[mon - 1];\r
+    if (v < s)\r
+      break;\r
+    v -= s;\r
+  }\r
+  day = (unsigned)v + 1;\r
+  s = UIntToStr(s, year, 4); *s++ = '-';\r
+  s = UIntToStr(s, mon, 2);  *s++ = '-';\r
+  s = UIntToStr(s, day, 2);  *s++ = ' ';\r
+  s = UIntToStr(s, hour, 2); *s++ = ':';\r
+  s = UIntToStr(s, min, 2);  *s++ = ':';\r
+  s = UIntToStr(s, sec, 2);\r
+}\r
+\r
+void PrintError(char *sz)\r
+{\r
+  printf("\nERROR: %s\n", sz);\r
+}\r
+\r
+#ifdef USE_WINDOWS_FILE\r
+#define kEmptyAttribChar '.'\r
+static void GetAttribString(UInt32 wa, Bool isDir, char *s)\r
+{\r
+  s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar);\r
+  s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar);\r
+  s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar);\r
+  s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar);\r
+  s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar);\r
+  s[5] = '\0';\r
+}\r
+#else\r
+static void GetAttribString(UInt32, Bool, char *s)\r
+{\r
+  s[0] = '\0';\r
+}\r
+#endif\r
+\r
+int MY_CDECL main(int numargs, char *args[])\r
+{\r
+  CFileInStream archiveStream;\r
+  CLookToRead lookStream;\r
+  CSzArEx db;\r
+  SRes res;\r
+  ISzAlloc allocImp;\r
+  ISzAlloc allocTempImp;\r
+  UInt16 *temp = NULL;\r
+  size_t tempSize = 0;\r
+\r
+  printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");\r
+  if (numargs == 1)\r
+  {\r
+    printf(\r
+      "Usage: 7zDec <command> <archive_name>\n\n"\r
+      "<Commands>\n"\r
+      "  e: Extract files from archive (without using directory names)\n"\r
+      "  l: List contents of archive\n"\r
+      "  t: Test integrity of archive\n"\r
+      "  x: eXtract files with full paths\n");\r
+    return 0;\r
+  }\r
+  if (numargs < 3)\r
+  {\r
+    PrintError("incorrect command");\r
+    return 1;\r
+  }\r
+\r
+  allocImp.Alloc = SzAlloc;\r
+  allocImp.Free = SzFree;\r
+\r
+  allocTempImp.Alloc = SzAllocTemp;\r
+  allocTempImp.Free = SzFreeTemp;\r
+\r
+  if (InFile_Open(&archiveStream.file, args[2]))\r
+  {\r
+    PrintError("can not open input file");\r
+    return 1;\r
+  }\r
+\r
+  FileInStream_CreateVTable(&archiveStream);\r
+  LookToRead_CreateVTable(&lookStream, False);\r
+  \r
+  lookStream.realStream = &archiveStream.s;\r
+  LookToRead_Init(&lookStream);\r
+\r
+  CrcGenerateTable();\r
+\r
+  SzArEx_Init(&db);\r
+  res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);\r
+  if (res == SZ_OK)\r
+  {\r
+    char *command = args[1];\r
+    int listCommand = 0, testCommand = 0, extractCommand = 0, fullPaths = 0;\r
+    if (strcmp(command, "l") == 0) listCommand = 1;\r
+    else if (strcmp(command, "t") == 0) testCommand = 1;\r
+    else if (strcmp(command, "e") == 0) extractCommand = 1;\r
+    else if (strcmp(command, "x") == 0) { extractCommand = 1; fullPaths = 1; }\r
+    else\r
+    {\r
+      PrintError("incorrect command");\r
+      res = SZ_ERROR_FAIL;\r
+    }\r
+\r
+    if (res == SZ_OK)\r
+    {\r
+      UInt32 i;\r
+\r
+      /*\r
+      if you need cache, use these 3 variables.\r
+      if you use external function, you can make these variable as static.\r
+      */\r
+      UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */\r
+      Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */\r
+      size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */\r
+\r
+      for (i = 0; i < db.db.NumFiles; i++)\r
+      {\r
+        size_t offset = 0;\r
+        size_t outSizeProcessed = 0;\r
+        const CSzFileItem *f = db.db.Files + i;\r
+        size_t len;\r
+        if (listCommand == 0 && f->IsDir && !fullPaths)\r
+          continue;\r
+        len = SzArEx_GetFileNameUtf16(&db, i, NULL);\r
+\r
+        if (len > tempSize)\r
+        {\r
+          SzFree(NULL, temp);\r
+          tempSize = len;\r
+          temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));\r
+          if (temp == 0)\r
+          {\r
+            res = SZ_ERROR_MEM;\r
+            break;\r
+          }\r
+        }\r
+\r
+        SzArEx_GetFileNameUtf16(&db, i, temp);\r
+        if (listCommand)\r
+        {\r
+          char attr[8], s[32], t[32];\r
+\r
+          GetAttribString(f->AttribDefined ? f->Attrib : 0, f->IsDir, attr);\r
+\r
+          UInt64ToStr(f->Size, s);\r
+          if (f->MTimeDefined)\r
+            ConvertFileTimeToString(&f->MTime, t);\r
+          else\r
+          {\r
+            size_t j;\r
+            for (j = 0; j < 19; j++)\r
+              t[j] = ' ';\r
+            t[j] = '\0';\r
+          }\r
+          \r
+          printf("%s %s %10s  ", t, attr, s);\r
+          res = PrintString(temp);\r
+          if (res != SZ_OK)\r
+            break;\r
+          if (f->IsDir)\r
+            printf("/");\r
+          printf("\n");\r
+          continue;\r
+        }\r
+        fputs(testCommand ?\r
+            "Testing    ":\r
+            "Extracting ",\r
+            stdout);\r
+        res = PrintString(temp);\r
+        if (res != SZ_OK)\r
+          break;\r
+        if (f->IsDir)\r
+          printf("/");\r
+        else\r
+        {\r
+          res = SzArEx_Extract(&db, &lookStream.s, i,\r
+              &blockIndex, &outBuffer, &outBufferSize,\r
+              &offset, &outSizeProcessed,\r
+              &allocImp, &allocTempImp);\r
+          if (res != SZ_OK)\r
+            break;\r
+        }\r
+        if (!testCommand)\r
+        {\r
+          CSzFile outFile;\r
+          size_t processedSize;\r
+          size_t j;\r
+          UInt16 *name = (UInt16 *)temp;\r
+          const UInt16 *destPath = (const UInt16 *)name;\r
+          for (j = 0; name[j] != 0; j++)\r
+            if (name[j] == '/')\r
+            {\r
+              if (fullPaths)\r
+              {\r
+                name[j] = 0;\r
+                MyCreateDir(name);\r
+                name[j] = CHAR_PATH_SEPARATOR;\r
+              }\r
+              else\r
+                destPath = name + j + 1;\r
+            }\r
+    \r
+          if (f->IsDir)\r
+          {\r
+            MyCreateDir(destPath);\r
+            printf("\n");\r
+            continue;\r
+          }\r
+          else if (OutFile_OpenUtf16(&outFile, destPath))\r
+          {\r
+            PrintError("can not open output file");\r
+            res = SZ_ERROR_FAIL;\r
+            break;\r
+          }\r
+          processedSize = outSizeProcessed;\r
+          if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)\r
+          {\r
+            PrintError("can not write output file");\r
+            res = SZ_ERROR_FAIL;\r
+            break;\r
+          }\r
+          if (File_Close(&outFile))\r
+          {\r
+            PrintError("can not close output file");\r
+            res = SZ_ERROR_FAIL;\r
+            break;\r
+          }\r
+          #ifdef USE_WINDOWS_FILE\r
+          if (f->AttribDefined)\r
+            SetFileAttributesW(destPath, f->Attrib);\r
+          #endif\r
+        }\r
+        printf("\n");\r
+      }\r
+      IAlloc_Free(&allocImp, outBuffer);\r
+    }\r
+  }\r
+  SzArEx_Free(&db, &allocImp);\r
+  SzFree(NULL, temp);\r
+\r
+  File_Close(&archiveStream.file);\r
+  if (res == SZ_OK)\r
+  {\r
+    printf("\nEverything is Ok\n");\r
+    return 0;\r
+  }\r
+  if (res == SZ_ERROR_UNSUPPORTED)\r
+    PrintError("decoder doesn't support this archive");\r
+  else if (res == SZ_ERROR_MEM)\r
+    PrintError("can not allocate memory");\r
+  else if (res == SZ_ERROR_CRC)\r
+    PrintError("CRC error");\r
+  else\r
+    printf("\nERROR #%d\n", res);\r
+  return 1;\r
+}\r
diff --git a/C/Util/7z/makefile b/C/Util/7z/makefile
new file mode 100755 (executable)
index 0000000..3b85364
--- /dev/null
@@ -0,0 +1,37 @@
+MY_STATIC_LINK=1\r
+CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT\r
+\r
+PROG = 7zDec.exe\r
+\r
+C_OBJS = \\r
+  $O\7zAlloc.obj \\r
+  $O\7zBuf.obj \\r
+  $O\7zBuf2.obj \\r
+  $O\7zCrc.obj \\r
+  $O\7zCrcOpt.obj \\r
+  $O\7zFile.obj \\r
+  $O\7zDec.obj \\r
+  $O\7zIn.obj \\r
+  $O\7zStream.obj \\r
+  $O\Bcj2.obj \\r
+  $O\Bra.obj \\r
+  $O\Bra86.obj \\r
+  $O\CpuArch.obj \\r
+  $O\Lzma2Dec.obj \\r
+  $O\LzmaDec.obj \\r
+  $O\Ppmd7.obj \\r
+  $O\Ppmd7Dec.obj \\r
+\r
+7Z_OBJS = \\r
+  $O\7zMain.obj \\r
+\r
+OBJS = \\r
+  $(7Z_OBJS) \\r
+  $(C_OBJS) \\r
+\r
+!include "../../../CPP/Build.mak"\r
+\r
+$(7Z_OBJS): $(*B).c\r
+       $(COMPL_O1)\r
+$(C_OBJS): ../../$(*B).c\r
+       $(COMPL_O2)\r
diff --git a/C/Util/7z/makefile.gcc b/C/Util/7z/makefile.gcc
new file mode 100755 (executable)
index 0000000..2fb1576
--- /dev/null
@@ -0,0 +1,70 @@
+PROG = 7zDec\r
+CXX = g++\r
+LIB =\r
+RM = rm -f\r
+CFLAGS = -c -O2 -Wall\r
+\r
+OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o\r
+\r
+all: $(PROG)\r
+\r
+$(PROG): $(OBJS)\r
+       $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)\r
+\r
+7zMain.o: 7zMain.c\r
+       $(CXX) $(CFLAGS) 7zMain.c\r
+\r
+7zAlloc.o: 7zAlloc.c\r
+       $(CXX) $(CFLAGS) ../../7zAlloc.c\r
+\r
+7zBuf.o: ../../7zBuf.c\r
+       $(CXX) $(CFLAGS) ../../7zBuf.c\r
+\r
+7zBuf2.o: ../../7zBuf2.c\r
+       $(CXX) $(CFLAGS) ../../7zBuf2.c\r
+\r
+7zCrc.o: ../../7zCrc.c\r
+       $(CXX) $(CFLAGS) ../../7zCrc.c\r
+\r
+7zCrcOpt.o: ../../7zCrc.c\r
+       $(CXX) $(CFLAGS) ../../7zCrcOpt.c\r
+\r
+7zDec.o: ../../7zDec.c\r
+       $(CXX) $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT ../../7zDec.c\r
+\r
+7zIn.o: ../../7zIn.c\r
+       $(CXX) $(CFLAGS) ../../7zIn.c\r
+\r
+CpuArch.o: ../../CpuArch.c\r
+       $(CXX) $(CFLAGS) ../../CpuArch.c\r
+\r
+LzmaDec.o: ../../LzmaDec.c\r
+       $(CXX) $(CFLAGS) ../../LzmaDec.c\r
+\r
+Lzma2Dec.o: ../../Lzma2Dec.c\r
+       $(CXX) $(CFLAGS) ../../Lzma2Dec.c\r
+\r
+Bra.o: ../../Bra.c\r
+       $(CXX) $(CFLAGS) ../../Bra.c\r
+\r
+Bra86.o: ../../Bra86.c\r
+       $(CXX) $(CFLAGS) ../../Bra86.c\r
+\r
+Bcj2.o: ../../Bcj2.c\r
+       $(CXX) $(CFLAGS) ../../Bcj2.c\r
+\r
+Ppmd7.o: ../../Ppmd7.c\r
+       $(CXX) $(CFLAGS) ../../Ppmd7.c\r
+\r
+Ppmd7Dec.o: ../../Ppmd7Dec.c\r
+       $(CXX) $(CFLAGS) ../../Ppmd7Dec.c\r
+\r
+7zFile.o: ../../7zFile.c\r
+       $(CXX) $(CFLAGS) ../../7zFile.c\r
+\r
+7zStream.o: ../../7zStream.c\r
+       $(CXX) $(CFLAGS) ../../7zStream.c\r
+\r
+clean:\r
+       -$(RM) $(PROG) $(OBJS)\r
+\r
diff --git a/C/Util/Lzma/LzmaUtil.c b/C/Util/Lzma/LzmaUtil.c
new file mode 100755 (executable)
index 0000000..f8de4a2
--- /dev/null
@@ -0,0 +1,254 @@
+/* LzmaUtil.c -- Test application for LZMA compression\r
+2010-09-20 : Igor Pavlov : Public domain */\r
+\r
+#define _CRT_SECURE_NO_WARNINGS\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include "../../Alloc.h"\r
+#include "../../7zFile.h"\r
+#include "../../7zVersion.h"\r
+#include "../../LzmaDec.h"\r
+#include "../../LzmaEnc.h"\r
+\r
+const char *kCantReadMessage = "Can not read input file";\r
+const char *kCantWriteMessage = "Can not write output file";\r
+const char *kCantAllocateMessage = "Can not allocate memory";\r
+const char *kDataErrorMessage = "Data error";\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+void PrintHelp(char *buffer)\r
+{\r
+  strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"\r
+      "\nUsage:  lzma <e|d> inputFile outputFile\n"\r
+             "  e: encode file\n"\r
+             "  d: decode file\n");\r
+}\r
+\r
+int PrintError(char *buffer, const char *message)\r
+{\r
+  strcat(buffer, "\nError: ");\r
+  strcat(buffer, message);\r
+  strcat(buffer, "\n");\r
+  return 1;\r
+}\r
+\r
+int PrintErrorNumber(char *buffer, SRes val)\r
+{\r
+  sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);\r
+  return 1;\r
+}\r
+\r
+int PrintUserError(char *buffer)\r
+{\r
+  return PrintError(buffer, "Incorrect command");\r
+}\r
+\r
+#define IN_BUF_SIZE (1 << 16)\r
+#define OUT_BUF_SIZE (1 << 16)\r
+\r
+static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,\r
+    UInt64 unpackSize)\r
+{\r
+  int thereIsSize = (unpackSize != (UInt64)(Int64)-1);\r
+  Byte inBuf[IN_BUF_SIZE];\r
+  Byte outBuf[OUT_BUF_SIZE];\r
+  size_t inPos = 0, inSize = 0, outPos = 0;\r
+  LzmaDec_Init(state);\r
+  for (;;)\r
+  {\r
+    if (inPos == inSize)\r
+    {\r
+      inSize = IN_BUF_SIZE;\r
+      RINOK(inStream->Read(inStream, inBuf, &inSize));\r
+      inPos = 0;\r
+    }\r
+    {\r
+      SRes res;\r
+      SizeT inProcessed = inSize - inPos;\r
+      SizeT outProcessed = OUT_BUF_SIZE - outPos;\r
+      ELzmaFinishMode finishMode = LZMA_FINISH_ANY;\r
+      ELzmaStatus status;\r
+      if (thereIsSize && outProcessed > unpackSize)\r
+      {\r
+        outProcessed = (SizeT)unpackSize;\r
+        finishMode = LZMA_FINISH_END;\r
+      }\r
+      \r
+      res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,\r
+        inBuf + inPos, &inProcessed, finishMode, &status);\r
+      inPos += inProcessed;\r
+      outPos += outProcessed;\r
+      unpackSize -= outProcessed;\r
+      \r
+      if (outStream)\r
+        if (outStream->Write(outStream, outBuf, outPos) != outPos)\r
+          return SZ_ERROR_WRITE;\r
+        \r
+      outPos = 0;\r
+      \r
+      if (res != SZ_OK || thereIsSize && unpackSize == 0)\r
+        return res;\r
+      \r
+      if (inProcessed == 0 && outProcessed == 0)\r
+      {\r
+        if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)\r
+          return SZ_ERROR_DATA;\r
+        return res;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)\r
+{\r
+  UInt64 unpackSize;\r
+  int i;\r
+  SRes res = 0;\r
+\r
+  CLzmaDec state;\r
+\r
+  /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */\r
+  unsigned char header[LZMA_PROPS_SIZE + 8];\r
+\r
+  /* Read and parse header */\r
+\r
+  RINOK(SeqInStream_Read(inStream, header, sizeof(header)));\r
+\r
+  unpackSize = 0;\r
+  for (i = 0; i < 8; i++)\r
+    unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8);\r
+\r
+  LzmaDec_Construct(&state);\r
+  RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc));\r
+  res = Decode2(&state, outStream, inStream, unpackSize);\r
+  LzmaDec_Free(&state, &g_Alloc);\r
+  return res;\r
+}\r
+\r
+static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs)\r
+{\r
+  CLzmaEncHandle enc;\r
+  SRes res;\r
+  CLzmaEncProps props;\r
+\r
+  rs = rs;\r
+\r
+  enc = LzmaEnc_Create(&g_Alloc);\r
+  if (enc == 0)\r
+    return SZ_ERROR_MEM;\r
+\r
+  LzmaEncProps_Init(&props);\r
+  res = LzmaEnc_SetProps(enc, &props);\r
+\r
+  if (res == SZ_OK)\r
+  {\r
+    Byte header[LZMA_PROPS_SIZE + 8];\r
+    size_t headerSize = LZMA_PROPS_SIZE;\r
+    int i;\r
+\r
+    res = LzmaEnc_WriteProperties(enc, header, &headerSize);\r
+    for (i = 0; i < 8; i++)\r
+      header[headerSize++] = (Byte)(fileSize >> (8 * i));\r
+    if (outStream->Write(outStream, header, headerSize) != headerSize)\r
+      res = SZ_ERROR_WRITE;\r
+    else\r
+    {\r
+      if (res == SZ_OK)\r
+        res = LzmaEnc_Encode(enc, outStream, inStream, NULL, &g_Alloc, &g_Alloc);\r
+    }\r
+  }\r
+  LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);\r
+  return res;\r
+}\r
+\r
+int main2(int numArgs, const char *args[], char *rs)\r
+{\r
+  CFileSeqInStream inStream;\r
+  CFileOutStream outStream;\r
+  char c;\r
+  int res;\r
+  int encodeMode;\r
+  Bool useOutFile = False;\r
+\r
+  FileSeqInStream_CreateVTable(&inStream);\r
+  File_Construct(&inStream.file);\r
+\r
+  FileOutStream_CreateVTable(&outStream);\r
+  File_Construct(&outStream.file);\r
+\r
+  if (numArgs == 1)\r
+  {\r
+    PrintHelp(rs);\r
+    return 0;\r
+  }\r
+\r
+  if (numArgs < 3 || numArgs > 4 || strlen(args[1]) != 1)\r
+    return PrintUserError(rs);\r
+\r
+  c = args[1][0];\r
+  encodeMode = (c == 'e' || c == 'E');\r
+  if (!encodeMode && c != 'd' && c != 'D')\r
+    return PrintUserError(rs);\r
+\r
+  {\r
+    size_t t4 = sizeof(UInt32);\r
+    size_t t8 = sizeof(UInt64);\r
+    if (t4 != 4 || t8 != 8)\r
+      return PrintError(rs, "Incorrect UInt32 or UInt64");\r
+  }\r
+\r
+  if (InFile_Open(&inStream.file, args[2]) != 0)\r
+    return PrintError(rs, "Can not open input file");\r
+\r
+  if (numArgs > 3)\r
+  {\r
+    useOutFile = True;\r
+    if (OutFile_Open(&outStream.file, args[3]) != 0)\r
+      return PrintError(rs, "Can not open output file");\r
+  }\r
+  else if (encodeMode)\r
+    PrintUserError(rs);\r
+\r
+  if (encodeMode)\r
+  {\r
+    UInt64 fileSize;\r
+    File_GetLength(&inStream.file, &fileSize);\r
+    res = Encode(&outStream.s, &inStream.s, fileSize, rs);\r
+  }\r
+  else\r
+  {\r
+    res = Decode(&outStream.s, useOutFile ? &inStream.s : NULL);\r
+  }\r
+\r
+  if (useOutFile)\r
+    File_Close(&outStream.file);\r
+  File_Close(&inStream.file);\r
+\r
+  if (res != SZ_OK)\r
+  {\r
+    if (res == SZ_ERROR_MEM)\r
+      return PrintError(rs, kCantAllocateMessage);\r
+    else if (res == SZ_ERROR_DATA)\r
+      return PrintError(rs, kDataErrorMessage);\r
+    else if (res == SZ_ERROR_WRITE)\r
+      return PrintError(rs, kCantWriteMessage);\r
+    else if (res == SZ_ERROR_READ)\r
+      return PrintError(rs, kCantReadMessage);\r
+    return PrintErrorNumber(rs, res);\r
+  }\r
+  return 0;\r
+}\r
+\r
+int MY_CDECL main(int numArgs, const char *args[])\r
+{\r
+  char rs[800] = { 0 };\r
+  int res = main2(numArgs, args, rs);\r
+  fputs(rs, stdout);\r
+  return res;\r
+}\r
diff --git a/C/Util/Lzma/LzmaUtil.dsp b/C/Util/Lzma/LzmaUtil.dsp
new file mode 100755 (executable)
index 0000000..4815511
--- /dev/null
@@ -0,0 +1,168 @@
+# Microsoft Developer Studio Project File - Name="LzmaUtil" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=LzmaUtil - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "LzmaUtil.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "LzmaUtil.mak" CFG="LzmaUtil - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "LzmaUtil - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "LzmaUtil - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "LzmaUtil - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MT /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x419 /d "NDEBUG"\r
+# ADD RSC /l 0x419 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\7lzma.exe"\r
+\r
+!ELSEIF  "$(CFG)" == "LzmaUtil - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE RSC /l 0x419 /d "_DEBUG"\r
+# ADD RSC /l 0x419 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\7lzma.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "LzmaUtil - Win32 Release"\r
+# Name "LzmaUtil - Win32 Debug"\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zFile.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zFile.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zStream.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zVersion.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Alloc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Alloc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\CpuArch.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzFind.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzFind.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzFindMt.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzFindMt.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzHash.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaDec.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaDec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaEnc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaEnc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\LzmaUtil.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Threads.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Threads.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Types.h\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/C/Util/Lzma/LzmaUtil.dsw b/C/Util/Lzma/LzmaUtil.dsw
new file mode 100755 (executable)
index 0000000..f435487
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "LzmaUtil"=.\LzmaUtil.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/C/Util/Lzma/makefile b/C/Util/Lzma/makefile
new file mode 100755 (executable)
index 0000000..e99e098
--- /dev/null
@@ -0,0 +1,28 @@
+MY_STATIC_LINK=1\r
+PROG = LZMAc.exe\r
+\r
+CFLAGS = $(CFLAGS) \\r
+\r
+LIB_OBJS = \\r
+  $O\LzmaUtil.obj \\r
+\r
+C_OBJS = \\r
+  $O\Alloc.obj \\r
+  $O\LzFind.obj \\r
+  $O\LzFindMt.obj \\r
+  $O\LzmaDec.obj \\r
+  $O\LzmaEnc.obj \\r
+  $O\7zFile.obj \\r
+  $O\7zStream.obj \\r
+  $O\Threads.obj \\r
+\r
+OBJS = \\r
+  $(LIB_OBJS) \\r
+  $(C_OBJS) \\r
+\r
+!include "../../../CPP/Build.mak"\r
+\r
+$(LIB_OBJS): $(*B).c\r
+       $(COMPL_O2)\r
+$(C_OBJS): ../../$(*B).c\r
+       $(COMPL_O2)\r
diff --git a/C/Util/Lzma/makefile.gcc b/C/Util/Lzma/makefile.gcc
new file mode 100755 (executable)
index 0000000..12a72bb
--- /dev/null
@@ -0,0 +1,44 @@
+PROG = lzma\r
+CXX = g++\r
+LIB =\r
+RM = rm -f\r
+CFLAGS = -c -O2 -Wall -D_7ZIP_ST\r
+\r
+OBJS = \\r
+  LzmaUtil.o \\r
+  Alloc.o \\r
+  LzFind.o \\r
+  LzmaDec.o \\r
+  LzmaEnc.o \\r
+  7zFile.o \\r
+  7zStream.o \\r
+\r
+\r
+all: $(PROG)\r
+\r
+$(PROG): $(OBJS)\r
+       $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)\r
+\r
+LzmaUtil.o: LzmaUtil.c\r
+       $(CXX) $(CFLAGS) LzmaUtil.c\r
+\r
+Alloc.o: ../../Alloc.c\r
+       $(CXX) $(CFLAGS) ../../Alloc.c\r
+\r
+LzFind.o: ../../LzFind.c\r
+       $(CXX) $(CFLAGS) ../../LzFind.c\r
+\r
+LzmaDec.o: ../../LzmaDec.c\r
+       $(CXX) $(CFLAGS) ../../LzmaDec.c\r
+\r
+LzmaEnc.o: ../../LzmaEnc.c\r
+       $(CXX) $(CFLAGS) ../../LzmaEnc.c\r
+\r
+7zFile.o: ../../7zFile.c\r
+       $(CXX) $(CFLAGS) ../../7zFile.c\r
+\r
+7zStream.o: ../../7zStream.c\r
+       $(CXX) $(CFLAGS) ../../7zStream.c\r
+\r
+clean:\r
+       -$(RM) $(PROG) $(OBJS)\r
diff --git a/C/Util/LzmaLib/LzmaLib.def b/C/Util/LzmaLib/LzmaLib.def
new file mode 100755 (executable)
index 0000000..43b9597
--- /dev/null
@@ -0,0 +1,4 @@
+EXPORTS\r
+  LzmaCompress\r
+  LzmaUncompress\r
+\r
diff --git a/C/Util/LzmaLib/LzmaLib.dsp b/C/Util/LzmaLib/LzmaLib.dsp
new file mode 100755 (executable)
index 0000000..bf52b63
--- /dev/null
@@ -0,0 +1,178 @@
+# Microsoft Developer Studio Project File - Name="LzmaLib" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=LzmaLib - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "LzmaLib.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "LzmaLib.mak" CFG="LzmaLib - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "LzmaLib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "LzmaLib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "LzmaLib - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /c\r
+# ADD CPP /nologo /Gr /MT /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /FD /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x419 /d "NDEBUG"\r
+# ADD RSC /l 0x419 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Util\LZMA.dll" /opt:NOWIN98\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ELSEIF  "$(CFG)" == "LzmaLib - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /GZ /c\r
+# SUBTRACT CPP /YX\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x419 /d "_DEBUG"\r
+# ADD RSC /l 0x419 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\LZMA.dll" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "LzmaLib - Win32 Release"\r
+# Name "LzmaLib - Win32 Debug"\r
+# Begin Group "Spec"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\LzmaLib.def\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\LzmaLibExports.c\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Alloc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Alloc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\IStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzFind.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzFind.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzFindMt.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzFindMt.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzHash.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaDec.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaDec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaEnc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaEnc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaLib.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaLib.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\resource.rc\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Threads.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Threads.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Types.h\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/C/Util/LzmaLib/LzmaLib.dsw b/C/Util/LzmaLib/LzmaLib.dsw
new file mode 100755 (executable)
index 0000000..f6c5559
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "LzmaLib"=.\LzmaLib.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/C/Util/LzmaLib/LzmaLibExports.c b/C/Util/LzmaLib/LzmaLibExports.c
new file mode 100755 (executable)
index 0000000..7434536
--- /dev/null
@@ -0,0 +1,12 @@
+/* LzmaLibExports.c -- LZMA library DLL Entry point\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#include <windows.h>\r
+\r
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)\r
+{\r
+  hInstance = hInstance;\r
+  dwReason = dwReason;\r
+  lpReserved = lpReserved;\r
+  return TRUE;\r
+}\r
diff --git a/C/Util/LzmaLib/makefile b/C/Util/LzmaLib/makefile
new file mode 100755 (executable)
index 0000000..e0f3114
--- /dev/null
@@ -0,0 +1,34 @@
+MY_STATIC_LINK=1\r
+SLIB = sLZMA.lib\r
+PROG = LZMA.dll\r
+SLIBPATH = $O\$(SLIB)\r
+\r
+DEF_FILE = LzmaLib.def\r
+CFLAGS = $(CFLAGS) \\r
+\r
+LIB_OBJS = \\r
+  $O\LzmaLibExports.obj \\r
+\r
+C_OBJS = \\r
+  $O\Alloc.obj \\r
+  $O\LzFind.obj \\r
+  $O\LzFindMt.obj \\r
+  $O\LzmaDec.obj \\r
+  $O\LzmaEnc.obj \\r
+  $O\LzmaLib.obj \\r
+  $O\Threads.obj \\r
+\r
+OBJS = \\r
+  $(LIB_OBJS) \\r
+  $(C_OBJS) \\r
+  $O\resource.res\r
+\r
+!include "../../../CPP/Build.mak"\r
+\r
+$(SLIBPATH): $O $(OBJS)\r
+       lib -out:$(SLIBPATH) $(OBJS) $(LIBS)\r
+\r
+$(LIB_OBJS): $(*B).c\r
+       $(COMPL_O2)\r
+$(C_OBJS): ../../$(*B).c\r
+       $(COMPL_O2)\r
diff --git a/C/Util/LzmaLib/resource.rc b/C/Util/LzmaLib/resource.rc
new file mode 100755 (executable)
index 0000000..cb62ed9
--- /dev/null
@@ -0,0 +1,4 @@
+#include "../../../CPP/7zip/MyVersionInfo.rc"\r
+\r
+MY_VERSION_INFO_DLL("LZMA library", "LZMA")\r
+\r
diff --git a/C/Util/SfxSetup/SfxSetup.c b/C/Util/SfxSetup/SfxSetup.c
new file mode 100755 (executable)
index 0000000..d4eb5c4
--- /dev/null
@@ -0,0 +1,592 @@
+/* SfxSetup.c - 7z SFX Setup\r
+2010-11-11 : Igor Pavlov : Public domain */\r
+\r
+#ifndef UNICODE\r
+#define UNICODE\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+#define _UNICODE\r
+#endif\r
+\r
+#ifdef _CONSOLE\r
+#include <stdio.h>\r
+#endif\r
+\r
+#include "../../7z.h"\r
+#include "../../7zAlloc.h"\r
+#include "../../7zCrc.h"\r
+#include "../../7zFile.h"\r
+#include "../../CpuArch.h"\r
+\r
+#define k_EXE_ExtIndex 1\r
+\r
+static const char *kExts[] =\r
+{\r
+  "bat",\r
+  "exe",\r
+  "inf",\r
+  "msi",\r
+  #ifdef UNDER_CE\r
+  "cab",\r
+  #endif\r
+  "html",\r
+  "htm"\r
+};\r
+\r
+static const char *kNames[] =\r
+{\r
+  "setup",\r
+  "install",\r
+  "run",\r
+  "start"\r
+};\r
+\r
+static unsigned FindExt(const wchar_t *s, unsigned *extLen)\r
+{\r
+  unsigned len = (unsigned)wcslen(s);\r
+  unsigned i;\r
+  for (i = len; i > 0; i--)\r
+  {\r
+    if (s[i - 1] == '.')\r
+    {\r
+      *extLen = len - i;\r
+      return i - 1;\r
+    }\r
+  }\r
+  *extLen = 0;\r
+  return len;\r
+}\r
+\r
+#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))\r
+\r
+static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, unsigned len)\r
+{\r
+  unsigned i;\r
+  for (i = 0; i < num; i++)\r
+  {\r
+    const char *item = items[i];\r
+    unsigned itemLen = (unsigned)strlen(item);\r
+    unsigned j;\r
+    if (len != itemLen)\r
+      continue;\r
+    for (j = 0; j < len; j++)\r
+    {\r
+      unsigned c = item[j];\r
+      if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])\r
+        break;\r
+    }\r
+    if (j == len)\r
+      return i;\r
+  }\r
+  return i;\r
+}\r
+\r
+#ifdef _CONSOLE\r
+static BOOL WINAPI HandlerRoutine(DWORD ctrlType)\r
+{\r
+  ctrlType = ctrlType;\r
+  return TRUE;\r
+}\r
+#endif\r
+\r
+static void PrintErrorMessage(const char *message)\r
+{\r
+  #ifdef _CONSOLE\r
+  printf("\n7-Zip Error: %s\n", message);\r
+  #else\r
+  #ifdef UNDER_CE\r
+  WCHAR messageW[256 + 4];\r
+  unsigned i;\r
+  for (i = 0; i < 256 && message[i] != 0; i++)\r
+    messageW[i] = message[i];\r
+  messageW[i] = 0;\r
+  MessageBoxW(0, messageW, L"7-Zip Error", MB_ICONERROR);\r
+  #else\r
+  MessageBoxA(0, message, "7-Zip Error", MB_ICONERROR);\r
+  #endif\r
+  #endif\r
+}\r
+\r
+static WRes MyCreateDir(const WCHAR *name)\r
+{\r
+  return CreateDirectoryW(name, NULL) ? 0 : GetLastError();\r
+}\r
+\r
+#ifdef UNDER_CE\r
+#define kBufferSize (1 << 13)\r
+#else\r
+#define kBufferSize (1 << 15)\r
+#endif\r
+\r
+#define kSignatureSearchLimit (1 << 22)\r
+\r
+static Bool FindSignature(CSzFile *stream, UInt64 *resPos)\r
+{\r
+  Byte buf[kBufferSize];\r
+  size_t numPrevBytes = 0;\r
+  *resPos = 0;\r
+  for (;;)\r
+  {\r
+    size_t numTests, pos;\r
+    if (*resPos > kSignatureSearchLimit)\r
+      return False;\r
+    \r
+    do\r
+    {\r
+      size_t processed = kBufferSize - numPrevBytes;\r
+      if (File_Read(stream, buf + numPrevBytes, &processed) != 0)\r
+        return False;\r
+      if (processed == 0)\r
+        return False;\r
+      numPrevBytes += processed;\r
+    }\r
+    while (numPrevBytes <= k7zStartHeaderSize);\r
+    \r
+    numTests = numPrevBytes - k7zStartHeaderSize;\r
+    for (pos = 0; pos < numTests; pos++)\r
+    {\r
+      for (; buf[pos] != '7' && pos < numTests; pos++);\r
+      if (pos == numTests)\r
+        break;\r
+      if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)\r
+        if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8))\r
+        {\r
+          *resPos += pos;\r
+          return True;\r
+        }\r
+    }\r
+    *resPos += numTests;\r
+    numPrevBytes -= numTests;\r
+    memmove(buf, buf + numTests, numPrevBytes);\r
+  }\r
+}\r
+\r
+static Bool DoesFileOrDirExist(const WCHAR *path)\r
+{\r
+  WIN32_FIND_DATAW fd;\r
+  HANDLE handle;\r
+  handle = FindFirstFileW(path, &fd);\r
+  if (handle == INVALID_HANDLE_VALUE)\r
+    return False;\r
+  FindClose(handle);\r
+  return True;\r
+}\r
+\r
+static WRes RemoveDirWithSubItems(WCHAR *path)\r
+{\r
+  WIN32_FIND_DATAW fd;\r
+  HANDLE handle;\r
+  WRes res = 0;\r
+  size_t len = wcslen(path);\r
+  wcscpy(path + len, L"*");\r
+  handle = FindFirstFileW(path, &fd);\r
+  path[len] = L'\0';\r
+  if (handle == INVALID_HANDLE_VALUE)\r
+    return GetLastError();\r
+  for (;;)\r
+  {\r
+    if (wcscmp(fd.cFileName, L".") != 0 &&\r
+        wcscmp(fd.cFileName, L"..") != 0)\r
+    {\r
+      wcscpy(path + len, fd.cFileName);\r
+      if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)\r
+      {\r
+        wcscat(path, L"\\");\r
+        res = RemoveDirWithSubItems(path);\r
+      }\r
+      else\r
+      {\r
+        SetFileAttributesW(path, 0);\r
+        if (DeleteFileW(path) == 0)\r
+          res = GetLastError();\r
+      }\r
+      if (res != 0)\r
+        break;\r
+    }\r
+    if (!FindNextFileW(handle, &fd))\r
+    {\r
+      res = GetLastError();\r
+      if (res == ERROR_NO_MORE_FILES)\r
+        res = 0;\r
+      break;\r
+    }\r
+  }\r
+  path[len] = L'\0';\r
+  FindClose(handle);\r
+  if (res == 0)\r
+  {\r
+    if (!RemoveDirectoryW(path))\r
+      res = GetLastError();\r
+  }\r
+  return res;\r
+}\r
+\r
+#ifdef _CONSOLE\r
+int MY_CDECL main()\r
+#else\r
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,\r
+  #ifdef UNDER_CE\r
+  LPWSTR\r
+  #else\r
+  LPSTR\r
+  #endif\r
+  lpCmdLine, int nCmdShow)\r
+#endif\r
+{\r
+  CFileInStream archiveStream;\r
+  CLookToRead lookStream;\r
+  CSzArEx db;\r
+  SRes res = SZ_OK;\r
+  ISzAlloc allocImp;\r
+  ISzAlloc allocTempImp;\r
+  WCHAR sfxPath[MAX_PATH + 2];\r
+  WCHAR path[MAX_PATH * 3 + 2];\r
+  size_t pathLen;\r
+  DWORD winRes;\r
+  const wchar_t *cmdLineParams;\r
+  const char *errorMessage = NULL;\r
+  Bool useShellExecute = True;\r
+\r
+  #ifdef _CONSOLE\r
+  SetConsoleCtrlHandler(HandlerRoutine, TRUE);\r
+  #else\r
+  hInstance = hInstance;\r
+  hPrevInstance = hPrevInstance;\r
+  lpCmdLine = lpCmdLine;\r
+  nCmdShow = nCmdShow;\r
+  #endif\r
+\r
+  CrcGenerateTable();\r
+\r
+  allocImp.Alloc = SzAlloc;\r
+  allocImp.Free = SzFree;\r
+\r
+  allocTempImp.Alloc = SzAllocTemp;\r
+  allocTempImp.Free = SzFreeTemp;\r
+\r
+  FileInStream_CreateVTable(&archiveStream);\r
+  LookToRead_CreateVTable(&lookStream, False);\r
\r
+  winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);\r
+  if (winRes == 0 || winRes > MAX_PATH)\r
+    return 1;\r
+  {\r
+    cmdLineParams = GetCommandLineW();\r
+    #ifndef UNDER_CE\r
+    {\r
+      Bool quoteMode = False;\r
+      for (;; cmdLineParams++)\r
+      {\r
+        wchar_t c = *cmdLineParams;\r
+        if (c == L'\"')\r
+          quoteMode = !quoteMode;\r
+        else if (c == 0 || (c == L' ' && !quoteMode))\r
+          break;\r
+      }\r
+    }\r
+    #endif\r
+  }\r
+\r
+  {\r
+    unsigned i;\r
+    DWORD d;\r
+    winRes = GetTempPathW(MAX_PATH, path);\r
+    if (winRes == 0 || winRes > MAX_PATH)\r
+      return 1;\r
+    pathLen = wcslen(path);\r
+    d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();\r
+    for (i = 0;; i++, d += GetTickCount())\r
+    {\r
+      if (i >= 100)\r
+      {\r
+        res = SZ_ERROR_FAIL;\r
+        break;\r
+      }\r
+      wcscpy(path + pathLen, L"7z");\r
+\r
+      {\r
+        wchar_t *s = path + wcslen(path);\r
+        UInt32 value = d;\r
+        unsigned k;\r
+        for (k = 0; k < 8; k++)\r
+        {\r
+          unsigned t = value & 0xF;\r
+          value >>= 4;\r
+          s[7 - k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));\r
+        }\r
+        s[k] = '\0';\r
+      }\r
+\r
+      if (DoesFileOrDirExist(path))\r
+        continue;\r
+      if (CreateDirectoryW(path, NULL))\r
+      {\r
+        wcscat(path, L"\\");\r
+        pathLen = wcslen(path);\r
+        break;\r
+      }\r
+      if (GetLastError() != ERROR_ALREADY_EXISTS)\r
+      {\r
+        res = SZ_ERROR_FAIL;\r
+        break;\r
+      }\r
+    }\r
+    if (res != SZ_OK)\r
+      errorMessage = "Can't create temp folder";\r
+  }\r
+\r
+  if (res != SZ_OK)\r
+  {\r
+    if (!errorMessage)\r
+      errorMessage = "Error";\r
+    PrintErrorMessage(errorMessage);\r
+    return 1;\r
+  }\r
+\r
+  if (InFile_OpenW(&archiveStream.file, sfxPath) != 0)\r
+  {\r
+    errorMessage = "can not open input file";\r
+    res = SZ_ERROR_FAIL;\r
+  }\r
+  else\r
+  {\r
+    UInt64 pos = 0;\r
+    if (!FindSignature(&archiveStream.file, &pos))\r
+      res = SZ_ERROR_FAIL;\r
+    else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0)\r
+      res = SZ_ERROR_FAIL;\r
+    if (res != 0)\r
+      errorMessage = "Can't find 7z archive";\r
+  }\r
+\r
+  if (res == SZ_OK)\r
+  {\r
+    lookStream.realStream = &archiveStream.s;\r
+    LookToRead_Init(&lookStream);\r
+  }\r
+\r
+  SzArEx_Init(&db);\r
+  if (res == SZ_OK)\r
+  {\r
+    res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);\r
+  }\r
+  if (res == SZ_OK)\r
+  {\r
+    UInt32 executeFileIndex = (UInt32)(Int32)-1;\r
+    UInt32 minPrice = 1 << 30;\r
+    UInt32 i;\r
+    UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */\r
+    Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */\r
+    size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */\r
+    \r
+    for (i = 0; i < db.db.NumFiles; i++)\r
+    {\r
+      size_t offset = 0;\r
+      size_t outSizeProcessed = 0;\r
+      const CSzFileItem *f = db.db.Files + i;\r
+      size_t len;\r
+      WCHAR *temp;\r
+      len = SzArEx_GetFileNameUtf16(&db, i, NULL);\r
+      \r
+      if (len >= MAX_PATH)\r
+      {\r
+        res = SZ_ERROR_FAIL;\r
+        break;\r
+      }\r
+      \r
+      temp = path + pathLen;\r
+      \r
+      SzArEx_GetFileNameUtf16(&db, i, temp);\r
+      {\r
+        res = SzArEx_Extract(&db, &lookStream.s, i,\r
+          &blockIndex, &outBuffer, &outBufferSize,\r
+          &offset, &outSizeProcessed,\r
+          &allocImp, &allocTempImp);\r
+        if (res != SZ_OK)\r
+          break;\r
+      }\r
+      {\r
+        CSzFile outFile;\r
+        size_t processedSize;\r
+        size_t j;\r
+        size_t nameStartPos = 0;\r
+        for (j = 0; temp[j] != 0; j++)\r
+        {\r
+          if (temp[j] == '/')\r
+          {\r
+            temp[j] = 0;\r
+            MyCreateDir(path);\r
+            temp[j] = CHAR_PATH_SEPARATOR;\r
+            nameStartPos = j + 1;\r
+          }\r
+        }\r
+\r
+        if (f->IsDir)\r
+        {\r
+          MyCreateDir(path);\r
+          continue;\r
+        }\r
+        else\r
+        {\r
+          unsigned extLen;\r
+          const WCHAR *name = temp + nameStartPos;\r
+          unsigned len = (unsigned)wcslen(name);\r
+          unsigned nameLen = FindExt(temp + nameStartPos, &extLen);\r
+          unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen);\r
+          unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen);\r
+\r
+          unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12));\r
+          if (minPrice > price)\r
+          {\r
+            minPrice = price;\r
+            executeFileIndex = i;\r
+            useShellExecute = (extPrice != k_EXE_ExtIndex);\r
+          }\r
+         \r
+          if (DoesFileOrDirExist(path))\r
+          {\r
+            errorMessage = "Duplicate file";\r
+            res = SZ_ERROR_FAIL;\r
+            break;\r
+          }\r
+          if (OutFile_OpenW(&outFile, path))\r
+          {\r
+            errorMessage = "Can't open output file";\r
+            res = SZ_ERROR_FAIL;\r
+            break;\r
+          }\r
+        }\r
+        processedSize = outSizeProcessed;\r
+        if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)\r
+        {\r
+          errorMessage = "Can't write output file";\r
+          res = SZ_ERROR_FAIL;\r
+        }\r
+        \r
+        #ifdef USE_WINDOWS_FILE\r
+        if (f->MTimeDefined)\r
+        {\r
+          FILETIME mTime;\r
+          mTime.dwLowDateTime = f->MTime.Low;\r
+          mTime.dwHighDateTime = f->MTime.High;\r
+          SetFileTime(outFile.handle, NULL, NULL, &mTime);\r
+        }\r
+        #endif\r
+        \r
+        {\r
+          SRes res2 = File_Close(&outFile);\r
+          if (res != SZ_OK)\r
+            break;\r
+          if (res2 != SZ_OK)\r
+          {\r
+            res = res2;\r
+            break;\r
+          }\r
+        }\r
+        #ifdef USE_WINDOWS_FILE\r
+        if (f->AttribDefined)\r
+          SetFileAttributesW(path, f->Attrib);\r
+        #endif\r
+      }\r
+    }\r
+\r
+    if (res == SZ_OK)\r
+    {\r
+      if (executeFileIndex == (UInt32)(Int32)-1)\r
+      {\r
+        errorMessage = "There is no file to execute";\r
+        res = SZ_ERROR_FAIL;\r
+      }\r
+      else\r
+      {\r
+        WCHAR *temp = path + pathLen;\r
+        UInt32 j;\r
+        SzArEx_GetFileNameUtf16(&db, executeFileIndex, temp);\r
+        for (j = 0; temp[j] != 0; j++)\r
+          if (temp[j] == '/')\r
+            temp[j] = CHAR_PATH_SEPARATOR;\r
+      }\r
+    }\r
+    IAlloc_Free(&allocImp, outBuffer);\r
+  }\r
+  SzArEx_Free(&db, &allocImp);\r
+\r
+  File_Close(&archiveStream.file);\r
+\r
+  if (res == SZ_OK)\r
+  {\r
+    HANDLE hProcess = 0;\r
+    if (useShellExecute)\r
+    {\r
+      SHELLEXECUTEINFO ei;\r
+      UINT32 executeRes;\r
+      BOOL success;\r
+      \r
+      memset(&ei, 0, sizeof(ei));\r
+      ei.cbSize = sizeof(ei);\r
+      ei.lpFile = path;\r
+      ei.fMask = SEE_MASK_NOCLOSEPROCESS\r
+          #ifndef UNDER_CE\r
+          | SEE_MASK_FLAG_DDEWAIT\r
+          #endif\r
+          /* | SEE_MASK_NO_CONSOLE */\r
+          ;\r
+      if (wcslen(cmdLineParams) != 0)\r
+        ei.lpParameters = cmdLineParams;\r
+      ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */\r
+      success = ShellExecuteEx(&ei);\r
+      executeRes = (UINT32)(UINT_PTR)ei.hInstApp;\r
+      if (!success || (executeRes <= 32 && executeRes != 0))  /* executeRes = 0 in Windows CE */\r
+        res = SZ_ERROR_FAIL;\r
+      else\r
+        hProcess = ei.hProcess;\r
+    }\r
+    else\r
+    {\r
+      STARTUPINFOW si;\r
+      PROCESS_INFORMATION pi;\r
+      WCHAR cmdLine[MAX_PATH * 3];\r
+\r
+      wcscpy(cmdLine, path);\r
+      wcscat(cmdLine, cmdLineParams);\r
+      memset(&si, 0, sizeof(si));\r
+      si.cb = sizeof(si);\r
+      if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0)\r
+        res = SZ_ERROR_FAIL;\r
+      else\r
+      {\r
+        CloseHandle(pi.hThread);\r
+        hProcess = pi.hProcess;\r
+      }\r
+    }\r
+    if (hProcess != 0)\r
+    {\r
+      WaitForSingleObject(hProcess, INFINITE);\r
+      CloseHandle(hProcess);\r
+    }\r
+  }\r
+\r
+  path[pathLen] = L'\0';\r
+  RemoveDirWithSubItems(path);\r
+\r
+  if (res == SZ_OK)\r
+    return 0;\r
+  \r
+  {\r
+    if (res == SZ_ERROR_UNSUPPORTED)\r
+      errorMessage = "Decoder doesn't support this archive";\r
+    else if (res == SZ_ERROR_MEM)\r
+      errorMessage = "Can't allocate required memory";\r
+    else if (res == SZ_ERROR_CRC)\r
+      errorMessage = "CRC error";\r
+    else\r
+    {\r
+      if (!errorMessage)\r
+        errorMessage = "ERROR";\r
+    }\r
+    if (errorMessage)\r
+      PrintErrorMessage(errorMessage);\r
+  }\r
+  return 1;\r
+}\r
diff --git a/C/Util/SfxSetup/SfxSetup.dsp b/C/Util/SfxSetup/SfxSetup.dsp
new file mode 100755 (executable)
index 0000000..10814a5
--- /dev/null
@@ -0,0 +1,198 @@
+# Microsoft Developer Studio Project File - Name="SfxSetup" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Application" 0x0101\r
+\r
+CFG=SfxSetup - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "SfxSetup.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "SfxSetup.mak" CFG="SfxSetup - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "SfxSetup - Win32 Release" (based on "Win32 (x86) Application")\r
+!MESSAGE "SfxSetup - Win32 Debug" (based on "Win32 (x86) Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "SfxSetup - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /c\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x419 /d "NDEBUG"\r
+# ADD RSC /l 0x419 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "SfxSetup - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x419 /d "_DEBUG"\r
+# ADD RSC /l 0x419 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "SfxSetup - Win32 Release"\r
+# Name "SfxSetup - Win32 Debug"\r
+# Begin Group "Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7z.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zAlloc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zAlloc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zBuf.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zBuf.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zCrc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zCrc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zCrcOpt.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zDec.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zFile.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zFile.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zIn.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\7zStream.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bcj2.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bcj2.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bra.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bra.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Bra86.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\CpuArch.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\CpuArch.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Lzma2Dec.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Lzma2Dec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaDec.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\LzmaDec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Types.h\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=.\SfxSetup.c\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/C/Util/SfxSetup/SfxSetup.dsw b/C/Util/SfxSetup/SfxSetup.dsw
new file mode 100755 (executable)
index 0000000..128fcdd
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "SfxSetup"=.\SfxSetup.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/C/Util/SfxSetup/makefile b/C/Util/SfxSetup/makefile
new file mode 100755 (executable)
index 0000000..5d91be1
--- /dev/null
@@ -0,0 +1,35 @@
+PROG = 7zS2.sfx\r
+LIBS = $(LIBS) \r
+CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE\r
+\r
+C_OBJS = \\r
+  $O\7zAlloc.obj \\r
+  $O\7zBuf.obj \\r
+  $O\7zBuf2.obj \\r
+  $O\7zCrc.obj \\r
+  $O\7zCrcOpt.obj \\r
+  $O\7zFile.obj \\r
+  $O\7zDec.obj \\r
+  $O\7zIn.obj \\r
+  $O\7zStream.obj \\r
+  $O\Bcj2.obj \\r
+  $O\Bra.obj \\r
+  $O\Bra86.obj \\r
+  $O\CpuArch.obj \\r
+  $O\Lzma2Dec.obj \\r
+  $O\LzmaDec.obj \\r
+\r
+7Z_OBJS = \\r
+  $O\SfxSetup.obj \\r
+\r
+OBJS = \\r
+  $(7Z_OBJS) \\r
+  $(C_OBJS) \\r
+  $O\resource.res\r
+\r
+!include "../../../CPP/Build.mak"\r
+\r
+$(7Z_OBJS): $(*B).c\r
+       $(COMPL_O1)\r
+$(C_OBJS): ../../$(*B).c\r
+       $(COMPL_O1)\r
diff --git a/C/Util/SfxSetup/makefile_con b/C/Util/SfxSetup/makefile_con
new file mode 100755 (executable)
index 0000000..3fbb6b6
--- /dev/null
@@ -0,0 +1,35 @@
+PROG = 7zS2con.sfx\r
+LIBS = $(LIBS) \r
+CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CONSOLE\r
+\r
+C_OBJS = \\r
+  $O\7zAlloc.obj \\r
+  $O\7zBuf.obj \\r
+  $O\7zBuf2.obj \\r
+  $O\7zCrc.obj \\r
+  $O\7zCrcOpt.obj \\r
+  $O\7zFile.obj \\r
+  $O\7zDec.obj \\r
+  $O\7zIn.obj \\r
+  $O\7zStream.obj \\r
+  $O\Bcj2.obj \\r
+  $O\Bra.obj \\r
+  $O\Bra86.obj \\r
+  $O\CpuArch.obj \\r
+  $O\Lzma2Dec.obj \\r
+  $O\LzmaDec.obj \\r
+\r
+7Z_OBJS = \\r
+  $O\SfxSetup.obj \\r
+\r
+OBJS = \\r
+  $(7Z_OBJS) \\r
+  $(C_OBJS) \\r
+  $O\resource.res\r
+\r
+!include "../../../CPP/Build.mak"\r
+\r
+$(7Z_OBJS): $(*B).c\r
+       $(COMPL_O1)\r
+$(C_OBJS): ../../$(*B).c\r
+       $(COMPL_O1)\r
diff --git a/C/Util/SfxSetup/resource.rc b/C/Util/SfxSetup/resource.rc
new file mode 100755 (executable)
index 0000000..efff95e
--- /dev/null
@@ -0,0 +1,6 @@
+#include "../../../CPP/7zip/MyVersionInfo.rc"\r
+\r
+MY_VERSION_INFO_APP("7z Setup SFX small", "7zS2.sfx")\r
+\r
+1  ICON "setup.ico"\r
+\r
diff --git a/C/Util/SfxSetup/setup.ico b/C/Util/SfxSetup/setup.ico
new file mode 100755 (executable)
index 0000000..dbb6ca8
Binary files /dev/null and b/C/Util/SfxSetup/setup.ico differ
diff --git a/C/Xz.c b/C/Xz.c
new file mode 100755 (executable)
index 0000000..0bdf047
--- /dev/null
+++ b/C/Xz.c
@@ -0,0 +1,88 @@
+/* Xz.c - Xz\r
+2009-04-15 : Igor Pavlov : Public domain */\r
+\r
+#include "7zCrc.h"\r
+#include "CpuArch.h"\r
+#include "Xz.h"\r
+#include "XzCrc64.h"\r
+\r
+Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };\r
+Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };\r
+\r
+unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)\r
+{\r
+  unsigned i = 0;\r
+  do\r
+  {\r
+    buf[i++] = (Byte)((v & 0x7F) | 0x80);\r
+    v >>= 7;\r
+  }\r
+  while (v != 0);\r
+  buf[i - 1] &= 0x7F;\r
+  return i;\r
+}\r
+\r
+void Xz_Construct(CXzStream *p)\r
+{\r
+  p->numBlocks = p->numBlocksAllocated = 0;\r
+  p->blocks = 0;\r
+  p->flags = 0;\r
+}\r
+\r
+void Xz_Free(CXzStream *p, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, p->blocks);\r
+  p->numBlocks = p->numBlocksAllocated = 0;\r
+  p->blocks = 0;\r
+}\r
+\r
+unsigned XzFlags_GetCheckSize(CXzStreamFlags f)\r
+{\r
+  int t = XzFlags_GetCheckType(f);\r
+  return (t == 0) ? 0 : (4 << ((t - 1) / 3));\r
+}\r
+\r
+void XzCheck_Init(CXzCheck *p, int mode)\r
+{\r
+  p->mode = mode;\r
+  switch (mode)\r
+  {\r
+    case XZ_CHECK_CRC32: p->crc = CRC_INIT_VAL; break;\r
+    case XZ_CHECK_CRC64: p->crc64 = CRC64_INIT_VAL; break;\r
+    case XZ_CHECK_SHA256: Sha256_Init(&p->sha); break;\r
+  }\r
+}\r
+\r
+void XzCheck_Update(CXzCheck *p, const void *data, size_t size)\r
+{\r
+  switch (p->mode)\r
+  {\r
+    case XZ_CHECK_CRC32: p->crc = CrcUpdate(p->crc, data, size); break;\r
+    case XZ_CHECK_CRC64: p->crc64 = Crc64Update(p->crc64, data, size); break;\r
+    case XZ_CHECK_SHA256: Sha256_Update(&p->sha, (const Byte *)data, size); break;\r
+  }\r
+}\r
+\r
+int XzCheck_Final(CXzCheck *p, Byte *digest)\r
+{\r
+  switch (p->mode)\r
+  {\r
+    case XZ_CHECK_CRC32:\r
+      SetUi32(digest, CRC_GET_DIGEST(p->crc));\r
+      break;\r
+    case XZ_CHECK_CRC64:\r
+    {\r
+      int i;\r
+      UInt64 v = CRC64_GET_DIGEST(p->crc64);\r
+      for (i = 0; i < 8; i++, v >>= 8)\r
+        digest[i] = (Byte)(v & 0xFF);\r
+      break;\r
+    }\r
+    case XZ_CHECK_SHA256:\r
+      Sha256_Final(&p->sha, digest);\r
+      break;\r
+    default:\r
+      return 0;\r
+  }\r
+  return 1;\r
+}\r
diff --git a/C/Xz.h b/C/Xz.h
new file mode 100755 (executable)
index 0000000..d307963
--- /dev/null
+++ b/C/Xz.h
@@ -0,0 +1,252 @@
+/* Xz.h - Xz interface\r
+2010-09-17 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __XZ_H\r
+#define __XZ_H\r
+\r
+#include "Sha256.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+#define XZ_ID_Subblock 1\r
+#define XZ_ID_Delta 3\r
+#define XZ_ID_X86 4\r
+#define XZ_ID_PPC 5\r
+#define XZ_ID_IA64 6\r
+#define XZ_ID_ARM 7\r
+#define XZ_ID_ARMT 8\r
+#define XZ_ID_SPARC 9\r
+#define XZ_ID_LZMA2 0x21\r
+\r
+unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value);\r
+unsigned Xz_WriteVarInt(Byte *buf, UInt64 v);\r
+\r
+/* ---------- xz block ---------- */\r
+\r
+#define XZ_BLOCK_HEADER_SIZE_MAX 1024\r
+\r
+#define XZ_NUM_FILTERS_MAX 4\r
+#define XZ_BF_NUM_FILTERS_MASK 3\r
+#define XZ_BF_PACK_SIZE (1 << 6)\r
+#define XZ_BF_UNPACK_SIZE (1 << 7)\r
+\r
+#define XZ_FILTER_PROPS_SIZE_MAX 20\r
+\r
+typedef struct\r
+{\r
+  UInt64 id;\r
+  UInt32 propsSize;\r
+  Byte props[XZ_FILTER_PROPS_SIZE_MAX];\r
+} CXzFilter;\r
+\r
+typedef struct\r
+{\r
+  UInt64 packSize;\r
+  UInt64 unpackSize;\r
+  Byte flags;\r
+  CXzFilter filters[XZ_NUM_FILTERS_MAX];\r
+} CXzBlock;\r
+\r
+#define XzBlock_GetNumFilters(p) (((p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1)\r
+#define XzBlock_HasPackSize(p)   (((p)->flags & XZ_BF_PACK_SIZE) != 0)\r
+#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0)\r
+\r
+SRes XzBlock_Parse(CXzBlock *p, const Byte *header);\r
+SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes);\r
+\r
+/* ---------- xz stream ---------- */\r
+\r
+#define XZ_SIG_SIZE 6\r
+#define XZ_FOOTER_SIG_SIZE 2\r
+\r
+extern Byte XZ_SIG[XZ_SIG_SIZE];\r
+extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];\r
+\r
+#define XZ_STREAM_FLAGS_SIZE 2\r
+#define XZ_STREAM_CRC_SIZE 4\r
+\r
+#define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE)\r
+#define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4)\r
+\r
+#define XZ_CHECK_MASK 0xF\r
+#define XZ_CHECK_NO 0\r
+#define XZ_CHECK_CRC32 1\r
+#define XZ_CHECK_CRC64 4\r
+#define XZ_CHECK_SHA256 10\r
+\r
+typedef struct\r
+{\r
+  int mode;\r
+  UInt32 crc;\r
+  UInt64 crc64;\r
+  CSha256 sha;\r
+} CXzCheck;\r
+\r
+void XzCheck_Init(CXzCheck *p, int mode);\r
+void XzCheck_Update(CXzCheck *p, const void *data, size_t size);\r
+int XzCheck_Final(CXzCheck *p, Byte *digest);\r
+\r
+typedef UInt16 CXzStreamFlags;\r
+\r
+#define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK)\r
+#define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK)\r
+#define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32)\r
+unsigned XzFlags_GetCheckSize(CXzStreamFlags f);\r
+\r
+SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf);\r
+SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream);\r
+\r
+typedef struct\r
+{\r
+  UInt64 unpackSize;\r
+  UInt64 totalSize;\r
+} CXzBlockSizes;\r
+\r
+typedef struct\r
+{\r
+  CXzStreamFlags flags;\r
+  size_t numBlocks;\r
+  size_t numBlocksAllocated;\r
+  CXzBlockSizes *blocks;\r
+  UInt64 startOffset;\r
+} CXzStream;\r
+\r
+void Xz_Construct(CXzStream *p);\r
+void Xz_Free(CXzStream *p, ISzAlloc *alloc);\r
+\r
+#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1)\r
+\r
+UInt64 Xz_GetUnpackSize(const CXzStream *p);\r
+UInt64 Xz_GetPackSize(const CXzStream *p);\r
+\r
+typedef struct\r
+{\r
+  size_t num;\r
+  size_t numAllocated;\r
+  CXzStream *streams;\r
+} CXzs;\r
+\r
+void Xzs_Construct(CXzs *p);\r
+void Xzs_Free(CXzs *p, ISzAlloc *alloc);\r
+SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc);\r
+\r
+UInt64 Xzs_GetNumBlocks(const CXzs *p);\r
+UInt64 Xzs_GetUnpackSize(const CXzs *p);\r
+\r
+typedef enum\r
+{\r
+  CODER_STATUS_NOT_SPECIFIED,               /* use main error code instead */\r
+  CODER_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */\r
+  CODER_STATUS_NOT_FINISHED,                /* stream was not finished */\r
+  CODER_STATUS_NEEDS_MORE_INPUT             /* you must provide more input bytes */\r
+} ECoderStatus;\r
+\r
+typedef enum\r
+{\r
+  CODER_FINISH_ANY,   /* finish at any point */\r
+  CODER_FINISH_END    /* block must be finished at the end */\r
+} ECoderFinishMode;\r
+\r
+typedef struct _IStateCoder\r
+{\r
+  void *p;\r
+  void (*Free)(void *p, ISzAlloc *alloc);\r
+  SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);\r
+  void (*Init)(void *p);\r
+  SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+      int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished);\r
+} IStateCoder;\r
+\r
+#define MIXCODER_NUM_FILTERS_MAX 4\r
+\r
+typedef struct\r
+{\r
+  ISzAlloc *alloc;\r
+  Byte *buf;\r
+  int numCoders;\r
+  int finished[MIXCODER_NUM_FILTERS_MAX - 1];\r
+  size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];\r
+  size_t size[MIXCODER_NUM_FILTERS_MAX - 1];\r
+  UInt64 ids[MIXCODER_NUM_FILTERS_MAX];\r
+  IStateCoder coders[MIXCODER_NUM_FILTERS_MAX];\r
+} CMixCoder;\r
+\r
+void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc);\r
+void MixCoder_Free(CMixCoder *p);\r
+void MixCoder_Init(CMixCoder *p);\r
+SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId);\r
+SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,\r
+    const Byte *src, SizeT *srcLen, int srcWasFinished,\r
+    ECoderFinishMode finishMode, ECoderStatus *status);\r
+\r
+typedef enum\r
+{\r
+  XZ_STATE_STREAM_HEADER,\r
+  XZ_STATE_STREAM_INDEX,\r
+  XZ_STATE_STREAM_INDEX_CRC,\r
+  XZ_STATE_STREAM_FOOTER,\r
+  XZ_STATE_STREAM_PADDING,\r
+  XZ_STATE_BLOCK_HEADER,\r
+  XZ_STATE_BLOCK,\r
+  XZ_STATE_BLOCK_FOOTER\r
+} EXzState;\r
+\r
+typedef struct\r
+{\r
+  EXzState state;\r
+  UInt32 pos;\r
+  unsigned alignPos;\r
+  unsigned indexPreSize;\r
+\r
+  CXzStreamFlags streamFlags;\r
+  \r
+  UInt32 blockHeaderSize;\r
+  UInt64 packSize;\r
+  UInt64 unpackSize;\r
+\r
+  UInt64 numBlocks;\r
+  UInt64 indexSize;\r
+  UInt64 indexPos;\r
+  UInt64 padSize;\r
+\r
+  UInt64 numStreams;\r
+\r
+  UInt32 crc;\r
+  CMixCoder decoder;\r
+  CXzBlock block;\r
+  CXzCheck check;\r
+  CSha256 sha;\r
+  Byte shaDigest[SHA256_DIGEST_SIZE];\r
+  Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];\r
+} CXzUnpacker;\r
+\r
+SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc);\r
+void XzUnpacker_Free(CXzUnpacker *p);\r
+\r
+/*\r
+finishMode:\r
+  It has meaning only if the decoding reaches output limit (*destLen).\r
+  LZMA_FINISH_ANY - use smallest number of input bytes\r
+  LZMA_FINISH_END - read EndOfStream marker after decoding\r
+\r
+Returns:\r
+  SZ_OK\r
+    status:\r
+      LZMA_STATUS_FINISHED_WITH_MARK\r
+      LZMA_STATUS_NOT_FINISHED\r
+  SZ_ERROR_DATA - Data error\r
+  SZ_ERROR_MEM  - Memory allocation error\r
+  SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).\r
+*/\r
+\r
+\r
+SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,\r
+    const Byte *src, SizeT *srcLen, /* int srcWasFinished, */ int finishMode,\r
+    ECoderStatus *status);\r
+\r
+Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/XzCrc64.c b/C/XzCrc64.c
new file mode 100755 (executable)
index 0000000..f688b07
--- /dev/null
@@ -0,0 +1,33 @@
+/* XzCrc64.c -- CRC64 calculation\r
+2010-04-16 : Igor Pavlov : Public domain */\r
+\r
+#include "XzCrc64.h"\r
+\r
+#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)\r
+UInt64 g_Crc64Table[256];\r
+\r
+void MY_FAST_CALL Crc64GenerateTable(void)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < 256; i++)\r
+  {\r
+    UInt64 r = i;\r
+    int j;\r
+    for (j = 0; j < 8; j++)\r
+      r = (r >> 1) ^ ((UInt64)kCrc64Poly & ~((r & 1) - 1));\r
+    g_Crc64Table[i] = r;\r
+  }\r
+}\r
+\r
+UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)\r
+{\r
+  const Byte *p = (const Byte *)data;\r
+  for (; size > 0 ; size--, p++)\r
+    v = CRC64_UPDATE_BYTE(v, *p);\r
+  return v;\r
+}\r
+\r
+UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size)\r
+{\r
+  return CRC64_GET_DIGEST(Crc64Update(CRC64_INIT_VAL, data, size));\r
+}\r
diff --git a/C/XzCrc64.h b/C/XzCrc64.h
new file mode 100755 (executable)
index 0000000..05d0d09
--- /dev/null
@@ -0,0 +1,26 @@
+/* XzCrc64.h -- CRC64 calculation\r
+2010-04-16 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __XZ_CRC64_H\r
+#define __XZ_CRC64_H\r
+\r
+#include <stddef.h>\r
+\r
+#include "Types.h"\r
+\r
+EXTERN_C_BEGIN\r
+\r
+extern UInt64 g_Crc64Table[];\r
+\r
+void MY_FAST_CALL Crc64GenerateTable(void);\r
+\r
+#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF)\r
+#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL)\r
+#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))\r
+\r
+UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size);\r
+UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size);\r
+\r
+EXTERN_C_END\r
+\r
+#endif\r
diff --git a/C/XzDec.c b/C/XzDec.c
new file mode 100755 (executable)
index 0000000..2eca1af
--- /dev/null
+++ b/C/XzDec.c
@@ -0,0 +1,875 @@
+/* XzDec.c -- Xz Decode\r
+2010-04-16 : Igor Pavlov : Public domain */\r
+\r
+/* #define XZ_DUMP */\r
+\r
+#ifdef XZ_DUMP\r
+#include <stdio.h>\r
+#endif\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include "7zCrc.h"\r
+#include "Alloc.h"\r
+#include "Bra.h"\r
+#include "CpuArch.h"\r
+#include "Delta.h"\r
+#include "Lzma2Dec.h"\r
+\r
+#ifdef USE_SUBBLOCK\r
+#include "SbDec.h"\r
+#endif\r
+\r
+#include "Xz.h"\r
+\r
+#define XZ_CHECK_SIZE_MAX 64\r
+\r
+#define CODER_BUF_SIZE (1 << 17)\r
+\r
+unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)\r
+{\r
+  int i, limit;\r
+  *value = 0;\r
+  limit = (maxSize > 9) ? 9 : (int)maxSize;\r
+\r
+  for (i = 0; i < limit;)\r
+  {\r
+    Byte b = p[i];\r
+    *value |= (UInt64)(b & 0x7F) << (7 * i++);\r
+    if ((b & 0x80) == 0)\r
+      return (b == 0 && i != 1) ? 0 : i;\r
+  }\r
+  return 0;\r
+}\r
+\r
+/* ---------- BraState ---------- */\r
+\r
+#define BRA_BUF_SIZE (1 << 14)\r
+\r
+typedef struct\r
+{\r
+  size_t bufPos;\r
+  size_t bufConv;\r
+  size_t bufTotal;\r
+\r
+  UInt32 methodId;\r
+  int encodeMode;\r
+  UInt32 delta;\r
+  UInt32 ip;\r
+  UInt32 x86State;\r
+  Byte deltaState[DELTA_STATE_SIZE];\r
+\r
+  Byte buf[BRA_BUF_SIZE];\r
+} CBraState;\r
+\r
+void BraState_Free(void *pp, ISzAlloc *alloc)\r
+{\r
+  alloc->Free(alloc, pp);\r
+}\r
+\r
+SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)\r
+{\r
+  CBraState *p = ((CBraState *)pp);\r
+  alloc = alloc;\r
+  p->encodeMode = 0;\r
+  p->ip = 0;\r
+  if (p->methodId == XZ_ID_Delta)\r
+  {\r
+    if (propSize != 1)\r
+      return SZ_ERROR_UNSUPPORTED;\r
+    p->delta = (unsigned)props[0] + 1;\r
+  }\r
+  else\r
+  {\r
+    if (propSize == 4)\r
+    {\r
+      UInt32 v = GetUi32(props);\r
+      switch(p->methodId)\r
+      {\r
+        case XZ_ID_PPC:\r
+        case XZ_ID_ARM:\r
+        case XZ_ID_SPARC:\r
+          if ((v & 3) != 0)\r
+            return SZ_ERROR_UNSUPPORTED;\r
+          break;\r
+        case XZ_ID_ARMT:\r
+          if ((v & 1) != 0)\r
+            return SZ_ERROR_UNSUPPORTED;\r
+          break;\r
+        case XZ_ID_IA64:\r
+          if ((v & 0xF) != 0)\r
+            return SZ_ERROR_UNSUPPORTED;\r
+          break;\r
+      }\r
+      p->ip = v;\r
+    }\r
+    else if (propSize != 0)\r
+      return SZ_ERROR_UNSUPPORTED;\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+void BraState_Init(void *pp)\r
+{\r
+  CBraState *p = ((CBraState *)pp);\r
+  p->bufPos = p->bufConv = p->bufTotal = 0;\r
+  x86_Convert_Init(p->x86State);\r
+  if (p->methodId == XZ_ID_Delta)\r
+    Delta_Init(p->deltaState);\r
+}\r
+\r
+#define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: p->bufConv = isa ## _Convert(p->buf, p->bufTotal, p->ip, p->encodeMode); break;\r
+\r
+static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+    int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)\r
+{\r
+  CBraState *p = ((CBraState *)pp);\r
+  SizeT destLenOrig = *destLen;\r
+  SizeT srcLenOrig = *srcLen;\r
+  *destLen = 0;\r
+  *srcLen = 0;\r
+  finishMode = finishMode;\r
+  *wasFinished = 0;\r
+  while (destLenOrig > 0)\r
+  {\r
+    if (p->bufPos != p->bufConv)\r
+    {\r
+      size_t curSize = p->bufConv - p->bufPos;\r
+      if (curSize > destLenOrig)\r
+        curSize = destLenOrig;\r
+      memcpy(dest, p->buf + p->bufPos, curSize);\r
+      p->bufPos += curSize;\r
+      *destLen += curSize;\r
+      dest += curSize;\r
+      destLenOrig -= curSize;\r
+      continue;\r
+    }\r
+    p->bufTotal -= p->bufPos;\r
+    memmove(p->buf, p->buf + p->bufPos, p->bufTotal);\r
+    p->bufPos = 0;\r
+    p->bufConv = 0;\r
+    {\r
+      size_t curSize = BRA_BUF_SIZE - p->bufTotal;\r
+      if (curSize > srcLenOrig)\r
+        curSize = srcLenOrig;\r
+      memcpy(p->buf + p->bufTotal, src, curSize);\r
+      *srcLen += curSize;\r
+      src += curSize;\r
+      srcLenOrig -= curSize;\r
+      p->bufTotal += curSize;\r
+    }\r
+    if (p->bufTotal == 0)\r
+      break;\r
+    switch(p->methodId)\r
+    {\r
+      case XZ_ID_Delta:\r
+        if (p->encodeMode)\r
+          Delta_Encode(p->deltaState, p->delta, p->buf, p->bufTotal);\r
+        else\r
+          Delta_Decode(p->deltaState, p->delta, p->buf, p->bufTotal);\r
+        p->bufConv = p->bufTotal;\r
+        break;\r
+      case XZ_ID_X86:\r
+        p->bufConv = x86_Convert(p->buf, p->bufTotal, p->ip, &p->x86State, p->encodeMode);\r
+        break;\r
+      CASE_BRA_CONV(PPC)\r
+      CASE_BRA_CONV(IA64)\r
+      CASE_BRA_CONV(ARM)\r
+      CASE_BRA_CONV(ARMT)\r
+      CASE_BRA_CONV(SPARC)\r
+      default:\r
+        return SZ_ERROR_UNSUPPORTED;\r
+    }\r
+    p->ip += (UInt32)p->bufConv;\r
+\r
+    if (p->bufConv == 0)\r
+    {\r
+      if (!srcWasFinished)\r
+        break;\r
+      p->bufConv = p->bufTotal;\r
+    }\r
+  }\r
+  if (p->bufTotal == p->bufPos && srcLenOrig == 0 && srcWasFinished)\r
+    *wasFinished = 1;\r
+  return SZ_OK;\r
+}\r
+\r
+SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)\r
+{\r
+  CBraState *decoder;\r
+  if (id != XZ_ID_Delta &&\r
+      id != XZ_ID_X86 &&\r
+      id != XZ_ID_PPC &&\r
+      id != XZ_ID_IA64 &&\r
+      id != XZ_ID_ARM &&\r
+      id != XZ_ID_ARMT &&\r
+      id != XZ_ID_SPARC)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  p->p = 0;\r
+  decoder = alloc->Alloc(alloc, sizeof(CBraState));\r
+  if (decoder == 0)\r
+    return SZ_ERROR_MEM;\r
+  decoder->methodId = (UInt32)id;\r
+  p->p = decoder;\r
+  p->Free = BraState_Free;\r
+  p->SetProps = BraState_SetProps;\r
+  p->Init = BraState_Init;\r
+  p->Code = BraState_Code;\r
+  return SZ_OK;\r
+}\r
+\r
+/* ---------- SbState ---------- */\r
+\r
+#ifdef USE_SUBBLOCK\r
+\r
+static void SbState_Free(void *pp, ISzAlloc *alloc)\r
+{\r
+  CSubblockDec *p = (CSubblockDec *)pp;\r
+  SubblockDec_Free(p, alloc);\r
+  alloc->Free(alloc, pp);\r
+}\r
+\r
+static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)\r
+{\r
+  pp = pp;\r
+  props = props;\r
+  alloc = alloc;\r
+  return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;\r
+}\r
+\r
+static void SbState_Init(void *pp)\r
+{\r
+  SubblockDec_Init((CSubblockDec *)pp);\r
+}\r
+\r
+static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+    int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)\r
+{\r
+  ECoderStatus status;\r
+  SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status);\r
+  srcWasFinished = srcWasFinished;\r
+  *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);\r
+  return res;\r
+}\r
+\r
+SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)\r
+{\r
+  CSubblockDec *decoder;\r
+  p->p = 0;\r
+  decoder = alloc->Alloc(alloc, sizeof(CSubblockDec));\r
+  if (decoder == 0)\r
+    return SZ_ERROR_MEM;\r
+  p->p = decoder;\r
+  p->Free = SbState_Free;\r
+  p->SetProps = SbState_SetProps;\r
+  p->Init = SbState_Init;\r
+  p->Code = SbState_Code;\r
+  SubblockDec_Construct(decoder);\r
+  return SZ_OK;\r
+}\r
+#endif\r
+\r
+/* ---------- Lzma2State ---------- */\r
+\r
+static void Lzma2State_Free(void *pp, ISzAlloc *alloc)\r
+{\r
+  Lzma2Dec_Free((CLzma2Dec *)pp, alloc);\r
+  alloc->Free(alloc, pp);\r
+}\r
+\r
+static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)\r
+{\r
+  if (propSize != 1)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  return Lzma2Dec_Allocate((CLzma2Dec *)pp, props[0], alloc);\r
+}\r
+\r
+static void Lzma2State_Init(void *pp)\r
+{\r
+  Lzma2Dec_Init((CLzma2Dec *)pp);\r
+}\r
+\r
+static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+    int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)\r
+{\r
+  ELzmaStatus status;\r
+  /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */\r
+  SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status);\r
+  srcWasFinished = srcWasFinished;\r
+  *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);\r
+  return res;\r
+}\r
+\r
+static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)\r
+{\r
+  CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec));\r
+  p->p = decoder;\r
+  if (decoder == 0)\r
+    return SZ_ERROR_MEM;\r
+  p->Free = Lzma2State_Free;\r
+  p->SetProps = Lzma2State_SetProps;\r
+  p->Init = Lzma2State_Init;\r
+  p->Code = Lzma2State_Code;\r
+  Lzma2Dec_Construct(decoder);\r
+  return SZ_OK;\r
+}\r
+\r
+\r
+void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)\r
+{\r
+  int i;\r
+  p->alloc = alloc;\r
+  p->buf = 0;\r
+  p->numCoders = 0;\r
+  for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)\r
+    p->coders[i].p = NULL;\r
+}\r
+\r
+void MixCoder_Free(CMixCoder *p)\r
+{\r
+  int i;\r
+  for (i = 0; i < p->numCoders; i++)\r
+  {\r
+    IStateCoder *sc = &p->coders[i];\r
+    if (p->alloc && sc->p)\r
+      sc->Free(sc->p, p->alloc);\r
+  }\r
+  p->numCoders = 0;\r
+  if (p->buf)\r
+    p->alloc->Free(p->alloc, p->buf);\r
+}\r
+\r
+void MixCoder_Init(CMixCoder *p)\r
+{\r
+  int i;\r
+  for (i = 0; i < p->numCoders - 1; i++)\r
+  {\r
+    p->size[i] = 0;\r
+    p->pos[i] = 0;\r
+    p->finished[i] = 0;\r
+  }\r
+  for (i = 0; i < p->numCoders; i++)\r
+  {\r
+    IStateCoder *coder = &p->coders[i];\r
+    coder->Init(coder->p);\r
+  }\r
+}\r
+\r
+SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)\r
+{\r
+  IStateCoder *sc = &p->coders[coderIndex];\r
+  p->ids[coderIndex] = methodId;\r
+  switch(methodId)\r
+  {\r
+    case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);\r
+    #ifdef USE_SUBBLOCK\r
+    case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc);\r
+    #endif\r
+  }\r
+  if (coderIndex == 0)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  return BraState_SetFromMethod(sc, methodId, p->alloc);\r
+}\r
+\r
+SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,\r
+    const Byte *src, SizeT *srcLen, int srcWasFinished,\r
+    ECoderFinishMode finishMode, ECoderStatus *status)\r
+{\r
+  SizeT destLenOrig = *destLen;\r
+  SizeT srcLenOrig = *srcLen;\r
+  Bool allFinished = True;\r
+  *destLen = 0;\r
+  *srcLen = 0;\r
+  *status = CODER_STATUS_NOT_FINISHED;\r
+\r
+  if (p->buf == 0)\r
+  {\r
+    p->buf = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));\r
+    if (p->buf == 0)\r
+      return SZ_ERROR_MEM;\r
+  }\r
+\r
+  if (p->numCoders != 1)\r
+    finishMode = CODER_FINISH_ANY;\r
+\r
+  for (;;)\r
+  {\r
+    Bool processed = False;\r
+    int i;\r
+    /*\r
+    if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)\r
+      break;\r
+    */\r
+\r
+    for (i = 0; i < p->numCoders; i++)\r
+    {\r
+      SRes res;\r
+      IStateCoder *coder = &p->coders[i];\r
+      Byte *destCur;\r
+      SizeT destLenCur, srcLenCur;\r
+      const Byte *srcCur;\r
+      int srcFinishedCur;\r
+      int encodingWasFinished;\r
+      \r
+      if (i == 0)\r
+      {\r
+        srcCur = src;\r
+        srcLenCur = srcLenOrig - *srcLen;\r
+        srcFinishedCur = srcWasFinished;\r
+      }\r
+      else\r
+      {\r
+        srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1];\r
+        srcLenCur = p->size[i - 1] - p->pos[i - 1];\r
+        srcFinishedCur = p->finished[i - 1];\r
+      }\r
+      \r
+      if (i == p->numCoders - 1)\r
+      {\r
+        destCur = dest;\r
+        destLenCur = destLenOrig - *destLen;\r
+      }\r
+      else\r
+      {\r
+        if (p->pos[i] != p->size[i])\r
+          continue;\r
+        destCur = p->buf + (CODER_BUF_SIZE * i);\r
+        destLenCur = CODER_BUF_SIZE;\r
+      }\r
+      \r
+      res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished);\r
+\r
+      if (!encodingWasFinished)\r
+        allFinished = False;\r
+\r
+      if (i == 0)\r
+      {\r
+        *srcLen += srcLenCur;\r
+        src += srcLenCur;\r
+      }\r
+      else\r
+      {\r
+        p->pos[i - 1] += srcLenCur;\r
+      }\r
+\r
+      if (i == p->numCoders - 1)\r
+      {\r
+        *destLen += destLenCur;\r
+        dest += destLenCur;\r
+      }\r
+      else\r
+      {\r
+        p->size[i] = destLenCur;\r
+        p->pos[i] = 0;\r
+        p->finished[i] = encodingWasFinished;\r
+      }\r
+      \r
+      if (res != SZ_OK)\r
+        return res;\r
+\r
+      if (destLenCur != 0 || srcLenCur != 0)\r
+        processed = True;\r
+    }\r
+    if (!processed)\r
+      break;\r
+  }\r
+  if (allFinished)\r
+    *status = CODER_STATUS_FINISHED_WITH_MARK;\r
+  return SZ_OK;\r
+}\r
+\r
+SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)\r
+{\r
+  *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE);\r
+  if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) !=\r
+      GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE))\r
+    return SZ_ERROR_NO_ARCHIVE;\r
+  return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED;\r
+}\r
+\r
+static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf)\r
+{\r
+  return\r
+      indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) &&\r
+      (GetUi32(buf) == CrcCalc(buf + 4, 6) &&\r
+      flags == GetBe16(buf + 8) &&\r
+      memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0);\r
+}\r
+\r
+#define READ_VARINT_AND_CHECK(buf, pos, size, res) \\r
+  { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \\r
+  if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }\r
+\r
+\r
+SRes XzBlock_Parse(CXzBlock *p, const Byte *header)\r
+{\r
+  unsigned pos;\r
+  int numFilters, i;\r
+  UInt32 headerSize = (UInt32)header[0] << 2;\r
+\r
+  if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))\r
+    return SZ_ERROR_ARCHIVE;\r
+\r
+  pos = 1;\r
+  if (pos == headerSize)\r
+    return SZ_ERROR_ARCHIVE;\r
+  p->flags = header[pos++];\r
+\r
+  if (XzBlock_HasPackSize(p))\r
+  {\r
+    READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize);\r
+    if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63)\r
+      return SZ_ERROR_ARCHIVE;\r
+  }\r
+\r
+  if (XzBlock_HasUnpackSize(p))\r
+    READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize);\r
+\r
+  numFilters = XzBlock_GetNumFilters(p);\r
+  for (i = 0; i < numFilters; i++)\r
+  {\r
+    CXzFilter *filter = p->filters + i;\r
+    UInt64 size;\r
+    READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id);\r
+    READ_VARINT_AND_CHECK(header, pos, headerSize, &size);\r
+    if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX)\r
+      return SZ_ERROR_ARCHIVE;\r
+    filter->propsSize = (UInt32)size;\r
+    memcpy(filter->props, header + pos, (size_t)size);\r
+    pos += (unsigned)size;\r
+\r
+    #ifdef XZ_DUMP\r
+    printf("\nf[%d] = %2X: ", i, filter->id);\r
+    {\r
+      int i;\r
+      for (i = 0; i < size; i++)\r
+        printf(" %2X", filter->props[i]);\r
+    }\r
+    #endif\r
+  }\r
+\r
+  while (pos < headerSize)\r
+    if (header[pos++] != 0)\r
+      return SZ_ERROR_ARCHIVE;\r
+  return SZ_OK;\r
+}\r
+\r
+SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)\r
+{\r
+  int i;\r
+  Bool needReInit = True;\r
+  int numFilters = XzBlock_GetNumFilters(block);\r
+  if (numFilters == p->numCoders)\r
+  {\r
+    for (i = 0; i < numFilters; i++)\r
+      if (p->ids[i] != block->filters[numFilters - 1 - i].id)\r
+        break;\r
+    needReInit = (i != numFilters);\r
+  }\r
+  if (needReInit)\r
+  {\r
+    MixCoder_Free(p);\r
+    p->numCoders = numFilters;\r
+    for (i = 0; i < numFilters; i++)\r
+    {\r
+      const CXzFilter *f = &block->filters[numFilters - 1 - i];\r
+      RINOK(MixCoder_SetFromMethod(p, i, f->id));\r
+    }\r
+  }\r
+  for (i = 0; i < numFilters; i++)\r
+  {\r
+    const CXzFilter *f = &block->filters[numFilters - 1 - i];\r
+    IStateCoder *sc = &p->coders[i];\r
+    RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));\r
+  }\r
+  MixCoder_Init(p);\r
+  return SZ_OK;\r
+}\r
+\r
+SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc)\r
+{\r
+  MixCoder_Construct(&p->decoder, alloc);\r
+  p->state = XZ_STATE_STREAM_HEADER;\r
+  p->pos = 0;\r
+  p->numStreams = 0;\r
+  return SZ_OK;\r
+}\r
+\r
+void XzUnpacker_Free(CXzUnpacker *p)\r
+{\r
+  MixCoder_Free(&p->decoder);\r
+}\r
+\r
+SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,\r
+    const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status)\r
+{\r
+  SizeT destLenOrig = *destLen;\r
+  SizeT srcLenOrig = *srcLen;\r
+  *destLen = 0;\r
+  *srcLen = 0;\r
+  *status = CODER_STATUS_NOT_SPECIFIED;\r
+  for (;;)\r
+  {\r
+    SizeT srcRem = srcLenOrig - *srcLen;\r
+\r
+    if (p->state == XZ_STATE_BLOCK)\r
+    {\r
+      SizeT destLen2 = destLenOrig - *destLen;\r
+      SizeT srcLen2 = srcLenOrig - *srcLen;\r
+      SRes res;\r
+      if (srcLen2 == 0 && destLen2 == 0)\r
+      {\r
+        *status = CODER_STATUS_NOT_FINISHED;\r
+        return SZ_OK;\r
+      }\r
+      \r
+      res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status);\r
+      XzCheck_Update(&p->check, dest, destLen2);\r
+      \r
+      (*srcLen) += srcLen2;\r
+      src += srcLen2;\r
+      p->packSize += srcLen2;\r
+      \r
+      (*destLen) += destLen2;\r
+      dest += destLen2;\r
+      p->unpackSize += destLen2;\r
+      \r
+      RINOK(res);\r
+      \r
+      if (*status == CODER_STATUS_FINISHED_WITH_MARK)\r
+      {\r
+        Byte temp[32];\r
+        unsigned num = Xz_WriteVarInt(temp, p->packSize + p->blockHeaderSize + XzFlags_GetCheckSize(p->streamFlags));\r
+        num += Xz_WriteVarInt(temp + num, p->unpackSize);\r
+        Sha256_Update(&p->sha, temp, num);\r
+        p->indexSize += num;\r
+        p->numBlocks++;\r
+        \r
+        p->state = XZ_STATE_BLOCK_FOOTER;\r
+        p->pos = 0;\r
+        p->alignPos = 0;\r
+      }\r
+      else if (srcLen2 == 0 && destLen2 == 0)\r
+        return SZ_OK;\r
+      \r
+      continue;\r
+    }\r
+\r
+    if (srcRem == 0)\r
+    {\r
+      *status = CODER_STATUS_NEEDS_MORE_INPUT;\r
+      return SZ_OK;\r
+    }\r
+\r
+    switch(p->state)\r
+    {\r
+      case XZ_STATE_STREAM_HEADER:\r
+      {\r
+        if (p->pos < XZ_STREAM_HEADER_SIZE)\r
+        {\r
+          if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos])\r
+            return SZ_ERROR_NO_ARCHIVE;\r
+          p->buf[p->pos++] = *src++;\r
+          (*srcLen)++;\r
+        }\r
+        else\r
+        {\r
+          RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));\r
+          p->state = XZ_STATE_BLOCK_HEADER;\r
+          Sha256_Init(&p->sha);\r
+          p->indexSize = 0;\r
+          p->numBlocks = 0;\r
+          p->pos = 0;\r
+        }\r
+        break;\r
+      }\r
+\r
+      case XZ_STATE_BLOCK_HEADER:\r
+      {\r
+        if (p->pos == 0)\r
+        {\r
+          p->buf[p->pos++] = *src++;\r
+          (*srcLen)++;\r
+          if (p->buf[0] == 0)\r
+          {\r
+            p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks);\r
+            p->indexPos = p->indexPreSize;\r
+            p->indexSize += p->indexPreSize;\r
+            Sha256_Final(&p->sha, p->shaDigest);\r
+            Sha256_Init(&p->sha);\r
+            p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize);\r
+            p->state = XZ_STATE_STREAM_INDEX;\r
+          }\r
+          p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4;\r
+        }\r
+        else if (p->pos != p->blockHeaderSize)\r
+        {\r
+          UInt32 cur = p->blockHeaderSize - p->pos;\r
+          if (cur > srcRem)\r
+            cur = (UInt32)srcRem;\r
+          memcpy(p->buf + p->pos, src, cur);\r
+          p->pos += cur;\r
+          (*srcLen) += cur;\r
+          src += cur;\r
+        }\r
+        else\r
+        {\r
+          RINOK(XzBlock_Parse(&p->block, p->buf));\r
+          p->state = XZ_STATE_BLOCK;\r
+          p->packSize = 0;\r
+          p->unpackSize = 0;\r
+          XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags));\r
+          RINOK(XzDec_Init(&p->decoder, &p->block));\r
+        }\r
+        break;\r
+      }\r
+\r
+      case XZ_STATE_BLOCK_FOOTER:\r
+      {\r
+        if (((p->packSize + p->alignPos) & 3) != 0)\r
+        {\r
+          (*srcLen)++;\r
+          p->alignPos++;\r
+          if (*src++ != 0)\r
+            return SZ_ERROR_CRC;\r
+        }\r
+        else\r
+        {\r
+          UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags);\r
+          UInt32 cur = checkSize - p->pos;\r
+          if (cur != 0)\r
+          {\r
+            if (cur > srcRem)\r
+              cur = (UInt32)srcRem;\r
+            memcpy(p->buf + p->pos, src, cur);\r
+            p->pos += cur;\r
+            (*srcLen) += cur;\r
+            src += cur;\r
+          }\r
+          else\r
+          {\r
+            Byte digest[XZ_CHECK_SIZE_MAX];\r
+            p->state = XZ_STATE_BLOCK_HEADER;\r
+            p->pos = 0;\r
+            if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0)\r
+              return SZ_ERROR_CRC;\r
+          }\r
+        }\r
+        break;\r
+      }\r
+\r
+      case XZ_STATE_STREAM_INDEX:\r
+      {\r
+        if (p->pos < p->indexPreSize)\r
+        {\r
+          (*srcLen)++;\r
+          if (*src++ != p->buf[p->pos++])\r
+            return SZ_ERROR_CRC;\r
+        }\r
+        else\r
+        {\r
+          if (p->indexPos < p->indexSize)\r
+          {\r
+            UInt64 cur = p->indexSize - p->indexPos;\r
+            if (srcRem > cur)\r
+              srcRem = (SizeT)cur;\r
+            p->crc = CrcUpdate(p->crc, src, srcRem);\r
+            Sha256_Update(&p->sha, src, srcRem);\r
+            (*srcLen) += srcRem;\r
+            src += srcRem;\r
+            p->indexPos += srcRem;\r
+          }\r
+          else if ((p->indexPos & 3) != 0)\r
+          {\r
+            Byte b = *src++;\r
+            p->crc = CRC_UPDATE_BYTE(p->crc, b);\r
+            (*srcLen)++;\r
+            p->indexPos++;\r
+            p->indexSize++;\r
+            if (b != 0)\r
+              return SZ_ERROR_CRC;\r
+          }\r
+          else\r
+          {\r
+            Byte digest[SHA256_DIGEST_SIZE];\r
+            p->state = XZ_STATE_STREAM_INDEX_CRC;\r
+            p->indexSize += 4;\r
+            p->pos = 0;\r
+            Sha256_Final(&p->sha, digest);\r
+            if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0)\r
+              return SZ_ERROR_CRC;\r
+          }\r
+        }\r
+        break;\r
+      }\r
+\r
+      case XZ_STATE_STREAM_INDEX_CRC:\r
+      {\r
+        if (p->pos < 4)\r
+        {\r
+          (*srcLen)++;\r
+          p->buf[p->pos++] = *src++;\r
+        }\r
+        else\r
+        {\r
+          p->state = XZ_STATE_STREAM_FOOTER;\r
+          p->pos = 0;\r
+          if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf))\r
+            return SZ_ERROR_CRC;\r
+        }\r
+        break;\r
+      }\r
+\r
+      case XZ_STATE_STREAM_FOOTER:\r
+      {\r
+        UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos;\r
+        if (cur > srcRem)\r
+          cur = (UInt32)srcRem;\r
+        memcpy(p->buf + p->pos, src, cur);\r
+        p->pos += cur;\r
+        (*srcLen) += cur;\r
+        src += cur;\r
+        if (p->pos == XZ_STREAM_FOOTER_SIZE)\r
+        {\r
+          p->state = XZ_STATE_STREAM_PADDING;\r
+          p->numStreams++;\r
+          p->padSize = 0;\r
+          if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf))\r
+            return SZ_ERROR_CRC;\r
+        }\r
+        break;\r
+      }\r
+\r
+      case XZ_STATE_STREAM_PADDING:\r
+      {\r
+        if (*src != 0)\r
+        {\r
+          if (((UInt32)p->padSize & 3) != 0)\r
+            return SZ_ERROR_NO_ARCHIVE;\r
+          p->pos = 0;\r
+          p->state = XZ_STATE_STREAM_HEADER;\r
+        }\r
+        else\r
+        {\r
+          (*srcLen)++;\r
+          src++;\r
+          p->padSize++;\r
+        }\r
+        break;\r
+      }\r
+      \r
+      case XZ_STATE_BLOCK: break; /* to disable GCC warning */\r
+    }\r
+  }\r
+  /*\r
+  if (p->state == XZ_STATE_FINISHED)\r
+    *status = CODER_STATUS_FINISHED_WITH_MARK;\r
+  return SZ_OK;\r
+  */\r
+}\r
+\r
+Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p)\r
+{\r
+  return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);\r
+}\r
diff --git a/C/XzEnc.c b/C/XzEnc.c
new file mode 100755 (executable)
index 0000000..e610140
--- /dev/null
+++ b/C/XzEnc.c
@@ -0,0 +1,497 @@
+/* XzEnc.c -- Xz Encode\r
+2009-06-04 : Igor Pavlov : Public domain */\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include "7zCrc.h"\r
+#include "Alloc.h"\r
+#include "Bra.h"\r
+#include "CpuArch.h"\r
+#ifdef USE_SUBBLOCK\r
+#include "SbEnc.h"\r
+#endif\r
+\r
+#include "XzEnc.h"\r
+\r
+static void *SzBigAlloc(void *p, size_t size) { p = p; return BigAlloc(size); }\r
+static void SzBigFree(void *p, void *address) { p = p; BigFree(address); }\r
+static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+#define XzBlock_ClearFlags(p)       (p)->flags = 0;\r
+#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1);\r
+#define XzBlock_SetHasPackSize(p)   (p)->flags |= XZ_BF_PACK_SIZE;\r
+#define XzBlock_SetHasUnpackSize(p) (p)->flags |= XZ_BF_UNPACK_SIZE;\r
+\r
+static SRes WriteBytes(ISeqOutStream *s, const void *buf, UInt32 size)\r
+{\r
+  return (s->Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE;\r
+}\r
+\r
+static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UInt32 *crc)\r
+{\r
+  *crc = CrcUpdate(*crc, buf, size);\r
+  return WriteBytes(s, buf, size);\r
+}\r
+\r
+SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)\r
+{\r
+  UInt32 crc;\r
+  Byte header[XZ_STREAM_HEADER_SIZE];\r
+  memcpy(header, XZ_SIG, XZ_SIG_SIZE);\r
+  header[XZ_SIG_SIZE] = (Byte)(f >> 8);\r
+  header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF);\r
+  crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE);\r
+  SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc);\r
+  return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE);\r
+}\r
+\r
+SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)\r
+{\r
+  Byte header[XZ_BLOCK_HEADER_SIZE_MAX];\r
+\r
+  unsigned pos = 1;\r
+  int numFilters, i;\r
+  header[pos++] = p->flags;\r
+\r
+  if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize);\r
+  if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize);\r
+  numFilters = XzBlock_GetNumFilters(p);\r
+  for (i = 0; i < numFilters; i++)\r
+  {\r
+    const CXzFilter *f = &p->filters[i];\r
+    pos += Xz_WriteVarInt(header + pos, f->id);\r
+    pos += Xz_WriteVarInt(header + pos, f->propsSize);\r
+    memcpy(header + pos, f->props, f->propsSize);\r
+    pos += f->propsSize;\r
+  }\r
+  while((pos & 3) != 0)\r
+    header[pos++] = 0;\r
+  header[0] = (Byte)(pos >> 2);\r
+  SetUi32(header + pos, CrcCalc(header, pos));\r
+  return WriteBytes(s, header, pos + 4);\r
+}\r
+\r
+SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)\r
+{\r
+  Byte buf[32];\r
+  UInt64 globalPos;\r
+  {\r
+    UInt32 crc = CRC_INIT_VAL;\r
+    unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks);\r
+    size_t i;\r
+\r
+    globalPos = pos;\r
+    buf[0] = 0;\r
+    RINOK(WriteBytesAndCrc(s, buf, pos, &crc));\r
+    for (i = 0; i < p->numBlocks; i++)\r
+    {\r
+      const CXzBlockSizes *block = &p->blocks[i];\r
+      pos = Xz_WriteVarInt(buf, block->totalSize);\r
+      pos += Xz_WriteVarInt(buf + pos, block->unpackSize);\r
+      globalPos += pos;\r
+      RINOK(WriteBytesAndCrc(s, buf, pos, &crc));\r
+    }\r
+    pos = ((unsigned)globalPos & 3);\r
+    if (pos != 0)\r
+    {\r
+      buf[0] = buf[1] = buf[2] = 0;\r
+      RINOK(WriteBytesAndCrc(s, buf, 4 - pos, &crc));\r
+      globalPos += 4 - pos;\r
+    }\r
+    {\r
+      SetUi32(buf, CRC_GET_DIGEST(crc));\r
+      RINOK(WriteBytes(s, buf, 4));\r
+      globalPos += 4;\r
+    }\r
+  }\r
+\r
+  {\r
+    UInt32 indexSize = (UInt32)((globalPos >> 2) - 1);\r
+    SetUi32(buf + 4, indexSize);\r
+    buf[8] = (Byte)(p->flags >> 8);\r
+    buf[9] = (Byte)(p->flags & 0xFF);\r
+    SetUi32(buf, CrcCalc(buf + 4, 6));\r
+    memcpy(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE);\r
+    return WriteBytes(s, buf, 12);\r
+  }\r
+}\r
+\r
+SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)\r
+{\r
+  if (p->blocks == 0 || p->numBlocksAllocated == p->numBlocks)\r
+  {\r
+    size_t num = (p->numBlocks + 1) * 2;\r
+    size_t newSize = sizeof(CXzBlockSizes) * num;\r
+    CXzBlockSizes *blocks;\r
+    if (newSize / sizeof(CXzBlockSizes) != num)\r
+      return SZ_ERROR_MEM;\r
+    blocks = alloc->Alloc(alloc, newSize);\r
+    if (blocks == 0)\r
+      return SZ_ERROR_MEM;\r
+    if (p->numBlocks != 0)\r
+    {\r
+      memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes));\r
+      Xz_Free(p, alloc);\r
+    }\r
+    p->blocks = blocks;\r
+    p->numBlocksAllocated = num;\r
+  }\r
+  {\r
+    CXzBlockSizes *block = &p->blocks[p->numBlocks++];\r
+    block->totalSize = totalSize;\r
+    block->unpackSize = unpackSize;\r
+  }\r
+  return SZ_OK;\r
+}\r
+\r
+/* ---------- CSeqCheckInStream ---------- */\r
+\r
+typedef struct\r
+{\r
+  ISeqInStream p;\r
+  ISeqInStream *realStream;\r
+  UInt64 processed;\r
+  CXzCheck check;\r
+} CSeqCheckInStream;\r
+\r
+void SeqCheckInStream_Init(CSeqCheckInStream *p, int mode)\r
+{\r
+  p->processed = 0;\r
+  XzCheck_Init(&p->check, mode);\r
+}\r
+\r
+void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)\r
+{\r
+  XzCheck_Final(&p->check, digest);\r
+}\r
+\r
+static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size)\r
+{\r
+  CSeqCheckInStream *p = (CSeqCheckInStream *)pp;\r
+  SRes res = p->realStream->Read(p->realStream, data, size);\r
+  XzCheck_Update(&p->check, data, *size);\r
+  p->processed += *size;\r
+  return res;\r
+}\r
+\r
+/* ---------- CSeqSizeOutStream ---------- */\r
+\r
+typedef struct\r
+{\r
+  ISeqOutStream p;\r
+  ISeqOutStream *realStream;\r
+  UInt64 processed;\r
+} CSeqSizeOutStream;\r
+\r
+static size_t MyWrite(void *pp, const void *data, size_t size)\r
+{\r
+  CSeqSizeOutStream *p = (CSeqSizeOutStream *)pp;\r
+  size = p->realStream->Write(p->realStream, data, size);\r
+  p->processed += size;\r
+  return size;\r
+}\r
+\r
+/* ---------- CSeqInFilter ---------- */\r
+\r
+/*\r
+typedef struct _IFilter\r
+{\r
+  void *p;\r
+  void (*Free)(void *p, ISzAlloc *alloc);\r
+  SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);\r
+  void (*Init)(void *p);\r
+  size_t (*Filter)(void *p, Byte *data, SizeT destLen);\r
+} IFilter;\r
+\r
+#define FILT_BUF_SIZE (1 << 19)\r
+\r
+typedef struct\r
+{\r
+  ISeqInStream p;\r
+  ISeqInStream *realStream;\r
+  UInt32 x86State;\r
+  UInt32 ip;\r
+  UInt64 processed;\r
+  CXzCheck check;\r
+  Byte buf[FILT_BUF_SIZE];\r
+  UInt32 bufferPos;\r
+  UInt32 convertedPosBegin;\r
+  UInt32 convertedPosEnd;\r
+  IFilter *filter;\r
+} CSeqInFilter;\r
+\r
+static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)\r
+{\r
+  CSeqInFilter *p = (CSeqInFilter *)pp;\r
+  size_t remSize = *size;\r
+  *size = 0;\r
+\r
+  while (remSize > 0)\r
+  {\r
+    int i;\r
+    if (p->convertedPosBegin != p->convertedPosEnd)\r
+    {\r
+      UInt32 sizeTemp = p->convertedPosEnd - p->convertedPosBegin;\r
+      if (remSize < sizeTemp)\r
+        sizeTemp = (UInt32)remSize;\r
+      memmove(data, p->buf + p->convertedPosBegin, sizeTemp);\r
+      p->convertedPosBegin += sizeTemp;\r
+      data = (void *)((Byte *)data + sizeTemp);\r
+      remSize -= sizeTemp;\r
+      *size += sizeTemp;\r
+      break;\r
+    }\r
+    for (i = 0; p->convertedPosEnd + i < p->bufferPos; i++)\r
+      p->buf[i] = p->buf[i + p->convertedPosEnd];\r
+    p->bufferPos = i;\r
+    p->convertedPosBegin = p->convertedPosEnd = 0;\r
+    {\r
+      size_t processedSizeTemp = FILT_BUF_SIZE - p->bufferPos;\r
+      RINOK(p->realStream->Read(p->realStream, p->buf + p->bufferPos, &processedSizeTemp));\r
+      p->bufferPos = p->bufferPos + (UInt32)processedSizeTemp;\r
+    }\r
+    p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);\r
+    if (p->convertedPosEnd == 0)\r
+    {\r
+      if (p->bufferPos == 0)\r
+        break;\r
+      else\r
+      {\r
+        p->convertedPosEnd = p->bufferPos;\r
+        continue;\r
+      }\r
+    }\r
+    if (p->convertedPosEnd > p->bufferPos)\r
+    {\r
+      for (; p->bufferPos < p->convertedPosEnd; p->bufferPos++)\r
+        p->buf[p->bufferPos] = 0;\r
+      p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);\r
+    }\r
+  }\r
+  return SZ_OK;\r
+}\r
+*/\r
+\r
+/*\r
+typedef struct\r
+{\r
+  ISeqInStream p;\r
+  ISeqInStream *realStream;\r
+  CMixCoder mixCoder;\r
+  Byte buf[FILT_BUF_SIZE];\r
+  UInt32 bufPos;\r
+  UInt32 bufSize;\r
+} CMixCoderSeqInStream;\r
+\r
+static SRes CMixCoderSeqInStream_Read(void *pp, void *data, size_t *size)\r
+{\r
+  CMixCoderSeqInStream *p = (CMixCoderSeqInStream *)pp;\r
+  SRes res = SZ_OK;\r
+  size_t remSize = *size;\r
+  *size = 0;\r
+  while (remSize > 0)\r
+  {\r
+    if (p->bufPos == p->bufSize)\r
+    {\r
+      size_t curSize;\r
+      p->bufPos = p->bufSize = 0;\r
+      if (*size != 0)\r
+        break;\r
+      curSize = FILT_BUF_SIZE;\r
+      RINOK(p->realStream->Read(p->realStream, p->buf, &curSize));\r
+      p->bufSize = (UInt32)curSize;\r
+    }\r
+    {\r
+      SizeT destLen = remSize;\r
+      SizeT srcLen = p->bufSize - p->bufPos;\r
+      res = MixCoder_Code(&p->mixCoder, data, &destLen, p->buf + p->bufPos, &srcLen, 0);\r
+      data = (void *)((Byte *)data + destLen);\r
+      remSize -= destLen;\r
+      *size += destLen;\r
+      p->bufPos += srcLen;\r
+    }\r
+  }\r
+  return res;\r
+}\r
+*/\r
+\r
+#ifdef USE_SUBBLOCK\r
+typedef struct\r
+{\r
+  ISeqInStream p;\r
+  CSubblockEnc sb;\r
+  UInt64 processed;\r
+} CSbEncInStream;\r
+\r
+void SbEncInStream_Init(CSbEncInStream *p)\r
+{\r
+  p->processed = 0;\r
+  SubblockEnc_Init(&p->sb);\r
+}\r
+\r
+static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)\r
+{\r
+  CSbEncInStream *p = (CSbEncInStream *)pp;\r
+  SRes res = SubblockEnc_Read(&p->sb, data, size);\r
+  p->processed += *size;\r
+  return res;\r
+}\r
+#endif\r
+\r
+typedef struct\r
+{\r
+  /* CMixCoderSeqInStream inStream; */\r
+  CLzma2EncHandle lzma2;\r
+  #ifdef USE_SUBBLOCK\r
+  CSbEncInStream sb;\r
+  #endif\r
+  ISzAlloc *alloc;\r
+  ISzAlloc *bigAlloc;\r
+} CLzma2WithFilters;\r
+\r
+\r
+static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, ISzAlloc *bigAlloc)\r
+{\r
+  p->alloc = alloc;\r
+  p->bigAlloc = bigAlloc;\r
+  p->lzma2 = NULL;\r
+  #ifdef USE_SUBBLOCK\r
+  p->sb.p.Read = SbEncInStream_Read;\r
+  SubblockEnc_Construct(&p->sb.sb, p->alloc);\r
+  #endif\r
+}\r
+\r
+static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)\r
+{\r
+  p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc);\r
+  if (p->lzma2 == 0)\r
+    return SZ_ERROR_MEM;\r
+  return SZ_OK;\r
+}\r
+\r
+static void Lzma2WithFilters_Free(CLzma2WithFilters *p)\r
+{\r
+  #ifdef USE_SUBBLOCK\r
+  SubblockEnc_Free(&p->sb.sb);\r
+  #endif\r
+  if (p->lzma2)\r
+  {\r
+    Lzma2Enc_Destroy(p->lzma2);\r
+    p->lzma2 = NULL;\r
+  }\r
+}\r
+\r
+static SRes Xz_Compress(CXzStream *xz,\r
+    CLzma2WithFilters *lzmaf,\r
+    ISeqOutStream *outStream,\r
+    ISeqInStream *inStream,\r
+    const CLzma2EncProps *lzma2Props,\r
+    Bool useSubblock,\r
+    ICompressProgress *progress)\r
+{\r
+  xz->flags = XZ_CHECK_CRC32;\r
+\r
+  RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props));\r
+  RINOK(Xz_WriteHeader(xz->flags, outStream));\r
+\r
+  {\r
+    CSeqCheckInStream checkInStream;\r
+    CSeqSizeOutStream seqSizeOutStream;\r
+    CXzBlock block;\r
+    int filterIndex = 0;\r
+    \r
+    XzBlock_ClearFlags(&block);\r
+    XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0));\r
+    \r
+    if (useSubblock)\r
+    {\r
+      CXzFilter *f = &block.filters[filterIndex++];\r
+      f->id = XZ_ID_Subblock;\r
+      f->propsSize = 0;\r
+    }\r
+\r
+    {\r
+      CXzFilter *f = &block.filters[filterIndex++];\r
+      f->id = XZ_ID_LZMA2;\r
+      f->propsSize = 1;\r
+      f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2);\r
+    }\r
+\r
+    seqSizeOutStream.p.Write = MyWrite;\r
+    seqSizeOutStream.realStream = outStream;\r
+    seqSizeOutStream.processed = 0;\r
+    \r
+    RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p));\r
+    \r
+    checkInStream.p.Read = SeqCheckInStream_Read;\r
+    checkInStream.realStream = inStream;\r
+    SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));\r
+    \r
+    #ifdef USE_SUBBLOCK\r
+    if (useSubblock)\r
+    {\r
+      lzmaf->sb.sb.inStream = &checkInStream.p;\r
+      SubblockEnc_Init(&lzmaf->sb.sb);\r
+    }\r
+    #endif\r
+    \r
+    {\r
+      UInt64 packPos = seqSizeOutStream.processed;\r
+      SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,\r
+        #ifdef USE_SUBBLOCK\r
+        useSubblock ? &lzmaf->sb.p:\r
+        #endif\r
+        &checkInStream.p,\r
+        progress);\r
+      RINOK(res);\r
+      block.unpackSize = checkInStream.processed;\r
+      block.packSize = seqSizeOutStream.processed - packPos;\r
+    }\r
+\r
+    {\r
+      unsigned padSize = 0;\r
+      Byte buf[128];\r
+      while((((unsigned)block.packSize + padSize) & 3) != 0)\r
+        buf[padSize++] = 0;\r
+      SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);\r
+      RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));\r
+      RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc));\r
+    }\r
+  }\r
+  return Xz_WriteFooter(xz, outStream);\r
+}\r
+\r
+SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,\r
+    const CLzma2EncProps *lzma2Props, Bool useSubblock,\r
+    ICompressProgress *progress)\r
+{\r
+  SRes res;\r
+  CXzStream xz;\r
+  CLzma2WithFilters lzmaf;\r
+  Xz_Construct(&xz);\r
+  Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc);\r
+  res = Lzma2WithFilters_Create(&lzmaf);\r
+  if (res == SZ_OK)\r
+    res = Xz_Compress(&xz, &lzmaf, outStream, inStream,\r
+        lzma2Props, useSubblock, progress);\r
+  Lzma2WithFilters_Free(&lzmaf);\r
+  Xz_Free(&xz, &g_Alloc);\r
+  return res;\r
+}\r
+\r
+SRes Xz_EncodeEmpty(ISeqOutStream *outStream)\r
+{\r
+  SRes res;\r
+  CXzStream xz;\r
+  Xz_Construct(&xz);\r
+  res = Xz_WriteHeader(xz.flags, outStream);\r
+  if (res == SZ_OK)\r
+    res = Xz_WriteFooter(&xz, outStream);\r
+  Xz_Free(&xz, &g_Alloc);\r
+  return res;\r
+}\r
diff --git a/C/XzEnc.h b/C/XzEnc.h
new file mode 100755 (executable)
index 0000000..aad9aa4
--- /dev/null
+++ b/C/XzEnc.h
@@ -0,0 +1,25 @@
+/* XzEnc.h -- Xz Encode\r
+2009-04-15 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __XZ_ENC_H\r
+#define __XZ_ENC_H\r
+\r
+#include "Lzma2Enc.h"\r
+\r
+#include "Xz.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,\r
+    const CLzma2EncProps *lzma2Props, Bool useSubblock,\r
+    ICompressProgress *progress);\r
+\r
+SRes Xz_EncodeEmpty(ISeqOutStream *outStream);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/C/XzIn.c b/C/XzIn.c
new file mode 100755 (executable)
index 0000000..356d019
--- /dev/null
+++ b/C/XzIn.c
@@ -0,0 +1,306 @@
+/* XzIn.c - Xz input\r
+2009-06-19 : Igor Pavlov : Public domain */\r
+\r
+#include <string.h>\r
+\r
+#include "7zCrc.h"\r
+#include "CpuArch.h"\r
+#include "Xz.h"\r
+\r
+SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)\r
+{\r
+  Byte sig[XZ_STREAM_HEADER_SIZE];\r
+  RINOK(SeqInStream_Read2(inStream, sig, XZ_STREAM_HEADER_SIZE, SZ_ERROR_NO_ARCHIVE));\r
+  if (memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0)\r
+    return SZ_ERROR_NO_ARCHIVE;\r
+  return Xz_ParseHeader(p, sig);\r
+}\r
+\r
+#define READ_VARINT_AND_CHECK(buf, pos, size, res) \\r
+  { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \\r
+  if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }\r
+\r
+SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes)\r
+{\r
+  Byte header[XZ_BLOCK_HEADER_SIZE_MAX];\r
+  unsigned headerSize;\r
+  *headerSizeRes = 0;\r
+  RINOK(SeqInStream_ReadByte(inStream, &header[0]));\r
+  headerSize = ((unsigned)header[0] << 2) + 4;\r
+  if (headerSize == 0)\r
+  {\r
+    *headerSizeRes = 1;\r
+    *isIndex = True;\r
+    return SZ_OK;\r
+  }\r
+\r
+  *isIndex = False;\r
+  *headerSizeRes = headerSize;\r
+  RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1));\r
+  return XzBlock_Parse(p, header);\r
+}\r
+\r
+#define ADD_SIZE_CHECH(size, val) \\r
+  { UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; }\r
+\r
+UInt64 Xz_GetUnpackSize(const CXzStream *p)\r
+{\r
+  UInt64 size = 0;\r
+  size_t i;\r
+  for (i = 0; i < p->numBlocks; i++)\r
+    ADD_SIZE_CHECH(size, p->blocks[i].unpackSize);\r
+  return size;\r
+}\r
+\r
+UInt64 Xz_GetPackSize(const CXzStream *p)\r
+{\r
+  UInt64 size = 0;\r
+  size_t i;\r
+  for (i = 0; i < p->numBlocks; i++)\r
+    ADD_SIZE_CHECH(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3);\r
+  return size;\r
+}\r
+\r
+/*\r
+SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)\r
+{\r
+  return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f));\r
+}\r
+*/\r
+\r
+static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)\r
+{\r
+  size_t i, numBlocks, crcStartPos, pos = 1;\r
+  UInt32 crc;\r
+\r
+  if (size < 5 || buf[0] != 0)\r
+    return SZ_ERROR_ARCHIVE;\r
+\r
+  size -= 4;\r
+  crc = CrcCalc(buf, size);\r
+  if (crc != GetUi32(buf + size))\r
+    return SZ_ERROR_ARCHIVE;\r
+\r
+  {\r
+    UInt64 numBlocks64;\r
+    READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64);\r
+    numBlocks = (size_t)numBlocks64;\r
+    if (numBlocks != numBlocks64 || numBlocks * 2 > size)\r
+      return SZ_ERROR_ARCHIVE;\r
+  }\r
+  \r
+  crcStartPos = pos;\r
+  Xz_Free(p, alloc);\r
+  if (numBlocks != 0)\r
+  {\r
+    p->numBlocks = numBlocks;\r
+    p->numBlocksAllocated = numBlocks;\r
+    p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);\r
+    if (p->blocks == 0)\r
+      return SZ_ERROR_MEM;\r
+    for (i = 0; i < numBlocks; i++)\r
+    {\r
+      CXzBlockSizes *block = &p->blocks[i];\r
+      READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize);\r
+      READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize);\r
+      if (block->totalSize == 0)\r
+        return SZ_ERROR_ARCHIVE;\r
+    }\r
+  }\r
+  while ((pos & 3) != 0)\r
+    if (buf[pos++] != 0)\r
+      return SZ_ERROR_ARCHIVE;\r
+  return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;\r
+}\r
+\r
+static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAlloc *alloc)\r
+{\r
+  SRes res;\r
+  size_t size;\r
+  Byte *buf;\r
+  if (indexSize > ((UInt32)1 << 31))\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  size = (size_t)indexSize;\r
+  if (size != indexSize)\r
+    return SZ_ERROR_UNSUPPORTED;\r
+  buf = alloc->Alloc(alloc, size);\r
+  if (buf == 0)\r
+    return SZ_ERROR_MEM;\r
+  res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED);\r
+  if (res == SZ_OK)\r
+    res = Xz_ReadIndex2(p, buf, size, alloc);\r
+  alloc->Free(alloc, buf);\r
+  return res;\r
+}\r
+\r
+static SRes SeekFromCur(ILookInStream *inStream, Int64 *res)\r
+{\r
+  return inStream->Seek(inStream, res, SZ_SEEK_CUR);\r
+}\r
+\r
+static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)\r
+{\r
+  UInt64 indexSize;\r
+  Byte buf[XZ_STREAM_FOOTER_SIZE];\r
+\r
+  if ((*startOffset & 3) != 0 || *startOffset < XZ_STREAM_FOOTER_SIZE)\r
+    return SZ_ERROR_NO_ARCHIVE;\r
+  *startOffset = -XZ_STREAM_FOOTER_SIZE;\r
+  RINOK(SeekFromCur(stream, startOffset));\r
+\r
+  RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));\r
+  \r
+  if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)\r
+  {\r
+    Int64 i = 0;\r
+    *startOffset += XZ_STREAM_FOOTER_SIZE;\r
+    for (;;)\r
+    {\r
+      int j;\r
+      size_t processedSize;\r
+      #define TEMP_BUF_SIZE (1 << 10)\r
+      Byte tempBuf[TEMP_BUF_SIZE];\r
+      if (*startOffset < XZ_STREAM_FOOTER_SIZE || i > (1 << 16))\r
+        return SZ_ERROR_NO_ARCHIVE;\r
+      processedSize = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;\r
+      i += processedSize;\r
+      *startOffset = -(Int64)processedSize;\r
+      RINOK(SeekFromCur(stream, startOffset));\r
+      RINOK(LookInStream_Read2(stream, tempBuf, processedSize, SZ_ERROR_NO_ARCHIVE));\r
+      for (j = (int)processedSize; j >= 0; j--)\r
+        if (tempBuf[j -1] != 0)\r
+          break;\r
+      if (j != 0)\r
+      {\r
+        if ((j & 3) != 0)\r
+          return SZ_ERROR_NO_ARCHIVE;\r
+        *startOffset += j;\r
+        if (*startOffset < XZ_STREAM_FOOTER_SIZE)\r
+          return SZ_ERROR_NO_ARCHIVE;\r
+        *startOffset -= XZ_STREAM_FOOTER_SIZE;\r
+        RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));\r
+        RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));\r
+        if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)\r
+          return SZ_ERROR_NO_ARCHIVE;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  \r
+  p->flags = (CXzStreamFlags)GetBe16(buf + 8);\r
+\r
+  if (!XzFlags_IsSupported(p->flags))\r
+    return SZ_ERROR_UNSUPPORTED;\r
+\r
+  if (GetUi32(buf) != CrcCalc(buf + 4, 6))\r
+    return SZ_ERROR_ARCHIVE;\r
+\r
+  indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;\r
+\r
+  *startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE);\r
+  RINOK(SeekFromCur(stream, startOffset));\r
+\r
+  RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));\r
+\r
+  {\r
+    UInt64 totalSize = Xz_GetPackSize(p);\r
+    UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize;\r
+    if (totalSize == XZ_SIZE_OVERFLOW ||\r
+      sum >= ((UInt64)1 << 63) ||\r
+      totalSize >= ((UInt64)1 << 63))\r
+      return SZ_ERROR_ARCHIVE;\r
+    *startOffset = -(Int64)sum;\r
+    RINOK(SeekFromCur(stream, startOffset));\r
+  }\r
+  {\r
+    CXzStreamFlags headerFlags;\r
+    CSecToRead secToRead;\r
+    SecToRead_CreateVTable(&secToRead);\r
+    secToRead.realStream = stream;\r
+\r
+    RINOK(Xz_ReadHeader(&headerFlags, &secToRead.s));\r
+    return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE;\r
+  }\r
+}\r
+\r
+\r
+/* ---------- Xz Streams ---------- */\r
+\r
+void Xzs_Construct(CXzs *p)\r
+{\r
+  p->num = p->numAllocated = 0;\r
+  p->streams = 0;\r
+}\r
+\r
+void Xzs_Free(CXzs *p, ISzAlloc *alloc)\r
+{\r
+  size_t i;\r
+  for (i = 0; i < p->num; i++)\r
+    Xz_Free(&p->streams[i], alloc);\r
+  alloc->Free(alloc, p->streams);\r
+  p->num = p->numAllocated = 0;\r
+  p->streams = 0;\r
+}\r
+\r
+UInt64 Xzs_GetNumBlocks(const CXzs *p)\r
+{\r
+  UInt64 num = 0;\r
+  size_t i;\r
+  for (i = 0; i < p->num; i++)\r
+    num += p->streams[i].numBlocks;\r
+  return num;\r
+}\r
+\r
+UInt64 Xzs_GetUnpackSize(const CXzs *p)\r
+{\r
+  UInt64 size = 0;\r
+  size_t i;\r
+  for (i = 0; i < p->num; i++)\r
+    ADD_SIZE_CHECH(size, Xz_GetUnpackSize(&p->streams[i]));\r
+  return size;\r
+}\r
+\r
+/*\r
+UInt64 Xzs_GetPackSize(const CXzs *p)\r
+{\r
+  UInt64 size = 0;\r
+  size_t i;\r
+  for (i = 0; i < p->num; i++)\r
+    ADD_SIZE_CHECH(size, Xz_GetTotalSize(&p->streams[i]));\r
+  return size;\r
+}\r
+*/\r
+\r
+SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc)\r
+{\r
+  Int64 endOffset = 0;\r
+  RINOK(stream->Seek(stream, &endOffset, SZ_SEEK_END));\r
+  *startOffset = endOffset;\r
+  for (;;)\r
+  {\r
+    CXzStream st;\r
+    SRes res;\r
+    Xz_Construct(&st);\r
+    res = Xz_ReadBackward(&st, stream, startOffset, alloc);\r
+    st.startOffset = *startOffset;\r
+    RINOK(res);\r
+    if (p->num == p->numAllocated)\r
+    {\r
+      size_t newNum = p->num + p->num / 4 + 1;\r
+      Byte *data = (Byte *)alloc->Alloc(alloc, newNum * sizeof(CXzStream));\r
+      if (data == 0)\r
+        return SZ_ERROR_MEM;\r
+      p->numAllocated = newNum;\r
+      memcpy(data, p->streams, p->num * sizeof(CXzStream));\r
+      alloc->Free(alloc, p->streams);\r
+      p->streams = (CXzStream *)data;\r
+    }\r
+    p->streams[p->num++] = st;\r
+    if (*startOffset == 0)\r
+      break;\r
+    RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));\r
+    if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)\r
+      return SZ_ERROR_PROGRESS;\r
+  }\r
+  return SZ_OK;\r
+}\r
diff --git a/CPP/7zip/Aes.mak b/CPP/7zip/Aes.mak
new file mode 100755 (executable)
index 0000000..7ce28cf
--- /dev/null
@@ -0,0 +1,7 @@
+C_OBJS = $(C_OBJS) \\r
+  $O\Aes.obj\r
+\r
+!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM"\r
+ASM_OBJS = $(ASM_OBJS) \\r
+  $O\AesOpt.obj\r
+!ENDIF\r
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/CPP/7zip/Archive/7z/7zCompressionMode.cpp
new file mode 100755 (executable)
index 0000000..232c638
--- /dev/null
@@ -0,0 +1,3 @@
+// CompressionMethod.cpp\r
+\r
+#include "StdAfx.h"\r
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h
new file mode 100755 (executable)
index 0000000..a388e1f
--- /dev/null
@@ -0,0 +1,50 @@
+// 7zCompressionMode.h\r
+\r
+#ifndef __7Z_COMPRESSION_MODE_H\r
+#define __7Z_COMPRESSION_MODE_H\r
+\r
+#include "../../../Common/MyString.h"\r
+\r
+#include "../../../Windows/PropVariant.h"\r
+\r
+#include "../../Common/MethodProps.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+struct CMethodFull: public CMethod\r
+{\r
+  UInt32 NumInStreams;\r
+  UInt32 NumOutStreams;\r
+  bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }\r
+};\r
+\r
+struct CBind\r
+{\r
+  UInt32 InCoder;\r
+  UInt32 InStream;\r
+  UInt32 OutCoder;\r
+  UInt32 OutStream;\r
+};\r
+\r
+struct CCompressionMethodMode\r
+{\r
+  CObjectVector<CMethodFull> Methods;\r
+  CRecordVector<CBind> Binds;\r
+  #ifndef _7ZIP_ST\r
+  UInt32 NumThreads;\r
+  #endif\r
+  bool PasswordIsDefined;\r
+  UString Password;\r
+\r
+  bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }\r
+  CCompressionMethodMode(): PasswordIsDefined(false)\r
+      #ifndef _7ZIP_ST\r
+      , NumThreads(1)\r
+      #endif\r
+  {}\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp
new file mode 100755 (executable)
index 0000000..3fcdd5f
--- /dev/null
@@ -0,0 +1,332 @@
+// 7zDecode.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Common/LimitedStreams.h"\r
+#include "../../Common/LockedStream.h"\r
+#include "../../Common/ProgressUtils.h"\r
+#include "../../Common/StreamObjects.h"\r
+\r
+#include "7zDecode.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,\r
+    CBindInfoEx &bindInfo)\r
+{\r
+  bindInfo.Clear();\r
+  int i;\r
+  for (i = 0; i < folder.BindPairs.Size(); i++)\r
+  {\r
+    NCoderMixer::CBindPair bindPair;\r
+    bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;\r
+    bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;\r
+    bindInfo.BindPairs.Add(bindPair);\r
+  }\r
+  UInt32 outStreamIndex = 0;\r
+  for (i = 0; i < folder.Coders.Size(); i++)\r
+  {\r
+    NCoderMixer::CCoderStreamsInfo coderStreamsInfo;\r
+    const CCoderInfo &coderInfo = folder.Coders[i];\r
+    coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;\r
+    coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;\r
+    bindInfo.Coders.Add(coderStreamsInfo);\r
+    bindInfo.CoderMethodIDs.Add(coderInfo.MethodID);\r
+    for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)\r
+      if (folder.FindBindPairForOutStream(outStreamIndex) < 0)\r
+        bindInfo.OutStreams.Add(outStreamIndex);\r
+  }\r
+  for (i = 0; i < folder.PackStreams.Size(); i++)\r
+    bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);\r
+}\r
+\r
+static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,\r
+    const NCoderMixer::CCoderStreamsInfo &a2)\r
+{\r
+  return (a1.NumInStreams == a2.NumInStreams) &&\r
+    (a1.NumOutStreams == a2.NumOutStreams);\r
+}\r
+\r
+static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2)\r
+{\r
+  return (a1.InIndex == a2.InIndex) &&\r
+    (a1.OutIndex == a2.OutIndex);\r
+}\r
+\r
+static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)\r
+{\r
+  if (a1.Coders.Size() != a2.Coders.Size())\r
+    return false;\r
+  int i;\r
+  for (i = 0; i < a1.Coders.Size(); i++)\r
+    if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))\r
+      return false;\r
+  if (a1.BindPairs.Size() != a2.BindPairs.Size())\r
+    return false;\r
+  for (i = 0; i < a1.BindPairs.Size(); i++)\r
+    if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))\r
+      return false;\r
+  for (i = 0; i < a1.CoderMethodIDs.Size(); i++)\r
+    if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])\r
+      return false;\r
+  if (a1.InStreams.Size() != a2.InStreams.Size())\r
+    return false;\r
+  if (a1.OutStreams.Size() != a2.OutStreams.Size())\r
+    return false;\r
+  return true;\r
+}\r
+\r
+CDecoder::CDecoder(bool multiThread)\r
+{\r
+  #ifndef _ST_MODE\r
+  multiThread = true;\r
+  #endif\r
+  _multiThread = multiThread;\r
+  _bindInfoExPrevIsDefined = false;\r
+}\r
+\r
+HRESULT CDecoder::Decode(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    IInStream *inStream,\r
+    UInt64 startPos,\r
+    const UInt64 *packSizes,\r
+    const CFolder &folderInfo,\r
+    ISequentialOutStream *outStream,\r
+    ICompressProgressInfo *compressProgress\r
+    #ifndef _NO_CRYPTO\r
+    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+    #endif\r
+    #if !defined(_7ZIP_ST) && !defined(_SFX)\r
+    , bool mtMode, UInt32 numThreads\r
+    #endif\r
+    )\r
+{\r
+  if (!folderInfo.CheckStructure())\r
+    return E_NOTIMPL;\r
+  #ifndef _NO_CRYPTO\r
+  passwordIsDefined = false;\r
+  #endif\r
+  CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;\r
+  \r
+  CLockedInStream lockedInStream;\r
+  lockedInStream.Init(inStream);\r
+  \r
+  for (int j = 0; j < folderInfo.PackStreams.Size(); j++)\r
+  {\r
+    CLockedSequentialInStreamImp *lockedStreamImpSpec = new\r
+        CLockedSequentialInStreamImp;\r
+    CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;\r
+    lockedStreamImpSpec->Init(&lockedInStream, startPos);\r
+    startPos += packSizes[j];\r
+    \r
+    CLimitedSequentialInStream *streamSpec = new\r
+        CLimitedSequentialInStream;\r
+    CMyComPtr<ISequentialInStream> inStream = streamSpec;\r
+    streamSpec->SetStream(lockedStreamImp);\r
+    streamSpec->Init(packSizes[j]);\r
+    inStreams.Add(inStream);\r
+  }\r
+  \r
+  int numCoders = folderInfo.Coders.Size();\r
+  \r
+  CBindInfoEx bindInfo;\r
+  ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);\r
+  bool createNewCoders;\r
+  if (!_bindInfoExPrevIsDefined)\r
+    createNewCoders = true;\r
+  else\r
+    createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);\r
+  if (createNewCoders)\r
+  {\r
+    int i;\r
+    _decoders.Clear();\r
+    // _decoders2.Clear();\r
+    \r
+    _mixerCoder.Release();\r
+\r
+    if (_multiThread)\r
+    {\r
+      _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT;\r
+      _mixerCoder = _mixerCoderMTSpec;\r
+      _mixerCoderCommon = _mixerCoderMTSpec;\r
+    }\r
+    else\r
+    {\r
+      #ifdef _ST_MODE\r
+      _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST;\r
+      _mixerCoder = _mixerCoderSTSpec;\r
+      _mixerCoderCommon = _mixerCoderSTSpec;\r
+      #endif\r
+    }\r
+    RINOK(_mixerCoderCommon->SetBindInfo(bindInfo));\r
+    \r
+    for (i = 0; i < numCoders; i++)\r
+    {\r
+      const CCoderInfo &coderInfo = folderInfo.Coders[i];\r
+\r
+  \r
+      CMyComPtr<ICompressCoder> decoder;\r
+      CMyComPtr<ICompressCoder2> decoder2;\r
+      RINOK(CreateCoder(\r
+          EXTERNAL_CODECS_LOC_VARS\r
+          coderInfo.MethodID, decoder, decoder2, false));\r
+      CMyComPtr<IUnknown> decoderUnknown;\r
+      if (coderInfo.IsSimpleCoder())\r
+      {\r
+        if (decoder == 0)\r
+          return E_NOTIMPL;\r
+\r
+        decoderUnknown = (IUnknown *)decoder;\r
+        \r
+        if (_multiThread)\r
+          _mixerCoderMTSpec->AddCoder(decoder);\r
+        #ifdef _ST_MODE\r
+        else\r
+          _mixerCoderSTSpec->AddCoder(decoder, false);\r
+        #endif\r
+      }\r
+      else\r
+      {\r
+        if (decoder2 == 0)\r
+          return E_NOTIMPL;\r
+        decoderUnknown = (IUnknown *)decoder2;\r
+        if (_multiThread)\r
+          _mixerCoderMTSpec->AddCoder2(decoder2);\r
+        #ifdef _ST_MODE\r
+        else\r
+          _mixerCoderSTSpec->AddCoder2(decoder2, false);\r
+        #endif\r
+      }\r
+      _decoders.Add(decoderUnknown);\r
+      #ifdef EXTERNAL_CODECS\r
+      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;\r
+      decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);\r
+      if (setCompressCodecsInfo)\r
+      {\r
+        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));\r
+      }\r
+      #endif\r
+    }\r
+    _bindInfoExPrev = bindInfo;\r
+    _bindInfoExPrevIsDefined = true;\r
+  }\r
+  int i;\r
+  _mixerCoderCommon->ReInit();\r
+  \r
+  UInt32 packStreamIndex = 0, unpackStreamIndex = 0;\r
+  UInt32 coderIndex = 0;\r
+  // UInt32 coder2Index = 0;\r
+  \r
+  for (i = 0; i < numCoders; i++)\r
+  {\r
+    const CCoderInfo &coderInfo = folderInfo.Coders[i];\r
+    CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];\r
+    \r
+    {\r
+      CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;\r
+      decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);\r
+      if (setDecoderProperties)\r
+      {\r
+        const CByteBuffer &props = coderInfo.Props;\r
+        size_t size = props.GetCapacity();\r
+        if (size > 0xFFFFFFFF)\r
+          return E_NOTIMPL;\r
+        // if (size > 0)\r
+        {\r
+          RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));\r
+        }\r
+      }\r
+    }\r
+\r
+    #if !defined(_7ZIP_ST) && !defined(_SFX)\r
+    if (mtMode)\r
+    {\r
+      CMyComPtr<ICompressSetCoderMt> setCoderMt;\r
+      decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);\r
+      if (setCoderMt)\r
+      {\r
+        RINOK(setCoderMt->SetNumberOfThreads(numThreads));\r
+      }\r
+    }\r
+    #endif\r
+\r
+    #ifndef _NO_CRYPTO\r
+    {\r
+      CMyComPtr<ICryptoSetPassword> cryptoSetPassword;\r
+      decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);\r
+      if (cryptoSetPassword)\r
+      {\r
+        if (getTextPassword == 0)\r
+          return E_FAIL;\r
+        CMyComBSTR passwordBSTR;\r
+        RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));\r
+        CByteBuffer buffer;\r
+        passwordIsDefined = true;\r
+        const UString password(passwordBSTR);\r
+        const UInt32 sizeInBytes = password.Length() * 2;\r
+        buffer.SetCapacity(sizeInBytes);\r
+        for (int i = 0; i < password.Length(); i++)\r
+        {\r
+          wchar_t c = password[i];\r
+          ((Byte *)buffer)[i * 2] = (Byte)c;\r
+          ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);\r
+        }\r
+        RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));\r
+      }\r
+    }\r
+    #endif\r
+\r
+    coderIndex++;\r
+    \r
+    UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;\r
+    UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;\r
+    CRecordVector<const UInt64 *> packSizesPointers;\r
+    CRecordVector<const UInt64 *> unpackSizesPointers;\r
+    packSizesPointers.Reserve(numInStreams);\r
+    unpackSizesPointers.Reserve(numOutStreams);\r
+    UInt32 j;\r
+    for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)\r
+      unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]);\r
+    \r
+    for (j = 0; j < numInStreams; j++, packStreamIndex++)\r
+    {\r
+      int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);\r
+      if (bindPairIndex >= 0)\r
+        packSizesPointers.Add(\r
+        &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);\r
+      else\r
+      {\r
+        int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);\r
+        if (index < 0)\r
+          return E_FAIL;\r
+        packSizesPointers.Add(&packSizes[index]);\r
+      }\r
+    }\r
+    \r
+    _mixerCoderCommon->SetCoderInfo(i,\r
+        &packSizesPointers.Front(),\r
+        &unpackSizesPointers.Front());\r
+  }\r
+  UInt32 mainCoder, temp;\r
+  bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);\r
+\r
+  if (_multiThread)\r
+    _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);\r
+  /*\r
+  else\r
+    _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;\r
+  */\r
+  \r
+  if (numCoders == 0)\r
+    return 0;\r
+  CRecordVector<ISequentialInStream *> inStreamPointers;\r
+  inStreamPointers.Reserve(inStreams.Size());\r
+  for (i = 0; i < inStreams.Size(); i++)\r
+    inStreamPointers.Add(inStreams[i]);\r
+  ISequentialOutStream *outStreamPointer = outStream;\r
+  return _mixerCoder->Code(&inStreamPointers.Front(), NULL,\r
+    inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h
new file mode 100755 (executable)
index 0000000..da213a1
--- /dev/null
@@ -0,0 +1,68 @@
+// 7zDecode.h\r
+\r
+#ifndef __7Z_DECODE_H\r
+#define __7Z_DECODE_H\r
+\r
+#include "../../IStream.h"\r
+#include "../../IPassword.h"\r
+\r
+#include "../Common/CoderMixer2.h"\r
+#include "../Common/CoderMixer2MT.h"\r
+#ifdef _ST_MODE\r
+#include "../Common/CoderMixer2ST.h"\r
+#endif\r
+\r
+#include "../../Common/CreateCoder.h"\r
+\r
+#include "7zItem.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+struct CBindInfoEx: public NCoderMixer::CBindInfo\r
+{\r
+  CRecordVector<CMethodId> CoderMethodIDs;\r
+  void Clear()\r
+  {\r
+    CBindInfo::Clear();\r
+    CoderMethodIDs.Clear();\r
+  }\r
+};\r
+\r
+class CDecoder\r
+{\r
+  bool _bindInfoExPrevIsDefined;\r
+  CBindInfoEx _bindInfoExPrev;\r
+  \r
+  bool _multiThread;\r
+  #ifdef _ST_MODE\r
+  NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec;\r
+  #endif\r
+  NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec;\r
+  NCoderMixer::CCoderMixer2 *_mixerCoderCommon;\r
+  \r
+  CMyComPtr<ICompressCoder2> _mixerCoder;\r
+  CObjectVector<CMyComPtr<IUnknown> > _decoders;\r
+  // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;\r
+public:\r
+  CDecoder(bool multiThread);\r
+  HRESULT Decode(\r
+      DECL_EXTERNAL_CODECS_LOC_VARS\r
+      IInStream *inStream,\r
+      UInt64 startPos,\r
+      const UInt64 *packSizes,\r
+      const CFolder &folder,\r
+      ISequentialOutStream *outStream,\r
+      ICompressProgressInfo *compressProgress\r
+      #ifndef _NO_CRYPTO\r
+      , ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined\r
+      #endif\r
+      #if !defined(_7ZIP_ST) && !defined(_SFX)\r
+      , bool mtMode, UInt32 numThreads\r
+      #endif\r
+      );\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp
new file mode 100755 (executable)
index 0000000..4b93449
--- /dev/null
@@ -0,0 +1,444 @@
+// 7zEncode.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Common/CreateCoder.h"\r
+#include "../../Common/FilterCoder.h"\r
+#include "../../Common/LimitedStreams.h"\r
+#include "../../Common/InOutTempBuffer.h"\r
+#include "../../Common/ProgressUtils.h"\r
+#include "../../Common/StreamObjects.h"\r
+\r
+#include "7zEncode.h"\r
+#include "7zSpecStream.h"\r
+\r
+static const UInt64 k_Delta = 0x03;\r
+static const UInt64 k_BCJ = 0x03030103;\r
+static const UInt64 k_BCJ2 = 0x0303011B;\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo,\r
+    const CRecordVector<CMethodId> decompressionMethods,\r
+    CFolder &folder)\r
+{\r
+  folder.Coders.Clear();\r
+  // bindInfo.CoderMethodIDs.Clear();\r
+  // folder.OutStreams.Clear();\r
+  folder.PackStreams.Clear();\r
+  folder.BindPairs.Clear();\r
+  int i;\r
+  for (i = 0; i < bindInfo.BindPairs.Size(); i++)\r
+  {\r
+    CBindPair bindPair;\r
+    bindPair.InIndex = bindInfo.BindPairs[i].InIndex;\r
+    bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;\r
+    folder.BindPairs.Add(bindPair);\r
+  }\r
+  for (i = 0; i < bindInfo.Coders.Size(); i++)\r
+  {\r
+    CCoderInfo coderInfo;\r
+    const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];\r
+    coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;\r
+    coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;\r
+    coderInfo.MethodID = decompressionMethods[i];\r
+    folder.Coders.Add(coderInfo);\r
+  }\r
+  for (i = 0; i < bindInfo.InStreams.Size(); i++)\r
+    folder.PackStreams.Add(bindInfo.InStreams[i]);\r
+}\r
+\r
+HRESULT CEncoder::CreateMixerCoder(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    const UInt64 *inSizeForReduce)\r
+{\r
+  _mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;\r
+  _mixerCoder = _mixerCoderSpec;\r
+  RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));\r
+  for (int i = 0; i < _options.Methods.Size(); i++)\r
+  {\r
+    const CMethodFull &methodFull = _options.Methods[i];\r
+    _codersInfo.Add(CCoderInfo());\r
+    CCoderInfo &encodingInfo = _codersInfo.Back();\r
+    encodingInfo.MethodID = methodFull.Id;\r
+    CMyComPtr<ICompressCoder> encoder;\r
+    CMyComPtr<ICompressCoder2> encoder2;\r
+    \r
+\r
+    RINOK(CreateCoder(\r
+        EXTERNAL_CODECS_LOC_VARS\r
+        methodFull.Id, encoder, encoder2, true));\r
+\r
+    if (!encoder && !encoder2)\r
+      return E_FAIL;\r
+\r
+    CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;\r
+   \r
+    #ifndef _7ZIP_ST\r
+    {\r
+      CMyComPtr<ICompressSetCoderMt> setCoderMt;\r
+      encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);\r
+      if (setCoderMt)\r
+      {\r
+        RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));\r
+      }\r
+    }\r
+    #endif\r
+        \r
+\r
+    RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));\r
+\r
+    /*\r
+    CMyComPtr<ICryptoResetSalt> resetSalt;\r
+    encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);\r
+    if (resetSalt != NULL)\r
+    {\r
+      resetSalt->ResetSalt();\r
+    }\r
+    */\r
+\r
+    #ifdef EXTERNAL_CODECS\r
+    CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;\r
+    encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);\r
+    if (setCompressCodecsInfo)\r
+    {\r
+      RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));\r
+    }\r
+    #endif\r
+    \r
+    CMyComPtr<ICryptoSetPassword> cryptoSetPassword;\r
+    encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);\r
+\r
+    if (cryptoSetPassword)\r
+    {\r
+      CByteBuffer buffer;\r
+      const UInt32 sizeInBytes = _options.Password.Length() * 2;\r
+      buffer.SetCapacity(sizeInBytes);\r
+      for (int i = 0; i < _options.Password.Length(); i++)\r
+      {\r
+        wchar_t c = _options.Password[i];\r
+        ((Byte *)buffer)[i * 2] = (Byte)c;\r
+        ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);\r
+      }\r
+      RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));\r
+    }\r
+\r
+    if (encoder)\r
+      _mixerCoderSpec->AddCoder(encoder);\r
+    else\r
+      _mixerCoderSpec->AddCoder2(encoder2);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CEncoder::Encode(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    ISequentialInStream *inStream,\r
+    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,\r
+    CFolder &folderItem,\r
+    ISequentialOutStream *outStream,\r
+    CRecordVector<UInt64> &packSizes,\r
+    ICompressProgressInfo *compressProgress)\r
+{\r
+  RINOK(EncoderConstr());\r
+\r
+  if (_mixerCoderSpec == NULL)\r
+  {\r
+    RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));\r
+  }\r
+  _mixerCoderSpec->ReInit();\r
+  // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);\r
+\r
+  CObjectVector<CInOutTempBuffer> inOutTempBuffers;\r
+  CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;\r
+  CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;\r
+  int numMethods = _bindInfo.Coders.Size();\r
+  int i;\r
+  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)\r
+  {\r
+    inOutTempBuffers.Add(CInOutTempBuffer());\r
+    inOutTempBuffers.Back().Create();\r
+    inOutTempBuffers.Back().InitWriting();\r
+  }\r
+  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)\r
+  {\r
+    CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;\r
+    CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;\r
+    tempBufferSpec->Init(&inOutTempBuffers[i - 1]);\r
+    tempBuffers.Add(tempBuffer);\r
+    tempBufferSpecs.Add(tempBufferSpec);\r
+  }\r
+\r
+  for (i = 0; i < numMethods; i++)\r
+    _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);\r
+\r
+  if (_bindInfo.InStreams.IsEmpty())\r
+    return E_FAIL;\r
+  UInt32 mainCoderIndex, mainStreamIndex;\r
+  _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);\r
+  \r
+  if (inStreamSize != NULL)\r
+  {\r
+    CRecordVector<const UInt64 *> sizePointers;\r
+    for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)\r
+      if (i == mainStreamIndex)\r
+        sizePointers.Add(inStreamSize);\r
+      else\r
+        sizePointers.Add(NULL);\r
+    _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);\r
+  }\r
+\r
+  \r
+  // UInt64 outStreamStartPos;\r
+  // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));\r
+  \r
+  CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;\r
+  CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;\r
+  CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;\r
+  CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;\r
+\r
+  inStreamSizeCountSpec->Init(inStream);\r
+  outStreamSizeCountSpec->SetStream(outStream);\r
+  outStreamSizeCountSpec->Init();\r
+\r
+  CRecordVector<ISequentialInStream *> inStreamPointers;\r
+  CRecordVector<ISequentialOutStream *> outStreamPointers;\r
+  inStreamPointers.Add(inStreamSizeCount);\r
+  outStreamPointers.Add(outStreamSizeCount);\r
+  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)\r
+    outStreamPointers.Add(tempBuffers[i - 1]);\r
+\r
+  for (i = 0; i < _codersInfo.Size(); i++)\r
+  {\r
+    CCoderInfo &encodingInfo = _codersInfo[i];\r
+    \r
+    CMyComPtr<ICryptoResetInitVector> resetInitVector;\r
+    _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);\r
+    if (resetInitVector != NULL)\r
+    {\r
+      resetInitVector->ResetInitVector();\r
+    }\r
+\r
+    CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;\r
+    _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);\r
+    if (writeCoderProperties != NULL)\r
+    {\r
+      CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;\r
+      CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);\r
+      outStreamSpec->Init();\r
+      writeCoderProperties->WriteCoderProperties(outStream);\r
+      outStreamSpec->CopyToBuffer(encodingInfo.Props);\r
+    }\r
+  }\r
+\r
+  UInt32 progressIndex = mainCoderIndex;\r
+\r
+  for (i = 0; i + 1 < _codersInfo.Size(); i++)\r
+  {\r
+    UInt64 m = _codersInfo[i].MethodID;\r
+    if (m == k_Delta || m == k_BCJ || m == k_BCJ2)\r
+      progressIndex = i + 1;\r
+  }\r
+\r
+  _mixerCoderSpec->SetProgressCoderIndex(progressIndex);\r
+  \r
+  RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,\r
+    &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));\r
+  \r
+  ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);\r
+  \r
+  packSizes.Add(outStreamSizeCountSpec->GetSize());\r
+  \r
+  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)\r
+  {\r
+    CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];\r
+    RINOK(inOutTempBuffer.WriteToStream(outStream));\r
+    packSizes.Add(inOutTempBuffer.GetDataSize());\r
+  }\r
+  \r
+  for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)\r
+  {\r
+    int binder = _bindInfo.FindBinderForInStream(\r
+        _bindReverseConverter->DestOutToSrcInMap[i]);\r
+    UInt64 streamSize;\r
+    if (binder < 0)\r
+      streamSize = inStreamSizeCountSpec->GetSize();\r
+    else\r
+      streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);\r
+    folderItem.UnpackSizes.Add(streamSize);\r
+  }\r
+  for (i = numMethods - 1; i >= 0; i--)\r
+    folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;\r
+  return S_OK;\r
+}\r
+\r
+\r
+CEncoder::CEncoder(const CCompressionMethodMode &options):\r
+  _bindReverseConverter(0),\r
+  _constructed(false)\r
+{\r
+  if (options.IsEmpty())\r
+    throw 1;\r
+\r
+  _options = options;\r
+  _mixerCoderSpec = NULL;\r
+}\r
+\r
+HRESULT CEncoder::EncoderConstr()\r
+{\r
+  if (_constructed)\r
+    return S_OK;\r
+  if (_options.Methods.IsEmpty())\r
+  {\r
+    // it has only password method;\r
+    if (!_options.PasswordIsDefined)\r
+      throw 1;\r
+    if (!_options.Binds.IsEmpty())\r
+      throw 1;\r
+    NCoderMixer::CCoderStreamsInfo coderStreamsInfo;\r
+    CMethodFull method;\r
+    \r
+    method.NumInStreams = 1;\r
+    method.NumOutStreams = 1;\r
+    coderStreamsInfo.NumInStreams = 1;\r
+    coderStreamsInfo.NumOutStreams = 1;\r
+    method.Id = k_AES;\r
+    \r
+    _options.Methods.Add(method);\r
+    _bindInfo.Coders.Add(coderStreamsInfo);\r
+  \r
+    _bindInfo.InStreams.Add(0);\r
+    _bindInfo.OutStreams.Add(0);\r
+  }\r
+  else\r
+  {\r
+\r
+  UInt32 numInStreams = 0, numOutStreams = 0;\r
+  int i;\r
+  for (i = 0; i < _options.Methods.Size(); i++)\r
+  {\r
+    const CMethodFull &methodFull = _options.Methods[i];\r
+    NCoderMixer::CCoderStreamsInfo coderStreamsInfo;\r
+    coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;\r
+    coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;\r
+    if (_options.Binds.IsEmpty())\r
+    {\r
+      if (i < _options.Methods.Size() - 1)\r
+      {\r
+        NCoderMixer::CBindPair bindPair;\r
+        bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;\r
+        bindPair.OutIndex = numOutStreams;\r
+        _bindInfo.BindPairs.Add(bindPair);\r
+      }\r
+      else\r
+        _bindInfo.OutStreams.Insert(0, numOutStreams);\r
+      for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)\r
+        _bindInfo.OutStreams.Add(numOutStreams + j);\r
+    }\r
+    \r
+    numInStreams += coderStreamsInfo.NumInStreams;\r
+    numOutStreams += coderStreamsInfo.NumOutStreams;\r
+\r
+    _bindInfo.Coders.Add(coderStreamsInfo);\r
+  }\r
+\r
+  if (!_options.Binds.IsEmpty())\r
+  {\r
+    for (i = 0; i < _options.Binds.Size(); i++)\r
+    {\r
+      NCoderMixer::CBindPair bindPair;\r
+      const CBind &bind = _options.Binds[i];\r
+      bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;\r
+      bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;\r
+      _bindInfo.BindPairs.Add(bindPair);\r
+    }\r
+    for (i = 0; i < (int)numOutStreams; i++)\r
+      if (_bindInfo.FindBinderForOutStream(i) == -1)\r
+        _bindInfo.OutStreams.Add(i);\r
+  }\r
+\r
+  for (i = 0; i < (int)numInStreams; i++)\r
+    if (_bindInfo.FindBinderForInStream(i) == -1)\r
+      _bindInfo.InStreams.Add(i);\r
+\r
+  if (_bindInfo.InStreams.IsEmpty())\r
+    throw 1; // this is error\r
+\r
+  // Make main stream first in list\r
+  int inIndex = _bindInfo.InStreams[0];\r
+  for (;;)\r
+  {\r
+    UInt32 coderIndex, coderStreamIndex;\r
+    _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);\r
+    UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);\r
+    int binder = _bindInfo.FindBinderForOutStream(outIndex);\r
+    if (binder >= 0)\r
+    {\r
+      inIndex = _bindInfo.BindPairs[binder].InIndex;\r
+      continue;\r
+    }\r
+    for (i = 0; i < _bindInfo.OutStreams.Size(); i++)\r
+      if (_bindInfo.OutStreams[i] == outIndex)\r
+      {\r
+        _bindInfo.OutStreams.Delete(i);\r
+        _bindInfo.OutStreams.Insert(0, outIndex);\r
+        break;\r
+      }\r
+    break;\r
+  }\r
+\r
+  if (_options.PasswordIsDefined)\r
+  {\r
+    int numCryptoStreams = _bindInfo.OutStreams.Size();\r
+\r
+    for (i = 0; i < numCryptoStreams; i++)\r
+    {\r
+      NCoderMixer::CBindPair bindPair;\r
+      bindPair.InIndex = numInStreams + i;\r
+      bindPair.OutIndex = _bindInfo.OutStreams[i];\r
+      _bindInfo.BindPairs.Add(bindPair);\r
+    }\r
+    _bindInfo.OutStreams.Clear();\r
+\r
+    /*\r
+    if (numCryptoStreams == 0)\r
+      numCryptoStreams = 1;\r
+    */\r
+\r
+    for (i = 0; i < numCryptoStreams; i++)\r
+    {\r
+      NCoderMixer::CCoderStreamsInfo coderStreamsInfo;\r
+      CMethodFull method;\r
+      method.NumInStreams = 1;\r
+      method.NumOutStreams = 1;\r
+      coderStreamsInfo.NumInStreams = method.NumOutStreams;\r
+      coderStreamsInfo.NumOutStreams = method.NumInStreams;\r
+      method.Id = k_AES;\r
+\r
+      _options.Methods.Add(method);\r
+      _bindInfo.Coders.Add(coderStreamsInfo);\r
+      _bindInfo.OutStreams.Add(numOutStreams + i);\r
+    }\r
+  }\r
+\r
+  }\r
+\r
+  for (int i = _options.Methods.Size() - 1; i >= 0; i--)\r
+  {\r
+    const CMethodFull &methodFull = _options.Methods[i];\r
+    _decompressionMethods.Add(methodFull.Id);\r
+  }\r
+\r
+  _bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo);\r
+  _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);\r
+  _constructed = true;\r
+  return S_OK;\r
+}\r
+\r
+CEncoder::~CEncoder()\r
+{\r
+  delete _bindReverseConverter;\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zEncode.h b/CPP/7zip/Archive/7z/7zEncode.h
new file mode 100755 (executable)
index 0000000..c75f02f
--- /dev/null
@@ -0,0 +1,55 @@
+// 7zEncode.h\r
+\r
+#ifndef __7Z_ENCODE_H\r
+#define __7Z_ENCODE_H\r
+\r
+// #include "../../Common/StreamObjects.h"\r
+\r
+#include "7zCompressionMode.h"\r
+\r
+#include "../Common/CoderMixer2.h"\r
+#include "../Common/CoderMixer2MT.h"\r
+#ifdef _ST_MODE\r
+#include "../Common/CoderMixer2ST.h"\r
+#endif\r
+#include "7zItem.h"\r
+\r
+#include "../../Common/CreateCoder.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+class CEncoder\r
+{\r
+  NCoderMixer::CCoderMixer2MT *_mixerCoderSpec;\r
+  CMyComPtr<ICompressCoder2> _mixerCoder;\r
+\r
+  CObjectVector<CCoderInfo> _codersInfo;\r
+\r
+  CCompressionMethodMode _options;\r
+  NCoderMixer::CBindInfo _bindInfo;\r
+  NCoderMixer::CBindInfo _decompressBindInfo;\r
+  NCoderMixer::CBindReverseConverter *_bindReverseConverter;\r
+  CRecordVector<CMethodId> _decompressionMethods;\r
+\r
+  HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS\r
+      const UInt64 *inSizeForReduce);\r
+\r
+  bool _constructed;\r
+public:\r
+  CEncoder(const CCompressionMethodMode &options);\r
+  ~CEncoder();\r
+  HRESULT EncoderConstr();\r
+  HRESULT Encode(\r
+      DECL_EXTERNAL_CODECS_LOC_VARS\r
+      ISequentialInStream *inStream,\r
+      const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,\r
+      CFolder &folderItem,\r
+      ISequentialOutStream *outStream,\r
+      CRecordVector<UInt64> &packSizes,\r
+      ICompressProgressInfo *compressProgress);\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp
new file mode 100755 (executable)
index 0000000..6e31943
--- /dev/null
@@ -0,0 +1,270 @@
+// 7zExtract.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../Common/ComTry.h"\r
+\r
+#include "../../Common/ProgressUtils.h"\r
+\r
+#include "7zDecode.h"\r
+// #include "7z1Decode.h"\r
+#include "7zFolderOutStream.h"\r
+#include "7zHandler.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+struct CExtractFolderInfo\r
+{\r
+  #ifdef _7Z_VOL\r
+  int VolumeIndex;\r
+  #endif\r
+  CNum FileIndex;\r
+  CNum FolderIndex;\r
+  CBoolVector ExtractStatuses;\r
+  UInt64 UnpackSize;\r
+  CExtractFolderInfo(\r
+    #ifdef _7Z_VOL\r
+    int volumeIndex,\r
+    #endif\r
+    CNum fileIndex, CNum folderIndex):\r
+    #ifdef _7Z_VOL\r
+    VolumeIndex(volumeIndex),\r
+    #endif\r
+    FileIndex(fileIndex),\r
+    FolderIndex(folderIndex),\r
+    UnpackSize(0)\r
+  {\r
+    if (fileIndex != kNumNoIndex)\r
+    {\r
+      ExtractStatuses.Reserve(1);\r
+      ExtractStatuses.Add(true);\r
+    }\r
+  };\r
+};\r
+\r
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,\r
+    Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)\r
+{\r
+  COM_TRY_BEGIN\r
+  bool testMode = (testModeSpec != 0);\r
+  CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;\r
+  UInt64 importantTotalUnpacked = 0;\r
+\r
+  bool allFilesMode = (numItems == (UInt32)-1);\r
+  if (allFilesMode)\r
+    numItems =\r
+    #ifdef _7Z_VOL\r
+    _refs.Size();\r
+    #else\r
+    _db.Files.Size();\r
+    #endif\r
+\r
+  if(numItems == 0)\r
+    return S_OK;\r
+\r
+  /*\r
+  if(_volumes.Size() != 1)\r
+    return E_FAIL;\r
+  const CVolume &volume = _volumes.Front();\r
+  const CArchiveDatabaseEx &_db = volume.Database;\r
+  IInStream *_inStream = volume.Stream;\r
+  */\r
+  \r
+  CObjectVector<CExtractFolderInfo> extractFolderInfoVector;\r
+  for (UInt32 ii = 0; ii < numItems; ii++)\r
+  {\r
+    // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];\r
+    UInt32 ref2Index = allFilesMode ? ii : indices[ii];\r
+    // const CRef2 &ref2 = _refs[ref2Index];\r
+\r
+    // for (UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)\r
+    {\r
+      #ifdef _7Z_VOL\r
+      // const CRef &ref = ref2.Refs[ri];\r
+      const CRef &ref = _refs[ref2Index];\r
+\r
+      int volumeIndex = ref.VolumeIndex;\r
+      const CVolume &volume = _volumes[volumeIndex];\r
+      const CArchiveDatabaseEx &db = volume.Database;\r
+      UInt32 fileIndex = ref.ItemIndex;\r
+      #else\r
+      const CArchiveDatabaseEx &db = _db;\r
+      UInt32 fileIndex = ref2Index;\r
+      #endif\r
+\r
+      CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex];\r
+      if (folderIndex == kNumNoIndex)\r
+      {\r
+        extractFolderInfoVector.Add(CExtractFolderInfo(\r
+            #ifdef _7Z_VOL\r
+            volumeIndex,\r
+            #endif\r
+            fileIndex, kNumNoIndex));\r
+        continue;\r
+      }\r
+      if (extractFolderInfoVector.IsEmpty() ||\r
+        folderIndex != extractFolderInfoVector.Back().FolderIndex\r
+        #ifdef _7Z_VOL\r
+        || volumeIndex != extractFolderInfoVector.Back().VolumeIndex\r
+        #endif\r
+        )\r
+      {\r
+        extractFolderInfoVector.Add(CExtractFolderInfo(\r
+            #ifdef _7Z_VOL\r
+            volumeIndex,\r
+            #endif\r
+            kNumNoIndex, folderIndex));\r
+        const CFolder &folderInfo = db.Folders[folderIndex];\r
+        UInt64 unpackSize = folderInfo.GetUnpackSize();\r
+        importantTotalUnpacked += unpackSize;\r
+        extractFolderInfoVector.Back().UnpackSize = unpackSize;\r
+      }\r
+      \r
+      CExtractFolderInfo &efi = extractFolderInfoVector.Back();\r
+      \r
+      // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];\r
+      CNum startIndex = db.FolderStartFileIndex[folderIndex];\r
+      for (CNum index = efi.ExtractStatuses.Size();\r
+          index <= fileIndex - startIndex; index++)\r
+      {\r
+        // UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize;\r
+        // Count partial_folder_size\r
+        // efi.UnpackSize += unpackSize;\r
+        // importantTotalUnpacked += unpackSize;\r
+        efi.ExtractStatuses.Add(index == fileIndex - startIndex);\r
+      }\r
+    }\r
+  }\r
+\r
+  RINOK(extractCallback->SetTotal(importantTotalUnpacked));\r
+\r
+  CDecoder decoder(\r
+    #ifdef _ST_MODE\r
+    false\r
+    #else\r
+    true\r
+    #endif\r
+    );\r
+  // CDecoder1 decoder;\r
+\r
+  UInt64 totalPacked = 0;\r
+  UInt64 totalUnpacked = 0;\r
+  UInt64 curPacked, curUnpacked;\r
+\r
+  CLocalProgress *lps = new CLocalProgress;\r
+  CMyComPtr<ICompressProgressInfo> progress = lps;\r
+  lps->Init(extractCallback, false);\r
+\r
+  for (int i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)\r
+  {\r
+    lps->OutSize = totalUnpacked;\r
+    lps->InSize = totalPacked;\r
+    RINOK(lps->SetCur());\r
+\r
+    if (i >= extractFolderInfoVector.Size())\r
+      break;\r
+    \r
+    const CExtractFolderInfo &efi = extractFolderInfoVector[i];\r
+    curUnpacked = efi.UnpackSize;\r
+    curPacked = 0;\r
+\r
+    CFolderOutStream *folderOutStream = new CFolderOutStream;\r
+    CMyComPtr<ISequentialOutStream> outStream(folderOutStream);\r
+\r
+    #ifdef _7Z_VOL\r
+    const CVolume &volume = _volumes[efi.VolumeIndex];\r
+    const CArchiveDatabaseEx &db = volume.Database;\r
+    #else\r
+    const CArchiveDatabaseEx &db = _db;\r
+    #endif\r
+\r
+    CNum startIndex;\r
+    if (efi.FileIndex != kNumNoIndex)\r
+      startIndex = efi.FileIndex;\r
+    else\r
+      startIndex = db.FolderStartFileIndex[efi.FolderIndex];\r
+\r
+    HRESULT result = folderOutStream->Init(&db,\r
+        #ifdef _7Z_VOL\r
+        volume.StartRef2Index,\r
+        #else\r
+        0,\r
+        #endif\r
+        startIndex,\r
+        &efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);\r
+\r
+    RINOK(result);\r
+\r
+    if (efi.FileIndex != kNumNoIndex)\r
+      continue;\r
+\r
+    CNum folderIndex = efi.FolderIndex;\r
+    const CFolder &folderInfo = db.Folders[folderIndex];\r
+\r
+    curPacked = _db.GetFolderFullPackSize(folderIndex);\r
+\r
+    CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];\r
+    UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);\r
+\r
+    #ifndef _NO_CRYPTO\r
+    CMyComPtr<ICryptoGetTextPassword> getTextPassword;\r
+    if (extractCallback)\r
+      extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);\r
+    #endif\r
+\r
+    try\r
+    {\r
+      #ifndef _NO_CRYPTO\r
+      bool passwordIsDefined;\r
+      #endif\r
+\r
+      HRESULT result = decoder.Decode(\r
+          EXTERNAL_CODECS_VARS\r
+          #ifdef _7Z_VOL\r
+          volume.Stream,\r
+          #else\r
+          _inStream,\r
+          #endif\r
+          folderStartPackPos,\r
+          &db.PackSizes[packStreamIndex],\r
+          folderInfo,\r
+          outStream,\r
+          progress\r
+          #ifndef _NO_CRYPTO\r
+          , getTextPassword, passwordIsDefined\r
+          #endif\r
+          #if !defined(_7ZIP_ST) && !defined(_SFX)\r
+          , true, _numThreads\r
+          #endif\r
+          );\r
+\r
+      if (result == S_FALSE)\r
+      {\r
+        RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));\r
+        continue;\r
+      }\r
+      if (result == E_NOTIMPL)\r
+      {\r
+        RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnSupportedMethod));\r
+        continue;\r
+      }\r
+      if (result != S_OK)\r
+        return result;\r
+      if (folderOutStream->WasWritingFinished() != S_OK)\r
+      {\r
+        RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));\r
+        continue;\r
+      }\r
+    }\r
+    catch(...)\r
+    {\r
+      RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));\r
+      continue;\r
+    }\r
+  }\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/CPP/7zip/Archive/7z/7zFolderInStream.cpp
new file mode 100755 (executable)
index 0000000..c49d341
--- /dev/null
@@ -0,0 +1,123 @@
+// 7zFolderInStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "7zFolderInStream.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+CFolderInStream::CFolderInStream()\r
+{\r
+  _inStreamWithHashSpec = new CSequentialInStreamWithCRC;\r
+  _inStreamWithHash = _inStreamWithHashSpec;\r
+}\r
+\r
+void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,\r
+    const UInt32 *fileIndices, UInt32 numFiles)\r
+{\r
+  _updateCallback = updateCallback;\r
+  _numFiles = numFiles;\r
+  _fileIndex = 0;\r
+  _fileIndices = fileIndices;\r
+  Processed.Clear();\r
+  CRCs.Clear();\r
+  Sizes.Clear();\r
+  _fileIsOpen = false;\r
+  _currentSizeIsDefined = false;\r
+}\r
+\r
+HRESULT CFolderInStream::OpenStream()\r
+{\r
+  _filePos = 0;\r
+  while (_fileIndex < _numFiles)\r
+  {\r
+    CMyComPtr<ISequentialInStream> stream;\r
+    HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);\r
+    if (result != S_OK && result != S_FALSE)\r
+      return result;\r
+    _fileIndex++;\r
+    _inStreamWithHashSpec->SetStream(stream);\r
+    _inStreamWithHashSpec->Init();\r
+    if (stream)\r
+    {\r
+      _fileIsOpen = true;\r
+      CMyComPtr<IStreamGetSize> streamGetSize;\r
+      stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);\r
+      if (streamGetSize)\r
+      {\r
+        RINOK(streamGetSize->GetSize(&_currentSize));\r
+        _currentSizeIsDefined = true;\r
+      }\r
+      return S_OK;\r
+    }\r
+    RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));\r
+    Sizes.Add(0);\r
+    Processed.Add(result == S_OK);\r
+    AddDigest();\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+void CFolderInStream::AddDigest()\r
+{\r
+  CRCs.Add(_inStreamWithHashSpec->GetCRC());\r
+}\r
+\r
+HRESULT CFolderInStream::CloseStream()\r
+{\r
+  RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));\r
+  _inStreamWithHashSpec->ReleaseStream();\r
+  _fileIsOpen = false;\r
+  _currentSizeIsDefined = false;\r
+  Processed.Add(true);\r
+  Sizes.Add(_filePos);\r
+  AddDigest();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != 0)\r
+    *processedSize = 0;\r
+  while (size > 0)\r
+  {\r
+    if (_fileIsOpen)\r
+    {\r
+      UInt32 processed2;\r
+      RINOK(_inStreamWithHash->Read(data, size, &processed2));\r
+      if (processed2 == 0)\r
+      {\r
+        RINOK(CloseStream());\r
+        continue;\r
+      }\r
+      if (processedSize != 0)\r
+        *processedSize = processed2;\r
+      _filePos += processed2;\r
+      break;\r
+    }\r
+    if (_fileIndex >= _numFiles)\r
+      break;\r
+    RINOK(OpenStream());\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)\r
+{\r
+  *value = 0;\r
+  int index2 = (int)subStream;\r
+  if (index2 < 0 || subStream > Sizes.Size())\r
+    return E_FAIL;\r
+  if (index2 < Sizes.Size())\r
+  {\r
+    *value = Sizes[index2];\r
+    return S_OK;\r
+  }\r
+  if (!_currentSizeIsDefined)\r
+    return S_FALSE;\r
+  *value = _currentSize;\r
+  return S_OK;\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.h b/CPP/7zip/Archive/7z/7zFolderInStream.h
new file mode 100755 (executable)
index 0000000..fc27b9b
--- /dev/null
@@ -0,0 +1,58 @@
+// 7zFolderInStream.h\r
+\r
+#ifndef __7Z_FOLDER_IN_STREAM_H\r
+#define __7Z_FOLDER_IN_STREAM_H\r
+\r
+#include "../../ICoder.h"\r
+#include "../IArchive.h"\r
+#include "../Common/InStreamWithCRC.h"\r
+\r
+#include "7zItem.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+class CFolderInStream:\r
+  public ISequentialInStream,\r
+  public ICompressGetSubStreamSize,\r
+  public CMyUnknownImp\r
+{\r
+  CSequentialInStreamWithCRC *_inStreamWithHashSpec;\r
+  CMyComPtr<ISequentialInStream> _inStreamWithHash;\r
+  CMyComPtr<IArchiveUpdateCallback> _updateCallback;\r
+\r
+  bool _currentSizeIsDefined;\r
+  bool _fileIsOpen;\r
+  UInt64 _currentSize;\r
+  UInt64 _filePos;\r
+  const UInt32 *_fileIndices;\r
+  UInt32 _numFiles;\r
+  UInt32 _fileIndex;\r
+\r
+  HRESULT OpenStream();\r
+  HRESULT CloseStream();\r
+  void AddDigest();\r
+\r
+public:\r
+  CRecordVector<bool> Processed;\r
+  CRecordVector<UInt32> CRCs;\r
+  CRecordVector<UInt64> Sizes;\r
+\r
+  MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);\r
+\r
+  CFolderInStream();\r
+  void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles);\r
+  UInt64 GetFullSize() const\r
+  {\r
+    UInt64 size = 0;\r
+    for (int i = 0; i < Sizes.Size(); i++)\r
+      size += Sizes[i];\r
+    return size;\r
+  }\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
new file mode 100755 (executable)
index 0000000..403ca60
--- /dev/null
@@ -0,0 +1,149 @@
+// 7zFolderOutStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "7zFolderOutStream.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+CFolderOutStream::CFolderOutStream()\r
+{\r
+  _crcStreamSpec = new COutStreamWithCRC;\r
+  _crcStream = _crcStreamSpec;\r
+}\r
+\r
+HRESULT CFolderOutStream::Init(\r
+    const CArchiveDatabaseEx *db,\r
+    UInt32 ref2Offset, UInt32 startIndex,\r
+    const CBoolVector *extractStatuses,\r
+    IArchiveExtractCallback *extractCallback,\r
+    bool testMode, bool checkCrc)\r
+{\r
+  _db = db;\r
+  _ref2Offset = ref2Offset;\r
+  _startIndex = startIndex;\r
+\r
+  _extractStatuses = extractStatuses;\r
+  _extractCallback = extractCallback;\r
+  _testMode = testMode;\r
+  _checkCrc = checkCrc;\r
+\r
+  _currentIndex = 0;\r
+  _fileIsOpen = false;\r
+  return ProcessEmptyFiles();\r
+}\r
+\r
+HRESULT CFolderOutStream::OpenFile()\r
+{\r
+  Int32 askMode = ((*_extractStatuses)[_currentIndex]) ? (_testMode ?\r
+      NExtract::NAskMode::kTest :\r
+      NExtract::NAskMode::kExtract) :\r
+      NExtract::NAskMode::kSkip;\r
+  CMyComPtr<ISequentialOutStream> realOutStream;\r
+  UInt32 index = _startIndex + _currentIndex;\r
+  RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));\r
+  _crcStreamSpec->SetStream(realOutStream);\r
+  _crcStreamSpec->Init(_checkCrc);\r
+  _fileIsOpen = true;\r
+  const CFileItem &fi = _db->Files[index];\r
+  _rem = fi.Size;\r
+  if (askMode == NExtract::NAskMode::kExtract && !realOutStream &&\r
+      !_db->IsItemAnti(index) && !fi.IsDir)\r
+    askMode = NExtract::NAskMode::kSkip;\r
+  return _extractCallback->PrepareOperation(askMode);\r
+}\r
+\r
+HRESULT CFolderOutStream::CloseFileAndSetResult(Int32 res)\r
+{\r
+  _crcStreamSpec->ReleaseStream();\r
+  _fileIsOpen = false;\r
+  _currentIndex++;\r
+  return _extractCallback->SetOperationResult(res);\r
+}\r
+\r
+HRESULT CFolderOutStream::CloseFileAndSetResult()\r
+{\r
+  const CFileItem &fi = _db->Files[_startIndex + _currentIndex];\r
+  return CloseFileAndSetResult(\r
+      (fi.IsDir || !fi.CrcDefined || !_checkCrc || fi.Crc == _crcStreamSpec->GetCRC()) ?\r
+      NExtract::NOperationResult::kOK :\r
+      NExtract::NOperationResult::kCRCError);\r
+}\r
+\r
+HRESULT CFolderOutStream::ProcessEmptyFiles()\r
+{\r
+  while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0)\r
+  {\r
+    RINOK(OpenFile());\r
+    RINOK(CloseFileAndSetResult());\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  while (size != 0)\r
+  {\r
+    if (_fileIsOpen)\r
+    {\r
+      UInt32 cur = size < _rem ? size : (UInt32)_rem;\r
+      RINOK(_crcStream->Write(data, cur, &cur));\r
+      if (cur == 0)\r
+        break;\r
+      data = (const Byte *)data + cur;\r
+      size -= cur;\r
+      _rem -= cur;\r
+      if (processedSize != NULL)\r
+        *processedSize += cur;\r
+      if (_rem == 0)\r
+      {\r
+        RINOK(CloseFileAndSetResult());\r
+        RINOK(ProcessEmptyFiles());\r
+        continue;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      RINOK(ProcessEmptyFiles());\r
+      if (_currentIndex == _extractStatuses->Size())\r
+      {\r
+        // we support partial extracting\r
+        if (processedSize != NULL)\r
+          *processedSize += size;\r
+        break;\r
+      }\r
+      RINOK(OpenFile());\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)\r
+{\r
+  *value = 0;\r
+  if ((int)subStream >= _extractStatuses->Size())\r
+    return S_FALSE;\r
+  *value = _db->Files[_startIndex + (int)subStream].Size;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)\r
+{\r
+  while (_currentIndex < _extractStatuses->Size())\r
+  {\r
+    if (_fileIsOpen)\r
+    {\r
+      RINOK(CloseFileAndSetResult(resultEOperationResult));\r
+    }\r
+    else\r
+    {\r
+      RINOK(OpenFile());\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.h b/CPP/7zip/Archive/7z/7zFolderOutStream.h
new file mode 100755 (executable)
index 0000000..c964b1d
--- /dev/null
@@ -0,0 +1,58 @@
+// 7zFolderOutStream.h\r
+\r
+#ifndef __7Z_FOLDER_OUT_STREAM_H\r
+#define __7Z_FOLDER_OUT_STREAM_H\r
+\r
+#include "../../IStream.h"\r
+#include "../IArchive.h"\r
+#include "../Common/OutStreamWithCRC.h"\r
+\r
+#include "7zIn.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+class CFolderOutStream:\r
+  public ISequentialOutStream,\r
+  public ICompressGetSubStreamSize,\r
+  public CMyUnknownImp\r
+{\r
+  COutStreamWithCRC *_crcStreamSpec;\r
+  CMyComPtr<ISequentialOutStream> _crcStream;\r
+  const CArchiveDatabaseEx *_db;\r
+  const CBoolVector *_extractStatuses;\r
+  CMyComPtr<IArchiveExtractCallback> _extractCallback;\r
+  UInt32 _ref2Offset;\r
+  UInt32 _startIndex;\r
+  int _currentIndex;\r
+  bool _testMode;\r
+  bool _checkCrc;\r
+  bool _fileIsOpen;\r
+  UInt64 _rem;\r
+\r
+  HRESULT OpenFile();\r
+  HRESULT CloseFileAndSetResult(Int32 res);\r
+  HRESULT CloseFileAndSetResult();\r
+  HRESULT ProcessEmptyFiles();\r
+public:\r
+  MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)\r
+\r
+  CFolderOutStream();\r
+\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);\r
+\r
+  HRESULT Init(\r
+      const CArchiveDatabaseEx *db,\r
+      UInt32 ref2Offset, UInt32 startIndex,\r
+      const CBoolVector *extractStatuses,\r
+      IArchiveExtractCallback *extractCallback,\r
+      bool testMode, bool checkCrc);\r
+  HRESULT FlushCorrupted(Int32 resultEOperationResult);\r
+  HRESULT WasWritingFinished() const\r
+      { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; }\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp
new file mode 100755 (executable)
index 0000000..c404b9c
--- /dev/null
@@ -0,0 +1,482 @@
+// 7zHandler.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../../C/CpuArch.h"\r
+\r
+#include "../../../Common/ComTry.h"\r
+#include "../../../Common/IntToString.h"\r
+\r
+#ifndef __7Z_SET_PROPERTIES\r
+#include "../../../Windows/System.h"\r
+#endif\r
+\r
+#include "../Common/ItemNameUtils.h"\r
+\r
+#include "7zHandler.h"\r
+#include "7zProperties.h"\r
+\r
+#ifdef __7Z_SET_PROPERTIES\r
+#ifdef EXTRACT_ONLY\r
+#include "../Common/ParseProperties.h"\r
+#endif\r
+#endif\r
+\r
+using namespace NWindows;\r
+\r
+extern UString ConvertMethodIdToString(UInt64 id);\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+CHandler::CHandler()\r
+{\r
+  _crcSize = 4;\r
+\r
+  #ifndef _NO_CRYPTO\r
+  _passwordIsDefined = false;\r
+  #endif\r
+\r
+  #ifdef EXTRACT_ONLY\r
+  #ifdef __7Z_SET_PROPERTIES\r
+  _numThreads = NSystem::GetNumberOfProcessors();\r
+  #endif\r
+  #else\r
+  Init();\r
+  #endif\r
+}\r
+\r
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)\r
+{\r
+  *numItems = _db.Files.Size();\r
+  return S_OK;\r
+}\r
+\r
+#ifdef _SFX\r
+\r
+IMP_IInArchive_ArcProps_NO\r
+\r
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)\r
+{\r
+  return E_NOTIMPL;\r
+}\r
+\r
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,\r
+      BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)\r
+{\r
+  return E_NOTIMPL;\r
+}\r
+\r
+\r
+#else\r
+\r
+STATPROPSTG kArcProps[] =\r
+{\r
+  { NULL, kpidMethod, VT_BSTR},\r
+  { NULL, kpidSolid, VT_BOOL},\r
+  { NULL, kpidNumBlocks, VT_UI4},\r
+  { NULL, kpidPhySize, VT_UI8},\r
+  { NULL, kpidHeadersSize, VT_UI8},\r
+  { NULL, kpidOffset, VT_UI8}\r
+};\r
+\r
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)\r
+{\r
+  COM_TRY_BEGIN\r
+  NCOM::CPropVariant prop;\r
+  switch(propID)\r
+  {\r
+    case kpidMethod:\r
+    {\r
+      UString resString;\r
+      CRecordVector<UInt64> ids;\r
+      int i;\r
+      for (i = 0; i < _db.Folders.Size(); i++)\r
+      {\r
+        const CFolder &f = _db.Folders[i];\r
+        for (int j = f.Coders.Size() - 1; j >= 0; j--)\r
+          ids.AddToUniqueSorted(f.Coders[j].MethodID);\r
+      }\r
+\r
+      for (i = 0; i < ids.Size(); i++)\r
+      {\r
+        UInt64 id = ids[i];\r
+        UString methodName;\r
+        /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);\r
+        if (methodName.IsEmpty())\r
+          methodName = ConvertMethodIdToString(id);\r
+        if (!resString.IsEmpty())\r
+          resString += L' ';\r
+        resString += methodName;\r
+      }\r
+      prop = resString;\r
+      break;\r
+    }\r
+    case kpidSolid: prop = _db.IsSolid(); break;\r
+    case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break;\r
+    case kpidHeadersSize:  prop = _db.HeadersSize; break;\r
+    case kpidPhySize:  prop = _db.PhySize; break;\r
+    case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break;\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+IMP_IInArchive_ArcProps\r
+\r
+#endif\r
+\r
+static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)\r
+{\r
+  UInt64 value;\r
+  if (v.GetItem(index, value))\r
+  {\r
+    FILETIME ft;\r
+    ft.dwLowDateTime = (DWORD)value;\r
+    ft.dwHighDateTime = (DWORD)(value >> 32);\r
+    prop = ft;\r
+  }\r
+}\r
+\r
+#ifndef _SFX\r
+\r
+static UString ConvertUInt32ToString(UInt32 value)\r
+{\r
+  wchar_t buffer[32];\r
+  ConvertUInt64ToString(value, buffer);\r
+  return buffer;\r
+}\r
+\r
+static UString GetStringForSizeValue(UInt32 value)\r
+{\r
+  for (int i = 31; i >= 0; i--)\r
+    if ((UInt32(1) << i) == value)\r
+      return ConvertUInt32ToString(i);\r
+  UString result;\r
+  if (value % (1 << 20) == 0)\r
+  {\r
+    result += ConvertUInt32ToString(value >> 20);\r
+    result += L"m";\r
+  }\r
+  else if (value % (1 << 10) == 0)\r
+  {\r
+    result += ConvertUInt32ToString(value >> 10);\r
+    result += L"k";\r
+  }\r
+  else\r
+  {\r
+    result += ConvertUInt32ToString(value);\r
+    result += L"b";\r
+  }\r
+  return result;\r
+}\r
+\r
+static const UInt64 k_Copy = 0x0;\r
+static const UInt64 k_Delta = 3;\r
+static const UInt64 k_LZMA2 = 0x21;\r
+static const UInt64 k_LZMA  = 0x030101;\r
+static const UInt64 k_PPMD  = 0x030401;\r
+\r
+static wchar_t GetHex(Byte value)\r
+{\r
+  return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));\r
+}\r
+static inline void AddHexToString(UString &res, Byte value)\r
+{\r
+  res += GetHex((Byte)(value >> 4));\r
+  res += GetHex((Byte)(value & 0xF));\r
+}\r
+\r
+#endif\r
+\r
+bool CHandler::IsEncrypted(UInt32 index2) const\r
+{\r
+  CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];\r
+  if (folderIndex != kNumNoIndex)\r
+    return _db.Folders[folderIndex].IsEncrypted();\r
+  return false;\r
+}\r
+\r
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID,  PROPVARIANT *value)\r
+{\r
+  COM_TRY_BEGIN\r
+  NCOM::CPropVariant prop;\r
+  \r
+  /*\r
+  const CRef2 &ref2 = _refs[index];\r
+  if (ref2.Refs.IsEmpty())\r
+    return E_FAIL;\r
+  const CRef &ref = ref2.Refs.Front();\r
+  */\r
+  \r
+  const CFileItem &item = _db.Files[index];\r
+  UInt32 index2 = index;\r
+\r
+  switch(propID)\r
+  {\r
+    case kpidPath:\r
+      if (!item.Name.IsEmpty())\r
+        prop = NItemName::GetOSName(item.Name);\r
+      break;\r
+    case kpidIsDir:  prop = item.IsDir; break;\r
+    case kpidSize:\r
+    {\r
+      prop = item.Size;\r
+      // prop = ref2.Size;\r
+      break;\r
+    }\r
+    case kpidPackSize:\r
+    {\r
+      // prop = ref2.PackSize;\r
+      {\r
+        CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];\r
+        if (folderIndex != kNumNoIndex)\r
+        {\r
+          if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)\r
+            prop = _db.GetFolderFullPackSize(folderIndex);\r
+          /*\r
+          else\r
+            prop = (UInt64)0;\r
+          */\r
+        }\r
+        else\r
+          prop = (UInt64)0;\r
+      }\r
+      break;\r
+    }\r
+    case kpidPosition:  { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }\r
+    case kpidCTime:  SetPropFromUInt64Def(_db.CTime, index2, prop); break;\r
+    case kpidATime:  SetPropFromUInt64Def(_db.ATime, index2, prop); break;\r
+    case kpidMTime:  SetPropFromUInt64Def(_db.MTime, index2, prop); break;\r
+    case kpidAttrib:  if (item.AttribDefined) prop = item.Attrib; break;\r
+    case kpidCRC:  if (item.CrcDefined) prop = item.Crc; break;\r
+    case kpidEncrypted:  prop = IsEncrypted(index2); break;\r
+    case kpidIsAnti:  prop = _db.IsItemAnti(index2); break;\r
+    #ifndef _SFX\r
+    case kpidMethod:\r
+      {\r
+        CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];\r
+        if (folderIndex != kNumNoIndex)\r
+        {\r
+          const CFolder &folderInfo = _db.Folders[folderIndex];\r
+          UString methodsString;\r
+          for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)\r
+          {\r
+            const CCoderInfo &coder = folderInfo.Coders[i];\r
+            if (!methodsString.IsEmpty())\r
+              methodsString += L' ';\r
+\r
+            UString methodName, propsString;\r
+            bool methodIsKnown = FindMethod(\r
+              EXTERNAL_CODECS_VARS\r
+              coder.MethodID, methodName);\r
+            \r
+            if (!methodIsKnown)\r
+              methodsString += ConvertMethodIdToString(coder.MethodID);\r
+            else\r
+            {\r
+              methodsString += methodName;\r
+              if (coder.MethodID == k_Delta && coder.Props.GetCapacity() == 1)\r
+                propsString = ConvertUInt32ToString((UInt32)coder.Props[0] + 1);\r
+              else if (coder.MethodID == k_LZMA && coder.Props.GetCapacity() == 5)\r
+              {\r
+                UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);\r
+                propsString = GetStringForSizeValue(dicSize);\r
+              }\r
+              else if (coder.MethodID == k_LZMA2 && coder.Props.GetCapacity() == 1)\r
+              {\r
+                Byte p = coder.Props[0];\r
+                UInt32 dicSize = (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11));\r
+                propsString = GetStringForSizeValue(dicSize);\r
+              }\r
+              else if (coder.MethodID == k_PPMD && coder.Props.GetCapacity() == 5)\r
+              {\r
+                Byte order = *(const Byte *)coder.Props;\r
+                propsString = L'o';\r
+                propsString += ConvertUInt32ToString(order);\r
+                propsString += L":mem";\r
+                UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);\r
+                propsString += GetStringForSizeValue(dicSize);\r
+              }\r
+              else if (coder.MethodID == k_AES && coder.Props.GetCapacity() >= 1)\r
+              {\r
+                const Byte *data = (const Byte *)coder.Props;\r
+                Byte firstByte = *data++;\r
+                UInt32 numCyclesPower = firstByte & 0x3F;\r
+                propsString = ConvertUInt32ToString(numCyclesPower);\r
+                /*\r
+                if ((firstByte & 0xC0) != 0)\r
+                {\r
+                  UInt32 saltSize = (firstByte >> 7) & 1;\r
+                  UInt32 ivSize = (firstByte >> 6) & 1;\r
+                  if (coder.Props.GetCapacity() >= 2)\r
+                  {\r
+                    Byte secondByte = *data++;\r
+                    saltSize += (secondByte >> 4);\r
+                    ivSize += (secondByte & 0x0F);\r
+                  }\r
+                }\r
+                */\r
+              }\r
+            }\r
+            if (!propsString.IsEmpty())\r
+            {\r
+              methodsString += L':';\r
+              methodsString += propsString;\r
+            }\r
+            else if (coder.Props.GetCapacity() > 0)\r
+            {\r
+              methodsString += L":[";\r
+              for (size_t bi = 0; bi < coder.Props.GetCapacity(); bi++)\r
+              {\r
+                if (bi > 5 && bi + 1 < coder.Props.GetCapacity())\r
+                {\r
+                  methodsString += L"..";\r
+                  break;\r
+                }\r
+                else\r
+                  AddHexToString(methodsString, coder.Props[bi]);\r
+              }\r
+              methodsString += L']';\r
+            }\r
+          }\r
+          prop = methodsString;\r
+        }\r
+      }\r
+      break;\r
+    case kpidBlock:\r
+      {\r
+        CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];\r
+        if (folderIndex != kNumNoIndex)\r
+          prop = (UInt32)folderIndex;\r
+      }\r
+      break;\r
+    case kpidPackedSize0:\r
+    case kpidPackedSize1:\r
+    case kpidPackedSize2:\r
+    case kpidPackedSize3:\r
+    case kpidPackedSize4:\r
+      {\r
+        CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];\r
+        if (folderIndex != kNumNoIndex)\r
+        {\r
+          const CFolder &folderInfo = _db.Folders[folderIndex];\r
+          if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&\r
+              folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))\r
+          {\r
+            prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);\r
+          }\r
+          else\r
+            prop = (UInt64)0;\r
+        }\r
+        else\r
+          prop = (UInt64)0;\r
+      }\r
+      break;\r
+    #endif\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CHandler::Open(IInStream *stream,\r
+    const UInt64 *maxCheckStartPosition,\r
+    IArchiveOpenCallback *openArchiveCallback)\r
+{\r
+  COM_TRY_BEGIN\r
+  Close();\r
+  #ifndef _SFX\r
+  _fileInfoPopIDs.Clear();\r
+  #endif\r
+  try\r
+  {\r
+    CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;\r
+\r
+    #ifndef _NO_CRYPTO\r
+    CMyComPtr<ICryptoGetTextPassword> getTextPassword;\r
+    if (openArchiveCallback)\r
+    {\r
+      openArchiveCallbackTemp.QueryInterface(\r
+          IID_ICryptoGetTextPassword, &getTextPassword);\r
+    }\r
+    #endif\r
+    CInArchive archive;\r
+    RINOK(archive.Open(stream, maxCheckStartPosition));\r
+    #ifndef _NO_CRYPTO\r
+    _passwordIsDefined = false;\r
+    UString password;\r
+    #endif\r
+    HRESULT result = archive.ReadDatabase(\r
+      EXTERNAL_CODECS_VARS\r
+      _db\r
+      #ifndef _NO_CRYPTO\r
+      , getTextPassword, _passwordIsDefined\r
+      #endif\r
+      );\r
+    RINOK(result);\r
+    _db.Fill();\r
+    _inStream = stream;\r
+  }\r
+  catch(...)\r
+  {\r
+    Close();\r
+    return S_FALSE;\r
+  }\r
+  // _inStream = stream;\r
+  #ifndef _SFX\r
+  FillPopIDs();\r
+  #endif\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CHandler::Close()\r
+{\r
+  COM_TRY_BEGIN\r
+  _inStream.Release();\r
+  _db.Clear();\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+#ifdef __7Z_SET_PROPERTIES\r
+#ifdef EXTRACT_ONLY\r
+\r
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)\r
+{\r
+  COM_TRY_BEGIN\r
+  const UInt32 numProcessors = NSystem::GetNumberOfProcessors();\r
+  _numThreads = numProcessors;\r
+\r
+  for (int i = 0; i < numProperties; i++)\r
+  {\r
+    UString name = names[i];\r
+    name.MakeUpper();\r
+    if (name.IsEmpty())\r
+      return E_INVALIDARG;\r
+    const PROPVARIANT &value = values[i];\r
+    UInt32 number;\r
+    int index = ParseStringToUInt32(name, number);\r
+    if (index == 0)\r
+    {\r
+      if(name.Left(2).CompareNoCase(L"MT") == 0)\r
+      {\r
+        RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));\r
+        continue;\r
+      }\r
+      else\r
+        return E_INVALIDARG;\r
+    }\r
+  }\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+#endif\r
+#endif\r
+\r
+IMPL_ISetCompressCodecsInfo\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h
new file mode 100755 (executable)
index 0000000..c0fd0e0
--- /dev/null
@@ -0,0 +1,119 @@
+// 7z/Handler.h\r
+\r
+#ifndef __7Z_HANDLER_H\r
+#define __7Z_HANDLER_H\r
+\r
+#include "../../ICoder.h"\r
+#include "../IArchive.h"\r
+\r
+#include "../../Common/CreateCoder.h"\r
+\r
+#ifndef EXTRACT_ONLY\r
+#include "../Common/HandlerOut.h"\r
+#endif\r
+\r
+#include "7zCompressionMode.h"\r
+#include "7zIn.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+#ifndef __7Z_SET_PROPERTIES\r
+\r
+#ifdef EXTRACT_ONLY\r
+#if !defined(_7ZIP_ST) && !defined(_SFX)\r
+#define __7Z_SET_PROPERTIES\r
+#endif\r
+#else\r
+#define __7Z_SET_PROPERTIES\r
+#endif\r
+\r
+#endif\r
+\r
+\r
+class CHandler:\r
+  #ifndef EXTRACT_ONLY\r
+  public NArchive::COutHandler,\r
+  #endif\r
+  public IInArchive,\r
+  #ifdef __7Z_SET_PROPERTIES\r
+  public ISetProperties,\r
+  #endif\r
+  #ifndef EXTRACT_ONLY\r
+  public IOutArchive,\r
+  #endif\r
+  PUBLIC_ISetCompressCodecsInfo\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_QUERYINTERFACE_BEGIN2(IInArchive)\r
+  #ifdef __7Z_SET_PROPERTIES\r
+  MY_QUERYINTERFACE_ENTRY(ISetProperties)\r
+  #endif\r
+  #ifndef EXTRACT_ONLY\r
+  MY_QUERYINTERFACE_ENTRY(IOutArchive)\r
+  #endif\r
+  QUERY_ENTRY_ISetCompressCodecsInfo\r
+  MY_QUERYINTERFACE_END\r
+  MY_ADDREF_RELEASE\r
+\r
+  INTERFACE_IInArchive(;)\r
+\r
+  #ifdef __7Z_SET_PROPERTIES\r
+  STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);\r
+  #endif\r
+\r
+  #ifndef EXTRACT_ONLY\r
+  INTERFACE_IOutArchive(;)\r
+  #endif\r
+\r
+  DECL_ISetCompressCodecsInfo\r
+\r
+  CHandler();\r
+\r
+private:\r
+  CMyComPtr<IInStream> _inStream;\r
+  NArchive::N7z::CArchiveDatabaseEx _db;\r
+  #ifndef _NO_CRYPTO\r
+  bool _passwordIsDefined;\r
+  #endif\r
+\r
+  #ifdef EXTRACT_ONLY\r
+  \r
+  #ifdef __7Z_SET_PROPERTIES\r
+  UInt32 _numThreads;\r
+  #endif\r
+\r
+  UInt32 _crcSize;\r
+\r
+  #else\r
+  \r
+  CRecordVector<CBind> _binds;\r
+\r
+  HRESULT SetCompressionMethod(CCompressionMethodMode &method,\r
+      CObjectVector<COneMethodInfo> &methodsInfo\r
+      #ifndef _7ZIP_ST\r
+      , UInt32 numThreads\r
+      #endif\r
+      );\r
+\r
+  HRESULT SetCompressionMethod(\r
+      CCompressionMethodMode &method,\r
+      CCompressionMethodMode &headerMethod);\r
+\r
+  #endif\r
+\r
+  bool IsEncrypted(UInt32 index2) const;\r
+  #ifndef _SFX\r
+\r
+  CRecordVector<UInt64> _fileInfoPopIDs;\r
+  void FillPopIDs();\r
+\r
+  #endif\r
+\r
+  DECL_EXTERNAL_CODECS_VARS\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
new file mode 100755 (executable)
index 0000000..59d6269
--- /dev/null
@@ -0,0 +1,483 @@
+// 7zHandlerOut.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../Windows/PropVariant.h"\r
+\r
+#include "../../../Common/ComTry.h"\r
+#include "../../../Common/StringToInt.h"\r
+\r
+#include "../../ICoder.h"\r
+\r
+#include "../Common/ItemNameUtils.h"\r
+#include "../Common/ParseProperties.h"\r
+\r
+#include "7zHandler.h"\r
+#include "7zOut.h"\r
+#include "7zUpdate.h"\r
+\r
+using namespace NWindows;\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+static const wchar_t *kLZMAMethodName = L"LZMA";\r
+static const wchar_t *kCopyMethod = L"Copy";\r
+static const wchar_t *kDefaultMethodName = kLZMAMethodName;\r
+\r
+static const UInt32 kLzmaAlgorithmX5 = 1;\r
+static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";\r
+static const UInt32 kDictionaryForHeaders =\r
+  #ifdef UNDER_CE\r
+  1 << 18\r
+  #else\r
+  1 << 20\r
+  #endif\r
+;\r
+static const UInt32 kNumFastBytesForHeaders = 273;\r
+static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;\r
+\r
+static inline bool IsCopyMethod(const UString &methodName)\r
+  { return (methodName.CompareNoCase(kCopyMethod) == 0); }\r
+\r
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)\r
+{\r
+  *type = NFileTimeType::kWindows;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CHandler::SetCompressionMethod(\r
+    CCompressionMethodMode &methodMode,\r
+    CCompressionMethodMode &headerMethod)\r
+{\r
+  HRESULT res = SetCompressionMethod(methodMode, _methods\r
+  #ifndef _7ZIP_ST\r
+  , _numThreads\r
+  #endif\r
+  );\r
+  RINOK(res);\r
+  methodMode.Binds = _binds;\r
+\r
+  if (_compressHeaders)\r
+  {\r
+    // headerMethod.Methods.Add(methodMode.Methods.Back());\r
+\r
+    CObjectVector<COneMethodInfo> headerMethodInfoVector;\r
+    COneMethodInfo oneMethodInfo;\r
+    oneMethodInfo.MethodName = kLZMAMethodName;\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kMatchFinder;\r
+      prop.Value = kLzmaMatchFinderForHeaders;\r
+      oneMethodInfo.Props.Add(prop);\r
+    }\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kAlgorithm;\r
+      prop.Value = kAlgorithmForHeaders;\r
+      oneMethodInfo.Props.Add(prop);\r
+    }\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kNumFastBytes;\r
+      prop.Value = (UInt32)kNumFastBytesForHeaders;\r
+      oneMethodInfo.Props.Add(prop);\r
+    }\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kDictionarySize;\r
+      prop.Value = (UInt32)kDictionaryForHeaders;\r
+      oneMethodInfo.Props.Add(prop);\r
+    }\r
+    headerMethodInfoVector.Add(oneMethodInfo);\r
+    HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector\r
+      #ifndef _7ZIP_ST\r
+      , 1\r
+      #endif\r
+    );\r
+    RINOK(res);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CHandler::SetCompressionMethod(\r
+    CCompressionMethodMode &methodMode,\r
+    CObjectVector<COneMethodInfo> &methodsInfo\r
+    #ifndef _7ZIP_ST\r
+    , UInt32 numThreads\r
+    #endif\r
+    )\r
+{\r
+  UInt32 level = _level;\r
+  \r
+  if (methodsInfo.IsEmpty())\r
+  {\r
+    COneMethodInfo oneMethodInfo;\r
+    oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);\r
+    methodsInfo.Add(oneMethodInfo);\r
+  }\r
+\r
+  bool needSolid = false;\r
+  for(int i = 0; i < methodsInfo.Size(); i++)\r
+  {\r
+    COneMethodInfo &oneMethodInfo = methodsInfo[i];\r
+    SetCompressionMethod2(oneMethodInfo\r
+      #ifndef _7ZIP_ST\r
+      , numThreads\r
+      #endif\r
+      );\r
+\r
+    if (!IsCopyMethod(oneMethodInfo.MethodName))\r
+      needSolid = true;\r
+\r
+    CMethodFull methodFull;\r
+\r
+    if (!FindMethod(\r
+        EXTERNAL_CODECS_VARS\r
+        oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams))\r
+      return E_INVALIDARG;\r
+    methodFull.Props = oneMethodInfo.Props;\r
+    methodMode.Methods.Add(methodFull);\r
+\r
+    if (!_numSolidBytesDefined)\r
+    {\r
+      for (int j = 0; j < methodFull.Props.Size(); j++)\r
+      {\r
+        const CProp &prop = methodFull.Props[j];\r
+        if ((prop.Id == NCoderPropID::kDictionarySize ||\r
+             prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)\r
+        {\r
+          _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;\r
+          const UInt64 kMinSize = (1 << 24);\r
+          if (_numSolidBytes < kMinSize)\r
+            _numSolidBytes = kMinSize;\r
+          _numSolidBytesDefined = true;\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  if (!needSolid && !_numSolidBytesDefined)\r
+  {\r
+    _numSolidBytesDefined = true;\r
+    _numSolidBytes  = 0;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined)\r
+{\r
+  ft = 0;\r
+  ftDefined = false;\r
+  if (!writeTime)\r
+    return S_OK;\r
+  NCOM::CPropVariant prop;\r
+  RINOK(updateCallback->GetProperty(index, propID, &prop));\r
+  if (prop.vt == VT_FILETIME)\r
+  {\r
+    ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);\r
+    ftDefined = true;\r
+  }\r
+  else if (prop.vt != VT_EMPTY)\r
+    return E_INVALIDARG;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,\r
+    IArchiveUpdateCallback *updateCallback)\r
+{\r
+  COM_TRY_BEGIN\r
+\r
+  const CArchiveDatabaseEx *db = 0;\r
+  #ifdef _7Z_VOL\r
+  if (_volumes.Size() > 1)\r
+    return E_FAIL;\r
+  const CVolume *volume = 0;\r
+  if (_volumes.Size() == 1)\r
+  {\r
+    volume = &_volumes.Front();\r
+    db = &volume->Database;\r
+  }\r
+  #else\r
+  if (_inStream != 0)\r
+    db = &_db;\r
+  #endif\r
+\r
+  CObjectVector<CUpdateItem> updateItems;\r
+  \r
+  for (UInt32 i = 0; i < numItems; i++)\r
+  {\r
+    Int32 newData, newProps;\r
+    UInt32 indexInArchive;\r
+    if (!updateCallback)\r
+      return E_FAIL;\r
+    RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive));\r
+    CUpdateItem ui;\r
+    ui.NewProps = IntToBool(newProps);\r
+    ui.NewData = IntToBool(newData);\r
+    ui.IndexInArchive = indexInArchive;\r
+    ui.IndexInClient = i;\r
+    ui.IsAnti = false;\r
+    ui.Size = 0;\r
+\r
+    if (ui.IndexInArchive != -1)\r
+    {\r
+      if (db == 0 || ui.IndexInArchive >= db->Files.Size())\r
+        return E_INVALIDARG;\r
+      const CFileItem &fi = db->Files[ui.IndexInArchive];\r
+      ui.Name = fi.Name;\r
+      ui.IsDir = fi.IsDir;\r
+      ui.Size = fi.Size;\r
+      ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);\r
+      \r
+      ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);\r
+      ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);\r
+      ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);\r
+    }\r
+\r
+    if (ui.NewProps)\r
+    {\r
+      bool nameIsDefined;\r
+      bool folderStatusIsDefined;\r
+      {\r
+        NCOM::CPropVariant prop;\r
+        RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));\r
+        if (prop.vt == VT_EMPTY)\r
+          ui.AttribDefined = false;\r
+        else if (prop.vt != VT_UI4)\r
+          return E_INVALIDARG;\r
+        else\r
+        {\r
+          ui.Attrib = prop.ulVal;\r
+          ui.AttribDefined = true;\r
+        }\r
+      }\r
+      \r
+      // we need MTime to sort files.\r
+      RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined));\r
+      RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined));\r
+      RINOK(GetTime(updateCallback, i, true,       kpidMTime, ui.MTime, ui.MTimeDefined));\r
+\r
+      {\r
+        NCOM::CPropVariant prop;\r
+        RINOK(updateCallback->GetProperty(i, kpidPath, &prop));\r
+        if (prop.vt == VT_EMPTY)\r
+          nameIsDefined = false;\r
+        else if (prop.vt != VT_BSTR)\r
+          return E_INVALIDARG;\r
+        else\r
+        {\r
+          ui.Name = NItemName::MakeLegalName(prop.bstrVal);\r
+          nameIsDefined = true;\r
+        }\r
+      }\r
+      {\r
+        NCOM::CPropVariant prop;\r
+        RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));\r
+        if (prop.vt == VT_EMPTY)\r
+          folderStatusIsDefined = false;\r
+        else if (prop.vt != VT_BOOL)\r
+          return E_INVALIDARG;\r
+        else\r
+        {\r
+          ui.IsDir = (prop.boolVal != VARIANT_FALSE);\r
+          folderStatusIsDefined = true;\r
+        }\r
+      }\r
+\r
+      {\r
+        NCOM::CPropVariant prop;\r
+        RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));\r
+        if (prop.vt == VT_EMPTY)\r
+          ui.IsAnti = false;\r
+        else if (prop.vt != VT_BOOL)\r
+          return E_INVALIDARG;\r
+        else\r
+          ui.IsAnti = (prop.boolVal != VARIANT_FALSE);\r
+      }\r
+\r
+      if (ui.IsAnti)\r
+      {\r
+        ui.AttribDefined = false;\r
+\r
+        ui.CTimeDefined = false;\r
+        ui.ATimeDefined = false;\r
+        ui.MTimeDefined = false;\r
+        \r
+        ui.Size = 0;\r
+      }\r
+\r
+      if (!folderStatusIsDefined && ui.AttribDefined)\r
+        ui.SetDirStatusFromAttrib();\r
+    }\r
+\r
+    if (ui.NewData)\r
+    {\r
+      NCOM::CPropVariant prop;\r
+      RINOK(updateCallback->GetProperty(i, kpidSize, &prop));\r
+      if (prop.vt != VT_UI8)\r
+        return E_INVALIDARG;\r
+      ui.Size = (UInt64)prop.uhVal.QuadPart;\r
+      if (ui.Size != 0 && ui.IsAnti)\r
+        return E_INVALIDARG;\r
+    }\r
+    updateItems.Add(ui);\r
+  }\r
+\r
+  CCompressionMethodMode methodMode, headerMethod;\r
+  RINOK(SetCompressionMethod(methodMode, headerMethod));\r
+  #ifndef _7ZIP_ST\r
+  methodMode.NumThreads = _numThreads;\r
+  headerMethod.NumThreads = 1;\r
+  #endif\r
+\r
+  CMyComPtr<ICryptoGetTextPassword2> getPassword2;\r
+  updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);\r
+\r
+  if (getPassword2)\r
+  {\r
+    CMyComBSTR password;\r
+    Int32 passwordIsDefined;\r
+    RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));\r
+    methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);\r
+    if (methodMode.PasswordIsDefined)\r
+      methodMode.Password = password;\r
+  }\r
+  else\r
+    methodMode.PasswordIsDefined = false;\r
+\r
+  bool compressMainHeader = _compressHeaders;  // check it\r
+\r
+  bool encryptHeaders = false;\r
+\r
+  if (methodMode.PasswordIsDefined)\r
+  {\r
+    if (_encryptHeadersSpecified)\r
+      encryptHeaders = _encryptHeaders;\r
+    #ifndef _NO_CRYPTO\r
+    else\r
+      encryptHeaders = _passwordIsDefined;\r
+    #endif\r
+    compressMainHeader = true;\r
+    if (encryptHeaders)\r
+    {\r
+      headerMethod.PasswordIsDefined = methodMode.PasswordIsDefined;\r
+      headerMethod.Password = methodMode.Password;\r
+    }\r
+  }\r
+\r
+  if (numItems < 2)\r
+    compressMainHeader = false;\r
+\r
+  CUpdateOptions options;\r
+  options.Method = &methodMode;\r
+  options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;\r
+  options.UseFilters = _level != 0 && _autoFilter;\r
+  options.MaxFilter = _level >= 8;\r
+\r
+  options.HeaderOptions.CompressMainHeader = compressMainHeader;\r
+  options.HeaderOptions.WriteCTime = WriteCTime;\r
+  options.HeaderOptions.WriteATime = WriteATime;\r
+  options.HeaderOptions.WriteMTime = WriteMTime;\r
+  \r
+  options.NumSolidFiles = _numSolidFiles;\r
+  options.NumSolidBytes = _numSolidBytes;\r
+  options.SolidExtension = _solidExtension;\r
+  options.RemoveSfxBlock = _removeSfxBlock;\r
+  options.VolumeMode = _volumeMode;\r
+\r
+  COutArchive archive;\r
+  CArchiveDatabase newDatabase;\r
+\r
+  CMyComPtr<ICryptoGetTextPassword> getPassword;\r
+  updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);\r
+  \r
+  HRESULT res = Update(\r
+      EXTERNAL_CODECS_VARS\r
+      #ifdef _7Z_VOL\r
+      volume ? volume->Stream: 0,\r
+      volume ? db : 0,\r
+      #else\r
+      _inStream,\r
+      db,\r
+      #endif\r
+      updateItems,\r
+      archive, newDatabase, outStream, updateCallback, options\r
+      #ifndef _NO_CRYPTO\r
+      , getPassword\r
+      #endif\r
+      );\r
+\r
+  RINOK(res);\r
+\r
+  updateItems.ClearAndFree();\r
+\r
+  return archive.WriteDatabase(EXTERNAL_CODECS_VARS\r
+      newDatabase, options.HeaderMethod, options.HeaderOptions);\r
+\r
+  COM_TRY_END\r
+}\r
+\r
+static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)\r
+{\r
+  stream = 0;\r
+  int index = ParseStringToUInt32(srcString, coder);\r
+  if (index == 0)\r
+    return E_INVALIDARG;\r
+  srcString.Delete(0, index);\r
+  if (srcString[0] == 'S')\r
+  {\r
+    srcString.Delete(0);\r
+    int index = ParseStringToUInt32(srcString, stream);\r
+    if (index == 0)\r
+      return E_INVALIDARG;\r
+    srcString.Delete(0, index);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+static HRESULT GetBindInfo(UString &srcString, CBind &bind)\r
+{\r
+  RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));\r
+  if (srcString[0] != ':')\r
+    return E_INVALIDARG;\r
+  srcString.Delete(0);\r
+  RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));\r
+  if (!srcString.IsEmpty())\r
+    return E_INVALIDARG;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)\r
+{\r
+  COM_TRY_BEGIN\r
+  _binds.Clear();\r
+  BeforeSetProperty();\r
+\r
+  for (int i = 0; i < numProperties; i++)\r
+  {\r
+    UString name = names[i];\r
+    name.MakeUpper();\r
+    if (name.IsEmpty())\r
+      return E_INVALIDARG;\r
+\r
+    const PROPVARIANT &value = values[i];\r
+\r
+    if (name[0] == 'B')\r
+    {\r
+      name.Delete(0);\r
+      CBind bind;\r
+      RINOK(GetBindInfo(name, bind));\r
+      _binds.Add(bind);\r
+      continue;\r
+    }\r
+\r
+    RINOK(SetProperty(name, value));\r
+  }\r
+\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zHeader.cpp b/CPP/7zip/Archive/7z/7zHeader.cpp
new file mode 100755 (executable)
index 0000000..d93670c
--- /dev/null
@@ -0,0 +1,14 @@
+// 7zHeader.cpp\r
+\r
+#include "StdAfx.h"\r
+#include "7zHeader.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};\r
+#ifdef _7Z_VOL\r
+Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};\r
+#endif\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zHeader.h b/CPP/7zip/Archive/7z/7zHeader.h
new file mode 100755 (executable)
index 0000000..57f455b
--- /dev/null
@@ -0,0 +1,97 @@
+// 7z/7zHeader.h\r
+\r
+#ifndef __7Z_HEADER_H\r
+#define __7Z_HEADER_H\r
+\r
+#include "../../../Common/Types.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+const int kSignatureSize = 6;\r
+extern Byte kSignature[kSignatureSize];\r
+\r
+// #define _7Z_VOL\r
+// 7z-MultiVolume is not finished yet.\r
+// It can work already, but I still do not like some\r
+// things of that new multivolume format.\r
+// So please keep it commented.\r
+\r
+#ifdef _7Z_VOL\r
+extern Byte kFinishSignature[kSignatureSize];\r
+#endif\r
+\r
+struct CArchiveVersion\r
+{\r
+  Byte Major;\r
+  Byte Minor;\r
+};\r
+\r
+const Byte kMajorVersion = 0;\r
+\r
+struct CStartHeader\r
+{\r
+  UInt64 NextHeaderOffset;\r
+  UInt64 NextHeaderSize;\r
+  UInt32 NextHeaderCRC;\r
+};\r
+\r
+const UInt32 kStartHeaderSize = 20;\r
+\r
+#ifdef _7Z_VOL\r
+struct CFinishHeader: public CStartHeader\r
+{\r
+  UInt64 ArchiveStartOffset;  // data offset from end if that struct\r
+  UInt64 AdditionalStartBlockSize; // start  signature & start header size\r
+};\r
+\r
+const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;\r
+#endif\r
+\r
+namespace NID\r
+{\r
+  enum EEnum\r
+  {\r
+    kEnd,\r
+\r
+    kHeader,\r
+\r
+    kArchiveProperties,\r
+    \r
+    kAdditionalStreamsInfo,\r
+    kMainStreamsInfo,\r
+    kFilesInfo,\r
+    \r
+    kPackInfo,\r
+    kUnpackInfo,\r
+    kSubStreamsInfo,\r
+\r
+    kSize,\r
+    kCRC,\r
+\r
+    kFolder,\r
+\r
+    kCodersUnpackSize,\r
+    kNumUnpackStream,\r
+\r
+    kEmptyStream,\r
+    kEmptyFile,\r
+    kAnti,\r
+\r
+    kName,\r
+    kCTime,\r
+    kATime,\r
+    kMTime,\r
+    kWinAttributes,\r
+    kComment,\r
+\r
+    kEncodedHeader,\r
+\r
+    kStartPos,\r
+    kDummy\r
+  };\r
+}\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
new file mode 100755 (executable)
index 0000000..f418bb1
--- /dev/null
@@ -0,0 +1,1276 @@
+// 7zIn.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../../C/7zCrc.h"\r
+#include "../../../../C/CpuArch.h"\r
+\r
+#include "../../Common/StreamObjects.h"\r
+#include "../../Common/StreamUtils.h"\r
+\r
+#include "7zDecode.h"\r
+#include "7zIn.h"\r
+\r
+#define Get16(p) GetUi16(p)\r
+#define Get32(p) GetUi32(p)\r
+#define Get64(p) GetUi64(p)\r
+\r
+// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader\r
+#ifndef _SFX\r
+#define FORMAT_7Z_RECOVERY\r
+#endif\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+static void BoolVector_Fill_False(CBoolVector &v, int size)\r
+{\r
+  v.Clear();\r
+  v.Reserve(size);\r
+  for (int i = 0; i < size; i++)\r
+    v.Add(false);\r
+}\r
+\r
+static bool BoolVector_GetAndSet(CBoolVector &v, UInt32 index)\r
+{\r
+  if (index >= (UInt32)v.Size())\r
+    return true;\r
+  bool res = v[index];\r
+  v[index] = true;\r
+  return res;\r
+}\r
+\r
+bool CFolder::CheckStructure() const\r
+{\r
+  const int kNumCodersMax = sizeof(UInt32) * 8; // don't change it\r
+  const int kMaskSize = sizeof(UInt32) * 8; // it must be >= kNumCodersMax\r
+  const int kNumBindsMax = 32;\r
+\r
+  if (Coders.Size() > kNumCodersMax || BindPairs.Size() > kNumBindsMax)\r
+    return false;\r
+\r
+  {\r
+    CBoolVector v;\r
+    BoolVector_Fill_False(v, BindPairs.Size() + PackStreams.Size());\r
+    \r
+    int i;\r
+    for (i = 0; i < BindPairs.Size(); i++)\r
+      if (BoolVector_GetAndSet(v, BindPairs[i].InIndex))\r
+        return false;\r
+    for (i = 0; i < PackStreams.Size(); i++)\r
+      if (BoolVector_GetAndSet(v, PackStreams[i]))\r
+        return false;\r
+    \r
+    BoolVector_Fill_False(v, UnpackSizes.Size());\r
+    for (i = 0; i < BindPairs.Size(); i++)\r
+      if (BoolVector_GetAndSet(v, BindPairs[i].OutIndex))\r
+        return false;\r
+  }\r
+  \r
+  UInt32 mask[kMaskSize];\r
+  int i;\r
+  for (i = 0; i < kMaskSize; i++)\r
+    mask[i] = 0;\r
+\r
+  {\r
+    CIntVector inStreamToCoder, outStreamToCoder;\r
+    for (i = 0; i < Coders.Size(); i++)\r
+    {\r
+      CNum j;\r
+      const CCoderInfo &coder = Coders[i];\r
+      for (j = 0; j < coder.NumInStreams; j++)\r
+        inStreamToCoder.Add(i);\r
+      for (j = 0; j < coder.NumOutStreams; j++)\r
+        outStreamToCoder.Add(i);\r
+    }\r
+    \r
+    for (i = 0; i < BindPairs.Size(); i++)\r
+    {\r
+      const CBindPair &bp = BindPairs[i];\r
+      mask[inStreamToCoder[bp.InIndex]] |= (1 << outStreamToCoder[bp.OutIndex]);\r
+    }\r
+  }\r
+  \r
+  for (i = 0; i < kMaskSize; i++)\r
+    for (int j = 0; j < kMaskSize; j++)\r
+      if (((1 << j) & mask[i]) != 0)\r
+        mask[i] |= mask[j];\r
+\r
+  for (i = 0; i < kMaskSize; i++)\r
+    if (((1 << i) & mask[i]) != 0)\r
+      return false;\r
+\r
+  return true;\r
+}\r
+\r
+class CInArchiveException {};\r
+\r
+static void ThrowException() { throw CInArchiveException(); }\r
+static inline void ThrowEndOfData()   { ThrowException(); }\r
+static inline void ThrowUnsupported() { ThrowException(); }\r
+static inline void ThrowIncorrect()   { ThrowException(); }\r
+static inline void ThrowUnsupportedVersion() { ThrowException(); }\r
+\r
+/*\r
+class CInArchiveException\r
+{\r
+public:\r
+  enum CCauseType\r
+  {\r
+    kUnsupportedVersion = 0,\r
+    kUnsupported,\r
+    kIncorrect,\r
+    kEndOfData\r
+  } Cause;\r
+  CInArchiveException(CCauseType cause): Cause(cause) {};\r
+};\r
+\r
+static void ThrowException(CInArchiveException::CCauseType c) { throw CInArchiveException(c); }\r
+static void ThrowEndOfData()   { ThrowException(CInArchiveException::kEndOfData); }\r
+static void ThrowUnsupported() { ThrowException(CInArchiveException::kUnsupported); }\r
+static void ThrowIncorrect()   { ThrowException(CInArchiveException::kIncorrect); }\r
+static void ThrowUnsupportedVersion() { ThrowException(CInArchiveException::kUnsupportedVersion); }\r
+*/\r
+\r
+class CStreamSwitch\r
+{\r
+  CInArchive *_archive;\r
+  bool _needRemove;\r
+public:\r
+  CStreamSwitch(): _needRemove(false) {}\r
+  ~CStreamSwitch() { Remove(); }\r
+  void Remove();\r
+  void Set(CInArchive *archive, const Byte *data, size_t size);\r
+  void Set(CInArchive *archive, const CByteBuffer &byteBuffer);\r
+  void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);\r
+};\r
+\r
+void CStreamSwitch::Remove()\r
+{\r
+  if (_needRemove)\r
+  {\r
+    _archive->DeleteByteStream();\r
+    _needRemove = false;\r
+  }\r
+}\r
+\r
+void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size)\r
+{\r
+  Remove();\r
+  _archive = archive;\r
+  _archive->AddByteStream(data, size);\r
+  _needRemove = true;\r
+}\r
+\r
+void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)\r
+{\r
+  Set(archive, byteBuffer, byteBuffer.GetCapacity());\r
+}\r
+\r
+void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)\r
+{\r
+  Remove();\r
+  Byte external = archive->ReadByte();\r
+  if (external != 0)\r
+  {\r
+    int dataIndex = (int)archive->ReadNum();\r
+    if (dataIndex < 0 || dataIndex >= dataVector->Size())\r
+      ThrowIncorrect();\r
+    Set(archive, (*dataVector)[dataIndex]);\r
+  }\r
+}\r
+\r
+Byte CInByte2::ReadByte()\r
+{\r
+  if (_pos >= _size)\r
+    ThrowEndOfData();\r
+  return _buffer[_pos++];\r
+}\r
+\r
+void CInByte2::ReadBytes(Byte *data, size_t size)\r
+{\r
+  if (size > _size - _pos)\r
+    ThrowEndOfData();\r
+  for (size_t i = 0; i < size; i++)\r
+    data[i] = _buffer[_pos++];\r
+}\r
+\r
+void CInByte2::SkipData(UInt64 size)\r
+{\r
+  if (size > _size - _pos)\r
+    ThrowEndOfData();\r
+  _pos += (size_t)size;\r
+}\r
+\r
+void CInByte2::SkipData()\r
+{\r
+  SkipData(ReadNumber());\r
+}\r
+\r
+UInt64 CInByte2::ReadNumber()\r
+{\r
+  if (_pos >= _size)\r
+    ThrowEndOfData();\r
+  Byte firstByte = _buffer[_pos++];\r
+  Byte mask = 0x80;\r
+  UInt64 value = 0;\r
+  for (int i = 0; i < 8; i++)\r
+  {\r
+    if ((firstByte & mask) == 0)\r
+    {\r
+      UInt64 highPart = firstByte & (mask - 1);\r
+      value += (highPart << (i * 8));\r
+      return value;\r
+    }\r
+    if (_pos >= _size)\r
+      ThrowEndOfData();\r
+    value |= ((UInt64)_buffer[_pos++] << (8 * i));\r
+    mask >>= 1;\r
+  }\r
+  return value;\r
+}\r
+\r
+CNum CInByte2::ReadNum()\r
+{\r
+  UInt64 value = ReadNumber();\r
+  if (value > kNumMax)\r
+    ThrowUnsupported();\r
+  return (CNum)value;\r
+}\r
+\r
+UInt32 CInByte2::ReadUInt32()\r
+{\r
+  if (_pos + 4 > _size)\r
+    ThrowEndOfData();\r
+  UInt32 res = Get32(_buffer + _pos);\r
+  _pos += 4;\r
+  return res;\r
+}\r
+\r
+UInt64 CInByte2::ReadUInt64()\r
+{\r
+  if (_pos + 8 > _size)\r
+    ThrowEndOfData();\r
+  UInt64 res = Get64(_buffer + _pos);\r
+  _pos += 8;\r
+  return res;\r
+}\r
+\r
+void CInByte2::ReadString(UString &s)\r
+{\r
+  const Byte *buf = _buffer + _pos;\r
+  size_t rem = (_size - _pos) / 2 * 2;\r
+  {\r
+    size_t i;\r
+    for (i = 0; i < rem; i += 2)\r
+      if (buf[i] == 0 && buf[i + 1] == 0)\r
+        break;\r
+    if (i == rem)\r
+      ThrowEndOfData();\r
+    rem = i;\r
+  }\r
+  int len = (int)(rem / 2);\r
+  if (len < 0 || (size_t)len * 2 != rem)\r
+    ThrowUnsupported();\r
+  wchar_t *p = s.GetBuffer(len);\r
+  int i;\r
+  for (i = 0; i < len; i++, buf += 2)\r
+    p[i] = (wchar_t)Get16(buf);\r
+  s.ReleaseBuffer(len);\r
+  _pos += rem + 2;\r
+}\r
+\r
+static inline bool TestSignature(const Byte *p)\r
+{\r
+  for (int i = 0; i < kSignatureSize; i++)\r
+    if (p[i] != kSignature[i])\r
+      return false;\r
+  return CrcCalc(p + 12, 20) == GetUi32(p + 8);\r
+}\r
+\r
+#ifdef FORMAT_7Z_RECOVERY\r
+static inline bool TestSignature2(const Byte *p)\r
+{\r
+  int i;\r
+  for (i = 0; i < kSignatureSize; i++)\r
+    if (p[i] != kSignature[i])\r
+      return false;\r
+  if (CrcCalc(p + 12, 20) == GetUi32(p + 8))\r
+    return true;\r
+  for (i = 8; i < kHeaderSize; i++)\r
+    if (p[i] != 0)\r
+      return false;\r
+  return (p[6] != 0 || p[7] != 0);\r
+}\r
+#else\r
+#define TestSignature2(p) TestSignature(p)\r
+#endif\r
+\r
+HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)\r
+{\r
+  RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));\r
+\r
+  if (TestSignature2(_header))\r
+    return S_OK;\r
+\r
+  CByteBuffer byteBuffer;\r
+  const UInt32 kBufferSize = (1 << 16);\r
+  byteBuffer.SetCapacity(kBufferSize);\r
+  Byte *buffer = byteBuffer;\r
+  UInt32 numPrevBytes = kHeaderSize;\r
+  memcpy(buffer, _header, kHeaderSize);\r
+  UInt64 curTestPos = _arhiveBeginStreamPosition;\r
+  for (;;)\r
+  {\r
+    if (searchHeaderSizeLimit != NULL)\r
+      if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)\r
+        break;\r
+    do\r
+    {\r
+      UInt32 numReadBytes = kBufferSize - numPrevBytes;\r
+      UInt32 processedSize;\r
+      RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));\r
+      numPrevBytes += processedSize;\r
+      if (processedSize == 0)\r
+        return S_FALSE;\r
+    }\r
+    while (numPrevBytes <= kHeaderSize);\r
+    UInt32 numTests = numPrevBytes - kHeaderSize;\r
+    for (UInt32 pos = 0; pos < numTests; pos++)\r
+    {\r
+      for (; buffer[pos] != '7' && pos < numTests; pos++);\r
+      if (pos == numTests)\r
+        break;\r
+      if (TestSignature(buffer + pos))\r
+      {\r
+        memcpy(_header, buffer + pos, kHeaderSize);\r
+        curTestPos += pos;\r
+        _arhiveBeginStreamPosition = curTestPos;\r
+        return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);\r
+      }\r
+    }\r
+    curTestPos += numTests;\r
+    numPrevBytes -= numTests;\r
+    memmove(buffer, buffer + numTests, numPrevBytes);\r
+  }\r
+  return S_FALSE;\r
+}\r
+\r
+// S_FALSE means that file is not archive\r
+HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)\r
+{\r
+  HeadersSize = 0;\r
+  Close();\r
+  RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))\r
+  RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));\r
+  _stream = stream;\r
+  return S_OK;\r
+}\r
+  \r
+void CInArchive::Close()\r
+{\r
+  _stream.Release();\r
+}\r
+\r
+void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)\r
+{\r
+  for (;;)\r
+  {\r
+    if (ReadID() == NID::kEnd)\r
+      break;\r
+    SkipData();\r
+  }\r
+}\r
+\r
+void CInArchive::GetNextFolderItem(CFolder &folder)\r
+{\r
+  CNum numCoders = ReadNum();\r
+\r
+  folder.Coders.Clear();\r
+  folder.Coders.Reserve((int)numCoders);\r
+  CNum numInStreams = 0;\r
+  CNum numOutStreams = 0;\r
+  CNum i;\r
+  for (i = 0; i < numCoders; i++)\r
+  {\r
+    folder.Coders.Add(CCoderInfo());\r
+    CCoderInfo &coder = folder.Coders.Back();\r
+\r
+    {\r
+      Byte mainByte = ReadByte();\r
+      int idSize = (mainByte & 0xF);\r
+      Byte longID[15];\r
+      ReadBytes(longID, idSize);\r
+      if (idSize > 8)\r
+        ThrowUnsupported();\r
+      UInt64 id = 0;\r
+      for (int j = 0; j < idSize; j++)\r
+        id |= (UInt64)longID[idSize - 1 - j] << (8 * j);\r
+      coder.MethodID = id;\r
+\r
+      if ((mainByte & 0x10) != 0)\r
+      {\r
+        coder.NumInStreams = ReadNum();\r
+        coder.NumOutStreams = ReadNum();\r
+      }\r
+      else\r
+      {\r
+        coder.NumInStreams = 1;\r
+        coder.NumOutStreams = 1;\r
+      }\r
+      if ((mainByte & 0x20) != 0)\r
+      {\r
+        CNum propsSize = ReadNum();\r
+        coder.Props.SetCapacity((size_t)propsSize);\r
+        ReadBytes((Byte *)coder.Props, (size_t)propsSize);\r
+      }\r
+      if ((mainByte & 0x80) != 0)\r
+        ThrowUnsupported();\r
+    }\r
+    numInStreams += coder.NumInStreams;\r
+    numOutStreams += coder.NumOutStreams;\r
+  }\r
+\r
+  CNum numBindPairs = numOutStreams - 1;\r
+  folder.BindPairs.Clear();\r
+  folder.BindPairs.Reserve(numBindPairs);\r
+  for (i = 0; i < numBindPairs; i++)\r
+  {\r
+    CBindPair bp;\r
+    bp.InIndex = ReadNum();\r
+    bp.OutIndex = ReadNum();\r
+    folder.BindPairs.Add(bp);\r
+  }\r
+\r
+  if (numInStreams < numBindPairs)\r
+    ThrowUnsupported();\r
+  CNum numPackStreams = numInStreams - numBindPairs;\r
+  folder.PackStreams.Reserve(numPackStreams);\r
+  if (numPackStreams == 1)\r
+  {\r
+    for (i = 0; i < numInStreams; i++)\r
+      if (folder.FindBindPairForInStream(i) < 0)\r
+      {\r
+        folder.PackStreams.Add(i);\r
+        break;\r
+      }\r
+    if (folder.PackStreams.Size() != 1)\r
+      ThrowUnsupported();\r
+  }\r
+  else\r
+    for (i = 0; i < numPackStreams; i++)\r
+      folder.PackStreams.Add(ReadNum());\r
+}\r
+\r
+void CInArchive::WaitAttribute(UInt64 attribute)\r
+{\r
+  for (;;)\r
+  {\r
+    UInt64 type = ReadID();\r
+    if (type == attribute)\r
+      return;\r
+    if (type == NID::kEnd)\r
+      ThrowIncorrect();\r
+    SkipData();\r
+  }\r
+}\r
+\r
+void CInArchive::ReadHashDigests(int numItems,\r
+    CBoolVector &digestsDefined,\r
+    CRecordVector<UInt32> &digests)\r
+{\r
+  ReadBoolVector2(numItems, digestsDefined);\r
+  digests.Clear();\r
+  digests.Reserve(numItems);\r
+  for (int i = 0; i < numItems; i++)\r
+  {\r
+    UInt32 crc = 0;\r
+    if (digestsDefined[i])\r
+      crc = ReadUInt32();\r
+    digests.Add(crc);\r
+  }\r
+}\r
+\r
+void CInArchive::ReadPackInfo(\r
+    UInt64 &dataOffset,\r
+    CRecordVector<UInt64> &packSizes,\r
+    CBoolVector &packCRCsDefined,\r
+    CRecordVector<UInt32> &packCRCs)\r
+{\r
+  dataOffset = ReadNumber();\r
+  CNum numPackStreams = ReadNum();\r
+\r
+  WaitAttribute(NID::kSize);\r
+  packSizes.Clear();\r
+  packSizes.Reserve(numPackStreams);\r
+  for (CNum i = 0; i < numPackStreams; i++)\r
+    packSizes.Add(ReadNumber());\r
+\r
+  UInt64 type;\r
+  for (;;)\r
+  {\r
+    type = ReadID();\r
+    if (type == NID::kEnd)\r
+      break;\r
+    if (type == NID::kCRC)\r
+    {\r
+      ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);\r
+      continue;\r
+    }\r
+    SkipData();\r
+  }\r
+  if (packCRCsDefined.IsEmpty())\r
+  {\r
+    BoolVector_Fill_False(packCRCsDefined, numPackStreams);\r
+    packCRCs.Reserve(numPackStreams);\r
+    packCRCs.Clear();\r
+    for (CNum i = 0; i < numPackStreams; i++)\r
+      packCRCs.Add(0);\r
+  }\r
+}\r
+\r
+void CInArchive::ReadUnpackInfo(\r
+    const CObjectVector<CByteBuffer> *dataVector,\r
+    CObjectVector<CFolder> &folders)\r
+{\r
+  WaitAttribute(NID::kFolder);\r
+  CNum numFolders = ReadNum();\r
+\r
+  {\r
+    CStreamSwitch streamSwitch;\r
+    streamSwitch.Set(this, dataVector);\r
+    folders.Clear();\r
+    folders.Reserve(numFolders);\r
+    for (CNum i = 0; i < numFolders; i++)\r
+    {\r
+      folders.Add(CFolder());\r
+      GetNextFolderItem(folders.Back());\r
+    }\r
+  }\r
+\r
+  WaitAttribute(NID::kCodersUnpackSize);\r
+\r
+  CNum i;\r
+  for (i = 0; i < numFolders; i++)\r
+  {\r
+    CFolder &folder = folders[i];\r
+    CNum numOutStreams = folder.GetNumOutStreams();\r
+    folder.UnpackSizes.Reserve(numOutStreams);\r
+    for (CNum j = 0; j < numOutStreams; j++)\r
+      folder.UnpackSizes.Add(ReadNumber());\r
+  }\r
+\r
+  for (;;)\r
+  {\r
+    UInt64 type = ReadID();\r
+    if (type == NID::kEnd)\r
+      return;\r
+    if (type == NID::kCRC)\r
+    {\r
+      CBoolVector crcsDefined;\r
+      CRecordVector<UInt32> crcs;\r
+      ReadHashDigests(numFolders, crcsDefined, crcs);\r
+      for (i = 0; i < numFolders; i++)\r
+      {\r
+        CFolder &folder = folders[i];\r
+        folder.UnpackCRCDefined = crcsDefined[i];\r
+        folder.UnpackCRC = crcs[i];\r
+      }\r
+      continue;\r
+    }\r
+    SkipData();\r
+  }\r
+}\r
+\r
+void CInArchive::ReadSubStreamsInfo(\r
+    const CObjectVector<CFolder> &folders,\r
+    CRecordVector<CNum> &numUnpackStreamsInFolders,\r
+    CRecordVector<UInt64> &unpackSizes,\r
+    CBoolVector &digestsDefined,\r
+    CRecordVector<UInt32> &digests)\r
+{\r
+  numUnpackStreamsInFolders.Clear();\r
+  numUnpackStreamsInFolders.Reserve(folders.Size());\r
+  UInt64 type;\r
+  for (;;)\r
+  {\r
+    type = ReadID();\r
+    if (type == NID::kNumUnpackStream)\r
+    {\r
+      for (int i = 0; i < folders.Size(); i++)\r
+        numUnpackStreamsInFolders.Add(ReadNum());\r
+      continue;\r
+    }\r
+    if (type == NID::kCRC || type == NID::kSize)\r
+      break;\r
+    if (type == NID::kEnd)\r
+      break;\r
+    SkipData();\r
+  }\r
+\r
+  if (numUnpackStreamsInFolders.IsEmpty())\r
+    for (int i = 0; i < folders.Size(); i++)\r
+      numUnpackStreamsInFolders.Add(1);\r
+\r
+  int i;\r
+  for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)\r
+  {\r
+    // v3.13 incorrectly worked with empty folders\r
+    // v4.07: we check that folder is empty\r
+    CNum numSubstreams = numUnpackStreamsInFolders[i];\r
+    if (numSubstreams == 0)\r
+      continue;\r
+    UInt64 sum = 0;\r
+    for (CNum j = 1; j < numSubstreams; j++)\r
+      if (type == NID::kSize)\r
+      {\r
+        UInt64 size = ReadNumber();\r
+        unpackSizes.Add(size);\r
+        sum += size;\r
+      }\r
+    unpackSizes.Add(folders[i].GetUnpackSize() - sum);\r
+  }\r
+  if (type == NID::kSize)\r
+    type = ReadID();\r
+\r
+  int numDigests = 0;\r
+  int numDigestsTotal = 0;\r
+  for (i = 0; i < folders.Size(); i++)\r
+  {\r
+    CNum numSubstreams = numUnpackStreamsInFolders[i];\r
+    if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)\r
+      numDigests += numSubstreams;\r
+    numDigestsTotal += numSubstreams;\r
+  }\r
+\r
+  for (;;)\r
+  {\r
+    if (type == NID::kCRC)\r
+    {\r
+      CBoolVector digestsDefined2;\r
+      CRecordVector<UInt32> digests2;\r
+      ReadHashDigests(numDigests, digestsDefined2, digests2);\r
+      int digestIndex = 0;\r
+      for (i = 0; i < folders.Size(); i++)\r
+      {\r
+        CNum numSubstreams = numUnpackStreamsInFolders[i];\r
+        const CFolder &folder = folders[i];\r
+        if (numSubstreams == 1 && folder.UnpackCRCDefined)\r
+        {\r
+          digestsDefined.Add(true);\r
+          digests.Add(folder.UnpackCRC);\r
+        }\r
+        else\r
+          for (CNum j = 0; j < numSubstreams; j++, digestIndex++)\r
+          {\r
+            digestsDefined.Add(digestsDefined2[digestIndex]);\r
+            digests.Add(digests2[digestIndex]);\r
+          }\r
+      }\r
+    }\r
+    else if (type == NID::kEnd)\r
+    {\r
+      if (digestsDefined.IsEmpty())\r
+      {\r
+        BoolVector_Fill_False(digestsDefined, numDigestsTotal);\r
+        digests.Clear();\r
+        for (int i = 0; i < numDigestsTotal; i++)\r
+          digests.Add(0);\r
+      }\r
+      return;\r
+    }\r
+    else\r
+      SkipData();\r
+    type = ReadID();\r
+  }\r
+}\r
+\r
+void CInArchive::ReadStreamsInfo(\r
+    const CObjectVector<CByteBuffer> *dataVector,\r
+    UInt64 &dataOffset,\r
+    CRecordVector<UInt64> &packSizes,\r
+    CBoolVector &packCRCsDefined,\r
+    CRecordVector<UInt32> &packCRCs,\r
+    CObjectVector<CFolder> &folders,\r
+    CRecordVector<CNum> &numUnpackStreamsInFolders,\r
+    CRecordVector<UInt64> &unpackSizes,\r
+    CBoolVector &digestsDefined,\r
+    CRecordVector<UInt32> &digests)\r
+{\r
+  for (;;)\r
+  {\r
+    UInt64 type = ReadID();\r
+    if (type > ((UInt32)1 << 30))\r
+      ThrowIncorrect();\r
+    switch((UInt32)type)\r
+    {\r
+      case NID::kEnd:\r
+        return;\r
+      case NID::kPackInfo:\r
+      {\r
+        ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);\r
+        break;\r
+      }\r
+      case NID::kUnpackInfo:\r
+      {\r
+        ReadUnpackInfo(dataVector, folders);\r
+        break;\r
+      }\r
+      case NID::kSubStreamsInfo:\r
+      {\r
+        ReadSubStreamsInfo(folders, numUnpackStreamsInFolders,\r
+            unpackSizes, digestsDefined, digests);\r
+        break;\r
+      }\r
+      default:\r
+        ThrowIncorrect();\r
+    }\r
+  }\r
+}\r
+\r
+void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)\r
+{\r
+  v.Clear();\r
+  v.Reserve(numItems);\r
+  Byte b = 0;\r
+  Byte mask = 0;\r
+  for (int i = 0; i < numItems; i++)\r
+  {\r
+    if (mask == 0)\r
+    {\r
+      b = ReadByte();\r
+      mask = 0x80;\r
+    }\r
+    v.Add((b & mask) != 0);\r
+    mask >>= 1;\r
+  }\r
+}\r
+\r
+void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)\r
+{\r
+  Byte allAreDefined = ReadByte();\r
+  if (allAreDefined == 0)\r
+  {\r
+    ReadBoolVector(numItems, v);\r
+    return;\r
+  }\r
+  v.Clear();\r
+  v.Reserve(numItems);\r
+  for (int i = 0; i < numItems; i++)\r
+    v.Add(true);\r
+}\r
+\r
+void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,\r
+    CUInt64DefVector &v, int numFiles)\r
+{\r
+  ReadBoolVector2(numFiles, v.Defined);\r
+\r
+  CStreamSwitch streamSwitch;\r
+  streamSwitch.Set(this, &dataVector);\r
+  v.Values.Reserve(numFiles);\r
+\r
+  for (int i = 0; i < numFiles; i++)\r
+  {\r
+    UInt64 t = 0;\r
+    if (v.Defined[i])\r
+      t = ReadUInt64();\r
+    v.Values.Add(t);\r
+  }\r
+}\r
+\r
+HRESULT CInArchive::ReadAndDecodePackedStreams(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    UInt64 baseOffset,\r
+    UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector\r
+    #ifndef _NO_CRYPTO\r
+    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+    #endif\r
+    )\r
+{\r
+  CRecordVector<UInt64> packSizes;\r
+  CBoolVector packCRCsDefined;\r
+  CRecordVector<UInt32> packCRCs;\r
+  CObjectVector<CFolder> folders;\r
+  \r
+  CRecordVector<CNum> numUnpackStreamsInFolders;\r
+  CRecordVector<UInt64> unpackSizes;\r
+  CBoolVector digestsDefined;\r
+  CRecordVector<UInt32> digests;\r
+  \r
+  ReadStreamsInfo(NULL,\r
+    dataOffset,\r
+    packSizes,\r
+    packCRCsDefined,\r
+    packCRCs,\r
+    folders,\r
+    numUnpackStreamsInFolders,\r
+    unpackSizes,\r
+    digestsDefined,\r
+    digests);\r
+  \r
+  // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;\r
+  \r
+  CNum packIndex = 0;\r
+  CDecoder decoder(\r
+    #ifdef _ST_MODE\r
+    false\r
+    #else\r
+    true\r
+    #endif\r
+    );\r
+  UInt64 dataStartPos = baseOffset + dataOffset;\r
+  for (int i = 0; i < folders.Size(); i++)\r
+  {\r
+    const CFolder &folder = folders[i];\r
+    dataVector.Add(CByteBuffer());\r
+    CByteBuffer &data = dataVector.Back();\r
+    UInt64 unpackSize64 = folder.GetUnpackSize();\r
+    size_t unpackSize = (size_t)unpackSize64;\r
+    if (unpackSize != unpackSize64)\r
+      ThrowUnsupported();\r
+    data.SetCapacity(unpackSize);\r
+    \r
+    CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;\r
+    CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;\r
+    outStreamSpec->Init(data, unpackSize);\r
+    \r
+    HRESULT result = decoder.Decode(\r
+      EXTERNAL_CODECS_LOC_VARS\r
+      _stream, dataStartPos,\r
+      &packSizes[packIndex], folder, outStream, NULL\r
+      #ifndef _NO_CRYPTO\r
+      , getTextPassword, passwordIsDefined\r
+      #endif\r
+      #if !defined(_7ZIP_ST) && !defined(_SFX)\r
+      , false, 1\r
+      #endif\r
+      );\r
+    RINOK(result);\r
+    \r
+    if (folder.UnpackCRCDefined)\r
+      if (CrcCalc(data, unpackSize) != folder.UnpackCRC)\r
+        ThrowIncorrect();\r
+    for (int j = 0; j < folder.PackStreams.Size(); j++)\r
+    {\r
+      UInt64 packSize = packSizes[packIndex++];\r
+      dataStartPos += packSize;\r
+      HeadersSize += packSize;\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CInArchive::ReadHeader(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    CArchiveDatabaseEx &db\r
+    #ifndef _NO_CRYPTO\r
+    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+    #endif\r
+    )\r
+{\r
+  UInt64 type = ReadID();\r
+\r
+  if (type == NID::kArchiveProperties)\r
+  {\r
+    ReadArchiveProperties(db.ArchiveInfo);\r
+    type = ReadID();\r
+  }\r
\r
+  CObjectVector<CByteBuffer> dataVector;\r
+  \r
+  if (type == NID::kAdditionalStreamsInfo)\r
+  {\r
+    HRESULT result = ReadAndDecodePackedStreams(\r
+        EXTERNAL_CODECS_LOC_VARS\r
+        db.ArchiveInfo.StartPositionAfterHeader,\r
+        db.ArchiveInfo.DataStartPosition2,\r
+        dataVector\r
+        #ifndef _NO_CRYPTO\r
+        , getTextPassword, passwordIsDefined\r
+        #endif\r
+        );\r
+    RINOK(result);\r
+    db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;\r
+    type = ReadID();\r
+  }\r
+\r
+  CRecordVector<UInt64> unpackSizes;\r
+  CBoolVector digestsDefined;\r
+  CRecordVector<UInt32> digests;\r
+  \r
+  if (type == NID::kMainStreamsInfo)\r
+  {\r
+    ReadStreamsInfo(&dataVector,\r
+        db.ArchiveInfo.DataStartPosition,\r
+        db.PackSizes,\r
+        db.PackCRCsDefined,\r
+        db.PackCRCs,\r
+        db.Folders,\r
+        db.NumUnpackStreamsVector,\r
+        unpackSizes,\r
+        digestsDefined,\r
+        digests);\r
+    db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader;\r
+    type = ReadID();\r
+  }\r
+  else\r
+  {\r
+    for (int i = 0; i < db.Folders.Size(); i++)\r
+    {\r
+      db.NumUnpackStreamsVector.Add(1);\r
+      CFolder &folder = db.Folders[i];\r
+      unpackSizes.Add(folder.GetUnpackSize());\r
+      digestsDefined.Add(folder.UnpackCRCDefined);\r
+      digests.Add(folder.UnpackCRC);\r
+    }\r
+  }\r
+\r
+  db.Files.Clear();\r
+\r
+  if (type == NID::kEnd)\r
+    return S_OK;\r
+  if (type != NID::kFilesInfo)\r
+    ThrowIncorrect();\r
+  \r
+  CNum numFiles = ReadNum();\r
+  db.Files.Reserve(numFiles);\r
+  CNum i;\r
+  for (i = 0; i < numFiles; i++)\r
+    db.Files.Add(CFileItem());\r
+\r
+  db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);\r
+  if (!db.PackSizes.IsEmpty())\r
+    db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);\r
+  if (numFiles > 0  && !digests.IsEmpty())\r
+    db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);\r
+\r
+  CBoolVector emptyStreamVector;\r
+  BoolVector_Fill_False(emptyStreamVector, (int)numFiles);\r
+  CBoolVector emptyFileVector;\r
+  CBoolVector antiFileVector;\r
+  CNum numEmptyStreams = 0;\r
+\r
+  for (;;)\r
+  {\r
+    UInt64 type = ReadID();\r
+    if (type == NID::kEnd)\r
+      break;\r
+    UInt64 size = ReadNumber();\r
+    size_t ppp = _inByteBack->_pos;\r
+    bool addPropIdToList = true;\r
+    bool isKnownType = true;\r
+    if (type > ((UInt32)1 << 30))\r
+      isKnownType = false;\r
+    else switch((UInt32)type)\r
+    {\r
+      case NID::kName:\r
+      {\r
+        CStreamSwitch streamSwitch;\r
+        streamSwitch.Set(this, &dataVector);\r
+        for (int i = 0; i < db.Files.Size(); i++)\r
+          _inByteBack->ReadString(db.Files[i].Name);\r
+        break;\r
+      }\r
+      case NID::kWinAttributes:\r
+      {\r
+        CBoolVector boolVector;\r
+        ReadBoolVector2(db.Files.Size(), boolVector);\r
+        CStreamSwitch streamSwitch;\r
+        streamSwitch.Set(this, &dataVector);\r
+        for (i = 0; i < numFiles; i++)\r
+        {\r
+          CFileItem &file = db.Files[i];\r
+          file.AttribDefined = boolVector[i];\r
+          if (file.AttribDefined)\r
+            file.Attrib = ReadUInt32();\r
+        }\r
+        break;\r
+      }\r
+      case NID::kEmptyStream:\r
+      {\r
+        ReadBoolVector(numFiles, emptyStreamVector);\r
+        for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)\r
+          if (emptyStreamVector[i])\r
+            numEmptyStreams++;\r
+\r
+        BoolVector_Fill_False(emptyFileVector, numEmptyStreams);\r
+        BoolVector_Fill_False(antiFileVector, numEmptyStreams);\r
+\r
+        break;\r
+      }\r
+      case NID::kEmptyFile:  ReadBoolVector(numEmptyStreams, emptyFileVector); break;\r
+      case NID::kAnti:  ReadBoolVector(numEmptyStreams, antiFileVector); break;\r
+      case NID::kStartPos:  ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break;\r
+      case NID::kCTime:  ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break;\r
+      case NID::kATime:  ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break;\r
+      case NID::kMTime:  ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break;\r
+      case NID::kDummy:\r
+      {\r
+        for (UInt64 j = 0; j < size; j++)\r
+          if (ReadByte() != 0)\r
+            ThrowIncorrect();\r
+        addPropIdToList = false;\r
+        break;\r
+      }\r
+      default:\r
+        addPropIdToList = isKnownType = false;\r
+    }\r
+    if (isKnownType)\r
+    {\r
+      if(addPropIdToList)\r
+        db.ArchiveInfo.FileInfoPopIDs.Add(type);\r
+    }\r
+    else\r
+      SkipData(size);\r
+    bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 ||\r
+        db.ArchiveInfo.Version.Minor > 2);\r
+    if (checkRecordsSize && _inByteBack->_pos - ppp != size)\r
+      ThrowIncorrect();\r
+  }\r
+\r
+  CNum emptyFileIndex = 0;\r
+  CNum sizeIndex = 0;\r
+\r
+  CNum numAntiItems = 0;\r
+  for (i = 0; i < numEmptyStreams; i++)\r
+    if (antiFileVector[i])\r
+      numAntiItems++;\r
+    \r
+  for (i = 0; i < numFiles; i++)\r
+  {\r
+    CFileItem &file = db.Files[i];\r
+    bool isAnti;\r
+    file.HasStream = !emptyStreamVector[i];\r
+    if (file.HasStream)\r
+    {\r
+      file.IsDir = false;\r
+      isAnti = false;\r
+      file.Size = unpackSizes[sizeIndex];\r
+      file.Crc = digests[sizeIndex];\r
+      file.CrcDefined = digestsDefined[sizeIndex];\r
+      sizeIndex++;\r
+    }\r
+    else\r
+    {\r
+      file.IsDir = !emptyFileVector[emptyFileIndex];\r
+      isAnti = antiFileVector[emptyFileIndex];\r
+      emptyFileIndex++;\r
+      file.Size = 0;\r
+      file.CrcDefined = false;\r
+    }\r
+    if (numAntiItems != 0)\r
+      db.IsAnti.Add(isAnti);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+\r
+void CArchiveDatabaseEx::FillFolderStartPackStream()\r
+{\r
+  FolderStartPackStreamIndex.Clear();\r
+  FolderStartPackStreamIndex.Reserve(Folders.Size());\r
+  CNum startPos = 0;\r
+  for (int i = 0; i < Folders.Size(); i++)\r
+  {\r
+    FolderStartPackStreamIndex.Add(startPos);\r
+    startPos += (CNum)Folders[i].PackStreams.Size();\r
+  }\r
+}\r
+\r
+void CArchiveDatabaseEx::FillStartPos()\r
+{\r
+  PackStreamStartPositions.Clear();\r
+  PackStreamStartPositions.Reserve(PackSizes.Size());\r
+  UInt64 startPos = 0;\r
+  for (int i = 0; i < PackSizes.Size(); i++)\r
+  {\r
+    PackStreamStartPositions.Add(startPos);\r
+    startPos += PackSizes[i];\r
+  }\r
+}\r
+\r
+void CArchiveDatabaseEx::FillFolderStartFileIndex()\r
+{\r
+  FolderStartFileIndex.Clear();\r
+  FolderStartFileIndex.Reserve(Folders.Size());\r
+  FileIndexToFolderIndexMap.Clear();\r
+  FileIndexToFolderIndexMap.Reserve(Files.Size());\r
+  \r
+  int folderIndex = 0;\r
+  CNum indexInFolder = 0;\r
+  for (int i = 0; i < Files.Size(); i++)\r
+  {\r
+    const CFileItem &file = Files[i];\r
+    bool emptyStream = !file.HasStream;\r
+    if (emptyStream && indexInFolder == 0)\r
+    {\r
+      FileIndexToFolderIndexMap.Add(kNumNoIndex);\r
+      continue;\r
+    }\r
+    if (indexInFolder == 0)\r
+    {\r
+      // v3.13 incorrectly worked with empty folders\r
+      // v4.07: Loop for skipping empty folders\r
+      for (;;)\r
+      {\r
+        if (folderIndex >= Folders.Size())\r
+          ThrowIncorrect();\r
+        FolderStartFileIndex.Add(i); // check it\r
+        if (NumUnpackStreamsVector[folderIndex] != 0)\r
+          break;\r
+        folderIndex++;\r
+      }\r
+    }\r
+    FileIndexToFolderIndexMap.Add(folderIndex);\r
+    if (emptyStream)\r
+      continue;\r
+    indexInFolder++;\r
+    if (indexInFolder >= NumUnpackStreamsVector[folderIndex])\r
+    {\r
+      folderIndex++;\r
+      indexInFolder = 0;\r
+    }\r
+  }\r
+}\r
+\r
+HRESULT CInArchive::ReadDatabase2(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    CArchiveDatabaseEx &db\r
+    #ifndef _NO_CRYPTO\r
+    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+    #endif\r
+    )\r
+{\r
+  db.Clear();\r
+  db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;\r
+\r
+  db.ArchiveInfo.Version.Major = _header[6];\r
+  db.ArchiveInfo.Version.Minor = _header[7];\r
+\r
+  if (db.ArchiveInfo.Version.Major != kMajorVersion)\r
+    ThrowUnsupportedVersion();\r
+\r
+  UInt32 crcFromArchive = Get32(_header + 8);\r
+  UInt64 nextHeaderOffset = Get64(_header + 0xC);\r
+  UInt64 nextHeaderSize = Get64(_header + 0x14);\r
+  UInt32 nextHeaderCRC = Get32(_header + 0x1C);\r
+  UInt32 crc = CrcCalc(_header + 0xC, 20);\r
+\r
+  #ifdef FORMAT_7Z_RECOVERY\r
+  if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)\r
+  {\r
+    UInt64 cur, cur2;\r
+    RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));\r
+    const int kCheckSize = 500;\r
+    Byte buf[kCheckSize];\r
+    RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2));\r
+    int checkSize = kCheckSize;\r
+    if (cur2 - cur < kCheckSize)\r
+      checkSize = (int)(cur2 - cur);\r
+    RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));\r
+    \r
+    RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));\r
+\r
+    int i;\r
+    for (i = (int)checkSize - 2; i >= 0; i--)\r
+      if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)\r
+        break;\r
+    if (i < 0)\r
+      return S_FALSE;\r
+    nextHeaderSize = checkSize - i;\r
+    nextHeaderOffset = cur2 - cur + i;\r
+    nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);\r
+    RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));\r
+  }\r
+  else\r
+  #endif\r
+  {\r
+    if (crc != crcFromArchive)\r
+      ThrowIncorrect();\r
+  }\r
+\r
+  db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;\r
+\r
+  if (nextHeaderSize == 0)\r
+    return S_OK;\r
+\r
+  if (nextHeaderSize > (UInt64)0xFFFFFFFF)\r
+    return S_FALSE;\r
+\r
+  if ((Int64)nextHeaderOffset < 0)\r
+    return S_FALSE;\r
+\r
+  RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));\r
+\r
+  CByteBuffer buffer2;\r
+  buffer2.SetCapacity((size_t)nextHeaderSize);\r
+\r
+  RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize));\r
+  HeadersSize += kHeaderSize + nextHeaderSize;\r
+  db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;\r
+\r
+  if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)\r
+    ThrowIncorrect();\r
+  \r
+  CStreamSwitch streamSwitch;\r
+  streamSwitch.Set(this, buffer2);\r
+  \r
+  CObjectVector<CByteBuffer> dataVector;\r
+  \r
+  UInt64 type = ReadID();\r
+  if (type != NID::kHeader)\r
+  {\r
+    if (type != NID::kEncodedHeader)\r
+      ThrowIncorrect();\r
+    HRESULT result = ReadAndDecodePackedStreams(\r
+        EXTERNAL_CODECS_LOC_VARS\r
+        db.ArchiveInfo.StartPositionAfterHeader,\r
+        db.ArchiveInfo.DataStartPosition2,\r
+        dataVector\r
+        #ifndef _NO_CRYPTO\r
+        , getTextPassword, passwordIsDefined\r
+        #endif\r
+        );\r
+    RINOK(result);\r
+    if (dataVector.Size() == 0)\r
+      return S_OK;\r
+    if (dataVector.Size() > 1)\r
+      ThrowIncorrect();\r
+    streamSwitch.Remove();\r
+    streamSwitch.Set(this, dataVector.Front());\r
+    if (ReadID() != NID::kHeader)\r
+      ThrowIncorrect();\r
+  }\r
+\r
+  db.HeadersSize = HeadersSize;\r
+\r
+  return ReadHeader(\r
+    EXTERNAL_CODECS_LOC_VARS\r
+    db\r
+    #ifndef _NO_CRYPTO\r
+    , getTextPassword, passwordIsDefined\r
+    #endif\r
+    );\r
+}\r
+\r
+HRESULT CInArchive::ReadDatabase(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    CArchiveDatabaseEx &db\r
+    #ifndef _NO_CRYPTO\r
+    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+    #endif\r
+    )\r
+{\r
+  try\r
+  {\r
+    return ReadDatabase2(\r
+      EXTERNAL_CODECS_LOC_VARS db\r
+      #ifndef _NO_CRYPTO\r
+      , getTextPassword, passwordIsDefined\r
+      #endif\r
+      );\r
+  }\r
+  catch(CInArchiveException &) { return S_FALSE; }\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h
new file mode 100755 (executable)
index 0000000..b82a020
--- /dev/null
@@ -0,0 +1,245 @@
+// 7zIn.h\r
+\r
+#ifndef __7Z_IN_H\r
+#define __7Z_IN_H\r
+\r
+#include "../../../Common/MyCom.h"\r
+\r
+#include "../../IPassword.h"\r
+#include "../../IStream.h"\r
+\r
+#include "../../Common/CreateCoder.h"\r
+#include "../../Common/InBuffer.h"\r
+\r
+#include "7zItem.h"\r
\r
+namespace NArchive {\r
+namespace N7z {\r
+  \r
+struct CInArchiveInfo\r
+{\r
+  CArchiveVersion Version;\r
+  UInt64 StartPosition;\r
+  UInt64 StartPositionAfterHeader;\r
+  UInt64 DataStartPosition;\r
+  UInt64 DataStartPosition2;\r
+  CRecordVector<UInt64> FileInfoPopIDs;\r
+  void Clear()\r
+  {\r
+    FileInfoPopIDs.Clear();\r
+  }\r
+};\r
+\r
+struct CArchiveDatabaseEx: public CArchiveDatabase\r
+{\r
+  CInArchiveInfo ArchiveInfo;\r
+  CRecordVector<UInt64> PackStreamStartPositions;\r
+  CRecordVector<CNum> FolderStartPackStreamIndex;\r
+  CRecordVector<CNum> FolderStartFileIndex;\r
+  CRecordVector<CNum> FileIndexToFolderIndexMap;\r
+\r
+  UInt64 HeadersSize;\r
+  UInt64 PhySize;\r
+\r
+  void Clear()\r
+  {\r
+    CArchiveDatabase::Clear();\r
+    ArchiveInfo.Clear();\r
+    PackStreamStartPositions.Clear();\r
+    FolderStartPackStreamIndex.Clear();\r
+    FolderStartFileIndex.Clear();\r
+    FileIndexToFolderIndexMap.Clear();\r
+\r
+    HeadersSize = 0;\r
+    PhySize = 0;\r
+  }\r
+\r
+  void FillFolderStartPackStream();\r
+  void FillStartPos();\r
+  void FillFolderStartFileIndex();\r
+\r
+  void Fill()\r
+  {\r
+    FillFolderStartPackStream();\r
+    FillStartPos();\r
+    FillFolderStartFileIndex();\r
+  }\r
+  \r
+  UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const\r
+  {\r
+    return ArchiveInfo.DataStartPosition +\r
+        PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];\r
+  }\r
+  \r
+  UInt64 GetFolderFullPackSize(int folderIndex) const\r
+  {\r
+    CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];\r
+    const CFolder &folder = Folders[folderIndex];\r
+    UInt64 size = 0;\r
+    for (int i = 0; i < folder.PackStreams.Size(); i++)\r
+      size += PackSizes[packStreamIndex + i];\r
+    return size;\r
+  }\r
+  \r
+  UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const\r
+  {\r
+    return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];\r
+  }\r
+\r
+  UInt64 GetFilePackSize(CNum fileIndex) const\r
+  {\r
+    CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];\r
+    if (folderIndex != kNumNoIndex)\r
+      if (FolderStartFileIndex[folderIndex] == fileIndex)\r
+        return GetFolderFullPackSize(folderIndex);\r
+    return 0;\r
+  }\r
+};\r
+\r
+class CInByte2\r
+{\r
+  const Byte *_buffer;\r
+  size_t _size;\r
+public:\r
+  size_t _pos;\r
+  void Init(const Byte *buffer, size_t size)\r
+  {\r
+    _buffer = buffer;\r
+    _size = size;\r
+    _pos = 0;\r
+  }\r
+  Byte ReadByte();\r
+  void ReadBytes(Byte *data, size_t size);\r
+  void SkipData(UInt64 size);\r
+  void SkipData();\r
+  UInt64 ReadNumber();\r
+  CNum ReadNum();\r
+  UInt32 ReadUInt32();\r
+  UInt64 ReadUInt64();\r
+  void ReadString(UString &s);\r
+};\r
+\r
+class CStreamSwitch;\r
+\r
+const UInt32 kHeaderSize = 32;\r
+\r
+class CInArchive\r
+{\r
+  friend class CStreamSwitch;\r
+\r
+  CMyComPtr<IInStream> _stream;\r
+\r
+  CObjectVector<CInByte2> _inByteVector;\r
+  CInByte2 *_inByteBack;\r
\r
+  UInt64 _arhiveBeginStreamPosition;\r
+\r
+  Byte _header[kHeaderSize];\r
+\r
+  UInt64 HeadersSize;\r
+\r
+  void AddByteStream(const Byte *buffer, size_t size)\r
+  {\r
+    _inByteVector.Add(CInByte2());\r
+    _inByteBack = &_inByteVector.Back();\r
+    _inByteBack->Init(buffer, size);\r
+  }\r
+  \r
+  void DeleteByteStream()\r
+  {\r
+    _inByteVector.DeleteBack();\r
+    if (!_inByteVector.IsEmpty())\r
+      _inByteBack = &_inByteVector.Back();\r
+  }\r
+\r
+private:\r
+  HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);\r
+  \r
+  void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }\r
+  Byte ReadByte() { return _inByteBack->ReadByte(); }\r
+  UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }\r
+  CNum ReadNum() { return _inByteBack->ReadNum(); }\r
+  UInt64 ReadID() { return _inByteBack->ReadNumber(); }\r
+  UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }\r
+  UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }\r
+  void SkipData(UInt64 size) { _inByteBack->SkipData(size); }\r
+  void SkipData() { _inByteBack->SkipData(); }\r
+  void WaitAttribute(UInt64 attribute);\r
+\r
+  void ReadArchiveProperties(CInArchiveInfo &archiveInfo);\r
+  void GetNextFolderItem(CFolder &itemInfo);\r
+  void ReadHashDigests(int numItems,\r
+      CBoolVector &digestsDefined, CRecordVector<UInt32> &digests);\r
+  \r
+  void ReadPackInfo(\r
+      UInt64 &dataOffset,\r
+      CRecordVector<UInt64> &packSizes,\r
+      CBoolVector &packCRCsDefined,\r
+      CRecordVector<UInt32> &packCRCs);\r
+  \r
+  void ReadUnpackInfo(\r
+      const CObjectVector<CByteBuffer> *dataVector,\r
+      CObjectVector<CFolder> &folders);\r
+  \r
+  void ReadSubStreamsInfo(\r
+      const CObjectVector<CFolder> &folders,\r
+      CRecordVector<CNum> &numUnpackStreamsInFolders,\r
+      CRecordVector<UInt64> &unpackSizes,\r
+      CBoolVector &digestsDefined,\r
+      CRecordVector<UInt32> &digests);\r
+\r
+  void ReadStreamsInfo(\r
+      const CObjectVector<CByteBuffer> *dataVector,\r
+      UInt64 &dataOffset,\r
+      CRecordVector<UInt64> &packSizes,\r
+      CBoolVector &packCRCsDefined,\r
+      CRecordVector<UInt32> &packCRCs,\r
+      CObjectVector<CFolder> &folders,\r
+      CRecordVector<CNum> &numUnpackStreamsInFolders,\r
+      CRecordVector<UInt64> &unpackSizes,\r
+      CBoolVector &digestsDefined,\r
+      CRecordVector<UInt32> &digests);\r
+\r
+\r
+  void ReadBoolVector(int numItems, CBoolVector &v);\r
+  void ReadBoolVector2(int numItems, CBoolVector &v);\r
+  void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,\r
+      CUInt64DefVector &v, int numFiles);\r
+  HRESULT ReadAndDecodePackedStreams(\r
+      DECL_EXTERNAL_CODECS_LOC_VARS\r
+      UInt64 baseOffset, UInt64 &dataOffset,\r
+      CObjectVector<CByteBuffer> &dataVector\r
+      #ifndef _NO_CRYPTO\r
+      , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+      #endif\r
+      );\r
+  HRESULT ReadHeader(\r
+      DECL_EXTERNAL_CODECS_LOC_VARS\r
+      CArchiveDatabaseEx &db\r
+      #ifndef _NO_CRYPTO\r
+      ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+      #endif\r
+      );\r
+  HRESULT ReadDatabase2(\r
+      DECL_EXTERNAL_CODECS_LOC_VARS\r
+      CArchiveDatabaseEx &db\r
+      #ifndef _NO_CRYPTO\r
+      ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+      #endif\r
+      );\r
+public:\r
+  HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive\r
+  void Close();\r
+\r
+  HRESULT ReadDatabase(\r
+      DECL_EXTERNAL_CODECS_LOC_VARS\r
+      CArchiveDatabaseEx &db\r
+      #ifndef _NO_CRYPTO\r
+      ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined\r
+      #endif\r
+      );\r
+};\r
+  \r
+}}\r
+  \r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h
new file mode 100755 (executable)
index 0000000..3b01a8d
--- /dev/null
@@ -0,0 +1,268 @@
+// 7zItem.h\r
+\r
+#ifndef __7Z_ITEM_H\r
+#define __7Z_ITEM_H\r
+\r
+#include "../../../Common/Buffer.h"\r
+#include "../../../Common/MyString.h"\r
+\r
+#include "../../Common/MethodId.h"\r
+\r
+#include "7zHeader.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+const UInt64 k_AES = 0x06F10701;\r
+\r
+typedef UInt32 CNum;\r
+const CNum kNumMax     = 0x7FFFFFFF;\r
+const CNum kNumNoIndex = 0xFFFFFFFF;\r
+\r
+struct CCoderInfo\r
+{\r
+  CMethodId MethodID;\r
+  CByteBuffer Props;\r
+  CNum NumInStreams;\r
+  CNum NumOutStreams;\r
+  bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }\r
+};\r
+\r
+struct CBindPair\r
+{\r
+  CNum InIndex;\r
+  CNum OutIndex;\r
+};\r
+\r
+struct CFolder\r
+{\r
+  CObjectVector<CCoderInfo> Coders;\r
+  CRecordVector<CBindPair> BindPairs;\r
+  CRecordVector<CNum> PackStreams;\r
+  CRecordVector<UInt64> UnpackSizes;\r
+  UInt32 UnpackCRC;\r
+  bool UnpackCRCDefined;\r
+\r
+  CFolder(): UnpackCRCDefined(false) {}\r
+\r
+  UInt64 GetUnpackSize() const // test it\r
+  {\r
+    if (UnpackSizes.IsEmpty())\r
+      return 0;\r
+    for (int i = UnpackSizes.Size() - 1; i >= 0; i--)\r
+      if (FindBindPairForOutStream(i) < 0)\r
+        return UnpackSizes[i];\r
+    throw 1;\r
+  }\r
+\r
+  CNum GetNumOutStreams() const\r
+  {\r
+    CNum result = 0;\r
+    for (int i = 0; i < Coders.Size(); i++)\r
+      result += Coders[i].NumOutStreams;\r
+    return result;\r
+  }\r
+\r
+  int FindBindPairForInStream(CNum inStreamIndex) const\r
+  {\r
+    for(int i = 0; i < BindPairs.Size(); i++)\r
+      if (BindPairs[i].InIndex == inStreamIndex)\r
+        return i;\r
+    return -1;\r
+  }\r
+  int FindBindPairForOutStream(CNum outStreamIndex) const\r
+  {\r
+    for(int i = 0; i < BindPairs.Size(); i++)\r
+      if (BindPairs[i].OutIndex == outStreamIndex)\r
+        return i;\r
+    return -1;\r
+  }\r
+  int FindPackStreamArrayIndex(CNum inStreamIndex) const\r
+  {\r
+    for(int i = 0; i < PackStreams.Size(); i++)\r
+      if (PackStreams[i] == inStreamIndex)\r
+        return i;\r
+    return -1;\r
+  }\r
+\r
+  bool IsEncrypted() const\r
+  {\r
+    for (int i = Coders.Size() - 1; i >= 0; i--)\r
+      if (Coders[i].MethodID == k_AES)\r
+        return true;\r
+    return false;\r
+  }\r
+\r
+  bool CheckStructure() const;\r
+};\r
+\r
+struct CUInt64DefVector\r
+{\r
+  CRecordVector<UInt64> Values;\r
+  CRecordVector<bool> Defined;\r
+  \r
+  void Clear()\r
+  {\r
+    Values.Clear();\r
+    Defined.Clear();\r
+  }\r
+  \r
+  void ReserveDown()\r
+  {\r
+    Values.ReserveDown();\r
+    Values.ReserveDown();\r
+  }\r
+\r
+  bool GetItem(int index, UInt64 &value) const\r
+  {\r
+    if (index < Defined.Size() && Defined[index])\r
+    {\r
+      value = Values[index];\r
+      return true;\r
+    }\r
+    value = 0;\r
+    return false;\r
+  }\r
+  \r
+  void SetItem(int index, bool defined, UInt64 value)\r
+  {\r
+    while (index >= Defined.Size())\r
+      Defined.Add(false);\r
+    Defined[index] = defined;\r
+    if (!defined)\r
+      return;\r
+    while (index >= Values.Size())\r
+      Values.Add(0);\r
+    Values[index] = value;\r
+  }\r
+\r
+  bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; }\r
+};\r
+\r
+struct CFileItem\r
+{\r
+  UInt64 Size;\r
+  UInt32 Attrib;\r
+  UInt32 Crc;\r
+  UString Name;\r
+\r
+  bool HasStream; // Test it !!! it means that there is\r
+                  // stream in some folder. It can be empty stream\r
+  bool IsDir;\r
+  bool CrcDefined;\r
+  bool AttribDefined;\r
+\r
+  CFileItem():\r
+    HasStream(true),\r
+    IsDir(false),\r
+    CrcDefined(false),\r
+    AttribDefined(false)\r
+      {}\r
+  void SetAttrib(UInt32 attrib)\r
+  {\r
+    AttribDefined = true;\r
+    Attrib = attrib;\r
+  }\r
+};\r
+\r
+struct CFileItem2\r
+{\r
+  UInt64 CTime;\r
+  UInt64 ATime;\r
+  UInt64 MTime;\r
+  UInt64 StartPos;\r
+  bool CTimeDefined;\r
+  bool ATimeDefined;\r
+  bool MTimeDefined;\r
+  bool StartPosDefined;\r
+  bool IsAnti;\r
+};\r
+\r
+struct CArchiveDatabase\r
+{\r
+  CRecordVector<UInt64> PackSizes;\r
+  CRecordVector<bool> PackCRCsDefined;\r
+  CRecordVector<UInt32> PackCRCs;\r
+  CObjectVector<CFolder> Folders;\r
+  CRecordVector<CNum> NumUnpackStreamsVector;\r
+  CObjectVector<CFileItem> Files;\r
+\r
+  CUInt64DefVector CTime;\r
+  CUInt64DefVector ATime;\r
+  CUInt64DefVector MTime;\r
+  CUInt64DefVector StartPos;\r
+  CRecordVector<bool> IsAnti;\r
+\r
+  void Clear()\r
+  {\r
+    PackSizes.Clear();\r
+    PackCRCsDefined.Clear();\r
+    PackCRCs.Clear();\r
+    Folders.Clear();\r
+    NumUnpackStreamsVector.Clear();\r
+    Files.Clear();\r
+    CTime.Clear();\r
+    ATime.Clear();\r
+    MTime.Clear();\r
+    StartPos.Clear();\r
+    IsAnti.Clear();\r
+  }\r
+\r
+  void ReserveDown()\r
+  {\r
+    PackSizes.ReserveDown();\r
+    PackCRCsDefined.ReserveDown();\r
+    PackCRCs.ReserveDown();\r
+    Folders.ReserveDown();\r
+    NumUnpackStreamsVector.ReserveDown();\r
+    Files.ReserveDown();\r
+    CTime.ReserveDown();\r
+    ATime.ReserveDown();\r
+    MTime.ReserveDown();\r
+    StartPos.ReserveDown();\r
+    IsAnti.ReserveDown();\r
+  }\r
+\r
+  bool IsEmpty() const\r
+  {\r
+    return (PackSizes.IsEmpty() &&\r
+      PackCRCsDefined.IsEmpty() &&\r
+      PackCRCs.IsEmpty() &&\r
+      Folders.IsEmpty() &&\r
+      NumUnpackStreamsVector.IsEmpty() &&\r
+      Files.IsEmpty());\r
+  }\r
+\r
+  bool CheckNumFiles() const\r
+  {\r
+    int size = Files.Size();\r
+    return (\r
+      CTime.CheckSize(size) &&\r
+      ATime.CheckSize(size) &&\r
+      MTime.CheckSize(size) &&\r
+      StartPos.CheckSize(size) &&\r
+      (size == IsAnti.Size() || IsAnti.Size() == 0));\r
+  }\r
+\r
+  bool IsSolid() const\r
+  {\r
+    for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)\r
+      if (NumUnpackStreamsVector[i] > 1)\r
+        return true;\r
+    return false;\r
+  }\r
+  bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }\r
+  void SetItemAnti(int index, bool isAnti)\r
+  {\r
+    while (index >= IsAnti.Size())\r
+      IsAnti.Add(false);\r
+    IsAnti[index] = isAnti;\r
+  }\r
+\r
+  void GetFile(int index, CFileItem &file, CFileItem2 &file2) const;\r
+  void AddFile(const CFileItem &file, const CFileItem2 &file2);\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp
new file mode 100755 (executable)
index 0000000..b34a2c9
--- /dev/null
@@ -0,0 +1,866 @@
+// 7zOut.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../../C/7zCrc.h"\r
+\r
+#include "../../../Common/AutoPtr.h"\r
+\r
+#include "../../Common/StreamObjects.h"\r
+\r
+#include "7zOut.h"\r
+\r
+static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size)\r
+{\r
+  while (size > 0)\r
+  {\r
+    UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);\r
+    UInt32 processedSize;\r
+    RINOK(stream->Write(data, curSize, &processedSize));\r
+    if (processedSize == 0)\r
+      return E_FAIL;\r
+    data = (const void *)((const Byte *)data + processedSize);\r
+    size -= processedSize;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+HRESULT COutArchive::WriteDirect(const void *data, UInt32 size)\r
+{\r
+  return ::WriteBytes(SeqStream, data, size);\r
+}\r
+\r
+HRESULT COutArchive::WriteSignature()\r
+{\r
+  Byte buf[8];\r
+  memcpy(buf, kSignature, kSignatureSize);\r
+  buf[kSignatureSize] = kMajorVersion;\r
+  buf[kSignatureSize + 1] = 3;\r
+  return WriteDirect(buf, 8);\r
+}\r
+\r
+#ifdef _7Z_VOL\r
+HRESULT COutArchive::WriteFinishSignature()\r
+{\r
+  RINOK(WriteDirect(kFinishSignature, kSignatureSize));\r
+  CArchiveVersion av;\r
+  av.Major = kMajorVersion;\r
+  av.Minor = 2;\r
+  RINOK(WriteDirectByte(av.Major));\r
+  return WriteDirectByte(av.Minor);\r
+}\r
+#endif\r
+\r
+static void SetUInt32(Byte *p, UInt32 d)\r
+{\r
+  for (int i = 0; i < 4; i++, d >>= 8)\r
+    p[i] = (Byte)d;\r
+}\r
+\r
+static void SetUInt64(Byte *p, UInt64 d)\r
+{\r
+  for (int i = 0; i < 8; i++, d >>= 8)\r
+    p[i] = (Byte)d;\r
+}\r
+\r
+HRESULT COutArchive::WriteStartHeader(const CStartHeader &h)\r
+{\r
+  Byte buf[24];\r
+  SetUInt64(buf + 4, h.NextHeaderOffset);\r
+  SetUInt64(buf + 12, h.NextHeaderSize);\r
+  SetUInt32(buf + 20, h.NextHeaderCRC);\r
+  SetUInt32(buf, CrcCalc(buf + 4, 20));\r
+  return WriteDirect(buf, 24);\r
+}\r
+\r
+#ifdef _7Z_VOL\r
+HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)\r
+{\r
+  CCRC crc;\r
+  crc.UpdateUInt64(h.NextHeaderOffset);\r
+  crc.UpdateUInt64(h.NextHeaderSize);\r
+  crc.UpdateUInt32(h.NextHeaderCRC);\r
+  crc.UpdateUInt64(h.ArchiveStartOffset);\r
+  crc.UpdateUInt64(h.AdditionalStartBlockSize);\r
+  RINOK(WriteDirectUInt32(crc.GetDigest()));\r
+  RINOK(WriteDirectUInt64(h.NextHeaderOffset));\r
+  RINOK(WriteDirectUInt64(h.NextHeaderSize));\r
+  RINOK(WriteDirectUInt32(h.NextHeaderCRC));\r
+  RINOK(WriteDirectUInt64(h.ArchiveStartOffset));\r
+  return WriteDirectUInt64(h.AdditionalStartBlockSize);\r
+}\r
+#endif\r
+\r
+HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)\r
+{\r
+  Close();\r
+  #ifdef _7Z_VOL\r
+  // endMarker = false;\r
+  _endMarker = endMarker;\r
+  #endif\r
+  SeqStream = stream;\r
+  if (!endMarker)\r
+  {\r
+    SeqStream.QueryInterface(IID_IOutStream, &Stream);\r
+    if (!Stream)\r
+    {\r
+      return E_NOTIMPL;\r
+      // endMarker = true;\r
+    }\r
+  }\r
+  #ifdef _7Z_VOL\r
+  if (endMarker)\r
+  {\r
+    /*\r
+    CStartHeader sh;\r
+    sh.NextHeaderOffset = (UInt32)(Int32)-1;\r
+    sh.NextHeaderSize = (UInt32)(Int32)-1;\r
+    sh.NextHeaderCRC = 0;\r
+    WriteStartHeader(sh);\r
+    */\r
+  }\r
+  else\r
+  #endif\r
+  {\r
+    if (!Stream)\r
+      return E_FAIL;\r
+    RINOK(WriteSignature());\r
+    RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+void COutArchive::Close()\r
+{\r
+  SeqStream.Release();\r
+  Stream.Release();\r
+}\r
+\r
+HRESULT COutArchive::SkipPrefixArchiveHeader()\r
+{\r
+  #ifdef _7Z_VOL\r
+  if (_endMarker)\r
+    return S_OK;\r
+  #endif\r
+  return Stream->Seek(24, STREAM_SEEK_CUR, NULL);\r
+}\r
+\r
+UInt64 COutArchive::GetPos() const\r
+{\r
+  if (_countMode)\r
+    return _countSize;\r
+  if (_writeToStream)\r
+    return _outByte.GetProcessedSize();\r
+  return _outByte2.GetPos();\r
+}\r
+\r
+void COutArchive::WriteBytes(const void *data, size_t size)\r
+{\r
+  if (_countMode)\r
+    _countSize += size;\r
+  else if (_writeToStream)\r
+  {\r
+    _outByte.WriteBytes(data, size);\r
+    _crc = CrcUpdate(_crc, data, size);\r
+  }\r
+  else\r
+    _outByte2.WriteBytes(data, size);\r
+}\r
+\r
+void COutArchive::WriteByte(Byte b)\r
+{\r
+  if (_countMode)\r
+    _countSize++;\r
+  else if (_writeToStream)\r
+  {\r
+    _outByte.WriteByte(b);\r
+    _crc = CRC_UPDATE_BYTE(_crc, b);\r
+  }\r
+  else\r
+    _outByte2.WriteByte(b);\r
+}\r
+\r
+void COutArchive::WriteUInt32(UInt32 value)\r
+{\r
+  for (int i = 0; i < 4; i++)\r
+  {\r
+    WriteByte((Byte)value);\r
+    value >>= 8;\r
+  }\r
+}\r
+\r
+void COutArchive::WriteUInt64(UInt64 value)\r
+{\r
+  for (int i = 0; i < 8; i++)\r
+  {\r
+    WriteByte((Byte)value);\r
+    value >>= 8;\r
+  }\r
+}\r
+\r
+void COutArchive::WriteNumber(UInt64 value)\r
+{\r
+  Byte firstByte = 0;\r
+  Byte mask = 0x80;\r
+  int i;\r
+  for (i = 0; i < 8; i++)\r
+  {\r
+    if (value < ((UInt64(1) << ( 7  * (i + 1)))))\r
+    {\r
+      firstByte |= Byte(value >> (8 * i));\r
+      break;\r
+    }\r
+    firstByte |= mask;\r
+    mask >>= 1;\r
+  }\r
+  WriteByte(firstByte);\r
+  for (;i > 0; i--)\r
+  {\r
+    WriteByte((Byte)value);\r
+    value >>= 8;\r
+  }\r
+}\r
+\r
+static UInt32 GetBigNumberSize(UInt64 value)\r
+{\r
+  int i;\r
+  for (i = 1; i < 9; i++)\r
+    if (value < (((UInt64)1 << (i * 7))))\r
+      break;\r
+  return i;\r
+}\r
+\r
+#ifdef _7Z_VOL\r
+UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props)\r
+{\r
+  UInt32 result = GetBigNumberSize(dataSize) * 2 + 41;\r
+  if (nameLength != 0)\r
+  {\r
+    nameLength = (nameLength + 1) * 2;\r
+    result += nameLength + GetBigNumberSize(nameLength) + 2;\r
+  }\r
+  if (props)\r
+  {\r
+    result += 20;\r
+  }\r
+  if (result >= 128)\r
+    result++;\r
+  result += kSignatureSize + 2 + kFinishHeaderSize;\r
+  return result;\r
+}\r
+\r
+UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props)\r
+{\r
+  UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props);\r
+  int testSize;\r
+  if (volSize > headersSizeBase)\r
+    testSize = volSize - headersSizeBase;\r
+  else\r
+    testSize = 1;\r
+  UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props);\r
+  UInt64 pureSize = 1;\r
+  if (volSize > headersSize)\r
+    pureSize = volSize - headersSize;\r
+  return pureSize;\r
+}\r
+#endif\r
+\r
+void COutArchive::WriteFolder(const CFolder &folder)\r
+{\r
+  WriteNumber(folder.Coders.Size());\r
+  int i;\r
+  for (i = 0; i < folder.Coders.Size(); i++)\r
+  {\r
+    const CCoderInfo &coder = folder.Coders[i];\r
+    {\r
+      size_t propsSize = coder.Props.GetCapacity();\r
+      \r
+      UInt64 id = coder.MethodID;\r
+      int idSize;\r
+      for (idSize = 1; idSize < sizeof(id); idSize++)\r
+        if ((id >> (8 * idSize)) == 0)\r
+          break;\r
+      BYTE longID[15];\r
+      for (int t = idSize - 1; t >= 0 ; t--, id >>= 8)\r
+        longID[t] = (Byte)(id & 0xFF);\r
+      Byte b;\r
+      b = (Byte)(idSize & 0xF);\r
+      bool isComplex = !coder.IsSimpleCoder();\r
+      b |= (isComplex ? 0x10 : 0);\r
+      b |= ((propsSize != 0) ? 0x20 : 0 );\r
+      WriteByte(b);\r
+      WriteBytes(longID, idSize);\r
+      if (isComplex)\r
+      {\r
+        WriteNumber(coder.NumInStreams);\r
+        WriteNumber(coder.NumOutStreams);\r
+      }\r
+      if (propsSize == 0)\r
+        continue;\r
+      WriteNumber(propsSize);\r
+      WriteBytes(coder.Props, propsSize);\r
+    }\r
+  }\r
+  for (i = 0; i < folder.BindPairs.Size(); i++)\r
+  {\r
+    const CBindPair &bindPair = folder.BindPairs[i];\r
+    WriteNumber(bindPair.InIndex);\r
+    WriteNumber(bindPair.OutIndex);\r
+  }\r
+  if (folder.PackStreams.Size() > 1)\r
+    for (i = 0; i < folder.PackStreams.Size(); i++)\r
+    {\r
+      WriteNumber(folder.PackStreams[i]);\r
+    }\r
+}\r
+\r
+void COutArchive::WriteBoolVector(const CBoolVector &boolVector)\r
+{\r
+  Byte b = 0;\r
+  Byte mask = 0x80;\r
+  for (int i = 0; i < boolVector.Size(); i++)\r
+  {\r
+    if (boolVector[i])\r
+      b |= mask;\r
+    mask >>= 1;\r
+    if (mask == 0)\r
+    {\r
+      WriteByte(b);\r
+      mask = 0x80;\r
+      b = 0;\r
+    }\r
+  }\r
+  if (mask != 0x80)\r
+    WriteByte(b);\r
+}\r
+\r
+\r
+void COutArchive::WriteHashDigests(\r
+    const CRecordVector<bool> &digestsDefined,\r
+    const CRecordVector<UInt32> &digests)\r
+{\r
+  int numDefined = 0;\r
+  int i;\r
+  for (i = 0; i < digestsDefined.Size(); i++)\r
+    if (digestsDefined[i])\r
+      numDefined++;\r
+  if (numDefined == 0)\r
+    return;\r
+\r
+  WriteByte(NID::kCRC);\r
+  if (numDefined == digestsDefined.Size())\r
+    WriteByte(1);\r
+  else\r
+  {\r
+    WriteByte(0);\r
+    WriteBoolVector(digestsDefined);\r
+  }\r
+  for (i = 0; i < digests.Size(); i++)\r
+    if (digestsDefined[i])\r
+      WriteUInt32(digests[i]);\r
+}\r
+\r
+void COutArchive::WritePackInfo(\r
+    UInt64 dataOffset,\r
+    const CRecordVector<UInt64> &packSizes,\r
+    const CRecordVector<bool> &packCRCsDefined,\r
+    const CRecordVector<UInt32> &packCRCs)\r
+{\r
+  if (packSizes.IsEmpty())\r
+    return;\r
+  WriteByte(NID::kPackInfo);\r
+  WriteNumber(dataOffset);\r
+  WriteNumber(packSizes.Size());\r
+  WriteByte(NID::kSize);\r
+  for (int i = 0; i < packSizes.Size(); i++)\r
+    WriteNumber(packSizes[i]);\r
+\r
+  WriteHashDigests(packCRCsDefined, packCRCs);\r
+  \r
+  WriteByte(NID::kEnd);\r
+}\r
+\r
+void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders)\r
+{\r
+  if (folders.IsEmpty())\r
+    return;\r
+\r
+  WriteByte(NID::kUnpackInfo);\r
+\r
+  WriteByte(NID::kFolder);\r
+  WriteNumber(folders.Size());\r
+  {\r
+    WriteByte(0);\r
+    for (int i = 0; i < folders.Size(); i++)\r
+      WriteFolder(folders[i]);\r
+  }\r
+  \r
+  WriteByte(NID::kCodersUnpackSize);\r
+  int i;\r
+  for (i = 0; i < folders.Size(); i++)\r
+  {\r
+    const CFolder &folder = folders[i];\r
+    for (int j = 0; j < folder.UnpackSizes.Size(); j++)\r
+      WriteNumber(folder.UnpackSizes[j]);\r
+  }\r
+\r
+  CRecordVector<bool> unpackCRCsDefined;\r
+  CRecordVector<UInt32> unpackCRCs;\r
+  for (i = 0; i < folders.Size(); i++)\r
+  {\r
+    const CFolder &folder = folders[i];\r
+    unpackCRCsDefined.Add(folder.UnpackCRCDefined);\r
+    unpackCRCs.Add(folder.UnpackCRC);\r
+  }\r
+  WriteHashDigests(unpackCRCsDefined, unpackCRCs);\r
+\r
+  WriteByte(NID::kEnd);\r
+}\r
+\r
+void COutArchive::WriteSubStreamsInfo(\r
+    const CObjectVector<CFolder> &folders,\r
+    const CRecordVector<CNum> &numUnpackStreamsInFolders,\r
+    const CRecordVector<UInt64> &unpackSizes,\r
+    const CRecordVector<bool> &digestsDefined,\r
+    const CRecordVector<UInt32> &digests)\r
+{\r
+  WriteByte(NID::kSubStreamsInfo);\r
+\r
+  int i;\r
+  for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)\r
+  {\r
+    if (numUnpackStreamsInFolders[i] != 1)\r
+    {\r
+      WriteByte(NID::kNumUnpackStream);\r
+      for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)\r
+        WriteNumber(numUnpackStreamsInFolders[i]);\r
+      break;\r
+    }\r
+  }\r
\r
+\r
+  bool needFlag = true;\r
+  CNum index = 0;\r
+  for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)\r
+    for (CNum j = 0; j < numUnpackStreamsInFolders[i]; j++)\r
+    {\r
+      if (j + 1 != numUnpackStreamsInFolders[i])\r
+      {\r
+        if (needFlag)\r
+          WriteByte(NID::kSize);\r
+        needFlag = false;\r
+        WriteNumber(unpackSizes[index]);\r
+      }\r
+      index++;\r
+    }\r
+\r
+  CRecordVector<bool> digestsDefined2;\r
+  CRecordVector<UInt32> digests2;\r
+\r
+  int digestIndex = 0;\r
+  for (i = 0; i < folders.Size(); i++)\r
+  {\r
+    int numSubStreams = (int)numUnpackStreamsInFolders[i];\r
+    if (numSubStreams == 1 && folders[i].UnpackCRCDefined)\r
+      digestIndex++;\r
+    else\r
+      for (int j = 0; j < numSubStreams; j++, digestIndex++)\r
+      {\r
+        digestsDefined2.Add(digestsDefined[digestIndex]);\r
+        digests2.Add(digests[digestIndex]);\r
+      }\r
+  }\r
+  WriteHashDigests(digestsDefined2, digests2);\r
+  WriteByte(NID::kEnd);\r
+}\r
+\r
+void COutArchive::SkipAlign(unsigned /* pos */, unsigned /* alignSize */)\r
+{\r
+  return;\r
+}\r
+\r
+/*\r
+7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.\r
+\r
+void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)\r
+{\r
+  pos += (unsigned)GetPos();\r
+  pos &= (alignSize - 1);\r
+  if (pos == 0)\r
+    return;\r
+  unsigned skip = alignSize - pos;\r
+  if (skip < 2)\r
+    skip += alignSize;\r
+  skip -= 2;\r
+  WriteByte(NID::kDummy);\r
+  WriteByte((Byte)skip);\r
+  for (unsigned i = 0; i < skip; i++)\r
+    WriteByte(0);\r
+}\r
+*/\r
+\r
+static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; }\r
+\r
+void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize)\r
+{\r
+  const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);\r
+  const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;\r
+  SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize);\r
+\r
+  WriteByte(type);\r
+  WriteNumber(dataSize);\r
+  if (numDefined == v.Size())\r
+    WriteByte(1);\r
+  else\r
+  {\r
+    WriteByte(0);\r
+    WriteBoolVector(v);\r
+  }\r
+  WriteByte(0);\r
+}\r
+\r
+void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)\r
+{\r
+  int numDefined = 0;\r
+\r
+  int i;\r
+  for (i = 0; i < v.Defined.Size(); i++)\r
+    if (v.Defined[i])\r
+      numDefined++;\r
+\r
+  if (numDefined == 0)\r
+    return;\r
+\r
+  WriteAlignedBoolHeader(v.Defined, numDefined, type, 8);\r
+  \r
+  for (i = 0; i < v.Defined.Size(); i++)\r
+    if (v.Defined[i])\r
+      WriteUInt64(v.Values[i]);\r
+}\r
+\r
+HRESULT COutArchive::EncodeStream(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    CEncoder &encoder, const CByteBuffer &data,\r
+    CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)\r
+{\r
+  CBufInStream *streamSpec = new CBufInStream;\r
+  CMyComPtr<ISequentialInStream> stream = streamSpec;\r
+  streamSpec->Init(data, data.GetCapacity());\r
+  CFolder folderItem;\r
+  folderItem.UnpackCRCDefined = true;\r
+  folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity());\r
+  UInt64 dataSize64 = data.GetCapacity();\r
+  RINOK(encoder.Encode(\r
+      EXTERNAL_CODECS_LOC_VARS\r
+      stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))\r
+  folders.Add(folderItem);\r
+  return S_OK;\r
+}\r
+\r
+void COutArchive::WriteHeader(\r
+    const CArchiveDatabase &db,\r
+    const CHeaderOptions &headerOptions,\r
+    UInt64 &headerOffset)\r
+{\r
+  int i;\r
+  \r
+  UInt64 packedSize = 0;\r
+  for (i = 0; i < db.PackSizes.Size(); i++)\r
+    packedSize += db.PackSizes[i];\r
+\r
+  headerOffset = packedSize;\r
+\r
+  WriteByte(NID::kHeader);\r
+\r
+  // Archive Properties\r
+\r
+  if (db.Folders.Size() > 0)\r
+  {\r
+    WriteByte(NID::kMainStreamsInfo);\r
+    WritePackInfo(0, db.PackSizes,\r
+        db.PackCRCsDefined,\r
+        db.PackCRCs);\r
+\r
+    WriteUnpackInfo(db.Folders);\r
+\r
+    CRecordVector<UInt64> unpackSizes;\r
+    CRecordVector<bool> digestsDefined;\r
+    CRecordVector<UInt32> digests;\r
+    for (i = 0; i < db.Files.Size(); i++)\r
+    {\r
+      const CFileItem &file = db.Files[i];\r
+      if (!file.HasStream)\r
+        continue;\r
+      unpackSizes.Add(file.Size);\r
+      digestsDefined.Add(file.CrcDefined);\r
+      digests.Add(file.Crc);\r
+    }\r
+\r
+    WriteSubStreamsInfo(\r
+        db.Folders,\r
+        db.NumUnpackStreamsVector,\r
+        unpackSizes,\r
+        digestsDefined,\r
+        digests);\r
+    WriteByte(NID::kEnd);\r
+  }\r
+\r
+  if (db.Files.IsEmpty())\r
+  {\r
+    WriteByte(NID::kEnd);\r
+    return;\r
+  }\r
+\r
+  WriteByte(NID::kFilesInfo);\r
+  WriteNumber(db.Files.Size());\r
+\r
+  {\r
+  /* ---------- Empty Streams ---------- */\r
+  CBoolVector emptyStreamVector;\r
+  emptyStreamVector.Reserve(db.Files.Size());\r
+  int numEmptyStreams = 0;\r
+  for (i = 0; i < db.Files.Size(); i++)\r
+    if (db.Files[i].HasStream)\r
+      emptyStreamVector.Add(false);\r
+    else\r
+    {\r
+      emptyStreamVector.Add(true);\r
+      numEmptyStreams++;\r
+    }\r
+  if (numEmptyStreams > 0)\r
+  {\r
+    WriteByte(NID::kEmptyStream);\r
+    WriteNumber(Bv_GetSizeInBytes(emptyStreamVector));\r
+    WriteBoolVector(emptyStreamVector);\r
+\r
+    CBoolVector emptyFileVector, antiVector;\r
+    emptyFileVector.Reserve(numEmptyStreams);\r
+    antiVector.Reserve(numEmptyStreams);\r
+    CNum numEmptyFiles = 0, numAntiItems = 0;\r
+    for (i = 0; i < db.Files.Size(); i++)\r
+    {\r
+      const CFileItem &file = db.Files[i];\r
+      if (!file.HasStream)\r
+      {\r
+        emptyFileVector.Add(!file.IsDir);\r
+        if (!file.IsDir)\r
+          numEmptyFiles++;\r
+        bool isAnti = db.IsItemAnti(i);\r
+        antiVector.Add(isAnti);\r
+        if (isAnti)\r
+          numAntiItems++;\r
+      }\r
+    }\r
+\r
+    if (numEmptyFiles > 0)\r
+    {\r
+      WriteByte(NID::kEmptyFile);\r
+      WriteNumber(Bv_GetSizeInBytes(emptyFileVector));\r
+      WriteBoolVector(emptyFileVector);\r
+    }\r
+\r
+    if (numAntiItems > 0)\r
+    {\r
+      WriteByte(NID::kAnti);\r
+      WriteNumber(Bv_GetSizeInBytes(antiVector));\r
+      WriteBoolVector(antiVector);\r
+    }\r
+  }\r
+  }\r
+\r
+\r
+  {\r
+    /* ---------- Names ---------- */\r
+    \r
+    int numDefined = 0;\r
+    size_t namesDataSize = 0;\r
+    for (int i = 0; i < db.Files.Size(); i++)\r
+    {\r
+      const UString &name = db.Files[i].Name;\r
+      if (!name.IsEmpty())\r
+        numDefined++;\r
+      namesDataSize += (name.Length() + 1) * 2;\r
+    }\r
+    \r
+    if (numDefined > 0)\r
+    {\r
+      namesDataSize++;\r
+      SkipAlign(2 + GetBigNumberSize(namesDataSize), 2);\r
+\r
+      WriteByte(NID::kName);\r
+      WriteNumber(namesDataSize);\r
+      WriteByte(0);\r
+      for (int i = 0; i < db.Files.Size(); i++)\r
+      {\r
+        const UString &name = db.Files[i].Name;\r
+        for (int t = 0; t <= name.Length(); t++)\r
+        {\r
+          wchar_t c = name[t];\r
+          WriteByte((Byte)c);\r
+          WriteByte((Byte)(c >> 8));\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  if (headerOptions.WriteCTime) WriteUInt64DefVector(db.CTime, NID::kCTime);\r
+  if (headerOptions.WriteATime) WriteUInt64DefVector(db.ATime, NID::kATime);\r
+  if (headerOptions.WriteMTime) WriteUInt64DefVector(db.MTime, NID::kMTime);\r
+  WriteUInt64DefVector(db.StartPos, NID::kStartPos);\r
+  \r
+  {\r
+    /* ---------- Write Attrib ---------- */\r
+    CBoolVector boolVector;\r
+    boolVector.Reserve(db.Files.Size());\r
+    int numDefined = 0;\r
+    for (i = 0; i < db.Files.Size(); i++)\r
+    {\r
+      bool defined = db.Files[i].AttribDefined;\r
+      boolVector.Add(defined);\r
+      if (defined)\r
+        numDefined++;\r
+    }\r
+    if (numDefined > 0)\r
+    {\r
+      WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttributes, 4);\r
+      for (i = 0; i < db.Files.Size(); i++)\r
+      {\r
+        const CFileItem &file = db.Files[i];\r
+        if (file.AttribDefined)\r
+          WriteUInt32(file.Attrib);\r
+      }\r
+    }\r
+  }\r
+\r
+  WriteByte(NID::kEnd); // for files\r
+  WriteByte(NID::kEnd); // for headers\r
+}\r
+\r
+HRESULT COutArchive::WriteDatabase(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    const CArchiveDatabase &db,\r
+    const CCompressionMethodMode *options,\r
+    const CHeaderOptions &headerOptions)\r
+{\r
+  if (!db.CheckNumFiles())\r
+    return E_FAIL;\r
+\r
+  UInt64 headerOffset;\r
+  UInt32 headerCRC;\r
+  UInt64 headerSize;\r
+  if (db.IsEmpty())\r
+  {\r
+    headerSize = 0;\r
+    headerOffset = 0;\r
+    headerCRC = CrcCalc(0, 0);\r
+  }\r
+  else\r
+  {\r
+    bool encodeHeaders = false;\r
+    if (options != 0)\r
+      if (options->IsEmpty())\r
+        options = 0;\r
+    if (options != 0)\r
+      if (options->PasswordIsDefined || headerOptions.CompressMainHeader)\r
+        encodeHeaders = true;\r
+\r
+    _outByte.SetStream(SeqStream);\r
+    _outByte.Init();\r
+    _crc = CRC_INIT_VAL;\r
+    _countMode = encodeHeaders;\r
+    _writeToStream = true;\r
+    _countSize = 0;\r
+    WriteHeader(db, headerOptions, headerOffset);\r
+\r
+    if (encodeHeaders)\r
+    {\r
+      CByteBuffer buf;\r
+      buf.SetCapacity(_countSize);\r
+      _outByte2.Init((Byte *)buf, _countSize);\r
+      \r
+      _countMode = false;\r
+      _writeToStream = false;\r
+      WriteHeader(db, headerOptions, headerOffset);\r
+      \r
+      if (_countSize != _outByte2.GetPos())\r
+        return E_FAIL;\r
+\r
+      CCompressionMethodMode encryptOptions;\r
+      encryptOptions.PasswordIsDefined = options->PasswordIsDefined;\r
+      encryptOptions.Password = options->Password;\r
+      CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);\r
+      CRecordVector<UInt64> packSizes;\r
+      CObjectVector<CFolder> folders;\r
+      RINOK(EncodeStream(\r
+          EXTERNAL_CODECS_LOC_VARS\r
+          encoder, buf,\r
+          packSizes, folders));\r
+\r
+      _writeToStream = true;\r
+      \r
+      if (folders.Size() == 0)\r
+        throw 1;\r
+\r
+      WriteID(NID::kEncodedHeader);\r
+      WritePackInfo(headerOffset, packSizes,\r
+        CRecordVector<bool>(), CRecordVector<UInt32>());\r
+      WriteUnpackInfo(folders);\r
+      WriteByte(NID::kEnd);\r
+      for (int i = 0; i < packSizes.Size(); i++)\r
+        headerOffset += packSizes[i];\r
+    }\r
+    RINOK(_outByte.Flush());\r
+    headerCRC = CRC_GET_DIGEST(_crc);\r
+    headerSize = _outByte.GetProcessedSize();\r
+  }\r
+  #ifdef _7Z_VOL\r
+  if (_endMarker)\r
+  {\r
+    CFinishHeader h;\r
+    h.NextHeaderSize = headerSize;\r
+    h.NextHeaderCRC = headerCRC;\r
+    h.NextHeaderOffset =\r
+        UInt64(0) - (headerSize +\r
+        4 + kFinishHeaderSize);\r
+    h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset;\r
+    h.AdditionalStartBlockSize = 0;\r
+    RINOK(WriteFinishHeader(h));\r
+    return WriteFinishSignature();\r
+  }\r
+  else\r
+  #endif\r
+  {\r
+    CStartHeader h;\r
+    h.NextHeaderSize = headerSize;\r
+    h.NextHeaderCRC = headerCRC;\r
+    h.NextHeaderOffset = headerOffset;\r
+    RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));\r
+    return WriteStartHeader(h);\r
+  }\r
+}\r
+\r
+void CArchiveDatabase::GetFile(int index, CFileItem &file, CFileItem2 &file2) const\r
+{\r
+  file = Files[index];\r
+  file2.CTimeDefined = CTime.GetItem(index, file2.CTime);\r
+  file2.ATimeDefined = ATime.GetItem(index, file2.ATime);\r
+  file2.MTimeDefined = MTime.GetItem(index, file2.MTime);\r
+  file2.StartPosDefined = StartPos.GetItem(index, file2.StartPos);\r
+  file2.IsAnti = IsItemAnti(index);\r
+}\r
+\r
+void CArchiveDatabase::AddFile(const CFileItem &file, const CFileItem2 &file2)\r
+{\r
+  int index = Files.Size();\r
+  CTime.SetItem(index, file2.CTimeDefined, file2.CTime);\r
+  ATime.SetItem(index, file2.ATimeDefined, file2.ATime);\r
+  MTime.SetItem(index, file2.MTimeDefined, file2.MTime);\r
+  StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);\r
+  SetItemAnti(index, file2.IsAnti);\r
+  Files.Add(file);\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h
new file mode 100755 (executable)
index 0000000..bdd465c
--- /dev/null
@@ -0,0 +1,152 @@
+// 7zOut.h\r
+\r
+#ifndef __7Z_OUT_H\r
+#define __7Z_OUT_H\r
+\r
+#include "7zCompressionMode.h"\r
+#include "7zEncode.h"\r
+#include "7zHeader.h"\r
+#include "7zItem.h"\r
+\r
+#include "../../Common/OutBuffer.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+class CWriteBufferLoc\r
+{\r
+  Byte *_data;\r
+  size_t _size;\r
+  size_t _pos;\r
+public:\r
+  CWriteBufferLoc(): _size(0), _pos(0) {}\r
+  void Init(Byte *data, size_t size)\r
+  {\r
+    _data = data;\r
+    _size = size;\r
+    _pos = 0;\r
+  }\r
+  void WriteBytes(const void *data, size_t size)\r
+  {\r
+    if (size > _size - _pos)\r
+      throw 1;\r
+    memcpy(_data + _pos, data, size);\r
+    _pos += size;\r
+  }\r
+  void WriteByte(Byte b)\r
+  {\r
+    if (_size == _pos)\r
+      throw 1;\r
+    _data[_pos++] = b;\r
+  }\r
+  size_t GetPos() const { return _pos; }\r
+};\r
+\r
+struct CHeaderOptions\r
+{\r
+  bool CompressMainHeader;\r
+  bool WriteCTime;\r
+  bool WriteATime;\r
+  bool WriteMTime;\r
+\r
+  CHeaderOptions():\r
+      CompressMainHeader(true),\r
+      WriteCTime(false),\r
+      WriteATime(false),\r
+      WriteMTime(true)\r
+      {}\r
+};\r
+\r
+class COutArchive\r
+{\r
+  UInt64 _prefixHeaderPos;\r
+\r
+  HRESULT WriteDirect(const void *data, UInt32 size);\r
+  \r
+  UInt64 GetPos() const;\r
+  void WriteBytes(const void *data, size_t size);\r
+  void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); }\r
+  void WriteByte(Byte b);\r
+  void WriteUInt32(UInt32 value);\r
+  void WriteUInt64(UInt64 value);\r
+  void WriteNumber(UInt64 value);\r
+  void WriteID(UInt64 value) { WriteNumber(value); }\r
+\r
+  void WriteFolder(const CFolder &folder);\r
+  HRESULT WriteFileHeader(const CFileItem &itemInfo);\r
+  void WriteBoolVector(const CBoolVector &boolVector);\r
+  void WriteHashDigests(\r
+      const CRecordVector<bool> &digestsDefined,\r
+      const CRecordVector<UInt32> &hashDigests);\r
+\r
+  void WritePackInfo(\r
+      UInt64 dataOffset,\r
+      const CRecordVector<UInt64> &packSizes,\r
+      const CRecordVector<bool> &packCRCsDefined,\r
+      const CRecordVector<UInt32> &packCRCs);\r
+\r
+  void WriteUnpackInfo(const CObjectVector<CFolder> &folders);\r
+\r
+  void WriteSubStreamsInfo(\r
+      const CObjectVector<CFolder> &folders,\r
+      const CRecordVector<CNum> &numUnpackStreamsInFolders,\r
+      const CRecordVector<UInt64> &unpackSizes,\r
+      const CRecordVector<bool> &digestsDefined,\r
+      const CRecordVector<UInt32> &hashDigests);\r
+\r
+  void SkipAlign(unsigned pos, unsigned alignSize);\r
+  void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);\r
+  void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);\r
+\r
+  HRESULT EncodeStream(\r
+      DECL_EXTERNAL_CODECS_LOC_VARS\r
+      CEncoder &encoder, const CByteBuffer &data,\r
+      CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);\r
+  void WriteHeader(\r
+      const CArchiveDatabase &db,\r
+      const CHeaderOptions &headerOptions,\r
+      UInt64 &headerOffset);\r
+  \r
+  bool _countMode;\r
+  bool _writeToStream;\r
+  size_t _countSize;\r
+  UInt32 _crc;\r
+  COutBuffer _outByte;\r
+  CWriteBufferLoc _outByte2;\r
+\r
+  #ifdef _7Z_VOL\r
+  bool _endMarker;\r
+  #endif\r
+\r
+  HRESULT WriteSignature();\r
+  #ifdef _7Z_VOL\r
+  HRESULT WriteFinishSignature();\r
+  #endif\r
+  HRESULT WriteStartHeader(const CStartHeader &h);\r
+  #ifdef _7Z_VOL\r
+  HRESULT WriteFinishHeader(const CFinishHeader &h);\r
+  #endif\r
+  CMyComPtr<IOutStream> Stream;\r
+public:\r
+\r
+  COutArchive() { _outByte.Create(1 << 16); }\r
+  CMyComPtr<ISequentialOutStream> SeqStream;\r
+  HRESULT Create(ISequentialOutStream *stream, bool endMarker);\r
+  void Close();\r
+  HRESULT SkipPrefixArchiveHeader();\r
+  HRESULT WriteDatabase(\r
+      DECL_EXTERNAL_CODECS_LOC_VARS\r
+      const CArchiveDatabase &db,\r
+      const CCompressionMethodMode *options,\r
+      const CHeaderOptions &headerOptions);\r
+\r
+  #ifdef _7Z_VOL\r
+  static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);\r
+  static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);\r
+  #endif\r
+\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp
new file mode 100755 (executable)
index 0000000..432da23
--- /dev/null
@@ -0,0 +1,164 @@
+// 7zProperties.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "7zProperties.h"\r
+#include "7zHeader.h"\r
+#include "7zHandler.h"\r
+\r
+// #define _MULTI_PACK\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+struct CPropMap\r
+{\r
+  UInt64 FilePropID;\r
+  STATPROPSTG StatPROPSTG;\r
+};\r
+\r
+CPropMap kPropMap[] =\r
+{\r
+  { NID::kName, { NULL, kpidPath, VT_BSTR } },\r
+  { NID::kSize, { NULL, kpidSize, VT_UI8 } },\r
+  { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },\r
+  \r
+  #ifdef _MULTI_PACK\r
+  { 100, { L"Pack0", kpidPackedSize0, VT_UI8 } },\r
+  { 101, { L"Pack1", kpidPackedSize1, VT_UI8 } },\r
+  { 102, { L"Pack2", kpidPackedSize2, VT_UI8 } },\r
+  { 103, { L"Pack3", kpidPackedSize3, VT_UI8 } },\r
+  { 104, { L"Pack4", kpidPackedSize4, VT_UI8 } },\r
+  #endif\r
+\r
+  { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },\r
+  { NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },\r
+  { NID::kATime, { NULL, kpidATime, VT_FILETIME } },\r
+  { NID::kWinAttributes, { NULL, kpidAttrib, VT_UI4 } },\r
+  { NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },\r
+\r
+  { NID::kCRC, { NULL, kpidCRC, VT_UI4 } },\r
+  \r
+  { NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }\r
+\r
+  #ifndef _SFX\r
+  ,\r
+  { 97, { NULL,kpidEncrypted, VT_BOOL } },\r
+  { 98, { NULL,kpidMethod, VT_BSTR } },\r
+  { 99, { NULL,kpidBlock, VT_UI4 } }\r
+  #endif\r
+};\r
+\r
+static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);\r
+\r
+static int FindPropInMap(UInt64 filePropID)\r
+{\r
+  for (int i = 0; i < kPropMapSize; i++)\r
+    if (kPropMap[i].FilePropID == filePropID)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+static void CopyOneItem(CRecordVector<UInt64> &src,\r
+    CRecordVector<UInt64> &dest, UInt32 item)\r
+{\r
+  for (int i = 0; i < src.Size(); i++)\r
+    if (src[i] == item)\r
+    {\r
+      dest.Add(item);\r
+      src.Delete(i);\r
+      return;\r
+    }\r
+}\r
+\r
+static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)\r
+{\r
+  for (int i = 0; i < src.Size(); i++)\r
+    if (src[i] == item)\r
+    {\r
+      src.Delete(i);\r
+      return;\r
+    }\r
+}\r
+\r
+static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)\r
+{\r
+  for (int i = 0; i < dest.Size(); i++)\r
+    if (dest[i] == item)\r
+    {\r
+      dest.Delete(i);\r
+      break;\r
+    }\r
+  dest.Insert(0, item);\r
+}\r
+\r
+void CHandler::FillPopIDs()\r
+{\r
+  _fileInfoPopIDs.Clear();\r
+\r
+  #ifdef _7Z_VOL\r
+  if(_volumes.Size() < 1)\r
+    return;\r
+  const CVolume &volume = _volumes.Front();\r
+  const CArchiveDatabaseEx &_db = volume.Database;\r
+  #endif\r
+\r
+  CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;\r
+\r
+  RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);\r
+  RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);\r
+\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);\r
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);\r
+  _fileInfoPopIDs += fileInfoPopIDs;\r
\r
+  #ifndef _SFX\r
+  _fileInfoPopIDs.Add(97);\r
+  _fileInfoPopIDs.Add(98);\r
+  _fileInfoPopIDs.Add(99);\r
+  #endif\r
+  #ifdef _MULTI_PACK\r
+  _fileInfoPopIDs.Add(100);\r
+  _fileInfoPopIDs.Add(101);\r
+  _fileInfoPopIDs.Add(102);\r
+  _fileInfoPopIDs.Add(103);\r
+  _fileInfoPopIDs.Add(104);\r
+  #endif\r
+\r
+  #ifndef _SFX\r
+  InsertToHead(_fileInfoPopIDs, NID::kMTime);\r
+  InsertToHead(_fileInfoPopIDs, NID::kPackInfo);\r
+  InsertToHead(_fileInfoPopIDs, NID::kSize);\r
+  InsertToHead(_fileInfoPopIDs, NID::kName);\r
+  #endif\r
+}\r
+\r
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)\r
+{\r
+  *numProperties = _fileInfoPopIDs.Size();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)\r
+{\r
+  if ((int)index >= _fileInfoPopIDs.Size())\r
+    return E_INVALIDARG;\r
+  int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);\r
+  if (indexInMap == -1)\r
+    return E_INVALIDARG;\r
+  const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;\r
+  *propID = srcItem.propid;\r
+  *varType = srcItem.vt;\r
+  *name = 0;\r
+  return S_OK;\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zProperties.h b/CPP/7zip/Archive/7z/7zProperties.h
new file mode 100755 (executable)
index 0000000..7b78130
--- /dev/null
@@ -0,0 +1,22 @@
+// 7zProperties.h\r
+\r
+#ifndef __7Z_PROPERTIES_H\r
+#define __7Z_PROPERTIES_H\r
+\r
+#include "../../PropID.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+enum\r
+{\r
+  kpidPackedSize0 = kpidUserDefined,\r
+  kpidPackedSize1,\r
+  kpidPackedSize2,\r
+  kpidPackedSize3,\r
+  kpidPackedSize4\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zRegister.cpp b/CPP/7zip/Archive/7z/7zRegister.cpp
new file mode 100755 (executable)
index 0000000..ac3d133
--- /dev/null
@@ -0,0 +1,18 @@
+// 7zRegister.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Common/RegisterArc.h"\r
+\r
+#include "7zHandler.h"\r
+static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; }\r
+#ifndef EXTRACT_ONLY\r
+static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; }\r
+#else\r
+#define CreateArcOut 0\r
+#endif\r
+\r
+static CArcInfo g_ArcInfo =\r
+  { L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };\r
+\r
+REGISTER_ARC(7z)\r
diff --git a/CPP/7zip/Archive/7z/7zSpecStream.cpp b/CPP/7zip/Archive/7z/7zSpecStream.cpp
new file mode 100755 (executable)
index 0000000..58f2ec4
--- /dev/null
@@ -0,0 +1,24 @@
+// 7zSpecStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "7zSpecStream.h"\r
+\r
+STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  UInt32 realProcessedSize;\r
+  HRESULT result = _stream->Read(data, size, &realProcessedSize);\r
+  _size += realProcessedSize;\r
+  if (processedSize != 0)\r
+    *processedSize = realProcessedSize;\r
+  return result;\r
+}\r
+\r
+STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(\r
+    UInt64 subStream, UInt64 *value)\r
+{\r
+  if (_getSubStreamSize == NULL)\r
+    return E_NOTIMPL;\r
+  return  _getSubStreamSize->GetSubStreamSize(subStream, value);\r
+}\r
+\r
diff --git a/CPP/7zip/Archive/7z/7zSpecStream.h b/CPP/7zip/Archive/7z/7zSpecStream.h
new file mode 100755 (executable)
index 0000000..0058ac2
--- /dev/null
@@ -0,0 +1,35 @@
+// 7zSpecStream.h\r
+\r
+#ifndef __7Z_SPEC_STREAM_H\r
+#define __7Z_SPEC_STREAM_H\r
+\r
+#include "../../IStream.h"\r
+#include "../../ICoder.h"\r
+#include "../../../Common/MyCom.h"\r
+\r
+class CSequentialInStreamSizeCount2:\r
+  public ISequentialInStream,\r
+  public ICompressGetSubStreamSize,\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<ISequentialInStream> _stream;\r
+  CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;\r
+  UInt64 _size;\r
+public:\r
+  void Init(ISequentialInStream *stream)\r
+  {\r
+    _stream = stream;\r
+    _getSubStreamSize = 0;\r
+    _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);\r
+    _size = 0;\r
+  }\r
+  UInt64 GetSize() const { return _size; }\r
+\r
+  MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+\r
+  STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
new file mode 100755 (executable)
index 0000000..4b4db06
--- /dev/null
@@ -0,0 +1,1177 @@
+// 7zUpdate.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../../C/CpuArch.h"\r
+\r
+#include "../../Common/LimitedStreams.h"\r
+#include "../../Common/ProgressUtils.h"\r
+\r
+#include "../../Common/CreateCoder.h"\r
+\r
+#include "../../Compress/CopyCoder.h"\r
+\r
+#include "../Common/ItemNameUtils.h"\r
+#include "../Common/OutStreamWithCRC.h"\r
+\r
+#include "7zDecode.h"\r
+#include "7zEncode.h"\r
+#include "7zFolderInStream.h"\r
+#include "7zHandler.h"\r
+#include "7zOut.h"\r
+#include "7zUpdate.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+static const UInt64 k_LZMA = 0x030101;\r
+static const UInt64 k_BCJ  = 0x03030103;\r
+static const UInt64 k_BCJ2 = 0x0303011B;\r
+\r
+static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";\r
+static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;\r
+static const UInt32 kAlgorithmForBCJ2_LZMA = 1;\r
+static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;\r
+\r
+#ifdef MY_CPU_X86_OR_AMD64\r
+#define USE_86_FILTER\r
+#endif\r
+\r
+static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,\r
+    UInt64 position, UInt64 size, ICompressProgressInfo *progress)\r
+{\r
+  RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));\r
+  CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;\r
+  CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);\r
+  streamSpec->SetStream(inStream);\r
+  streamSpec->Init(size);\r
+\r
+  NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;\r
+  CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;\r
+  RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));\r
+  return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);\r
+}\r
+\r
+static int GetReverseSlashPos(const UString &name)\r
+{\r
+  int slashPos = name.ReverseFind(L'/');\r
+  #ifdef _WIN32\r
+  int slash1Pos = name.ReverseFind(L'\\');\r
+  slashPos = MyMax(slashPos, slash1Pos);\r
+  #endif\r
+  return slashPos;\r
+}\r
+\r
+int CUpdateItem::GetExtensionPos() const\r
+{\r
+  int slashPos = GetReverseSlashPos(Name);\r
+  int dotPos = Name.ReverseFind(L'.');\r
+  if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))\r
+    return Name.Length();\r
+  return dotPos + 1;\r
+}\r
+\r
+UString CUpdateItem::GetExtension() const\r
+{\r
+  return Name.Mid(GetExtensionPos());\r
+}\r
+\r
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }\r
+\r
+#define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b))\r
+\r
+static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)\r
+{\r
+  size_t c1 = a1.GetCapacity();\r
+  size_t c2 = a2.GetCapacity();\r
+  RINOZ_COMP(c1, c2);\r
+  for (size_t i = 0; i < c1; i++)\r
+    RINOZ_COMP(a1[i], a2[i]);\r
+  return 0;\r
+}\r
+\r
+static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2)\r
+{\r
+  RINOZ_COMP(c1.NumInStreams, c2.NumInStreams);\r
+  RINOZ_COMP(c1.NumOutStreams, c2.NumOutStreams);\r
+  RINOZ_COMP(c1.MethodID, c2.MethodID);\r
+  return CompareBuffers(c1.Props, c2.Props);\r
+}\r
+\r
+static int CompareBindPairs(const CBindPair &b1, const CBindPair &b2)\r
+{\r
+  RINOZ_COMP(b1.InIndex, b2.InIndex);\r
+  return MyCompare(b1.OutIndex, b2.OutIndex);\r
+}\r
+\r
+static int CompareFolders(const CFolder &f1, const CFolder &f2)\r
+{\r
+  int s1 = f1.Coders.Size();\r
+  int s2 = f2.Coders.Size();\r
+  RINOZ_COMP(s1, s2);\r
+  int i;\r
+  for (i = 0; i < s1; i++)\r
+    RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i]));\r
+  s1 = f1.BindPairs.Size();\r
+  s2 = f2.BindPairs.Size();\r
+  RINOZ_COMP(s1, s2);\r
+  for (i = 0; i < s1; i++)\r
+    RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i]));\r
+  return 0;\r
+}\r
+\r
+/*\r
+static int CompareFiles(const CFileItem &f1, const CFileItem &f2)\r
+{\r
+  return MyStringCompareNoCase(f1.Name, f2.Name);\r
+}\r
+*/\r
+\r
+struct CFolderRepack\r
+{\r
+  int FolderIndex;\r
+  int Group;\r
+  CNum NumCopyFiles;\r
+};\r
+\r
+static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *param)\r
+{\r
+  RINOZ_COMP(p1->Group, p2->Group);\r
+  int i1 = p1->FolderIndex;\r
+  int i2 = p2->FolderIndex;\r
+  const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;\r
+  RINOZ(CompareFolders(\r
+      db.Folders[i1],\r
+      db.Folders[i2]));\r
+  return MyCompare(i1, i2);\r
+  /*\r
+  RINOZ_COMP(\r
+      db.NumUnpackStreamsVector[i1],\r
+      db.NumUnpackStreamsVector[i2]);\r
+  if (db.NumUnpackStreamsVector[i1] == 0)\r
+    return 0;\r
+  return CompareFiles(\r
+      db.Files[db.FolderStartFileIndex[i1]],\r
+      db.Files[db.FolderStartFileIndex[i2]]);\r
+  */\r
+}\r
+\r
+////////////////////////////////////////////////////////////\r
+\r
+static int CompareEmptyItems(const int *p1, const int *p2, void *param)\r
+{\r
+  const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;\r
+  const CUpdateItem &u1 = updateItems[*p1];\r
+  const CUpdateItem &u2 = updateItems[*p2];\r
+  if (u1.IsDir != u2.IsDir)\r
+    return (u1.IsDir) ? 1 : -1;\r
+  if (u1.IsDir)\r
+  {\r
+    if (u1.IsAnti != u2.IsAnti)\r
+      return (u1.IsAnti ? 1 : -1);\r
+    int n = MyStringCompareNoCase(u1.Name, u2.Name);\r
+    return -n;\r
+  }\r
+  if (u1.IsAnti != u2.IsAnti)\r
+    return (u1.IsAnti ? 1 : -1);\r
+  return MyStringCompareNoCase(u1.Name, u2.Name);\r
+}\r
+\r
+static const char *g_Exts =\r
+  " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"\r
+  " zip jar ear war msi"\r
+  " 3gp avi mov mpeg mpg mpe wmv"\r
+  " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"\r
+  " swf "\r
+  " chm hxi hxs"\r
+  " gif jpeg jpg jp2 png tiff  bmp ico psd psp"\r
+  " awg ps eps cgm dxf svg vrml wmf emf ai md"\r
+  " cad dwg pps key sxi"\r
+  " max 3ds"\r
+  " iso bin nrg mdf img pdi tar cpio xpi"\r
+  " vfd vhd vud vmc vsv"\r
+  " vmdk dsk nvram vmem vmsd vmsn vmss vmtm"\r
+  " inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"\r
+  " f77 f f90 f95"\r
+  " asm sql manifest dep "\r
+  " mak clw csproj vcproj sln dsp dsw "\r
+  " class "\r
+  " bat cmd"\r
+  " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"\r
+  " awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"\r
+  " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"\r
+  " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"\r
+  " abw afp cwk lwp wpd wps wpt wrf wri"\r
+  " abf afm bdf fon mgf otf pcf pfa snf ttf"\r
+  " dbf mdb nsf ntf wdb db fdb gdb"\r
+  " exe dll ocx vbx sfx sys tlb awx com obj lib out o so "\r
+  " pdb pch idb ncb opt";\r
+\r
+int GetExtIndex(const char *ext)\r
+{\r
+  int extIndex = 1;\r
+  const char *p = g_Exts;\r
+  for (;;)\r
+  {\r
+    char c = *p++;\r
+    if (c == 0)\r
+      return extIndex;\r
+    if (c == ' ')\r
+      continue;\r
+    int pos = 0;\r
+    for (;;)\r
+    {\r
+      char c2 = ext[pos++];\r
+      if (c2 == 0 && (c == 0 || c == ' '))\r
+        return extIndex;\r
+      if (c != c2)\r
+        break;\r
+      c = *p++;\r
+    }\r
+    extIndex++;\r
+    for (;;)\r
+    {\r
+      if (c == 0)\r
+        return extIndex;\r
+      if (c == ' ')\r
+        break;\r
+      c = *p++;\r
+    }\r
+  }\r
+}\r
+\r
+struct CRefItem\r
+{\r
+  const CUpdateItem *UpdateItem;\r
+  UInt32 Index;\r
+  UInt32 ExtensionPos;\r
+  UInt32 NamePos;\r
+  int ExtensionIndex;\r
+  CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):\r
+    UpdateItem(&ui),\r
+    Index(index),\r
+    ExtensionPos(0),\r
+    NamePos(0),\r
+    ExtensionIndex(0)\r
+  {\r
+    if (sortByType)\r
+    {\r
+      int slashPos = GetReverseSlashPos(ui.Name);\r
+      NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);\r
+      int dotPos = ui.Name.ReverseFind(L'.');\r
+      if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))\r
+        ExtensionPos = ui.Name.Length();\r
+      else\r
+      {\r
+        ExtensionPos = dotPos + 1;\r
+        UString us = ui.Name.Mid(ExtensionPos);\r
+        if (!us.IsEmpty())\r
+        {\r
+          us.MakeLower();\r
+          int i;\r
+          AString s;\r
+          for (i = 0; i < us.Length(); i++)\r
+          {\r
+            wchar_t c = us[i];\r
+            if (c >= 0x80)\r
+              break;\r
+            s += (char)c;\r
+          }\r
+          if (i == us.Length())\r
+            ExtensionIndex = GetExtIndex(s);\r
+          else\r
+            ExtensionIndex = 0;\r
+        }\r
+      }\r
+    }\r
+  }\r
+};\r
+\r
+static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)\r
+{\r
+  const CRefItem &a1 = *p1;\r
+  const CRefItem &a2 = *p2;\r
+  const CUpdateItem &u1 = *a1.UpdateItem;\r
+  const CUpdateItem &u2 = *a2.UpdateItem;\r
+  int n;\r
+  if (u1.IsDir != u2.IsDir)\r
+    return (u1.IsDir) ? 1 : -1;\r
+  if (u1.IsDir)\r
+  {\r
+    if (u1.IsAnti != u2.IsAnti)\r
+      return (u1.IsAnti ? 1 : -1);\r
+    n = MyStringCompareNoCase(u1.Name, u2.Name);\r
+    return -n;\r
+  }\r
+  bool sortByType = *(bool *)param;\r
+  if (sortByType)\r
+  {\r
+    RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex);\r
+    RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));\r
+    RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));\r
+    if (!u1.MTimeDefined && u2.MTimeDefined) return 1;\r
+    if (u1.MTimeDefined && !u2.MTimeDefined) return -1;\r
+    if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime);\r
+    RINOZ_COMP(u1.Size, u2.Size);\r
+  }\r
+  return MyStringCompareNoCase(u1.Name, u2.Name);\r
+}\r
+\r
+struct CSolidGroup\r
+{\r
+  CRecordVector<UInt32> Indices;\r
+};\r
+\r
+static wchar_t *g_ExeExts[] =\r
+{\r
+  L"dll",\r
+  L"exe",\r
+  L"ocx",\r
+  L"sfx",\r
+  L"sys"\r
+};\r
+\r
+static bool IsExeExt(const UString &ext)\r
+{\r
+  for (int i = 0; i < sizeof(g_ExeExts) / sizeof(g_ExeExts[0]); i++)\r
+    if (ext.CompareNoCase(g_ExeExts[i]) == 0)\r
+      return true;\r
+  return false;\r
+}\r
+\r
+#ifdef USE_86_FILTER\r
+\r
+static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult)\r
+{\r
+  methodResult.Id = methodID;\r
+  methodResult.NumInStreams = numInStreams;\r
+  methodResult.NumOutStreams = 1;\r
+}\r
+\r
+static void MakeExeMethod(const CCompressionMethodMode &method,\r
+    bool bcj2Filter, CCompressionMethodMode &exeMethod)\r
+{\r
+  exeMethod = method;\r
+  if (bcj2Filter)\r
+  {\r
+    CMethodFull methodFull;\r
+    GetMethodFull(k_BCJ2, 4, methodFull);\r
+    exeMethod.Methods.Insert(0, methodFull);\r
+    GetMethodFull(k_LZMA, 1, methodFull);\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kAlgorithm;\r
+      prop.Value = kAlgorithmForBCJ2_LZMA;\r
+      methodFull.Props.Add(prop);\r
+    }\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kMatchFinder;\r
+      prop.Value = kMatchFinderForBCJ2_LZMA;\r
+      methodFull.Props.Add(prop);\r
+    }\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kDictionarySize;\r
+      prop.Value = kDictionaryForBCJ2_LZMA;\r
+      methodFull.Props.Add(prop);\r
+    }\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kNumFastBytes;\r
+      prop.Value = kNumFastBytesForBCJ2_LZMA;\r
+      methodFull.Props.Add(prop);\r
+    }\r
+    {\r
+      CProp prop;\r
+      prop.Id = NCoderPropID::kNumThreads;\r
+      prop.Value = (UInt32)1;\r
+      methodFull.Props.Add(prop);\r
+    }\r
+\r
+    exeMethod.Methods.Add(methodFull);\r
+    exeMethod.Methods.Add(methodFull);\r
+    CBind bind;\r
+\r
+    bind.OutCoder = 0;\r
+    bind.InStream = 0;\r
+\r
+    bind.InCoder = 1;\r
+    bind.OutStream = 0;\r
+    exeMethod.Binds.Add(bind);\r
+\r
+    bind.InCoder = 2;\r
+    bind.OutStream = 1;\r
+    exeMethod.Binds.Add(bind);\r
+\r
+    bind.InCoder = 3;\r
+    bind.OutStream = 2;\r
+    exeMethod.Binds.Add(bind);\r
+  }\r
+  else\r
+  {\r
+    CMethodFull methodFull;\r
+    GetMethodFull(k_BCJ, 1, methodFull);\r
+    exeMethod.Methods.Insert(0, methodFull);\r
+    CBind bind;\r
+    bind.OutCoder = 0;\r
+    bind.InStream = 0;\r
+    bind.InCoder = 1;\r
+    bind.OutStream = 0;\r
+    exeMethod.Binds.Add(bind);\r
+  }\r
+}\r
+\r
+#endif\r
+\r
+static void FromUpdateItemToFileItem(const CUpdateItem &ui,\r
+    CFileItem &file, CFileItem2 &file2)\r
+{\r
+  file.Name = NItemName::MakeLegalName(ui.Name);\r
+  if (ui.AttribDefined)\r
+    file.SetAttrib(ui.Attrib);\r
+  \r
+  file2.CTime = ui.CTime;  file2.CTimeDefined = ui.CTimeDefined;\r
+  file2.ATime = ui.ATime;  file2.ATimeDefined = ui.ATimeDefined;\r
+  file2.MTime = ui.MTime;  file2.MTimeDefined = ui.MTimeDefined;\r
+  file2.IsAnti = ui.IsAnti;\r
+  file2.StartPosDefined = false;\r
+\r
+  file.Size = ui.Size;\r
+  file.IsDir = ui.IsDir;\r
+  file.HasStream = ui.HasStream();\r
+}\r
+\r
+class CFolderOutStream2:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  COutStreamWithCRC *_crcStreamSpec;\r
+  CMyComPtr<ISequentialOutStream> _crcStream;\r
+  const CArchiveDatabaseEx *_db;\r
+  const CBoolVector *_extractStatuses;\r
+  CMyComPtr<ISequentialOutStream> _outStream;\r
+  UInt32 _startIndex;\r
+  int _currentIndex;\r
+  bool _fileIsOpen;\r
+  UInt64 _rem;\r
+\r
+  void OpenFile();\r
+  void CloseFile();\r
+  HRESULT CloseFileAndSetResult();\r
+  HRESULT ProcessEmptyFiles();\r
+public:\r
+  MY_UNKNOWN_IMP\r
+  \r
+  CFolderOutStream2()\r
+  {\r
+    _crcStreamSpec = new COutStreamWithCRC;\r
+    _crcStream = _crcStreamSpec;\r
+  }\r
+\r
+  HRESULT Init(const CArchiveDatabaseEx *db, UInt32 startIndex,\r
+      const CBoolVector *extractStatuses, ISequentialOutStream *outStream);\r
+  void ReleaseOutStream();\r
+  HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; }\r
+\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+HRESULT CFolderOutStream2::Init(const CArchiveDatabaseEx *db, UInt32 startIndex,\r
+    const CBoolVector *extractStatuses, ISequentialOutStream *outStream)\r
+{\r
+  _db = db;\r
+  _startIndex = startIndex;\r
+  _extractStatuses = extractStatuses;\r
+  _outStream = outStream;\r
+\r
+  _currentIndex = 0;\r
+  _fileIsOpen = false;\r
+  return ProcessEmptyFiles();\r
+}\r
+\r
+void CFolderOutStream2::ReleaseOutStream()\r
+{\r
+  _outStream.Release();\r
+  _crcStreamSpec->ReleaseStream();\r
+}\r
+\r
+void CFolderOutStream2::OpenFile()\r
+{\r
+  _crcStreamSpec->SetStream((*_extractStatuses)[_currentIndex] ? _outStream : NULL);\r
+  _crcStreamSpec->Init(true);\r
+  _fileIsOpen = true;\r
+  _rem = _db->Files[_startIndex + _currentIndex].Size;\r
+}\r
+\r
+void CFolderOutStream2::CloseFile()\r
+{\r
+  _crcStreamSpec->ReleaseStream();\r
+  _fileIsOpen = false;\r
+  _currentIndex++;\r
+}\r
+\r
+HRESULT CFolderOutStream2::CloseFileAndSetResult()\r
+{\r
+  const CFileItem &file = _db->Files[_startIndex + _currentIndex];\r
+  CloseFile();\r
+  return (file.IsDir || !file.CrcDefined || file.Crc == _crcStreamSpec->GetCRC()) ? S_OK: S_FALSE;\r
+}\r
+\r
+HRESULT CFolderOutStream2::ProcessEmptyFiles()\r
+{\r
+  while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0)\r
+  {\r
+    OpenFile();\r
+    RINOK(CloseFileAndSetResult());\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  while (size != 0)\r
+  {\r
+    if (_fileIsOpen)\r
+    {\r
+      UInt32 cur = size < _rem ? size : (UInt32)_rem;\r
+      RINOK(_crcStream->Write(data, cur, &cur));\r
+      if (cur == 0)\r
+        break;\r
+      data = (const Byte *)data + cur;\r
+      size -= cur;\r
+      _rem -= cur;\r
+      if (processedSize != NULL)\r
+        *processedSize += cur;\r
+      if (_rem == 0)\r
+      {\r
+        RINOK(CloseFileAndSetResult());\r
+        RINOK(ProcessEmptyFiles());\r
+        continue;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      RINOK(ProcessEmptyFiles());\r
+      if (_currentIndex == _extractStatuses->Size())\r
+      {\r
+        // we don't support partial extracting\r
+        return E_FAIL;\r
+      }\r
+      OpenFile();\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+class CThreadDecoder: public CVirtThread\r
+{\r
+public:\r
+  HRESULT Result;\r
+  CMyComPtr<IInStream> InStream;\r
+\r
+  CFolderOutStream2 *FosSpec;\r
+  CMyComPtr<ISequentialOutStream> Fos;\r
+\r
+  UInt64 StartPos;\r
+  const UInt64 *PackSizes;\r
+  const CFolder *Folder;\r
+  #ifndef _NO_CRYPTO\r
+  CMyComPtr<ICryptoGetTextPassword> GetTextPassword;\r
+  #endif\r
+\r
+  DECL_EXTERNAL_CODECS_VARS\r
+  CDecoder Decoder;\r
+\r
+  #ifndef _7ZIP_ST\r
+  bool MtMode;\r
+  UInt32 NumThreads;\r
+  #endif\r
+\r
+  CThreadDecoder():\r
+    Decoder(true)\r
+  {\r
+    #ifndef _7ZIP_ST\r
+    MtMode = false;\r
+    NumThreads = 1;\r
+    #endif\r
+    FosSpec = new CFolderOutStream2;\r
+    Fos = FosSpec;\r
+    Result = E_FAIL;\r
+  }\r
+  virtual void Execute();\r
+};\r
+\r
+void CThreadDecoder::Execute()\r
+{\r
+  try\r
+  {\r
+    #ifndef _NO_CRYPTO\r
+    bool passwordIsDefined;\r
+    #endif\r
+    Result = Decoder.Decode(\r
+      EXTERNAL_CODECS_VARS\r
+      InStream,\r
+      StartPos,\r
+      PackSizes,\r
+      *Folder,\r
+      Fos,\r
+      NULL\r
+      #ifndef _NO_CRYPTO\r
+      , GetTextPassword, passwordIsDefined\r
+      #endif\r
+      #ifndef _7ZIP_ST\r
+      , MtMode, NumThreads\r
+      #endif\r
+      );\r
+  }\r
+  catch(...)\r
+  {\r
+    Result = E_FAIL;\r
+  }\r
+  if (Result == S_OK)\r
+    Result = FosSpec->CheckFinishedState();\r
+  FosSpec->ReleaseOutStream();\r
+}\r
+\r
+bool static Is86FilteredFolder(const CFolder &f)\r
+{\r
+  for (int i = 0; i < f.Coders.Size(); i++)\r
+  {\r
+    CMethodId m = f.Coders[i].MethodID;\r
+    if (m == k_BCJ || m == k_BCJ2)\r
+      return true;\r
+  }\r
+  return false;\r
+}\r
+\r
+#ifndef _NO_CRYPTO\r
+\r
+class CCryptoGetTextPassword:\r
+  public ICryptoGetTextPassword,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  UString Password;\r
+\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);\r
+};\r
+\r
+STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)\r
+{\r
+  return StringToBstr(Password, password);\r
+}\r
+\r
+#endif\r
+\r
+static const int kNumGroupsMax = 4;\r
+\r
+#ifdef USE_86_FILTER\r
+static bool Is86Group(int group) { return (group & 1) != 0; }\r
+#endif\r
+static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }\r
+static int GetGroupIndex(bool encrypted, int bcjFiltered)\r
+  { return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }\r
+\r
+HRESULT Update(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    IInStream *inStream,\r
+    const CArchiveDatabaseEx *db,\r
+    const CObjectVector<CUpdateItem> &updateItems,\r
+    COutArchive &archive,\r
+    CArchiveDatabase &newDatabase,\r
+    ISequentialOutStream *seqOutStream,\r
+    IArchiveUpdateCallback *updateCallback,\r
+    const CUpdateOptions &options\r
+    #ifndef _NO_CRYPTO\r
+    , ICryptoGetTextPassword *getDecoderPassword\r
+    #endif\r
+    )\r
+{\r
+  UInt64 numSolidFiles = options.NumSolidFiles;\r
+  if (numSolidFiles == 0)\r
+    numSolidFiles = 1;\r
+  /*\r
+  CMyComPtr<IOutStream> outStream;\r
+  RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));\r
+  if (!outStream)\r
+    return E_NOTIMPL;\r
+  */\r
+\r
+  UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0;\r
+  if (startBlockSize > 0 && !options.RemoveSfxBlock)\r
+  {\r
+    RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));\r
+  }\r
+\r
+  CRecordVector<int> fileIndexToUpdateIndexMap;\r
+  CRecordVector<CFolderRepack> folderRefs;\r
+  UInt64 complexity = 0;\r
+  UInt64 inSizeForReduce2 = 0;\r
+  bool needEncryptedRepack = false;\r
+  if (db != 0)\r
+  {\r
+    fileIndexToUpdateIndexMap.Reserve(db->Files.Size());\r
+    int i;\r
+    for (i = 0; i < db->Files.Size(); i++)\r
+      fileIndexToUpdateIndexMap.Add(-1);\r
+\r
+    for (i = 0; i < updateItems.Size(); i++)\r
+    {\r
+      int index = updateItems[i].IndexInArchive;\r
+      if (index != -1)\r
+        fileIndexToUpdateIndexMap[index] = i;\r
+    }\r
+\r
+    for (i = 0; i < db->Folders.Size(); i++)\r
+    {\r
+      CNum indexInFolder = 0;\r
+      CNum numCopyItems = 0;\r
+      CNum numUnpackStreams = db->NumUnpackStreamsVector[i];\r
+      UInt64 repackSize = 0;\r
+      for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++)\r
+      {\r
+        const CFileItem &file = db->Files[fi];\r
+        if (file.HasStream)\r
+        {\r
+          indexInFolder++;\r
+          int updateIndex = fileIndexToUpdateIndexMap[fi];\r
+          if (updateIndex >= 0 && !updateItems[updateIndex].NewData)\r
+          {\r
+            numCopyItems++;\r
+            repackSize += file.Size;\r
+          }\r
+        }\r
+      }\r
+\r
+      if (numCopyItems == 0)\r
+        continue;\r
+\r
+      CFolderRepack rep;\r
+      rep.FolderIndex = i;\r
+      rep.NumCopyFiles = numCopyItems;\r
+      const CFolder &f = db->Folders[i];\r
+      bool isEncrypted = f.IsEncrypted();\r
+      rep.Group = GetGroupIndex(isEncrypted, Is86FilteredFolder(f));\r
+      folderRefs.Add(rep);\r
+      if (numCopyItems == numUnpackStreams)\r
+        complexity += db->GetFolderFullPackSize(i);\r
+      else\r
+      {\r
+        complexity += repackSize;\r
+        if (repackSize > inSizeForReduce2)\r
+          inSizeForReduce2 = repackSize;\r
+        if (isEncrypted)\r
+          needEncryptedRepack = true;\r
+      }\r
+    }\r
+    folderRefs.Sort(CompareFolderRepacks, (void *)db);\r
+  }\r
+\r
+  UInt64 inSizeForReduce = 0;\r
+  int i;\r
+  for (i = 0; i < updateItems.Size(); i++)\r
+  {\r
+    const CUpdateItem &ui = updateItems[i];\r
+    if (ui.NewData)\r
+    {\r
+      complexity += ui.Size;\r
+      if (numSolidFiles != 1)\r
+        inSizeForReduce += ui.Size;\r
+      else if (ui.Size > inSizeForReduce)\r
+        inSizeForReduce = ui.Size;\r
+    }\r
+  }\r
+\r
+  if (inSizeForReduce2 > inSizeForReduce)\r
+    inSizeForReduce = inSizeForReduce2;\r
+\r
+  const UInt32 kMinReduceSize = (1 << 16);\r
+  if (inSizeForReduce < kMinReduceSize)\r
+    inSizeForReduce = kMinReduceSize;\r
+\r
+  RINOK(updateCallback->SetTotal(complexity));\r
+\r
+  CLocalProgress *lps = new CLocalProgress;\r
+  CMyComPtr<ICompressProgressInfo> progress = lps;\r
+  lps->Init(updateCallback, true);\r
+\r
+  CThreadDecoder threadDecoder;\r
+  if (!folderRefs.IsEmpty())\r
+  {\r
+    #ifdef EXTERNAL_CODECS\r
+    threadDecoder._codecsInfo = codecsInfo;\r
+    threadDecoder._externalCodecs = *externalCodecs;\r
+    #endif\r
+    RINOK(threadDecoder.Create());\r
+  }\r
+\r
+  CObjectVector<CSolidGroup> groups;\r
+  for (i = 0; i < kNumGroupsMax; i++)\r
+    groups.Add(CSolidGroup());\r
+\r
+  {\r
+    // ---------- Split files to 2 groups ----------\r
+\r
+    bool useFilters = options.UseFilters;\r
+    const CCompressionMethodMode &method = *options.Method;\r
+    if (method.Methods.Size() != 1 || method.Binds.Size() != 0)\r
+      useFilters = false;\r
+    for (i = 0; i < updateItems.Size(); i++)\r
+    {\r
+      const CUpdateItem &ui = updateItems[i];\r
+      if (!ui.NewData || !ui.HasStream())\r
+        continue;\r
+      bool filteredGroup = false;\r
+      if (useFilters)\r
+      {\r
+        int dotPos = ui.Name.ReverseFind(L'.');\r
+        if (dotPos >= 0)\r
+          filteredGroup = IsExeExt(ui.Name.Mid(dotPos + 1));\r
+      }\r
+      groups[GetGroupIndex(method.PasswordIsDefined, filteredGroup)].Indices.Add(i);\r
+    }\r
+  }\r
+\r
+  #ifndef _NO_CRYPTO\r
+\r
+  CCryptoGetTextPassword *getPasswordSpec = NULL;\r
+  if (needEncryptedRepack)\r
+  {\r
+    getPasswordSpec = new CCryptoGetTextPassword;\r
+    threadDecoder.GetTextPassword = getPasswordSpec;\r
+\r
+    if (options.Method->PasswordIsDefined)\r
+      getPasswordSpec->Password = options.Method->Password;\r
+    else\r
+    {\r
+      if (!getDecoderPassword)\r
+        return E_NOTIMPL;\r
+      CMyComBSTR password;\r
+      RINOK(getDecoderPassword->CryptoGetTextPassword(&password));\r
+      getPasswordSpec->Password = password;\r
+    }\r
+  }\r
+\r
+  #endif\r
+\r
+  // ---------- Compress ----------\r
+\r
+  RINOK(archive.Create(seqOutStream, false));\r
+  RINOK(archive.SkipPrefixArchiveHeader());\r
+\r
+  int folderRefIndex = 0;\r
+  lps->ProgressOffset = 0;\r
+\r
+  for (int groupIndex = 0; groupIndex < kNumGroupsMax; groupIndex++)\r
+  {\r
+    const CSolidGroup &group = groups[groupIndex];\r
+\r
+    CCompressionMethodMode method;\r
+    #ifdef USE_86_FILTER\r
+    if (Is86Group(groupIndex))\r
+      MakeExeMethod(*options.Method, options.MaxFilter, method);\r
+    else\r
+    #endif\r
+      method = *options.Method;\r
+\r
+    if (IsEncryptedGroup(groupIndex))\r
+    {\r
+      if (!method.PasswordIsDefined)\r
+      {\r
+        #ifndef _NO_CRYPTO\r
+        if (getPasswordSpec)\r
+          method.Password = getPasswordSpec->Password;\r
+        #endif\r
+        method.PasswordIsDefined = true;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      method.PasswordIsDefined = false;\r
+      method.Password.Empty();\r
+    }\r
+\r
+    CEncoder encoder(method);\r
+\r
+    for (; folderRefIndex < folderRefs.Size(); folderRefIndex++)\r
+    {\r
+      const CFolderRepack &rep = folderRefs[folderRefIndex];\r
+      if (rep.Group != groupIndex)\r
+        break;\r
+      int folderIndex = rep.FolderIndex;\r
+      \r
+      if (rep.NumCopyFiles == db->NumUnpackStreamsVector[folderIndex])\r
+      {\r
+        UInt64 packSize = db->GetFolderFullPackSize(folderIndex);\r
+        RINOK(WriteRange(inStream, archive.SeqStream,\r
+          db->GetFolderStreamPos(folderIndex, 0), packSize, progress));\r
+        lps->ProgressOffset += packSize;\r
+        \r
+        const CFolder &folder = db->Folders[folderIndex];\r
+        CNum startIndex = db->FolderStartPackStreamIndex[folderIndex];\r
+        for (int j = 0; j < folder.PackStreams.Size(); j++)\r
+        {\r
+          newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]);\r
+          // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);\r
+          // newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]);\r
+        }\r
+        newDatabase.Folders.Add(folder);\r
+      }\r
+      else\r
+      {\r
+        CStreamBinder sb;\r
+        RINOK(sb.CreateEvents());\r
+        CMyComPtr<ISequentialOutStream> sbOutStream;\r
+        CMyComPtr<ISequentialInStream> sbInStream;\r
+        sb.CreateStreams(&sbInStream, &sbOutStream);\r
+        CBoolVector extractStatuses;\r
+        \r
+        CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];\r
+        CNum indexInFolder = 0;\r
+        \r
+        for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)\r
+        {\r
+          bool needExtract = false;\r
+          if (db->Files[fi].HasStream)\r
+          {\r
+            indexInFolder++;\r
+            int updateIndex = fileIndexToUpdateIndexMap[fi];\r
+            if (updateIndex >= 0 && !updateItems[updateIndex].NewData)\r
+              needExtract = true;\r
+          }\r
+          extractStatuses.Add(needExtract);\r
+        }\r
+\r
+        RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));\r
+        sbOutStream.Release();\r
+        \r
+        threadDecoder.InStream = inStream;\r
+        threadDecoder.Folder = &db->Folders[folderIndex];\r
+        threadDecoder.StartPos = db->GetFolderStreamPos(folderIndex, 0);\r
+        threadDecoder.PackSizes = &db->PackSizes[db->FolderStartPackStreamIndex[folderIndex]];\r
+        \r
+        threadDecoder.Start();\r
+        \r
+        int startPackIndex = newDatabase.PackSizes.Size();\r
+        CFolder newFolder;\r
+        RINOK(encoder.Encode(\r
+          EXTERNAL_CODECS_LOC_VARS\r
+          sbInStream, NULL, &inSizeForReduce, newFolder,\r
+          archive.SeqStream, newDatabase.PackSizes, progress));\r
+        \r
+        threadDecoder.WaitFinish();\r
+\r
+        RINOK(threadDecoder.Result);\r
+\r
+        for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)\r
+          lps->OutSize += newDatabase.PackSizes[startPackIndex];\r
+        lps->InSize += newFolder.GetUnpackSize();\r
+        \r
+        newDatabase.Folders.Add(newFolder);\r
+      }\r
+      \r
+      newDatabase.NumUnpackStreamsVector.Add(rep.NumCopyFiles);\r
+      \r
+      CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];\r
+      \r
+      CNum indexInFolder = 0;\r
+      for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)\r
+      {\r
+        CFileItem file;\r
+        CFileItem2 file2;\r
+        db->GetFile(fi, file, file2);\r
+        if (file.HasStream)\r
+        {\r
+          indexInFolder++;\r
+          int updateIndex = fileIndexToUpdateIndexMap[fi];\r
+          if (updateIndex >= 0)\r
+          {\r
+            const CUpdateItem &ui = updateItems[updateIndex];\r
+            if (ui.NewData)\r
+              continue;\r
+            if (ui.NewProps)\r
+            {\r
+              CFileItem uf;\r
+              FromUpdateItemToFileItem(ui, uf, file2);\r
+              uf.Size = file.Size;\r
+              uf.Crc = file.Crc;\r
+              uf.CrcDefined = file.CrcDefined;\r
+              uf.HasStream = file.HasStream;\r
+              file = uf;\r
+            }\r
+            newDatabase.AddFile(file, file2);\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    int numFiles = group.Indices.Size();\r
+    if (numFiles == 0)\r
+      continue;\r
+    CRecordVector<CRefItem> refItems;\r
+    refItems.Reserve(numFiles);\r
+    bool sortByType = (numSolidFiles > 1);\r
+    for (i = 0; i < numFiles; i++)\r
+      refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType));\r
+    refItems.Sort(CompareUpdateItems, (void *)&sortByType);\r
+    \r
+    CRecordVector<UInt32> indices;\r
+    indices.Reserve(numFiles);\r
+\r
+    for (i = 0; i < numFiles; i++)\r
+    {\r
+      UInt32 index = refItems[i].Index;\r
+      indices.Add(index);\r
+      /*\r
+      const CUpdateItem &ui = updateItems[index];\r
+      CFileItem file;\r
+      if (ui.NewProps)\r
+        FromUpdateItemToFileItem(ui, file);\r
+      else\r
+        file = db.Files[ui.IndexInArchive];\r
+      if (file.IsAnti || file.IsDir)\r
+        return E_FAIL;\r
+      newDatabase.Files.Add(file);\r
+      */\r
+    }\r
+    \r
+    for (i = 0; i < numFiles;)\r
+    {\r
+      UInt64 totalSize = 0;\r
+      int numSubFiles;\r
+      UString prevExtension;\r
+      for (numSubFiles = 0; i + numSubFiles < numFiles &&\r
+          numSubFiles < numSolidFiles; numSubFiles++)\r
+      {\r
+        const CUpdateItem &ui = updateItems[indices[i + numSubFiles]];\r
+        totalSize += ui.Size;\r
+        if (totalSize > options.NumSolidBytes)\r
+          break;\r
+        if (options.SolidExtension)\r
+        {\r
+          UString ext = ui.GetExtension();\r
+          if (numSubFiles == 0)\r
+            prevExtension = ext;\r
+          else\r
+            if (ext.CompareNoCase(prevExtension) != 0)\r
+              break;\r
+        }\r
+      }\r
+      if (numSubFiles < 1)\r
+        numSubFiles = 1;\r
+\r
+      CFolderInStream *inStreamSpec = new CFolderInStream;\r
+      CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec);\r
+      inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);\r
+      \r
+      CFolder folderItem;\r
+\r
+      int startPackIndex = newDatabase.PackSizes.Size();\r
+      RINOK(encoder.Encode(\r
+          EXTERNAL_CODECS_LOC_VARS\r
+          solidInStream, NULL, &inSizeForReduce, folderItem,\r
+          archive.SeqStream, newDatabase.PackSizes, progress));\r
+\r
+      for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)\r
+        lps->OutSize += newDatabase.PackSizes[startPackIndex];\r
+\r
+      lps->InSize += folderItem.GetUnpackSize();\r
+      // for ()\r
+      // newDatabase.PackCRCsDefined.Add(false);\r
+      // newDatabase.PackCRCs.Add(0);\r
+      \r
+      newDatabase.Folders.Add(folderItem);\r
+      \r
+      CNum numUnpackStreams = 0;\r
+      for (int subIndex = 0; subIndex < numSubFiles; subIndex++)\r
+      {\r
+        const CUpdateItem &ui = updateItems[indices[i + subIndex]];\r
+        CFileItem file;\r
+        CFileItem2 file2;\r
+        if (ui.NewProps)\r
+          FromUpdateItemToFileItem(ui, file, file2);\r
+        else\r
+          db->GetFile(ui.IndexInArchive, file, file2);\r
+        if (file2.IsAnti || file.IsDir)\r
+          return E_FAIL;\r
+        \r
+        /*\r
+        CFileItem &file = newDatabase.Files[\r
+              startFileIndexInDatabase + i + subIndex];\r
+        */\r
+        if (!inStreamSpec->Processed[subIndex])\r
+        {\r
+          continue;\r
+          // file.Name += L".locked";\r
+        }\r
+\r
+        file.Crc = inStreamSpec->CRCs[subIndex];\r
+        file.Size = inStreamSpec->Sizes[subIndex];\r
+        if (file.Size != 0)\r
+        {\r
+          file.CrcDefined = true;\r
+          file.HasStream = true;\r
+          numUnpackStreams++;\r
+        }\r
+        else\r
+        {\r
+          file.CrcDefined = false;\r
+          file.HasStream = false;\r
+        }\r
+        newDatabase.AddFile(file, file2);\r
+      }\r
+      // numUnpackStreams = 0 is very bad case for locked files\r
+      // v3.13 doesn't understand it.\r
+      newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);\r
+      i += numSubFiles;\r
+    }\r
+  }\r
+\r
+  if (folderRefIndex != folderRefs.Size())\r
+    return E_FAIL;\r
+\r
+  /*\r
+  folderRefs.ClearAndFree();\r
+  fileIndexToUpdateIndexMap.ClearAndFree();\r
+  groups.ClearAndFree();\r
+  */\r
+\r
+  {\r
+    // ---------- Write Folders & Empty Files ----------\r
+    \r
+    CRecordVector<int> emptyRefs;\r
+    for (i = 0; i < updateItems.Size(); i++)\r
+    {\r
+      const CUpdateItem &ui = updateItems[i];\r
+      if (ui.NewData)\r
+      {\r
+        if (ui.HasStream())\r
+          continue;\r
+      }\r
+      else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream)\r
+        continue;\r
+      emptyRefs.Add(i);\r
+    }\r
+    emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);\r
+    for (i = 0; i < emptyRefs.Size(); i++)\r
+    {\r
+      const CUpdateItem &ui = updateItems[emptyRefs[i]];\r
+      CFileItem file;\r
+      CFileItem2 file2;\r
+      if (ui.NewProps)\r
+        FromUpdateItemToFileItem(ui, file, file2);\r
+      else\r
+        db->GetFile(ui.IndexInArchive, file, file2);\r
+      newDatabase.AddFile(file, file2);\r
+    }\r
+  }\r
+    \r
+  newDatabase.ReserveDown();\r
+  return S_OK;\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/7z/7zUpdate.h b/CPP/7zip/Archive/7z/7zUpdate.h
new file mode 100755 (executable)
index 0000000..f3dc885
--- /dev/null
@@ -0,0 +1,88 @@
+// 7zUpdate.h\r
+\r
+#ifndef __7Z_UPDATE_H\r
+#define __7Z_UPDATE_H\r
+\r
+#include "7zCompressionMode.h"\r
+#include "7zIn.h"\r
+#include "7zOut.h"\r
+\r
+#include "../IArchive.h"\r
+\r
+namespace NArchive {\r
+namespace N7z {\r
+\r
+struct CUpdateItem\r
+{\r
+  int IndexInArchive;\r
+  int IndexInClient;\r
+  \r
+  UInt64 CTime;\r
+  UInt64 ATime;\r
+  UInt64 MTime;\r
+\r
+  UInt64 Size;\r
+  UString Name;\r
+\r
+  UInt32 Attrib;\r
+  \r
+  bool NewData;\r
+  bool NewProps;\r
+\r
+  bool IsAnti;\r
+  bool IsDir;\r
+\r
+  bool AttribDefined;\r
+  bool CTimeDefined;\r
+  bool ATimeDefined;\r
+  bool MTimeDefined;\r
+\r
+  bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }\r
+\r
+  CUpdateItem():\r
+      IsAnti(false),\r
+      IsDir(false),\r
+      AttribDefined(false),\r
+      CTimeDefined(false),\r
+      ATimeDefined(false),\r
+      MTimeDefined(false)\r
+      {}\r
+  void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };\r
+\r
+  int GetExtensionPos() const;\r
+  UString GetExtension() const;\r
+};\r
+\r
+struct CUpdateOptions\r
+{\r
+  const CCompressionMethodMode *Method;\r
+  const CCompressionMethodMode *HeaderMethod;\r
+  bool UseFilters;\r
+  bool MaxFilter;\r
+\r
+  CHeaderOptions HeaderOptions;\r
+\r
+  UInt64 NumSolidFiles;\r
+  UInt64 NumSolidBytes;\r
+  bool SolidExtension;\r
+  bool RemoveSfxBlock;\r
+  bool VolumeMode;\r
+};\r
+\r
+HRESULT Update(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    IInStream *inStream,\r
+    const CArchiveDatabaseEx *db,\r
+    const CObjectVector<CUpdateItem> &updateItems,\r
+    COutArchive &archive,\r
+    CArchiveDatabase &newDatabase,\r
+    ISequentialOutStream *seqOutStream,\r
+    IArchiveUpdateCallback *updateCallback,\r
+    const CUpdateOptions &options\r
+    #ifndef _NO_CRYPTO\r
+    , ICryptoGetTextPassword *getDecoderPassword\r
+    #endif\r
+    );\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/7z/StdAfx.cpp b/CPP/7zip/Archive/7z/StdAfx.cpp
new file mode 100755 (executable)
index 0000000..c6d3b1f
--- /dev/null
@@ -0,0 +1,3 @@
+// StdAfx.cpp\r
+\r
+#include "StdAfx.h"\r
diff --git a/CPP/7zip/Archive/7z/StdAfx.h b/CPP/7zip/Archive/7z/StdAfx.h
new file mode 100755 (executable)
index 0000000..a4e6173
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../../Common/MyWindows.h"\r
+#include "../../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Archive.def b/CPP/7zip/Archive/Archive.def
new file mode 100755 (executable)
index 0000000..839245e
--- /dev/null
@@ -0,0 +1,6 @@
+EXPORTS\r
+  CreateObject PRIVATE\r
+  GetHandlerProperty PRIVATE\r
+  GetNumberOfFormats PRIVATE\r
+  GetHandlerProperty2 PRIVATE\r
+  CreateObject PRIVATE\r
diff --git a/CPP/7zip/Archive/Archive2.def b/CPP/7zip/Archive/Archive2.def
new file mode 100755 (executable)
index 0000000..190fbd8
--- /dev/null
@@ -0,0 +1,9 @@
+EXPORTS\r
+  CreateObject PRIVATE\r
+  GetHandlerProperty PRIVATE\r
+  GetNumberOfFormats PRIVATE\r
+  GetHandlerProperty2 PRIVATE\r
+  CreateObject PRIVATE\r
+  GetNumberOfMethods PRIVATE\r
+  GetMethodProperty PRIVATE\r
+  SetLargePageMode PRIVATE\r
diff --git a/CPP/7zip/Archive/ArchiveExports.cpp b/CPP/7zip/Archive/ArchiveExports.cpp
new file mode 100755 (executable)
index 0000000..5d6cf92
--- /dev/null
@@ -0,0 +1,135 @@
+// ArchiveExports.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Common/ComTry.h"\r
+\r
+#include "../../Windows/PropVariant.h"\r
+\r
+#include "../Common/RegisterArc.h"\r
+\r
+static const unsigned int kNumArcsMax = 48;\r
+static unsigned int g_NumArcs = 0;\r
+static unsigned int g_DefaultArcIndex = 0;\r
+static const CArcInfo *g_Arcs[kNumArcsMax];\r
+void RegisterArc(const CArcInfo *arcInfo)\r
+{\r
+  if (g_NumArcs < kNumArcsMax)\r
+  {\r
+    const wchar_t *p = arcInfo->Name;\r
+    if (p[0] == '7' && p[1] == 'z' && p[2] == 0)\r
+      g_DefaultArcIndex = g_NumArcs;\r
+    g_Arcs[g_NumArcs++] = arcInfo;\r
+  }\r
+}\r
+\r
+DEFINE_GUID(CLSID_CArchiveHandler,\r
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);\r
+\r
+#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])\r
+\r
+static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)\r
+{\r
+  if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)\r
+    value->vt = VT_BSTR;\r
+  return S_OK;\r
+}\r
+\r
+static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)\r
+{\r
+  return SetPropString((const char *)&guid, sizeof(GUID), value);\r
+}\r
+\r
+int FindFormatCalssId(const GUID *clsID)\r
+{\r
+  GUID cls = *clsID;\r
+  CLS_ARC_ID_ITEM(cls) = 0;\r
+  if (cls != CLSID_CArchiveHandler)\r
+    return -1;\r
+  Byte id = CLS_ARC_ID_ITEM(*clsID);\r
+  for (unsigned i = 0; i < g_NumArcs; i++)\r
+    if (g_Arcs[i]->ClassId == id)\r
+      return (int)i;\r
+  return -1;\r
+}\r
+\r
+STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)\r
+{\r
+  COM_TRY_BEGIN\r
+  {\r
+    int needIn = (*iid == IID_IInArchive);\r
+    int needOut = (*iid == IID_IOutArchive);\r
+    if (!needIn && !needOut)\r
+      return E_NOINTERFACE;\r
+    int formatIndex = FindFormatCalssId(clsid);\r
+    if (formatIndex < 0)\r
+      return CLASS_E_CLASSNOTAVAILABLE;\r
+    \r
+    const CArcInfo &arc = *g_Arcs[formatIndex];\r
+    if (needIn)\r
+    {\r
+      *outObject = arc.CreateInArchive();\r
+      ((IInArchive *)*outObject)->AddRef();\r
+    }\r
+    else\r
+    {\r
+      if (!arc.CreateOutArchive)\r
+        return CLASS_E_CLASSNOTAVAILABLE;\r
+      *outObject = arc.CreateOutArchive();\r
+      ((IOutArchive *)*outObject)->AddRef();\r
+    }\r
+  }\r
+  COM_TRY_END\r
+  return S_OK;\r
+}\r
+\r
+STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (formatIndex >= g_NumArcs)\r
+    return E_INVALIDARG;\r
+  const CArcInfo &arc = *g_Arcs[formatIndex];\r
+  NWindows::NCOM::CPropVariant prop;\r
+  switch(propID)\r
+  {\r
+    case NArchive::kName:\r
+      prop = arc.Name;\r
+      break;\r
+    case NArchive::kClassID:\r
+    {\r
+      GUID clsId = CLSID_CArchiveHandler;\r
+      CLS_ARC_ID_ITEM(clsId) = arc.ClassId;\r
+      return SetPropGUID(clsId, value);\r
+    }\r
+    case NArchive::kExtension:\r
+      if (arc.Ext != 0)\r
+        prop = arc.Ext;\r
+      break;\r
+    case NArchive::kAddExtension:\r
+      if (arc.AddExt != 0)\r
+        prop = arc.AddExt;\r
+      break;\r
+    case NArchive::kUpdate:\r
+      prop = (bool)(arc.CreateOutArchive != 0);\r
+      break;\r
+    case NArchive::kKeepName:\r
+      prop = arc.KeepName;\r
+      break;\r
+    case NArchive::kStartSignature:\r
+      return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)\r
+{\r
+  return GetHandlerProperty2(g_DefaultArcIndex, propID, value);\r
+}\r
+\r
+STDAPI GetNumberOfFormats(UINT32 *numFormats)\r
+{\r
+  *numFormats = g_NumArcs;\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp
new file mode 100755 (executable)
index 0000000..417e8a7
--- /dev/null
@@ -0,0 +1,121 @@
+// CoderMixer2.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "CoderMixer2.h"\r
+\r
+namespace NCoderMixer {\r
+\r
+CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):\r
+  _srcBindInfo(srcBindInfo)\r
+{\r
+  srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);\r
+\r
+  UInt32  j;\r
+  for (j = 0; j < NumSrcInStreams; j++)\r
+  {\r
+    _srcInToDestOutMap.Add(0);\r
+    DestOutToSrcInMap.Add(0);\r
+  }\r
+  for (j = 0; j < _numSrcOutStreams; j++)\r
+  {\r
+    _srcOutToDestInMap.Add(0);\r
+    _destInToSrcOutMap.Add(0);\r
+  }\r
+\r
+  UInt32 destInOffset = 0;\r
+  UInt32 destOutOffset = 0;\r
+  UInt32 srcInOffset = NumSrcInStreams;\r
+  UInt32 srcOutOffset = _numSrcOutStreams;\r
+\r
+  for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)\r
+  {\r
+    const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];\r
+\r
+    srcInOffset -= srcCoderInfo.NumInStreams;\r
+    srcOutOffset -= srcCoderInfo.NumOutStreams;\r
+    \r
+    UInt32 j;\r
+    for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)\r
+    {\r
+      UInt32 index = srcInOffset + j;\r
+      _srcInToDestOutMap[index] = destOutOffset;\r
+      DestOutToSrcInMap[destOutOffset] = index;\r
+    }\r
+    for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)\r
+    {\r
+      UInt32 index = srcOutOffset + j;\r
+      _srcOutToDestInMap[index] = destInOffset;\r
+      _destInToSrcOutMap[destInOffset] = index;\r
+    }\r
+  }\r
+}\r
+\r
+void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)\r
+{\r
+  destBindInfo.Coders.Clear();\r
+  destBindInfo.BindPairs.Clear();\r
+  destBindInfo.InStreams.Clear();\r
+  destBindInfo.OutStreams.Clear();\r
+\r
+  int i;\r
+  for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)\r
+  {\r
+    const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];\r
+    CCoderStreamsInfo destCoderInfo;\r
+    destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;\r
+    destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;\r
+    destBindInfo.Coders.Add(destCoderInfo);\r
+  }\r
+  for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)\r
+  {\r
+    const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];\r
+    CBindPair destBindPair;\r
+    destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];\r
+    destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];\r
+    destBindInfo.BindPairs.Add(destBindPair);\r
+  }\r
+  for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)\r
+    destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);\r
+  for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)\r
+    destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);\r
+}\r
+\r
+CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):\r
+    NumInStreams(numInStreams),\r
+    NumOutStreams(numOutStreams)\r
+{\r
+  InSizes.Reserve(NumInStreams);\r
+  InSizePointers.Reserve(NumInStreams);\r
+  OutSizes.Reserve(NumOutStreams);\r
+  OutSizePointers.Reserve(NumOutStreams);\r
+}\r
+\r
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,\r
+    CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)\r
+{\r
+  sizes.Clear();\r
+  sizePointers.Clear();\r
+  for(UInt32 i = 0; i < numItems; i++)\r
+  {\r
+    if (srcSizes == 0 || srcSizes[i] == NULL)\r
+    {\r
+      sizes.Add(0);\r
+      sizePointers.Add(NULL);\r
+    }\r
+    else\r
+    {\r
+      sizes.Add(*srcSizes[i]);\r
+      sizePointers.Add(&sizes.Back());\r
+    }\r
+  }\r
+}\r
+\r
+void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes,\r
+      const UInt64 **outSizes)\r
+{\r
+  SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);\r
+  SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);\r
+}\r
+\r
+}\r
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h
new file mode 100755 (executable)
index 0000000..b1893b2
--- /dev/null
@@ -0,0 +1,174 @@
+// CoderMixer2.h\r
+\r
+#ifndef __CODER_MIXER2_H\r
+#define __CODER_MIXER2_H\r
+\r
+#include "../../../Common/MyVector.h"\r
+#include "../../../Common/Types.h"\r
+#include "../../../Common/MyCom.h"\r
+#include "../../ICoder.h"\r
+\r
+namespace NCoderMixer {\r
+\r
+struct CBindPair\r
+{\r
+  UInt32 InIndex;\r
+  UInt32 OutIndex;\r
+};\r
+\r
+struct CCoderStreamsInfo\r
+{\r
+  UInt32 NumInStreams;\r
+  UInt32 NumOutStreams;\r
+};\r
+\r
+struct CBindInfo\r
+{\r
+  CRecordVector<CCoderStreamsInfo> Coders;\r
+  CRecordVector<CBindPair> BindPairs;\r
+  CRecordVector<UInt32> InStreams;\r
+  CRecordVector<UInt32> OutStreams;\r
+\r
+  void Clear()\r
+  {\r
+    Coders.Clear();\r
+    BindPairs.Clear();\r
+    InStreams.Clear();\r
+    OutStreams.Clear();\r
+  }\r
+\r
+  /*\r
+  UInt32 GetCoderStartOutStream(UInt32 coderIndex) const\r
+  {\r
+    UInt32 numOutStreams = 0;\r
+    for (UInt32 i = 0; i < coderIndex; i++)\r
+      numOutStreams += Coders[i].NumOutStreams;\r
+    return numOutStreams;\r
+  }\r
+  */\r
+\r
+\r
+  void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const\r
+  {\r
+    numInStreams = 0;\r
+    numOutStreams = 0;\r
+    for (int i = 0; i < Coders.Size(); i++)\r
+    {\r
+      const CCoderStreamsInfo &coderStreamsInfo = Coders[i];\r
+      numInStreams += coderStreamsInfo.NumInStreams;\r
+      numOutStreams += coderStreamsInfo.NumOutStreams;\r
+    }\r
+  }\r
+\r
+  int FindBinderForInStream(UInt32 inStream) const\r
+  {\r
+    for (int i = 0; i < BindPairs.Size(); i++)\r
+      if (BindPairs[i].InIndex == inStream)\r
+        return i;\r
+    return -1;\r
+  }\r
+  int FindBinderForOutStream(UInt32 outStream) const\r
+  {\r
+    for (int i = 0; i < BindPairs.Size(); i++)\r
+      if (BindPairs[i].OutIndex == outStream)\r
+        return i;\r
+    return -1;\r
+  }\r
+\r
+  UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const\r
+  {\r
+    UInt32 streamIndex = 0;\r
+    for (UInt32 i = 0; i < coderIndex; i++)\r
+      streamIndex += Coders[i].NumInStreams;\r
+    return streamIndex;\r
+  }\r
+\r
+  UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const\r
+  {\r
+    UInt32 streamIndex = 0;\r
+    for (UInt32 i = 0; i < coderIndex; i++)\r
+      streamIndex += Coders[i].NumOutStreams;\r
+    return streamIndex;\r
+  }\r
+\r
+\r
+  void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,\r
+      UInt32 &coderStreamIndex) const\r
+  {\r
+    for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)\r
+    {\r
+      UInt32 curSize = Coders[coderIndex].NumInStreams;\r
+      if (streamIndex < curSize)\r
+      {\r
+        coderStreamIndex = streamIndex;\r
+        return;\r
+      }\r
+      streamIndex -= curSize;\r
+    }\r
+    throw 1;\r
+  }\r
+  void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,\r
+      UInt32 &coderStreamIndex) const\r
+  {\r
+    for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)\r
+    {\r
+      UInt32 curSize = Coders[coderIndex].NumOutStreams;\r
+      if (streamIndex < curSize)\r
+      {\r
+        coderStreamIndex = streamIndex;\r
+        return;\r
+      }\r
+      streamIndex -= curSize;\r
+    }\r
+    throw 1;\r
+  }\r
+};\r
+\r
+class CBindReverseConverter\r
+{\r
+  UInt32 _numSrcOutStreams;\r
+  NCoderMixer::CBindInfo _srcBindInfo;\r
+  CRecordVector<UInt32> _srcInToDestOutMap;\r
+  CRecordVector<UInt32> _srcOutToDestInMap;\r
+  CRecordVector<UInt32> _destInToSrcOutMap;\r
+public:\r
+  UInt32 NumSrcInStreams;\r
+  CRecordVector<UInt32> DestOutToSrcInMap;\r
+\r
+  CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo);\r
+  void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);\r
+};\r
+\r
+struct CCoderInfo2\r
+{\r
+  CMyComPtr<ICompressCoder> Coder;\r
+  CMyComPtr<ICompressCoder2> Coder2;\r
+  UInt32 NumInStreams;\r
+  UInt32 NumOutStreams;\r
+\r
+  CRecordVector<UInt64> InSizes;\r
+  CRecordVector<UInt64> OutSizes;\r
+  CRecordVector<const UInt64 *> InSizePointers;\r
+  CRecordVector<const UInt64 *> OutSizePointers;\r
+\r
+  CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams);\r
+  void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);\r
+\r
+  HRESULT QueryInterface(REFGUID iid, void** pp) const\r
+  {\r
+    IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;\r
+    return p->QueryInterface(iid, pp);\r
+  }\r
+};\r
+\r
+class CCoderMixer2\r
+{\r
+public:\r
+  virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0;\r
+  virtual void ReInit() = 0;\r
+  virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;\r
+};\r
+\r
+}\r
+#endif\r
+\r
diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
new file mode 100755 (executable)
index 0000000..3047b13
--- /dev/null
@@ -0,0 +1,240 @@
+// CoderMixer2MT.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "CoderMixer2MT.h"\r
+\r
+namespace NCoderMixer {\r
+\r
+CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):\r
+    CCoderInfo2(numInStreams, numOutStreams)\r
+{\r
+  InStreams.Reserve(NumInStreams);\r
+  InStreamPointers.Reserve(NumInStreams);\r
+  OutStreams.Reserve(NumOutStreams);\r
+  OutStreamPointers.Reserve(NumOutStreams);\r
+}\r
+\r
+void CCoder2::Execute() { Code(NULL); }\r
+\r
+void CCoder2::Code(ICompressProgressInfo *progress)\r
+{\r
+  InStreamPointers.Clear();\r
+  OutStreamPointers.Clear();\r
+  UInt32 i;\r
+  for (i = 0; i < NumInStreams; i++)\r
+  {\r
+    if (InSizePointers[i] != NULL)\r
+      InSizePointers[i] = &InSizes[i];\r
+    InStreamPointers.Add((ISequentialInStream *)InStreams[i]);\r
+  }\r
+  for (i = 0; i < NumOutStreams; i++)\r
+  {\r
+    if (OutSizePointers[i] != NULL)\r
+      OutSizePointers[i] = &OutSizes[i];\r
+    OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);\r
+  }\r
+  if (Coder)\r
+    Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],\r
+        InSizePointers[0], OutSizePointers[0], progress);\r
+  else\r
+    Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,\r
+      &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);\r
+  {\r
+    int i;\r
+    for (i = 0; i < InStreams.Size(); i++)\r
+      InStreams[i].Release();\r
+    for (i = 0; i < OutStreams.Size(); i++)\r
+      OutStreams[i].Release();\r
+  }\r
+}\r
+\r
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,\r
+    CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)\r
+{\r
+  sizes.Clear();\r
+  sizePointers.Clear();\r
+  for (UInt32 i = 0; i < numItems; i++)\r
+  {\r
+    if (srcSizes == 0 || srcSizes[i] == NULL)\r
+    {\r
+      sizes.Add(0);\r
+      sizePointers.Add(NULL);\r
+    }\r
+    else\r
+    {\r
+      sizes.Add(*srcSizes[i]);\r
+      sizePointers.Add(&sizes.Back());\r
+    }\r
+  }\r
+}\r
+\r
+\r
+void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)\r
+{\r
+  SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);\r
+  SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);\r
+}\r
+\r
+//////////////////////////////////////\r
+// CCoderMixer2MT\r
+\r
+HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)\r
+{\r
+  _bindInfo = bindInfo;\r
+  _streamBinders.Clear();\r
+  for (int i = 0; i < _bindInfo.BindPairs.Size(); i++)\r
+  {\r
+    _streamBinders.Add(CStreamBinder());\r
+    RINOK(_streamBinders.Back().CreateEvents());\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+void CCoderMixer2MT::AddCoderCommon()\r
+{\r
+  const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];\r
+  CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);\r
+  _coders.Add(threadCoderInfo);\r
+}\r
+\r
+void CCoderMixer2MT::AddCoder(ICompressCoder *coder)\r
+{\r
+  AddCoderCommon();\r
+  _coders.Back().Coder = coder;\r
+}\r
+\r
+void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)\r
+{\r
+  AddCoderCommon();\r
+  _coders.Back().Coder2 = coder;\r
+}\r
+\r
+\r
+void CCoderMixer2MT::ReInit()\r
+{\r
+  for (int i = 0; i < _streamBinders.Size(); i++)\r
+    _streamBinders[i].ReInit();\r
+}\r
+\r
+\r
+HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)\r
+{\r
+  /*\r
+  if (_coders.Size() != _bindInfo.Coders.Size())\r
+    throw 0;\r
+  */\r
+  int i;\r
+  for (i = 0; i < _coders.Size(); i++)\r
+  {\r
+    CCoder2 &coderInfo = _coders[i];\r
+    const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];\r
+    coderInfo.InStreams.Clear();\r
+    UInt32 j;\r
+    for (j = 0; j < coderStreamsInfo.NumInStreams; j++)\r
+      coderInfo.InStreams.Add(NULL);\r
+    coderInfo.OutStreams.Clear();\r
+    for (j = 0; j < coderStreamsInfo.NumOutStreams; j++)\r
+      coderInfo.OutStreams.Add(NULL);\r
+  }\r
+\r
+  for (i = 0; i < _bindInfo.BindPairs.Size(); i++)\r
+  {\r
+    const CBindPair &bindPair = _bindInfo.BindPairs[i];\r
+    UInt32 inCoderIndex, inCoderStreamIndex;\r
+    UInt32 outCoderIndex, outCoderStreamIndex;\r
+    _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);\r
+    _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);\r
+\r
+    _streamBinders[i].CreateStreams(\r
+        &_coders[inCoderIndex].InStreams[inCoderStreamIndex],\r
+        &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);\r
+\r
+    CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize;\r
+    _coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize);\r
+    _coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize);\r
+    if (inSetSize && outSetSize)\r
+    {\r
+      const UInt32 kBufSize = 1 << 19;\r
+      inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize);\r
+      outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize);\r
+    }\r
+  }\r
+\r
+  for (i = 0; i < _bindInfo.InStreams.Size(); i++)\r
+  {\r
+    UInt32 inCoderIndex, inCoderStreamIndex;\r
+    _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);\r
+    _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];\r
+  }\r
+  \r
+  for (i = 0; i < _bindInfo.OutStreams.Size(); i++)\r
+  {\r
+    UInt32 outCoderIndex, outCoderStreamIndex;\r
+    _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);\r
+    _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)\r
+{\r
+  for (int i = 0; i < _coders.Size(); i++)\r
+    if (_coders[i].Result == code)\r
+      return code;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,\r
+      const UInt64 ** /* inSizes */,\r
+      UInt32 numInStreams,\r
+      ISequentialOutStream **outStreams,\r
+      const UInt64 ** /* outSizes */,\r
+      UInt32 numOutStreams,\r
+      ICompressProgressInfo *progress)\r
+{\r
+  if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||\r
+      numOutStreams != (UInt32)_bindInfo.OutStreams.Size())\r
+    return E_INVALIDARG;\r
+\r
+  Init(inStreams, outStreams);\r
+\r
+  int i;\r
+  for (i = 0; i < _coders.Size(); i++)\r
+    if (i != _progressCoderIndex)\r
+    {\r
+      RINOK(_coders[i].Create());\r
+    }\r
+\r
+  for (i = 0; i < _coders.Size(); i++)\r
+    if (i != _progressCoderIndex)\r
+      _coders[i].Start();\r
+\r
+  _coders[_progressCoderIndex].Code(progress);\r
+\r
+  for (i = 0; i < _coders.Size(); i++)\r
+    if (i != _progressCoderIndex)\r
+      _coders[i].WaitFinish();\r
+\r
+  RINOK(ReturnIfError(E_ABORT));\r
+  RINOK(ReturnIfError(E_OUTOFMEMORY));\r
+\r
+  for (i = 0; i < _coders.Size(); i++)\r
+  {\r
+    HRESULT result = _coders[i].Result;\r
+    if (result != S_OK && result != E_FAIL && result != S_FALSE)\r
+      return result;\r
+  }\r
+\r
+  RINOK(ReturnIfError(S_FALSE));\r
+\r
+  for (i = 0; i < _coders.Size(); i++)\r
+  {\r
+    HRESULT result = _coders[i].Result;\r
+    if (result != S_OK)\r
+      return result;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+}\r
diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.h b/CPP/7zip/Archive/Common/CoderMixer2MT.h
new file mode 100755 (executable)
index 0000000..acecc39
--- /dev/null
@@ -0,0 +1,80 @@
+// CoderMixer2MT.h\r
+\r
+#ifndef __CODER_MIXER2_MT_H\r
+#define __CODER_MIXER2_MT_H\r
+\r
+#include "CoderMixer2.h"\r
+#include "../../../Common/MyCom.h"\r
+#include "../../Common/StreamBinder.h"\r
+#include "../../Common/VirtThread.h"\r
+\r
+namespace NCoderMixer {\r
+\r
+struct CCoder2: public CCoderInfo2, public CVirtThread\r
+{\r
+  HRESULT Result;\r
+  CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;\r
+  CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;\r
+  CRecordVector<ISequentialInStream*> InStreamPointers;\r
+  CRecordVector<ISequentialOutStream*> OutStreamPointers;\r
+\r
+  CCoder2(UInt32 numInStreams, UInt32 numOutStreams);\r
+  void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);\r
+  virtual void Execute();\r
+  void Code(ICompressProgressInfo *progress);\r
+};\r
+\r
+\r
+/*\r
+  SetBindInfo()\r
+  for each coder\r
+    AddCoder[2]()\r
+  SetProgressIndex(UInt32 coderIndex);\r
\r
+  for each file\r
+  {\r
+    ReInit()\r
+    for each coder\r
+      SetCoderInfo\r
+    Code\r
+  }\r
+*/\r
+\r
+class CCoderMixer2MT:\r
+  public ICompressCoder2,\r
+  public CCoderMixer2,\r
+  public CMyUnknownImp\r
+{\r
+  CBindInfo _bindInfo;\r
+  CObjectVector<CStreamBinder> _streamBinders;\r
+  int _progressCoderIndex;\r
+\r
+  void AddCoderCommon();\r
+  HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);\r
+  HRESULT ReturnIfError(HRESULT code);\r
+public:\r
+  CObjectVector<CCoder2> _coders;\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(Code)(ISequentialInStream **inStreams,\r
+      const UInt64 **inSizes,\r
+      UInt32 numInStreams,\r
+      ISequentialOutStream **outStreams,\r
+      const UInt64 **outSizes,\r
+      UInt32 numOutStreams,\r
+      ICompressProgressInfo *progress);\r
+\r
+  HRESULT SetBindInfo(const CBindInfo &bindInfo);\r
+  void AddCoder(ICompressCoder *coder);\r
+  void AddCoder2(ICompressCoder2 *coder);\r
+  void SetProgressCoderIndex(int coderIndex) {  _progressCoderIndex = coderIndex; }\r
+\r
+  void ReInit();\r
+  void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)\r
+    {  _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }\r
+  UInt64 GetWriteProcessedSize(UInt32 binderIndex) const\r
+    {  return _streamBinders[binderIndex].ProcessedSize; }\r
+};\r
+\r
+}\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.cpp b/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
new file mode 100755 (executable)
index 0000000..62d05af
--- /dev/null
@@ -0,0 +1,15 @@
+// CrossThreadProgress.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "CrossThreadProgress.h"\r
+\r
+STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)\r
+{\r
+  InSize = inSize;\r
+  OutSize = outSize;\r
+  ProgressEvent.Set();\r
+  WaitEvent.Lock();\r
+  return Result;\r
+}\r
+\r
diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.h b/CPP/7zip/Archive/Common/CrossThreadProgress.h
new file mode 100755 (executable)
index 0000000..d414958
--- /dev/null
@@ -0,0 +1,37 @@
+// CrossThreadProgress.h\r
+\r
+#ifndef __CROSSTHREADPROGRESS_H\r
+#define __CROSSTHREADPROGRESS_H\r
+\r
+#include "../../ICoder.h"\r
+#include "../../../Windows/Synchronization.h"\r
+#include "../../../Common/MyCom.h"\r
+\r
+class CCrossThreadProgress:\r
+  public ICompressProgressInfo,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  const UInt64 *InSize;\r
+  const UInt64 *OutSize;\r
+  HRESULT Result;\r
+  NWindows::NSynchronization::CAutoResetEvent ProgressEvent;\r
+  NWindows::NSynchronization::CAutoResetEvent WaitEvent;\r
+\r
+  HRes Create()\r
+  {\r
+    RINOK(ProgressEvent.CreateIfNotCreated());\r
+    return WaitEvent.CreateIfNotCreated();\r
+  }\r
+  void Init()\r
+  {\r
+    ProgressEvent.Reset();\r
+    WaitEvent.Reset();\r
+  }\r
+\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/DummyOutStream.cpp b/CPP/7zip/Archive/Common/DummyOutStream.cpp
new file mode 100755 (executable)
index 0000000..237e01e
--- /dev/null
@@ -0,0 +1,22 @@
+// DummyOutStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "DummyOutStream.h"\r
+\r
+STDMETHODIMP CDummyOutStream::Write(const void *data,  UInt32 size, UInt32 *processedSize)\r
+{\r
+  UInt32 realProcessedSize;\r
+  HRESULT result;\r
+  if(!_stream)\r
+  {\r
+    realProcessedSize = size;\r
+    result = S_OK;\r
+  }\r
+  else\r
+    result = _stream->Write(data, size, &realProcessedSize);\r
+  _size += realProcessedSize;\r
+  if(processedSize != NULL)\r
+    *processedSize = realProcessedSize;\r
+  return result;\r
+}\r
diff --git a/CPP/7zip/Archive/Common/DummyOutStream.h b/CPP/7zip/Archive/Common/DummyOutStream.h
new file mode 100755 (executable)
index 0000000..c993bb3
--- /dev/null
@@ -0,0 +1,24 @@
+// DummyOutStream.h\r
+\r
+#ifndef __DUMMYOUTSTREAM_H\r
+#define __DUMMYOUTSTREAM_H\r
+\r
+#include "../../IStream.h"\r
+#include "Common/MyCom.h"\r
+\r
+class CDummyOutStream:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<ISequentialOutStream> _stream;\r
+  UInt64 _size;\r
+public:\r
+  void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }\r
+  void ReleaseStream() { _stream.Release(); }\r
+  void Init() { _size = 0; }\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  UInt64 GetSize() const { return _size; }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp
new file mode 100755 (executable)
index 0000000..c2254a7
--- /dev/null
@@ -0,0 +1,623 @@
+// HandlerOut.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../Common/StringToInt.h"\r
+\r
+#include "../../../Windows/PropVariant.h"\r
+\r
+#ifndef _7ZIP_ST\r
+#include "../../../Windows/System.h"\r
+#endif\r
+\r
+#include "../../ICoder.h"\r
+\r
+#include "../Common/ParseProperties.h"\r
+\r
+#include "HandlerOut.h"\r
+\r
+using namespace NWindows;\r
+\r
+namespace NArchive {\r
+\r
+static const wchar_t *kCopyMethod = L"Copy";\r
+static const wchar_t *kLZMAMethodName = L"LZMA";\r
+static const wchar_t *kLZMA2MethodName = L"LZMA2";\r
+static const wchar_t *kBZip2MethodName = L"BZip2";\r
+static const wchar_t *kPpmdMethodName = L"PPMd";\r
+static const wchar_t *kDeflateMethodName = L"Deflate";\r
+static const wchar_t *kDeflate64MethodName = L"Deflate64";\r
+\r
+static const wchar_t *kLzmaMatchFinderX1 = L"HC4";\r
+static const wchar_t *kLzmaMatchFinderX5 = L"BT4";\r
+\r
+static const UInt32 kLzmaAlgoX1 = 0;\r
+static const UInt32 kLzmaAlgoX5 = 1;\r
+\r
+static const UInt32 kLzmaDicSizeX1 = 1 << 16;\r
+static const UInt32 kLzmaDicSizeX3 = 1 << 20;\r
+static const UInt32 kLzmaDicSizeX5 = 1 << 24;\r
+static const UInt32 kLzmaDicSizeX7 = 1 << 25;\r
+static const UInt32 kLzmaDicSizeX9 = 1 << 26;\r
+\r
+static const UInt32 kLzmaFastBytesX1 = 32;\r
+static const UInt32 kLzmaFastBytesX7 = 64;\r
+\r
+static const UInt32 kPpmdMemSizeX1 = (1 << 22);\r
+static const UInt32 kPpmdMemSizeX5 = (1 << 24);\r
+static const UInt32 kPpmdMemSizeX7 = (1 << 26);\r
+static const UInt32 kPpmdMemSizeX9 = (192 << 20);\r
+\r
+static const UInt32 kPpmdOrderX1 = 4;\r
+static const UInt32 kPpmdOrderX5 = 6;\r
+static const UInt32 kPpmdOrderX7 = 16;\r
+static const UInt32 kPpmdOrderX9 = 32;\r
+\r
+static const UInt32 kDeflateAlgoX1 = 0;\r
+static const UInt32 kDeflateAlgoX5 = 1;\r
+\r
+static const UInt32 kDeflateFastBytesX1 = 32;\r
+static const UInt32 kDeflateFastBytesX7 = 64;\r
+static const UInt32 kDeflateFastBytesX9 = 128;\r
+\r
+static const UInt32 kDeflatePassesX1 = 1;\r
+static const UInt32 kDeflatePassesX7 = 3;\r
+static const UInt32 kDeflatePassesX9 = 10;\r
+\r
+static const UInt32 kBZip2NumPassesX1 = 1;\r
+static const UInt32 kBZip2NumPassesX7 = 2;\r
+static const UInt32 kBZip2NumPassesX9 = 7;\r
+\r
+static const UInt32 kBZip2DicSizeX1 = 100000;\r
+static const UInt32 kBZip2DicSizeX3 = 500000;\r
+static const UInt32 kBZip2DicSizeX5 = 900000;\r
+\r
+static const wchar_t *kDefaultMethodName = kLZMAMethodName;\r
+\r
+static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";\r
+static const UInt32 kDictionaryForHeaders = 1 << 20;\r
+static const UInt32 kNumFastBytesForHeaders = 273;\r
+static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;\r
+\r
+static bool AreEqual(const UString &methodName, const wchar_t *s)\r
+  { return (methodName.CompareNoCase(s) == 0); }\r
+\r
+bool COneMethodInfo::IsLzma() const\r
+{\r
+  return\r
+    AreEqual(MethodName, kLZMAMethodName) ||\r
+    AreEqual(MethodName, kLZMA2MethodName);\r
+}\r
+\r
+static inline bool IsBZip2Method(const UString &methodName)\r
+  { return AreEqual(methodName, kBZip2MethodName); }\r
+\r
+static inline bool IsPpmdMethod(const UString &methodName)\r
+  { return AreEqual(methodName, kPpmdMethodName); }\r
+\r
+static inline bool IsDeflateMethod(const UString &methodName)\r
+{\r
+  return\r
+    AreEqual(methodName, kDeflateMethodName) ||\r
+    AreEqual(methodName, kDeflate64MethodName);\r
+}\r
+\r
+struct CNameToPropID\r
+{\r
+  PROPID PropID;\r
+  VARTYPE VarType;\r
+  const wchar_t *Name;\r
+};\r
+\r
+static CNameToPropID g_NameToPropID[] =\r
+{\r
+  { NCoderPropID::kBlockSize, VT_UI4, L"C" },\r
+  { NCoderPropID::kDictionarySize, VT_UI4, L"D" },\r
+  { NCoderPropID::kUsedMemorySize, VT_UI4, L"MEM" },\r
+\r
+  { NCoderPropID::kOrder, VT_UI4, L"O" },\r
+  { NCoderPropID::kPosStateBits, VT_UI4, L"PB" },\r
+  { NCoderPropID::kLitContextBits, VT_UI4, L"LC" },\r
+  { NCoderPropID::kLitPosBits, VT_UI4, L"LP" },\r
+  { NCoderPropID::kEndMarker, VT_BOOL, L"eos" },\r
+\r
+  { NCoderPropID::kNumPasses, VT_UI4, L"Pass" },\r
+  { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },\r
+  { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },\r
+  { NCoderPropID::kAlgorithm, VT_UI4, L"a" },\r
+  { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },\r
+  { NCoderPropID::kNumThreads, VT_UI4, L"mt" },\r
+  { NCoderPropID::kDefaultProp, VT_UI4, L"" }\r
+};\r
+\r
+static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)\r
+{\r
+  if (varType == srcProp.vt)\r
+  {\r
+    destProp = srcProp;\r
+    return true;\r
+  }\r
+  if (varType == VT_UI1)\r
+  {\r
+    if (srcProp.vt == VT_UI4)\r
+    {\r
+      UInt32 value = srcProp.ulVal;\r
+      if (value > 0xFF)\r
+        return false;\r
+      destProp = (Byte)value;\r
+      return true;\r
+    }\r
+  }\r
+  else if (varType == VT_BOOL)\r
+  {\r
+    bool res;\r
+    if (SetBoolProperty(res, srcProp) != S_OK)\r
+      return false;\r
+    destProp = res;\r
+    return true;\r
+  }\r
+  return false;\r
+}\r
+    \r
+static int FindPropIdExact(const UString &name)\r
+{\r
+  for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)\r
+    if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+static int FindPropIdStart(const UString &name)\r
+{\r
+  for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)\r
+  {\r
+    UString t = g_NameToPropID[i].Name;\r
+    if (t.CompareNoCase(name.Left(t.Length())) == 0)\r
+      return i;\r
+  }\r
+  return -1;\r
+}\r
+\r
+static void SetMethodProp(COneMethodInfo &m, PROPID propID, const NCOM::CPropVariant &value)\r
+{\r
+  for (int j = 0; j < m.Props.Size(); j++)\r
+    if (m.Props[j].Id == propID)\r
+      return;\r
+  CProp prop;\r
+  prop.Id = propID;\r
+  prop.Value = value;\r
+  m.Props.Add(prop);\r
+}\r
+\r
+void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo\r
+    #ifndef _7ZIP_ST\r
+    , UInt32 numThreads\r
+    #endif\r
+    )\r
+{\r
+  UInt32 level = _level;\r
+  if (oneMethodInfo.MethodName.IsEmpty())\r
+    oneMethodInfo.MethodName = kDefaultMethodName;\r
+  \r
+  if (oneMethodInfo.IsLzma())\r
+  {\r
+    UInt32 dicSize =\r
+      (level >= 9 ? kLzmaDicSizeX9 :\r
+      (level >= 7 ? kLzmaDicSizeX7 :\r
+      (level >= 5 ? kLzmaDicSizeX5 :\r
+      (level >= 3 ? kLzmaDicSizeX3 :\r
+                    kLzmaDicSizeX1))));\r
+    \r
+    UInt32 algo =\r
+      (level >= 5 ? kLzmaAlgoX5 :\r
+                    kLzmaAlgoX1);\r
+    \r
+    UInt32 fastBytes =\r
+      (level >= 7 ? kLzmaFastBytesX7 :\r
+                    kLzmaFastBytesX1);\r
+    \r
+    const wchar_t *matchFinder =\r
+      (level >= 5 ? kLzmaMatchFinderX5 :\r
+                    kLzmaMatchFinderX1);\r
+    \r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);\r
+    #ifndef _7ZIP_ST\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);\r
+    #endif\r
+  }\r
+  else if (IsDeflateMethod(oneMethodInfo.MethodName))\r
+  {\r
+    UInt32 fastBytes =\r
+      (level >= 9 ? kDeflateFastBytesX9 :\r
+      (level >= 7 ? kDeflateFastBytesX7 :\r
+                    kDeflateFastBytesX1));\r
+    \r
+    UInt32 numPasses =\r
+      (level >= 9 ? kDeflatePassesX9 :\r
+      (level >= 7 ? kDeflatePassesX7 :\r
+                    kDeflatePassesX1));\r
+    \r
+    UInt32 algo =\r
+      (level >= 5 ? kDeflateAlgoX5 :\r
+                    kDeflateAlgoX1);\r
+    \r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);\r
+  }\r
+  else if (IsBZip2Method(oneMethodInfo.MethodName))\r
+  {\r
+    UInt32 numPasses =\r
+      (level >= 9 ? kBZip2NumPassesX9 :\r
+      (level >= 7 ? kBZip2NumPassesX7 :\r
+                    kBZip2NumPassesX1));\r
+    \r
+    UInt32 dicSize =\r
+      (level >= 5 ? kBZip2DicSizeX5 :\r
+      (level >= 3 ? kBZip2DicSizeX3 :\r
+                    kBZip2DicSizeX1));\r
+    \r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);\r
+    #ifndef _7ZIP_ST\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);\r
+    #endif\r
+  }\r
+  else if (IsPpmdMethod(oneMethodInfo.MethodName))\r
+  {\r
+    UInt32 useMemSize =\r
+      (level >= 9 ? kPpmdMemSizeX9 :\r
+      (level >= 7 ? kPpmdMemSizeX7 :\r
+      (level >= 5 ? kPpmdMemSizeX5 :\r
+                    kPpmdMemSizeX1)));\r
+    \r
+    UInt32 order =\r
+      (level >= 9 ? kPpmdOrderX9 :\r
+      (level >= 7 ? kPpmdOrderX7 :\r
+      (level >= 5 ? kPpmdOrderX5 :\r
+                    kPpmdOrderX1)));\r
+    \r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);\r
+    SetMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);\r
+  }\r
+}\r
+\r
+static void SplitParams(const UString &srcString, UStringVector &subStrings)\r
+{\r
+  subStrings.Clear();\r
+  UString name;\r
+  int len = srcString.Length();\r
+  if (len == 0)\r
+    return;\r
+  for (int i = 0; i < len; i++)\r
+  {\r
+    wchar_t c = srcString[i];\r
+    if (c == L':')\r
+    {\r
+      subStrings.Add(name);\r
+      name.Empty();\r
+    }\r
+    else\r
+      name += c;\r
+  }\r
+  subStrings.Add(name);\r
+}\r
+\r
+static void SplitParam(const UString &param, UString &name, UString &value)\r
+{\r
+  int eqPos = param.Find(L'=');\r
+  if (eqPos >= 0)\r
+  {\r
+    name = param.Left(eqPos);\r
+    value = param.Mid(eqPos + 1);\r
+    return;\r
+  }\r
+  for(int i = 0; i < param.Length(); i++)\r
+  {\r
+    wchar_t c = param[i];\r
+    if (c >= L'0' && c <= L'9')\r
+    {\r
+      name = param.Left(i);\r
+      value = param.Mid(i);\r
+      return;\r
+    }\r
+  }\r
+  name = param;\r
+}\r
+\r
+HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)\r
+{\r
+  CProp prop;\r
+  int index = FindPropIdExact(name);\r
+  if (index < 0)\r
+    return E_INVALIDARG;\r
+  const CNameToPropID &nameToPropID = g_NameToPropID[index];\r
+  prop.Id = nameToPropID.PropID;\r
+\r
+  if (prop.Id == NCoderPropID::kBlockSize ||\r
+      prop.Id == NCoderPropID::kDictionarySize ||\r
+      prop.Id == NCoderPropID::kUsedMemorySize)\r
+  {\r
+    UInt32 dicSize;\r
+    RINOK(ParsePropDictionaryValue(value, dicSize));\r
+    prop.Value = dicSize;\r
+  }\r
+  else\r
+  {\r
+    NCOM::CPropVariant propValue;\r
+    \r
+    if (nameToPropID.VarType == VT_BSTR)\r
+      propValue = value;\r
+    else if (nameToPropID.VarType == VT_BOOL)\r
+    {\r
+      bool res;\r
+      if (!StringToBool(value, res))\r
+        return E_INVALIDARG;\r
+      propValue = res;\r
+    }\r
+    else\r
+    {\r
+      UInt32 number;\r
+      if (ParseStringToUInt32(value, number) == value.Length())\r
+        propValue = number;\r
+      else\r
+        propValue = value;\r
+    }\r
+    \r
+    if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))\r
+      return E_INVALIDARG;\r
+  }\r
+  oneMethodInfo.Props.Add(prop);\r
+  return S_OK;\r
+}\r
+\r
+HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)\r
+{\r
+  UStringVector params;\r
+  SplitParams(srcString, params);\r
+  if (params.Size() > 0)\r
+    oneMethodInfo.MethodName = params[0];\r
+  for (int i = 1; i < params.Size(); i++)\r
+  {\r
+    const UString &param = params[i];\r
+    UString name, value;\r
+    SplitParam(param, name, value);\r
+    RINOK(SetParam(oneMethodInfo, name, value));\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT COutHandler::SetSolidSettings(const UString &s)\r
+{\r
+  UString s2 = s;\r
+  s2.MakeUpper();\r
+  for (int i = 0; i < s2.Length();)\r
+  {\r
+    const wchar_t *start = ((const wchar_t *)s2) + i;\r
+    const wchar_t *end;\r
+    UInt64 v = ConvertStringToUInt64(start, &end);\r
+    if (start == end)\r
+    {\r
+      if (s2[i++] != 'E')\r
+        return E_INVALIDARG;\r
+      _solidExtension = true;\r
+      continue;\r
+    }\r
+    i += (int)(end - start);\r
+    if (i == s2.Length())\r
+      return E_INVALIDARG;\r
+    wchar_t c = s2[i++];\r
+    switch(c)\r
+    {\r
+      case 'F':\r
+        if (v < 1)\r
+          v = 1;\r
+        _numSolidFiles = v;\r
+        break;\r
+      case 'B':\r
+        _numSolidBytes = v;\r
+        _numSolidBytesDefined = true;\r
+        break;\r
+      case 'K':\r
+        _numSolidBytes = (v << 10);\r
+        _numSolidBytesDefined = true;\r
+        break;\r
+      case 'M':\r
+        _numSolidBytes = (v << 20);\r
+        _numSolidBytesDefined = true;\r
+        break;\r
+      case 'G':\r
+        _numSolidBytes = (v << 30);\r
+        _numSolidBytesDefined = true;\r
+        break;\r
+      default:\r
+        return E_INVALIDARG;\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)\r
+{\r
+  bool isSolid;\r
+  switch(value.vt)\r
+  {\r
+    case VT_EMPTY:\r
+      isSolid = true;\r
+      break;\r
+    case VT_BOOL:\r
+      isSolid = (value.boolVal != VARIANT_FALSE);\r
+      break;\r
+    case VT_BSTR:\r
+      if (StringToBool(value.bstrVal, isSolid))\r
+        break;\r
+      return SetSolidSettings(value.bstrVal);\r
+    default:\r
+      return E_INVALIDARG;\r
+  }\r
+  if (isSolid)\r
+    InitSolid();\r
+  else\r
+    _numSolidFiles = 1;\r
+  return S_OK;\r
+}\r
+\r
+void COutHandler::Init()\r
+{\r
+  _removeSfxBlock = false;\r
+  _compressHeaders = true;\r
+  _encryptHeadersSpecified = false;\r
+  _encryptHeaders = false;\r
+  \r
+  WriteCTime = false;\r
+  WriteATime = false;\r
+  WriteMTime = true;\r
+  \r
+  #ifndef _7ZIP_ST\r
+  _numThreads = NSystem::GetNumberOfProcessors();\r
+  #endif\r
+  \r
+  _level = 5;\r
+  _autoFilter = true;\r
+  _volumeMode = false;\r
+  _crcSize = 4;\r
+  InitSolid();\r
+}\r
+\r
+void COutHandler::BeforeSetProperty()\r
+{\r
+  Init();\r
+  #ifndef _7ZIP_ST\r
+  numProcessors = NSystem::GetNumberOfProcessors();\r
+  #endif\r
+\r
+  mainDicSize = 0xFFFFFFFF;\r
+  mainDicMethodIndex = 0xFFFFFFFF;\r
+  minNumber = 0;\r
+  _crcSize = 4;\r
+}\r
+\r
+HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)\r
+{\r
+  UString name = nameSpec;\r
+  name.MakeUpper();\r
+  if (name.IsEmpty())\r
+    return E_INVALIDARG;\r
+  \r
+  if (name[0] == 'X')\r
+  {\r
+    name.Delete(0);\r
+    _level = 9;\r
+    return ParsePropValue(name, value, _level);\r
+  }\r
+  \r
+  if (name[0] == L'S')\r
+  {\r
+    name.Delete(0);\r
+    if (name.IsEmpty())\r
+      return SetSolidSettings(value);\r
+    if (value.vt != VT_EMPTY)\r
+      return E_INVALIDARG;\r
+    return SetSolidSettings(name);\r
+  }\r
+  \r
+  if (name == L"CRC")\r
+  {\r
+    _crcSize = 4;\r
+    name.Delete(0, 3);\r
+    return ParsePropValue(name, value, _crcSize);\r
+  }\r
+  \r
+  UInt32 number;\r
+  int index = ParseStringToUInt32(name, number);\r
+  UString realName = name.Mid(index);\r
+  if (index == 0)\r
+  {\r
+    if(name.Left(2).CompareNoCase(L"MT") == 0)\r
+    {\r
+      #ifndef _7ZIP_ST\r
+      RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));\r
+      #endif\r
+      return S_OK;\r
+    }\r
+    if (name.CompareNoCase(L"RSFX") == 0)  return SetBoolProperty(_removeSfxBlock, value);\r
+    if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);\r
+    if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);\r
+    if (name.CompareNoCase(L"HCF") == 0)\r
+    {\r
+      bool compressHeadersFull = true;\r
+      RINOK(SetBoolProperty(compressHeadersFull, value));\r
+      if (!compressHeadersFull)\r
+        return E_INVALIDARG;\r
+      return S_OK;\r
+    }\r
+    if (name.CompareNoCase(L"HE") == 0)\r
+    {\r
+      RINOK(SetBoolProperty(_encryptHeaders, value));\r
+      _encryptHeadersSpecified = true;\r
+      return S_OK;\r
+    }\r
+    if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);\r
+    if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);\r
+    if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);\r
+    if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);\r
+    number = 0;\r
+  }\r
+  if (number > 10000)\r
+    return E_FAIL;\r
+  if (number < minNumber)\r
+    return E_INVALIDARG;\r
+  number -= minNumber;\r
+  for(int j = _methods.Size(); j <= (int)number; j++)\r
+  {\r
+    COneMethodInfo oneMethodInfo;\r
+    _methods.Add(oneMethodInfo);\r
+  }\r
+  \r
+  COneMethodInfo &oneMethodInfo = _methods[number];\r
+  \r
+  if (realName.Length() == 0)\r
+  {\r
+    if (value.vt != VT_BSTR)\r
+      return E_INVALIDARG;\r
+    \r
+    RINOK(SetParams(oneMethodInfo, value.bstrVal));\r
+  }\r
+  else\r
+  {\r
+    int index = FindPropIdStart(realName);\r
+    if (index < 0)\r
+      return E_INVALIDARG;\r
+    const CNameToPropID &nameToPropID = g_NameToPropID[index];\r
+    CProp prop;\r
+    prop.Id = nameToPropID.PropID;\r
+\r
+    if (prop.Id == NCoderPropID::kBlockSize ||\r
+        prop.Id == NCoderPropID::kDictionarySize ||\r
+        prop.Id == NCoderPropID::kUsedMemorySize)\r
+    {\r
+      UInt32 dicSize;\r
+      RINOK(ParsePropDictionaryValue(realName.Mid(MyStringLen(nameToPropID.Name)), value, dicSize));\r
+      prop.Value = dicSize;\r
+      if (number <= mainDicMethodIndex)\r
+        mainDicSize = dicSize;\r
+    }\r
+    else\r
+    {\r
+      int index = FindPropIdExact(realName);\r
+      if (index < 0)\r
+        return E_INVALIDARG;\r
+      const CNameToPropID &nameToPropID = g_NameToPropID[index];\r
+      prop.Id = nameToPropID.PropID;\r
+      if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))\r
+        return E_INVALIDARG;\r
+    }\r
+    oneMethodInfo.Props.Add(prop);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+}\r
diff --git a/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h
new file mode 100755 (executable)
index 0000000..c4ccf37
--- /dev/null
@@ -0,0 +1,87 @@
+// HandlerOut.h\r
+\r
+#ifndef __HANDLER_OUT_H\r
+#define __HANDLER_OUT_H\r
+\r
+#include "../../../Common/MyString.h"\r
+#include "../../Common/MethodProps.h"\r
+\r
+namespace NArchive {\r
+\r
+struct COneMethodInfo\r
+{\r
+  CObjectVector<CProp> Props;\r
+  UString MethodName;\r
+\r
+  bool IsLzma() const;\r
+};\r
+\r
+class COutHandler\r
+{\r
+public:\r
+  HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);\r
+  \r
+  HRESULT SetSolidSettings(const UString &s);\r
+  HRESULT SetSolidSettings(const PROPVARIANT &value);\r
+\r
+  #ifndef _7ZIP_ST\r
+  UInt32 _numThreads;\r
+  #endif\r
+\r
+  UInt32 _crcSize;\r
+\r
+  CObjectVector<COneMethodInfo> _methods;\r
+  bool _removeSfxBlock;\r
+  \r
+  UInt64 _numSolidFiles;\r
+  UInt64 _numSolidBytes;\r
+  bool _numSolidBytesDefined;\r
+  bool _solidExtension;\r
+\r
+  bool _compressHeaders;\r
+  bool _encryptHeadersSpecified;\r
+  bool _encryptHeaders;\r
+\r
+  bool WriteCTime;\r
+  bool WriteATime;\r
+  bool WriteMTime;\r
+\r
+  bool _autoFilter;\r
+  UInt32 _level;\r
+\r
+  bool _volumeMode;\r
+\r
+  HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);\r
+  HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);\r
+\r
+  void SetCompressionMethod2(COneMethodInfo &oneMethodInfo\r
+      #ifndef _7ZIP_ST\r
+      , UInt32 numThreads\r
+      #endif\r
+      );\r
+\r
+  void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }\r
+  void InitSolidSize()  { _numSolidBytes = (UInt64)(Int64)(-1); }\r
+  void InitSolid()\r
+  {\r
+    InitSolidFiles();\r
+    InitSolidSize();\r
+    _solidExtension = false;\r
+    _numSolidBytesDefined = false;\r
+  }\r
+\r
+  void Init();\r
+\r
+  COutHandler() { Init(); }\r
+\r
+  void BeforeSetProperty();\r
+\r
+  UInt32 minNumber;\r
+  UInt32 numProcessors;\r
+  UInt32 mainDicSize;\r
+  UInt32 mainDicMethodIndex;\r
+};\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
new file mode 100755 (executable)
index 0000000..6338d0a
--- /dev/null
@@ -0,0 +1,42 @@
+// InStreamWithCRC.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "InStreamWithCRC.h"\r
+\r
+STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  UInt32 realProcessedSize;\r
+  HRESULT result = _stream->Read(data, size, &realProcessedSize);\r
+  _size += realProcessedSize;\r
+  if (size > 0 && realProcessedSize == 0)\r
+    _wasFinished = true;\r
+  _crc = CrcUpdate(_crc, data, realProcessedSize);\r
+  if(processedSize != NULL)\r
+    *processedSize = realProcessedSize;\r
+  return result;\r
+}\r
+\r
+STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  UInt32 realProcessedSize;\r
+  HRESULT result = _stream->Read(data, size, &realProcessedSize);\r
+  /*\r
+  if (size > 0 && realProcessedSize == 0)\r
+    _wasFinished = true;\r
+  */\r
+  _size += realProcessedSize;\r
+  _crc = CrcUpdate(_crc, data, realProcessedSize);\r
+  if(processedSize != NULL)\r
+    *processedSize = realProcessedSize;\r
+  return result;\r
+}\r
+\r
+STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  if (seekOrigin != STREAM_SEEK_SET || offset != 0)\r
+    return E_FAIL;\r
+  _size = 0;\r
+  _crc = CRC_INIT_VAL;\r
+  return _stream->Seek(offset, seekOrigin, newPosition);\r
+}\r
diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.h b/CPP/7zip/Archive/Common/InStreamWithCRC.h
new file mode 100755 (executable)
index 0000000..1a4b2c9
--- /dev/null
@@ -0,0 +1,67 @@
+// InStreamWithCRC.h\r
+\r
+#ifndef __IN_STREAM_WITH_CRC_H\r
+#define __IN_STREAM_WITH_CRC_H\r
+\r
+#include "../../../../C/7zCrc.h"\r
+\r
+#include "../../../Common/MyCom.h"\r
+\r
+#include "../../IStream.h"\r
+\r
+class CSequentialInStreamWithCRC:\r
+  public ISequentialInStream,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+private:\r
+  CMyComPtr<ISequentialInStream> _stream;\r
+  UInt64 _size;\r
+  UInt32 _crc;\r
+  bool _wasFinished;\r
+public:\r
+  void SetStream(ISequentialInStream *stream) { _stream = stream;  }\r
+  void Init()\r
+  {\r
+    _size = 0;\r
+    _wasFinished = false;\r
+    _crc = CRC_INIT_VAL;\r
+  }\r
+  void ReleaseStream() { _stream.Release(); }\r
+  UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }\r
+  UInt64 GetSize() const { return _size; }\r
+  bool WasFinished() const { return _wasFinished; }\r
+};\r
+\r
+class CInStreamWithCRC:\r
+  public IInStream,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP1(IInStream)\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+private:\r
+  CMyComPtr<IInStream> _stream;\r
+  UInt64 _size;\r
+  UInt32 _crc;\r
+  // bool _wasFinished;\r
+public:\r
+  void SetStream(IInStream *stream) { _stream = stream;  }\r
+  void Init()\r
+  {\r
+    _size = 0;\r
+    // _wasFinished = false;\r
+    _crc = CRC_INIT_VAL;\r
+  }\r
+  void ReleaseStream() { _stream.Release(); }\r
+  UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }\r
+  UInt64 GetSize() const { return _size; }\r
+  // bool WasFinished() const { return _wasFinished; }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
new file mode 100755 (executable)
index 0000000..287ddce
--- /dev/null
@@ -0,0 +1,61 @@
+// Archive/Common/ItemNameUtils.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../../C/Types.h"\r
+\r
+#include "ItemNameUtils.h"\r
+\r
+namespace NArchive {\r
+namespace NItemName {\r
+\r
+static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;\r
+static const wchar_t kDirDelimiter = L'/';\r
+\r
+UString MakeLegalName(const UString &name)\r
+{\r
+  UString zipName = name;\r
+  zipName.Replace(kOSDirDelimiter, kDirDelimiter);\r
+  return zipName;\r
+}\r
+\r
+UString GetOSName(const UString &name)\r
+{\r
+  UString newName = name;\r
+  newName.Replace(kDirDelimiter, kOSDirDelimiter);\r
+  return newName;\r
+}\r
+\r
+UString GetOSName2(const UString &name)\r
+{\r
+  if (name.IsEmpty())\r
+    return UString();\r
+  UString newName = GetOSName(name);\r
+  if (newName[newName.Length() - 1] == kOSDirDelimiter)\r
+    newName.Delete(newName.Length() - 1);\r
+  return newName;\r
+}\r
+\r
+bool HasTailSlash(const AString &name, UINT codePage)\r
+{\r
+  if (name.IsEmpty())\r
+    return false;\r
+  LPCSTR prev =\r
+  #if defined(_WIN32) && !defined(UNDER_CE)\r
+    CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);\r
+  #else\r
+    (LPCSTR)(name) + (name.Length() - 1);\r
+  #endif\r
+  return (*prev == '/');\r
+}\r
+\r
+#ifndef _WIN32\r
+UString WinNameToOSName(const UString &name)\r
+{\r
+  UString newName = name;\r
+  newName.Replace(L'\\', kOSDirDelimiter);\r
+  return newName;\r
+}\r
+#endif\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h
new file mode 100755 (executable)
index 0000000..8b91d1c
--- /dev/null
@@ -0,0 +1,24 @@
+// Archive/Common/ItemNameUtils.h\r
+\r
+#ifndef __ARCHIVE_ITEMNAMEUTILS_H\r
+#define __ARCHIVE_ITEMNAMEUTILS_H\r
+\r
+#include "../../../Common/MyString.h"\r
+\r
+namespace NArchive {\r
+namespace NItemName {\r
+\r
+  UString MakeLegalName(const UString &name);\r
+  UString GetOSName(const UString &name);\r
+  UString GetOSName2(const UString &name);\r
+  bool HasTailSlash(const AString &name, UINT codePage);\r
+\r
+  #ifdef _WIN32\r
+  inline UString WinNameToOSName(const UString &name)  { return name; }\r
+  #else\r
+  UString WinNameToOSName(const UString &name);\r
+  #endif\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp
new file mode 100755 (executable)
index 0000000..83b3da1
--- /dev/null
@@ -0,0 +1,190 @@
+// MultiStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "MultiStream.h"\r
+\r
+STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize)\r
+    *processedSize = 0;\r
+  if (size == 0)\r
+    return S_OK;\r
+  if (_pos >= _totalLength)\r
+    return (_pos == _totalLength) ? S_OK : E_FAIL;\r
+\r
+  {\r
+    int left = 0, mid = _streamIndex, right = Streams.Size();\r
+    for (;;)\r
+    {\r
+      CSubStreamInfo &m = Streams[mid];\r
+      if (_pos < m.GlobalOffset)\r
+        right = mid;\r
+      else if (_pos >= m.GlobalOffset + m.Size)\r
+        left = mid + 1;\r
+      else\r
+      {\r
+        _streamIndex = mid;\r
+        break;\r
+      }\r
+      mid = (left + right) / 2;\r
+    }\r
+    _streamIndex = mid;\r
+  }\r
+  \r
+  CSubStreamInfo &s = Streams[_streamIndex];\r
+  UInt64 localPos = _pos - s.GlobalOffset;\r
+  if (localPos != s.LocalPos)\r
+  {\r
+    RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos));\r
+  }\r
+  UInt64 rem = s.Size - localPos;\r
+  if (size > rem)\r
+    size = (UInt32)rem;\r
+  HRESULT result = s.Stream->Read(data, size, &size);\r
+  _pos += size;\r
+  s.LocalPos += size;\r
+  if (processedSize)\r
+    *processedSize = size;\r
+  return result;\r
+}\r
+  \r
+STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  switch(seekOrigin)\r
+  {\r
+    case STREAM_SEEK_SET: _pos = offset; break;\r
+    case STREAM_SEEK_CUR: _pos = _pos + offset; break;\r
+    case STREAM_SEEK_END: _pos = _totalLength + offset; break;\r
+    default: return STG_E_INVALIDFUNCTION;\r
+  }\r
+  if (newPosition != 0)\r
+    *newPosition = _pos;\r
+  return S_OK;\r
+}\r
+\r
+\r
+/*\r
+class COutVolumeStream:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  int _volIndex;\r
+  UInt64 _volSize;\r
+  UInt64 _curPos;\r
+  CMyComPtr<ISequentialOutStream> _volumeStream;\r
+  COutArchive _archive;\r
+  CCRC _crc;\r
+\r
+public:\r
+  MY_UNKNOWN_IMP\r
+\r
+  CFileItem _file;\r
+  CUpdateOptions _options;\r
+  CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;\r
+  void Init(IArchiveUpdateCallback2 *volumeCallback,\r
+      const UString &name)\r
+  {\r
+    _file.Name = name;\r
+    _file.IsStartPosDefined = true;\r
+    _file.StartPos = 0;\r
+    \r
+    VolumeCallback = volumeCallback;\r
+    _volIndex = 0;\r
+    _volSize = 0;\r
+  }\r
+  \r
+  HRESULT Flush();\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+HRESULT COutVolumeStream::Flush()\r
+{\r
+  if (_volumeStream)\r
+  {\r
+    _file.UnPackSize = _curPos;\r
+    _file.FileCRC = _crc.GetDigest();\r
+    RINOK(WriteVolumeHeader(_archive, _file, _options));\r
+    _archive.Close();\r
+    _volumeStream.Release();\r
+    _file.StartPos += _file.UnPackSize;\r
+  }\r
+  return S_OK;\r
+}\r
+*/\r
+\r
+/*\r
+STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if(processedSize != NULL)\r
+    *processedSize = 0;\r
+  while(size > 0)\r
+  {\r
+    if (_streamIndex >= Streams.Size())\r
+    {\r
+      CSubStreamInfo subStream;\r
+      RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));\r
+      RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));\r
+      subStream.Pos = 0;\r
+      Streams.Add(subStream);\r
+      continue;\r
+    }\r
+    CSubStreamInfo &subStream = Streams[_streamIndex];\r
+    if (_offsetPos >= subStream.Size)\r
+    {\r
+      _offsetPos -= subStream.Size;\r
+      _streamIndex++;\r
+      continue;\r
+    }\r
+    if (_offsetPos != subStream.Pos)\r
+    {\r
+      CMyComPtr<IOutStream> outStream;\r
+      RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));\r
+      RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));\r
+      subStream.Pos = _offsetPos;\r
+    }\r
+\r
+    UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);\r
+    UInt32 realProcessed;\r
+    RINOK(subStream.Stream->Write(data, curSize, &realProcessed));\r
+    data = (void *)((Byte *)data + realProcessed);\r
+    size -= realProcessed;\r
+    subStream.Pos += realProcessed;\r
+    _offsetPos += realProcessed;\r
+    _absPos += realProcessed;\r
+    if (_absPos > _length)\r
+      _length = _absPos;\r
+    if(processedSize != NULL)\r
+      *processedSize += realProcessed;\r
+    if (subStream.Pos == subStream.Size)\r
+    {\r
+      _streamIndex++;\r
+      _offsetPos = 0;\r
+    }\r
+    if (realProcessed != curSize && realProcessed == 0)\r
+      return E_FAIL;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  if(seekOrigin >= 3)\r
+    return STG_E_INVALIDFUNCTION;\r
+  switch(seekOrigin)\r
+  {\r
+    case STREAM_SEEK_SET:\r
+      _absPos = offset;\r
+      break;\r
+    case STREAM_SEEK_CUR:\r
+      _absPos += offset;\r
+      break;\r
+    case STREAM_SEEK_END:\r
+      _absPos = _length + offset;\r
+      break;\r
+  }\r
+  _offsetPos = _absPos;\r
+  _streamIndex = 0;\r
+  return S_OK;\r
+}\r
+*/\r
diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h
new file mode 100755 (executable)
index 0000000..74ec6ad
--- /dev/null
@@ -0,0 +1,84 @@
+// MultiStream.h\r
+\r
+#ifndef __MULTI_STREAM_H\r
+#define __MULTI_STREAM_H\r
+\r
+#include "../../../Common/MyCom.h"\r
+#include "../../../Common/MyVector.h"\r
+\r
+#include "../../IStream.h"\r
+\r
+class CMultiStream:\r
+  public IInStream,\r
+  public CMyUnknownImp\r
+{\r
+  UInt64 _pos;\r
+  UInt64 _totalLength;\r
+  int _streamIndex;\r
+public:\r
+  struct CSubStreamInfo\r
+  {\r
+    CMyComPtr<IInStream> Stream;\r
+    UInt64 Size;\r
+    UInt64 GlobalOffset;\r
+    UInt64 LocalPos;\r
+  };\r
+  CObjectVector<CSubStreamInfo> Streams;\r
+  \r
+  HRESULT Init()\r
+  {\r
+    UInt64 total = 0;\r
+    for (int i = 0; i < Streams.Size(); i++)\r
+    {\r
+      CSubStreamInfo &s = Streams[i];\r
+      s.GlobalOffset = total;\r
+      total += Streams[i].Size;\r
+      RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos));\r
+    }\r
+    _totalLength = total;\r
+    _pos = 0;\r
+    _streamIndex = 0;\r
+    return S_OK;\r
+  }\r
+\r
+  MY_UNKNOWN_IMP1(IInStream)\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+};\r
+\r
+/*\r
+class COutMultiStream:\r
+  public IOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  int _streamIndex; // required stream\r
+  UInt64 _offsetPos; // offset from start of _streamIndex index\r
+  UInt64 _absPos;\r
+  UInt64 _length;\r
+\r
+  struct CSubStreamInfo\r
+  {\r
+    CMyComPtr<ISequentialOutStream> Stream;\r
+    UInt64 Size;\r
+    UInt64 Pos;\r
+ };\r
+  CObjectVector<CSubStreamInfo> Streams;\r
+public:\r
+  CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;\r
+  void Init()\r
+  {\r
+    _streamIndex = 0;\r
+    _offsetPos = 0;\r
+    _absPos = 0;\r
+    _length = 0;\r
+  }\r
+\r
+  MY_UNKNOWN_IMP1(IOutStream)\r
+\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+};\r
+*/\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp b/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
new file mode 100755 (executable)
index 0000000..e0d3894
--- /dev/null
@@ -0,0 +1,18 @@
+// OutStreamWithCRC.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "OutStreamWithCRC.h"\r
+\r
+STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  HRESULT result = S_OK;\r
+  if (_stream)\r
+    result = _stream->Write(data, size, &size);\r
+  if (_calculate)\r
+    _crc = CrcUpdate(_crc, data, size);\r
+  _size += size;\r
+  if (processedSize != NULL)\r
+    *processedSize = size;\r
+  return result;\r
+}\r
diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/CPP/7zip/Archive/Common/OutStreamWithCRC.h
new file mode 100755 (executable)
index 0000000..d9eb646
--- /dev/null
@@ -0,0 +1,36 @@
+// OutStreamWithCRC.h\r
+\r
+#ifndef __OUT_STREAM_WITH_CRC_H\r
+#define __OUT_STREAM_WITH_CRC_H\r
+\r
+#include "../../../../C/7zCrc.h"\r
+\r
+#include "../../../Common/MyCom.h"\r
+\r
+#include "../../IStream.h"\r
+\r
+class COutStreamWithCRC:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<ISequentialOutStream> _stream;\r
+  UInt64 _size;\r
+  UInt32 _crc;\r
+  bool _calculate;\r
+public:\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  void SetStream(ISequentialOutStream *stream) { _stream = stream; }\r
+  void ReleaseStream() { _stream.Release(); }\r
+  void Init(bool calculate = true)\r
+  {\r
+    _size = 0;\r
+    _calculate = calculate;\r
+    _crc = CRC_INIT_VAL;\r
+  }\r
+  void InitCRC() { _crc = CRC_INIT_VAL; }\r
+  UInt64 GetSize() const { return _size; }\r
+  UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp
new file mode 100755 (executable)
index 0000000..5550a23
--- /dev/null
@@ -0,0 +1,177 @@
+// ParseProperties.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "ParseProperties.h"\r
+\r
+#include "Common/StringToInt.h"\r
+#include "Common/MyCom.h"\r
+\r
+HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)\r
+{\r
+  if (prop.vt == VT_UI4)\r
+  {\r
+    if (!name.IsEmpty())\r
+      return E_INVALIDARG;\r
+    resValue = prop.ulVal;\r
+  }\r
+  else if (prop.vt == VT_EMPTY)\r
+  {\r
+    if(!name.IsEmpty())\r
+    {\r
+      const wchar_t *start = name;\r
+      const wchar_t *end;\r
+      UInt64 v = ConvertStringToUInt64(start, &end);\r
+      if (end - start != name.Length())\r
+        return E_INVALIDARG;\r
+      resValue = (UInt32)v;\r
+    }\r
+  }\r
+  else\r
+    return E_INVALIDARG;\r
+  return S_OK;\r
+}\r
+\r
+static const int kLogarithmicSizeLimit = 32;\r
+static const wchar_t kByteSymbol = L'B';\r
+static const wchar_t kKiloByteSymbol = L'K';\r
+static const wchar_t kMegaByteSymbol = L'M';\r
+\r
+HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)\r
+{\r
+  UString srcString = srcStringSpec;\r
+  srcString.MakeUpper();\r
+\r
+  const wchar_t *start = srcString;\r
+  const wchar_t *end;\r
+  UInt64 number = ConvertStringToUInt64(start, &end);\r
+  int numDigits = (int)(end - start);\r
+  if (numDigits == 0 || srcString.Length() > numDigits + 1)\r
+    return E_INVALIDARG;\r
+  if (srcString.Length() == numDigits)\r
+  {\r
+    if (number >= kLogarithmicSizeLimit)\r
+      return E_INVALIDARG;\r
+    dicSize = (UInt32)1 << (int)number;\r
+    return S_OK;\r
+  }\r
+  switch (srcString[numDigits])\r
+  {\r
+    case kByteSymbol:\r
+      if (number >= ((UInt64)1 << kLogarithmicSizeLimit))\r
+        return E_INVALIDARG;\r
+      dicSize = (UInt32)number;\r
+      break;\r
+    case kKiloByteSymbol:\r
+      if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))\r
+        return E_INVALIDARG;\r
+      dicSize = (UInt32)(number << 10);\r
+      break;\r
+    case kMegaByteSymbol:\r
+      if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))\r
+        return E_INVALIDARG;\r
+      dicSize = (UInt32)(number << 20);\r
+      break;\r
+    default:\r
+      return E_INVALIDARG;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)\r
+{\r
+  if (name.IsEmpty())\r
+  {\r
+    if (prop.vt == VT_UI4)\r
+    {\r
+      UInt32 logDicSize = prop.ulVal;\r
+      if (logDicSize >= 32)\r
+        return E_INVALIDARG;\r
+      resValue = (UInt32)1 << logDicSize;\r
+      return S_OK;\r
+    }\r
+    if (prop.vt == VT_BSTR)\r
+      return ParsePropDictionaryValue(prop.bstrVal, resValue);\r
+    return E_INVALIDARG;\r
+  }\r
+  return ParsePropDictionaryValue(name, resValue);\r
+}\r
+\r
+bool StringToBool(const UString &s, bool &res)\r
+{\r
+  if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)\r
+  {\r
+    res = true;\r
+    return true;\r
+  }\r
+  if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)\r
+  {\r
+    res = false;\r
+    return true;\r
+  }\r
+  return false;\r
+}\r
+\r
+HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)\r
+{\r
+  switch(value.vt)\r
+  {\r
+    case VT_EMPTY:\r
+      dest = true;\r
+      return S_OK;\r
+    case VT_BOOL:\r
+      dest = (value.boolVal != VARIANT_FALSE);\r
+      return S_OK;\r
+    /*\r
+    case VT_UI4:\r
+      dest = (value.ulVal != 0);\r
+      break;\r
+    */\r
+    case VT_BSTR:\r
+      return StringToBool(value.bstrVal, dest) ?  S_OK : E_INVALIDARG;\r
+  }\r
+  return E_INVALIDARG;\r
+}\r
+\r
+int ParseStringToUInt32(const UString &srcString, UInt32 &number)\r
+{\r
+  const wchar_t *start = srcString;\r
+  const wchar_t *end;\r
+  UInt64 number64 = ConvertStringToUInt64(start, &end);\r
+  if (number64 > 0xFFFFFFFF)\r
+  {\r
+    number = 0;\r
+    return 0;\r
+  }\r
+  number = (UInt32)number64;\r
+  return (int)(end - start);\r
+}\r
+\r
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)\r
+{\r
+  if (name.IsEmpty())\r
+  {\r
+    switch(prop.vt)\r
+    {\r
+      case VT_UI4:\r
+        numThreads = prop.ulVal;\r
+        break;\r
+      default:\r
+      {\r
+        bool val;\r
+        RINOK(SetBoolProperty(val, prop));\r
+        numThreads = (val ? defaultNumThreads : 1);\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  else\r
+  {\r
+    UInt32 number;\r
+    int index = ParseStringToUInt32(name, number);\r
+    if (index != name.Length())\r
+      return E_INVALIDARG;\r
+    numThreads = number;\r
+  }\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/Archive/Common/ParseProperties.h b/CPP/7zip/Archive/Common/ParseProperties.h
new file mode 100755 (executable)
index 0000000..c64fc1e
--- /dev/null
@@ -0,0 +1,18 @@
+// ParseProperties.h\r
+\r
+#ifndef __PARSEPROPERTIES_H\r
+#define __PARSEPROPERTIES_H\r
+\r
+#include "Common/MyString.h"\r
+#include "Common/Types.h"\r
+\r
+HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);\r
+HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);\r
+HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);\r
+\r
+bool StringToBool(const UString &s, bool &res);\r
+HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);\r
+int ParseStringToUInt32(const UString &srcString, UInt32 &number);\r
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Common/StdAfx.h b/CPP/7zip/Archive/Common/StdAfx.h
new file mode 100755 (executable)
index 0000000..a4e6173
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../../Common/MyWindows.h"\r
+#include "../../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/DllExports2.cpp b/CPP/7zip/Archive/DllExports2.cpp
new file mode 100755 (executable)
index 0000000..a45b5c9
--- /dev/null
@@ -0,0 +1,74 @@
+// DLLExports.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Common/MyInitGuid.h"\r
+\r
+#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)\r
+#include "../../../C/Alloc.h"\r
+#endif\r
+\r
+#include "../../Common/ComTry.h"\r
+\r
+#include "../../Windows/NtCheck.h"\r
+#include "../../Windows/PropVariant.h"\r
+\r
+#include "../ICoder.h"\r
+#include "../IPassword.h"\r
+\r
+#include "IArchive.h"\r
+\r
+HINSTANCE g_hInstance;\r
+\r
+#define NT_CHECK_FAIL_ACTION return FALSE;\r
+\r
+extern "C"\r
+BOOL WINAPI DllMain(\r
+  #ifdef UNDER_CE\r
+  HANDLE\r
+  #else\r
+  HINSTANCE\r
+  #endif\r
+  hInstance, DWORD dwReason, LPVOID /*lpReserved*/)\r
+{\r
+  if (dwReason == DLL_PROCESS_ATTACH)\r
+  {\r
+    g_hInstance = (HINSTANCE)hInstance;\r
+    NT_CHECK;\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+DEFINE_GUID(CLSID_CArchiveHandler,\r
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);\r
+\r
+static const UInt16 kDecodeId = 0x2790;\r
+\r
+DEFINE_GUID(CLSID_CCodec,\r
+0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\r
+\r
+STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);\r
+STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);\r
+\r
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)\r
+{\r
+  // COM_TRY_BEGIN\r
+  *outObject = 0;\r
+  if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter)\r
+  {\r
+    return CreateCoder(clsid, iid, outObject);\r
+  }\r
+  else\r
+  {\r
+    return CreateArchiver(clsid, iid, outObject);\r
+  }\r
+  // COM_TRY_END\r
+}\r
+\r
+STDAPI SetLargePageMode()\r
+{\r
+  #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)\r
+  SetLargePageSize();\r
+  #endif\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h
new file mode 100755 (executable)
index 0000000..e4101cc
--- /dev/null
@@ -0,0 +1,234 @@
+// IArchive.h\r
+\r
+#ifndef __IARCHIVE_H\r
+#define __IARCHIVE_H\r
+\r
+#include "../IProgress.h"\r
+#include "../IStream.h"\r
+#include "../PropID.h"\r
+\r
+#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)\r
+#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)\r
+\r
+namespace NFileTimeType\r
+{\r
+  enum EEnum\r
+  {\r
+    kWindows,\r
+    kUnix,\r
+    kDOS\r
+  };\r
+}\r
+\r
+namespace NArchive\r
+{\r
+  enum\r
+  {\r
+    kName = 0,\r
+    kClassID,\r
+    kExtension,\r
+    kAddExtension,\r
+    kUpdate,\r
+    kKeepName,\r
+    kStartSignature,\r
+    kFinishSignature,\r
+    kAssociate\r
+  };\r
+\r
+  namespace NExtract\r
+  {\r
+    namespace NAskMode\r
+    {\r
+      enum\r
+      {\r
+        kExtract = 0,\r
+        kTest,\r
+        kSkip\r
+      };\r
+    }\r
+    namespace NOperationResult\r
+    {\r
+      enum\r
+      {\r
+        kOK = 0,\r
+        kUnSupportedMethod,\r
+        kDataError,\r
+        kCRCError\r
+      };\r
+    }\r
+  }\r
+  namespace NUpdate\r
+  {\r
+    namespace NOperationResult\r
+    {\r
+      enum\r
+      {\r
+        kOK = 0,\r
+        kError\r
+      };\r
+    }\r
+  }\r
+}\r
+\r
+#define INTERFACE_IArchiveOpenCallback(x) \\r
+  STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \\r
+  STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \\r
+\r
+ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)\r
+{\r
+  INTERFACE_IArchiveOpenCallback(PURE);\r
+};\r
+\r
+\r
+#define INTERFACE_IArchiveExtractCallback(x) \\r
+  INTERFACE_IProgress(x) \\r
+  STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,  Int32 askExtractMode) x; \\r
+  STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \\r
+  STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \\r
+\r
+ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)\r
+{\r
+  INTERFACE_IArchiveExtractCallback(PURE)\r
+};\r
+\r
+\r
+#define INTERFACE_IArchiveOpenVolumeCallback(x) \\r
+  STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \\r
+  STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \\r
+\r
+ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)\r
+{\r
+  INTERFACE_IArchiveOpenVolumeCallback(PURE);\r
+};\r
+\r
+\r
+ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)\r
+{\r
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;\r
+};\r
+\r
+\r
+ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)\r
+{\r
+  STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;\r
+};\r
+\r
+\r
+/*\r
+IInArchive::Extract:\r
+  indices must be sorted\r
+  numItems = 0xFFFFFFFF means "all files"\r
+  testMode != 0 means "test files without writing to outStream"\r
+*/\r
+\r
+#define INTERFACE_IInArchive(x) \\r
+  STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \\r
+  STDMETHOD(Close)() x; \\r
+  STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \\r
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \\r
+  STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \\r
+  STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \\r
+  STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \\r
+  STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \\r
+  STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \\r
+  STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x;\r
+\r
+ARCHIVE_INTERFACE(IInArchive, 0x60)\r
+{\r
+  INTERFACE_IInArchive(PURE)\r
+};\r
+\r
+ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61)\r
+{\r
+  STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;\r
+};\r
+\r
+#define INTERFACE_IArchiveUpdateCallback(x) \\r
+  INTERFACE_IProgress(x); \\r
+  STDMETHOD(GetUpdateItemInfo)(UInt32 index,  \\r
+      Int32 *newData, /*1 - new data, 0 - old data */ \\r
+      Int32 *newProperties, /* 1 - new properties, 0 - old properties */ \\r
+      UInt32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ \\r
+      )  x; \\r
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \\r
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \\r
+  STDMETHOD(SetOperationResult)(Int32 operationResult) x; \\r
+\r
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)\r
+{\r
+  INTERFACE_IArchiveUpdateCallback(PURE);\r
+};\r
+\r
+#define INTERFACE_IArchiveUpdateCallback2(x) \\r
+  INTERFACE_IArchiveUpdateCallback(x) \\r
+  STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \\r
+  STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \\r
+\r
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)\r
+{\r
+  INTERFACE_IArchiveUpdateCallback2(PURE);\r
+};\r
+\r
+\r
+#define INTERFACE_IOutArchive(x) \\r
+  STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \\r
+  STDMETHOD(GetFileTimeType)(UInt32 *type) x;\r
+\r
+ARCHIVE_INTERFACE(IOutArchive, 0xA0)\r
+{\r
+  INTERFACE_IOutArchive(PURE)\r
+};\r
+\r
+\r
+ARCHIVE_INTERFACE(ISetProperties, 0x03)\r
+{\r
+  STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;\r
+};\r
+\r
+\r
+#define IMP_IInArchive_GetProp(k) \\r
+  (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \\r
+    { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \\r
+    const STATPROPSTG &srcItem = k[index]; \\r
+    *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \\r
+\r
+#define IMP_IInArchive_GetProp_WITH_NAME(k) \\r
+  (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \\r
+    { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \\r
+    const STATPROPSTG &srcItem = k[index]; \\r
+    *propID = srcItem.propid; *varType = srcItem.vt; \\r
+    if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \\r
+\r
+#define IMP_IInArchive_Props \\r
+  STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \\r
+    { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \\r
+  STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)\r
+\r
+#define IMP_IInArchive_Props_WITH_NAME \\r
+  STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \\r
+    { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \\r
+  STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)\r
+\r
+\r
+#define IMP_IInArchive_ArcProps \\r
+  STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \\r
+    { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \\r
+  STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)\r
+\r
+#define IMP_IInArchive_ArcProps_WITH_NAME \\r
+  STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \\r
+    { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \\r
+  STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps)\r
+\r
+#define IMP_IInArchive_ArcProps_NO_Table \\r
+  STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \\r
+    { *numProperties = 0; return S_OK; } \\r
+  STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \\r
+    { return E_NOTIMPL; } \\r
+\r
+#define IMP_IInArchive_ArcProps_NO \\r
+  IMP_IInArchive_ArcProps_NO_Table \\r
+  STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \\r
+    { value->vt = VT_EMPTY; return S_OK; }\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/Icons/7z.ico b/CPP/7zip/Archive/Icons/7z.ico
new file mode 100755 (executable)
index 0000000..319753a
Binary files /dev/null and b/CPP/7zip/Archive/Icons/7z.ico differ
diff --git a/CPP/7zip/Archive/LzmaHandler.cpp b/CPP/7zip/Archive/LzmaHandler.cpp
new file mode 100755 (executable)
index 0000000..9b8db45
--- /dev/null
@@ -0,0 +1,430 @@
+// LzmaHandler.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/CpuArch.h"\r
+\r
+#include "Common/ComTry.h"\r
+#include "Common/IntToString.h"\r
+\r
+#include "Windows/PropVariant.h"\r
+\r
+#include "../Common/CreateCoder.h"\r
+#include "../Common/ProgressUtils.h"\r
+#include "../Common/RegisterArc.h"\r
+#include "../Common/StreamUtils.h"\r
+\r
+#include "../Compress/LzmaDecoder.h"\r
+\r
+#include "Common/DummyOutStream.h"\r
+\r
+using namespace NWindows;\r
+\r
+namespace NArchive {\r
+namespace NLzma {\r
+\r
+static bool CheckDicSize(const Byte *p)\r
+{\r
+  UInt32 dicSize = GetUi32(p);\r
+  for (int i = 1; i <= 30; i++)\r
+    if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i))\r
+      return true;\r
+  return (dicSize == 0xFFFFFFFF);\r
+}\r
+\r
+STATPROPSTG kProps[] =\r
+{\r
+  { NULL, kpidSize, VT_UI8},\r
+  { NULL, kpidPackSize, VT_UI8},\r
+  { NULL, kpidMethod, VT_BSTR}\r
+};\r
+\r
+struct CHeader\r
+{\r
+  UInt64 Size;\r
+  Byte FilterID;\r
+  Byte LzmaProps[5];\r
+\r
+  UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); }\r
+  bool HasSize() const { return (Size != (UInt64)(Int64)-1); }\r
+  bool Parse(const Byte *buf, bool isThereFilter);\r
+};\r
+\r
+bool CHeader::Parse(const Byte *buf, bool isThereFilter)\r
+{\r
+  FilterID = 0;\r
+  if (isThereFilter)\r
+    FilterID = buf[0];\r
+  const Byte *sig = buf + (isThereFilter ? 1 : 0);\r
+  for (int i = 0; i < 5; i++)\r
+    LzmaProps[i] = sig[i];\r
+  Size = GetUi64(sig + 5);\r
+  return\r
+    LzmaProps[0] < 5 * 5 * 9 &&\r
+    FilterID < 2 &&\r
+    (!HasSize() || Size < ((UInt64)1 << 56)) &&\r
+    CheckDicSize(LzmaProps + 1);\r
+}\r
+\r
+class CDecoder\r
+{\r
+  NCompress::NLzma::CDecoder *_lzmaDecoderSpec;\r
+  CMyComPtr<ICompressCoder> _lzmaDecoder;\r
+  CMyComPtr<ISequentialOutStream> _bcjStream;\r
+public:\r
+  ~CDecoder();\r
+  HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS\r
+      bool filtered, ISequentialInStream *inStream);\r
+\r
+  HRESULT Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress);\r
+\r
+  UInt64 GetInputProcessedSize() const { return _lzmaDecoderSpec->GetInputProcessedSize(); }\r
+\r
+  void ReleaseInStream() { if (_lzmaDecoder) _lzmaDecoderSpec->ReleaseInStream(); }\r
+\r
+  HRESULT ReadInput(Byte *data, UInt32 size, UInt32 *processedSize)\r
+    { return _lzmaDecoderSpec->ReadFromInputStream(data, size, processedSize); }\r
+};\r
+\r
+static const UInt64 k_BCJ = 0x03030103;\r
+  \r
+HRESULT CDecoder::Create(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    bool filteredMode, ISequentialInStream *inStream)\r
+{\r
+  if (!_lzmaDecoder)\r
+  {\r
+    _lzmaDecoderSpec = new NCompress::NLzma::CDecoder;\r
+    _lzmaDecoder = _lzmaDecoderSpec;\r
+  }\r
+\r
+  if (filteredMode)\r
+  {\r
+    if (!_bcjStream)\r
+    {\r
+      CMyComPtr<ICompressCoder> coder;\r
+      RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS k_BCJ, coder, false));\r
+      if (!coder)\r
+        return E_NOTIMPL;\r
+      coder.QueryInterface(IID_ISequentialOutStream, &_bcjStream);\r
+      if (!_bcjStream)\r
+        return E_NOTIMPL;\r
+    }\r
+  }\r
+\r
+  return _lzmaDecoderSpec->SetInStream(inStream);\r
+}\r
+\r
+CDecoder::~CDecoder()\r
+{\r
+  ReleaseInStream();\r
+}\r
+\r
+HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,\r
+    ICompressProgressInfo *progress)\r
+{\r
+  if (header.FilterID > 1)\r
+    return E_NOTIMPL;\r
+\r
+  {\r
+    CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;\r
+    _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);\r
+    if (!setDecoderProperties)\r
+      return E_NOTIMPL;\r
+    RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5));\r
+  }\r
+\r
+  CMyComPtr<ICompressSetOutStream> setOutStream;\r
+\r
+  bool filteredMode = (header.FilterID == 1);\r
+\r
+  if (filteredMode)\r
+  {\r
+    _bcjStream.QueryInterface(IID_ICompressSetOutStream, &setOutStream);\r
+    if (!setOutStream)\r
+      return E_NOTIMPL;\r
+    RINOK(setOutStream->SetOutStream(outStream));\r
+    outStream = _bcjStream;\r
+  }\r
+\r
+  const UInt64 *Size = header.HasSize() ? &header.Size : NULL;\r
+  HRESULT res = _lzmaDecoderSpec->CodeResume(outStream, Size, progress);\r
+\r
+  if (filteredMode)\r
+  {\r
+    CMyComPtr<IOutStreamFlush> flush;\r
+    _bcjStream.QueryInterface(IID_IOutStreamFlush, &flush);\r
+    if (flush)\r
+    {\r
+      HRESULT res2 = flush->Flush();\r
+      if (res == S_OK)\r
+        res = res2;\r
+    }\r
+    HRESULT res2 = setOutStream->ReleaseOutStream();\r
+    if (res == S_OK)\r
+      res = res2;\r
+  }\r
+  RINOK(res);\r
+\r
+  return S_OK;\r
+}\r
+\r
+\r
+class CHandler:\r
+  public IInArchive,\r
+  public IArchiveOpenSeq,\r
+  PUBLIC_ISetCompressCodecsInfo\r
+  public CMyUnknownImp\r
+{\r
+  CHeader _header;\r
+  bool _lzma86;\r
+  UInt64 _startPosition;\r
+  UInt64 _packSize;\r
+  bool _packSizeDefined;\r
+  CMyComPtr<IInStream> _stream;\r
+  CMyComPtr<ISequentialInStream> _seqStream;\r
+\r
+  DECL_EXTERNAL_CODECS_VARS\r
+  DECL_ISetCompressCodecsInfo\r
+\r
+public:\r
+  MY_QUERYINTERFACE_BEGIN2(IInArchive)\r
+  MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq)\r
+  QUERY_ENTRY_ISetCompressCodecsInfo\r
+  MY_QUERYINTERFACE_END\r
+  MY_ADDREF_RELEASE\r
+\r
+  INTERFACE_IInArchive(;)\r
+  STDMETHOD(OpenSeq)(ISequentialInStream *stream);\r
+\r
+  CHandler(bool lzma86) { _lzma86 = lzma86; }\r
+\r
+  unsigned GetHeaderSize() const { return 5 + 8 + (_lzma86 ? 1 : 0); }\r
+\r
+};\r
+\r
+IMP_IInArchive_Props\r
+IMP_IInArchive_ArcProps_NO_Table\r
+\r
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)\r
+{\r
+  NCOM::CPropVariant prop;\r
+  switch(propID)\r
+  {\r
+    case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)\r
+{\r
+  *numItems = 1;\r
+  return S_OK;\r
+}\r
+\r
+static void DictSizeToString(UInt32 value, char *s)\r
+{\r
+  for (int i = 0; i <= 31; i++)\r
+    if ((UInt32(1) << i) == value)\r
+    {\r
+      ::ConvertUInt32ToString(i, s);\r
+      return;\r
+    }\r
+  char c = 'b';\r
+  if ((value & ((1 << 20) - 1)) == 0)\r
+  {\r
+    value >>= 20;\r
+    c = 'm';\r
+  }\r
+  else if ((value & ((1 << 10) - 1)) == 0)\r
+  {\r
+    value >>= 10;\r
+    c = 'k';\r
+  }\r
+  ::ConvertUInt32ToString(value, s);\r
+  int p = MyStringLen(s);\r
+  s[p++] = c;\r
+  s[p++] = '\0';\r
+}\r
+\r
+static void MyStrCat(char *d, const char *s)\r
+{\r
+  MyStringCopy(d + MyStringLen(d), s);\r
+}\r
+\r
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID,  PROPVARIANT *value)\r
+{\r
+  NCOM::CPropVariant prop;\r
+  switch(propID)\r
+  {\r
+    case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break;\r
+    case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;\r
+    case kpidMethod:\r
+      if (_stream)\r
+      {\r
+        char s[64];\r
+        s[0] = '\0';\r
+        if (_header.FilterID != 0)\r
+          MyStrCat(s, "BCJ ");\r
+        MyStrCat(s, "LZMA:");\r
+        DictSizeToString(_header.GetDicSize(), s + MyStringLen(s));\r
+        prop = s;\r
+      }\r
+      break;\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)\r
+{\r
+  RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &_startPosition));\r
+  \r
+  const UInt32 kBufSize = 1 + 5 + 8 + 1;\r
+  Byte buf[kBufSize];\r
+  \r
+  RINOK(ReadStream_FALSE(inStream, buf, kBufSize));\r
+  \r
+  if (!_header.Parse(buf, _lzma86))\r
+    return S_FALSE;\r
+  const Byte *start = buf + GetHeaderSize();\r
+  if (start[0] != 0)\r
+    return S_FALSE;\r
+  \r
+  UInt64 endPos;\r
+  RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));\r
+  _packSize = endPos - _startPosition;\r
+  _packSizeDefined = true;\r
+  \r
+  _stream = inStream;\r
+  _seqStream = inStream;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)\r
+{\r
+  Close();\r
+  _seqStream = stream;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::Close()\r
+{\r
+  _packSizeDefined = false;\r
+  _stream.Release();\r
+  _seqStream.Release();\r
+   return S_OK;\r
+}\r
+\r
+\r
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,\r
+    Int32 testMode, IArchiveExtractCallback *extractCallback)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (numItems == 0)\r
+    return S_OK;\r
+  if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))\r
+    return E_INVALIDARG;\r
+\r
+  if (_stream)\r
+    extractCallback->SetTotal(_packSize);\r
+    \r
+  \r
+  CMyComPtr<ISequentialOutStream> realOutStream;\r
+  Int32 askMode = testMode ?\r
+      NExtract::NAskMode::kTest :\r
+      NExtract::NAskMode::kExtract;\r
+  RINOK(extractCallback->GetStream(0, &realOutStream, askMode));\r
+  if (!testMode && !realOutStream)\r
+    return S_OK;\r
+  \r
+  extractCallback->PrepareOperation(askMode);\r
+\r
+  CDummyOutStream *outStreamSpec = new CDummyOutStream;\r
+  CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);\r
+  outStreamSpec->SetStream(realOutStream);\r
+  outStreamSpec->Init();\r
+  realOutStream.Release();\r
+\r
+  CLocalProgress *lps = new CLocalProgress;\r
+  CMyComPtr<ICompressProgressInfo> progress = lps;\r
+  lps->Init(extractCallback, true);\r
+\r
+  if (_stream)\r
+  {\r
+    RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));\r
+  }\r
+\r
+  CDecoder decoder;\r
+  HRESULT result = decoder.Create(\r
+      EXTERNAL_CODECS_VARS\r
+      _lzma86, _seqStream);\r
+  RINOK(result);\r
\r
+  Int32 opRes = NExtract::NOperationResult::kOK;\r
+  bool firstItem = true;\r
+\r
+  for (;;)\r
+  {\r
+    lps->OutSize = outStreamSpec->GetSize();\r
+    lps->InSize = _packSize = decoder.GetInputProcessedSize();\r
+    _packSizeDefined = true;\r
+    RINOK(lps->SetCur());\r
+\r
+    CHeader st;\r
+\r
+    const UInt32 kBufSize = 1 + 5 + 8;\r
+    Byte buf[kBufSize];\r
+    const UInt32 headerSize = GetHeaderSize();\r
+    UInt32 processed;\r
+    RINOK(decoder.ReadInput(buf, headerSize, &processed));\r
+    if (processed != headerSize)\r
+      break;\r
+  \r
+    if (!st.Parse(buf, _lzma86))\r
+      break;\r
+    firstItem = false;\r
+\r
+    result = decoder.Code(st, outStream, progress);\r
+    if (result == E_NOTIMPL)\r
+    {\r
+      opRes = NExtract::NOperationResult::kUnSupportedMethod;\r
+      break;\r
+    }\r
+    if (result == S_FALSE)\r
+    {\r
+      opRes = NExtract::NOperationResult::kDataError;\r
+      break;\r
+    }\r
+    RINOK(result);\r
+  }\r
+  if (firstItem)\r
+    return E_FAIL;\r
+  outStream.Release();\r
+  return extractCallback->SetOperationResult(opRes);\r
+  COM_TRY_END\r
+}\r
+\r
+IMPL_ISetCompressCodecsInfo\r
+\r
+static IInArchive *CreateArc() { return new CHandler(false); }\r
+static IInArchive *CreateArc86() { return new CHandler(true); }\r
+\r
+namespace NLzmaAr {\r
+  \r
+static CArcInfo g_ArcInfo =\r
+  { L"lzma", L"lzma", 0, 0xA, { 0 }, 0, true, CreateArc, NULL };\r
+REGISTER_ARC(Lzma)\r
+\r
+}\r
+\r
+namespace NLzma86Ar {\r
+\r
+static CArcInfo g_ArcInfo =\r
+  { L"lzma86", L"lzma86", 0, 0xB, { 0 }, 0, true, CreateArc86, NULL };\r
+REGISTER_ARC(Lzma86)\r
+\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/SplitHandler.cpp b/CPP/7zip/Archive/SplitHandler.cpp
new file mode 100755 (executable)
index 0000000..cb98a77
--- /dev/null
@@ -0,0 +1,366 @@
+// SplitHandler.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/ComTry.h"\r
+#include "Common/MyString.h"\r
+\r
+#include "Windows/PropVariant.h"\r
+\r
+#include "../Common/ProgressUtils.h"\r
+#include "../Common/RegisterArc.h"\r
+\r
+#include "../Compress/CopyCoder.h"\r
+\r
+#include "Common/MultiStream.h"\r
+\r
+using namespace NWindows;\r
+\r
+namespace NArchive {\r
+namespace NSplit {\r
+\r
+STATPROPSTG kProps[] =\r
+{\r
+  { NULL, kpidPath, VT_BSTR},\r
+  { NULL, kpidSize, VT_UI8}\r
+};\r
+\r
+STATPROPSTG kArcProps[] =\r
+{\r
+  { NULL, kpidNumVolumes, VT_UI4}\r
+};\r
+\r
+class CHandler:\r
+  public IInArchive,\r
+  public IInArchiveGetStream,\r
+  public CMyUnknownImp\r
+{\r
+  UString _subName;\r
+  CObjectVector<CMyComPtr<IInStream> > _streams;\r
+  CRecordVector<UInt64> _sizes;\r
+  UInt64 _totalSize;\r
+public:\r
+  MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)\r
+  INTERFACE_IInArchive(;)\r
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);\r
+};\r
+\r
+IMP_IInArchive_Props\r
+IMP_IInArchive_ArcProps\r
+\r
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)\r
+{\r
+  NCOM::CPropVariant prop;\r
+  switch(propID)\r
+  {\r
+    case kpidMainSubfile: prop = (UInt32)0; break;\r
+    case kpidNumVolumes: prop = (UInt32)_streams.Size(); break;\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+}\r
+\r
+struct CSeqName\r
+{\r
+  UString _unchangedPart;\r
+  UString _changedPart;\r
+  bool _splitStyle;\r
+  \r
+  UString GetNextName()\r
+  {\r
+    UString newName;\r
+    if (_splitStyle)\r
+    {\r
+      int i;\r
+      int numLetters = _changedPart.Length();\r
+      for (i = numLetters - 1; i >= 0; i--)\r
+      {\r
+        wchar_t c = _changedPart[i];\r
+        if (c == 'z')\r
+        {\r
+          c = 'a';\r
+          newName = c + newName;\r
+          continue;\r
+        }\r
+        else if (c == 'Z')\r
+        {\r
+          c = 'A';\r
+          newName = c + newName;\r
+          continue;\r
+        }\r
+        c++;\r
+        if ((c == 'z' || c == 'Z') && i == 0)\r
+        {\r
+          _unchangedPart += c;\r
+          wchar_t newChar = (c == 'z') ? L'a' : L'A';\r
+          newName.Empty();\r
+          numLetters++;\r
+          for (int k = 0; k < numLetters; k++)\r
+            newName += newChar;\r
+          break;\r
+        }\r
+        newName = c + newName;\r
+        i--;\r
+        for (; i >= 0; i--)\r
+          newName = _changedPart[i] + newName;\r
+        break;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      int i;\r
+      int numLetters = _changedPart.Length();\r
+      for (i = numLetters - 1; i >= 0; i--)\r
+      {\r
+        wchar_t c = _changedPart[i];\r
+        if (c == L'9')\r
+        {\r
+          c = L'0';\r
+          newName = c + newName;\r
+          if (i == 0)\r
+            newName = UString(L'1') + newName;\r
+          continue;\r
+        }\r
+        c++;\r
+        newName = c + newName;\r
+        i--;\r
+        for (; i >= 0; i--)\r
+          newName = _changedPart[i] + newName;\r
+        break;\r
+      }\r
+    }\r
+    _changedPart = newName;\r
+    return _unchangedPart + _changedPart;\r
+  }\r
+};\r
+\r
+STDMETHODIMP CHandler::Open(IInStream *stream,\r
+    const UInt64 * /* maxCheckStartPosition */,\r
+    IArchiveOpenCallback *openArchiveCallback)\r
+{\r
+  COM_TRY_BEGIN\r
+  Close();\r
+  if (openArchiveCallback == 0)\r
+    return S_FALSE;\r
+  // try\r
+  {\r
+    CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;\r
+    CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;\r
+    if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback,\r
+        &openVolumeCallback) != S_OK)\r
+      return S_FALSE;\r
+    \r
+    UString name;\r
+    {\r
+      NCOM::CPropVariant prop;\r
+      RINOK(openVolumeCallback->GetProperty(kpidName, &prop));\r
+      if (prop.vt != VT_BSTR)\r
+        return S_FALSE;\r
+      name = prop.bstrVal;\r
+    }\r
+    \r
+    int dotPos = name.ReverseFind('.');\r
+    UString prefix, ext;\r
+    if (dotPos >= 0)\r
+    {\r
+      prefix = name.Left(dotPos + 1);\r
+      ext = name.Mid(dotPos + 1);\r
+    }\r
+    else\r
+      ext = name;\r
+    UString extBig = ext;\r
+    extBig.MakeUpper();\r
+\r
+    CSeqName seqName;\r
+\r
+    int numLetters = 2;\r
+    bool splitStyle = false;\r
+    if (extBig.Right(2) == L"AA")\r
+    {\r
+      splitStyle = true;\r
+      while (numLetters < extBig.Length())\r
+      {\r
+        if (extBig[extBig.Length() - numLetters - 1] != 'A')\r
+          break;\r
+        numLetters++;\r
+      }\r
+    }\r
+    else if (ext.Right(2) == L"01")\r
+    {\r
+      while (numLetters < extBig.Length())\r
+      {\r
+        if (extBig[extBig.Length() - numLetters - 1] != '0')\r
+          break;\r
+        numLetters++;\r
+      }\r
+      if (numLetters != ext.Length())\r
+        return S_FALSE;\r
+    }\r
+    else\r
+      return S_FALSE;\r
+\r
+    _streams.Add(stream);\r
+\r
+    seqName._unchangedPart = prefix + ext.Left(extBig.Length() - numLetters);\r
+    seqName._changedPart = ext.Right(numLetters);\r
+    seqName._splitStyle = splitStyle;\r
+\r
+    if (prefix.Length() < 1)\r
+      _subName = L"file";\r
+    else\r
+      _subName = prefix.Left(prefix.Length() - 1);\r
+\r
+    _totalSize = 0;\r
+    UInt64 size;\r
+    {\r
+      NCOM::CPropVariant prop;\r
+      RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));\r
+      if (prop.vt != VT_UI8)\r
+        return E_INVALIDARG;\r
+      size = prop.uhVal.QuadPart;\r
+    }\r
+    _totalSize += size;\r
+    _sizes.Add(size);\r
+    \r
+    if (openArchiveCallback != NULL)\r
+    {\r
+      UInt64 numFiles = _streams.Size();\r
+      RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));\r
+    }\r
+\r
+    for (;;)\r
+    {\r
+      UString fullName = seqName.GetNextName();\r
+      CMyComPtr<IInStream> nextStream;\r
+      HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);\r
+      if (result == S_FALSE)\r
+        break;\r
+      if (result != S_OK)\r
+        return result;\r
+      if (!stream)\r
+        break;\r
+      {\r
+        NCOM::CPropVariant prop;\r
+        RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));\r
+        if (prop.vt != VT_UI8)\r
+          return E_INVALIDARG;\r
+        size = prop.uhVal.QuadPart;\r
+      }\r
+      _totalSize += size;\r
+      _sizes.Add(size);\r
+      _streams.Add(nextStream);\r
+      if (openArchiveCallback != NULL)\r
+      {\r
+        UInt64 numFiles = _streams.Size();\r
+        RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));\r
+      }\r
+    }\r
+  }\r
+  /*\r
+  catch(...)\r
+  {\r
+    return S_FALSE;\r
+  }\r
+  */\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CHandler::Close()\r
+{\r
+  _sizes.Clear();\r
+  _streams.Clear();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)\r
+{\r
+  *numItems = _streams.IsEmpty() ? 0 : 1;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)\r
+{\r
+  NWindows::NCOM::CPropVariant prop;\r
+  switch(propID)\r
+  {\r
+    case kpidPath: prop = _subName; break;\r
+    case kpidSize:\r
+    case kpidPackSize:\r
+      prop = _totalSize;\r
+      break;\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,\r
+    Int32 testMode, IArchiveExtractCallback *extractCallback)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (numItems == 0)\r
+    return S_OK;\r
+  if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))\r
+    return E_INVALIDARG;\r
+\r
+  UInt64 currentTotalSize = 0;\r
+  RINOK(extractCallback->SetTotal(_totalSize));\r
+  CMyComPtr<ISequentialOutStream> outStream;\r
+  Int32 askMode = testMode ?\r
+      NExtract::NAskMode::kTest :\r
+      NExtract::NAskMode::kExtract;\r
+  RINOK(extractCallback->GetStream(0, &outStream, askMode));\r
+  if (!testMode && !outStream)\r
+    return S_OK;\r
+  RINOK(extractCallback->PrepareOperation(askMode));\r
+  \r
+  NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;\r
+  CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;\r
+\r
+  CLocalProgress *lps = new CLocalProgress;\r
+  CMyComPtr<ICompressProgressInfo> progress = lps;\r
+  lps->Init(extractCallback, false);\r
+\r
+  for (int i = 0; i < _streams.Size(); i++)\r
+  {\r
+    lps->InSize = lps->OutSize = currentTotalSize;\r
+    RINOK(lps->SetCur());\r
+    IInStream *inStream = _streams[i];\r
+    RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));\r
+    RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));\r
+    currentTotalSize += copyCoderSpec->TotalSize;\r
+  }\r
+  outStream.Release();\r
+  return extractCallback->SetOperationResult(NExtract::NOperationResult::kOK);\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (index != 0)\r
+    return E_INVALIDARG;\r
+  *stream = 0;\r
+  CMultiStream *streamSpec = new CMultiStream;\r
+  CMyComPtr<ISequentialInStream> streamTemp = streamSpec;\r
+  for (int i = 0; i < _streams.Size(); i++)\r
+  {\r
+    CMultiStream::CSubStreamInfo subStreamInfo;\r
+    subStreamInfo.Stream = _streams[i];\r
+    subStreamInfo.Size = _sizes[i];\r
+    streamSpec->Streams.Add(subStreamInfo);\r
+  }\r
+  streamSpec->Init();\r
+  *stream = streamTemp.Detach();\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+static IInArchive *CreateArc() { return new CHandler; }\r
+\r
+static CArcInfo g_ArcInfo =\r
+{ L"Split", L"001", 0, 0xEA, { 0 }, 0, false, CreateArc, 0 };\r
+\r
+REGISTER_ARC(Split)\r
+\r
+}}\r
diff --git a/CPP/7zip/Archive/StdAfx.h b/CPP/7zip/Archive/StdAfx.h
new file mode 100755 (executable)
index 0000000..f56e92f
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../Common/MyWindows.h"\r
+#include "../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp
new file mode 100755 (executable)
index 0000000..e4029e0
--- /dev/null
@@ -0,0 +1,707 @@
+// XzHandler.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+#include "../../../C/XzCrc64.h"\r
+#include "../../../C/XzEnc.h"\r
+\r
+#include "../../Common/ComTry.h"\r
+#include "../../Common/IntToString.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+#include "../Common/CWrappers.h"\r
+#include "../Common/ProgressUtils.h"\r
+#include "../Common/RegisterArc.h"\r
+#include "../Common/StreamUtils.h"\r
+\r
+#include "../Compress/CopyCoder.h"\r
+\r
+#include "IArchive.h"\r
+\r
+#include "Common/HandlerOut.h"\r
+\r
+using namespace NWindows;\r
+\r
+namespace NCompress {\r
+namespace NLzma2 {\r
+\r
+HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);\r
+\r
+}}\r
+\r
+static void *SzAlloc(void *, size_t size) { return MyAlloc(size); }\r
+static void SzFree(void *, void *address) { MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+namespace NArchive {\r
+namespace NXz {\r
+\r
+struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;\r
+\r
+class CHandler:\r
+  public IInArchive,\r
+  public IArchiveOpenSeq,\r
+  #ifndef EXTRACT_ONLY\r
+  public IOutArchive,\r
+  public ISetProperties,\r
+  public COutHandler,\r
+  #endif\r
+  public CMyUnknownImp\r
+{\r
+  Int64 _startPosition;\r
+  UInt64 _packSize;\r
+  UInt64 _unpackSize;\r
+  UInt64 _numBlocks;\r
+  AString _methodsString;\r
+  bool _useSeq;\r
+  UInt64 _unpackSizeDefined;\r
+  UInt64 _packSizeDefined;\r
+  \r
+  CMyComPtr<IInStream> _stream;\r
+  CMyComPtr<ISequentialInStream> _seqStream;\r
+\r
+  UInt32 _crcSize;\r
+\r
+  void Init()\r
+  {\r
+    _crcSize = 4;\r
+    COutHandler::Init();\r
+  }\r
+\r
+  HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *callback);\r
+\r
+public:\r
+  MY_QUERYINTERFACE_BEGIN2(IInArchive)\r
+  MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq)\r
+  #ifndef EXTRACT_ONLY\r
+  MY_QUERYINTERFACE_ENTRY(IOutArchive)\r
+  MY_QUERYINTERFACE_ENTRY(ISetProperties)\r
+  #endif\r
+  MY_QUERYINTERFACE_END\r
+  MY_ADDREF_RELEASE\r
+\r
+  INTERFACE_IInArchive(;)\r
+  STDMETHOD(OpenSeq)(ISequentialInStream *stream);\r
+\r
+  #ifndef EXTRACT_ONLY\r
+  INTERFACE_IOutArchive(;)\r
+  STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);\r
+  #endif\r
+\r
+  CHandler();\r
+};\r
+\r
+CHandler::CHandler()\r
+{\r
+  Init();\r
+}\r
+\r
+STATPROPSTG kProps[] =\r
+{\r
+  { NULL, kpidSize, VT_UI8},\r
+  { NULL, kpidPackSize, VT_UI8},\r
+  { NULL, kpidMethod, VT_BSTR}\r
+};\r
+\r
+STATPROPSTG kArcProps[] =\r
+{\r
+  { NULL, kpidMethod, VT_BSTR},\r
+  { NULL, kpidNumBlocks, VT_UI4}\r
+};\r
+\r
+IMP_IInArchive_Props\r
+IMP_IInArchive_ArcProps\r
+\r
+static char GetHex(Byte value)\r
+{\r
+  return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));\r
+}\r
+\r
+static inline void AddHexToString(AString &res, Byte value)\r
+{\r
+  res += GetHex((Byte)(value >> 4));\r
+  res += GetHex((Byte)(value & 0xF));\r
+}\r
+\r
+static AString ConvertUInt32ToString(UInt32 value)\r
+{\r
+  char temp[32];\r
+  ::ConvertUInt32ToString(value, temp);\r
+  return temp;\r
+}\r
+\r
+static AString Lzma2PropToString(int prop)\r
+{\r
+  if ((prop & 1) == 0)\r
+    return ConvertUInt32ToString(prop / 2 + 12);\r
+  AString res;\r
+  char c;\r
+\r
+  UInt32 size = (2 | ((prop) & 1)) << ((prop) / 2 + 1);\r
+\r
+  if (prop > 17)\r
+  {\r
+    res = ConvertUInt32ToString(size >> 10);\r
+    c = 'm';\r
+  }\r
+  else\r
+  {\r
+    res = ConvertUInt32ToString(size);\r
+    c = 'k';\r
+  }\r
+  return res + c;\r
+}\r
+\r
+struct CMethodNamePair\r
+{\r
+  UInt32 Id;\r
+  const char *Name;\r
+};\r
+\r
+static CMethodNamePair g_NamePairs[] =\r
+{\r
+  { XZ_ID_Subblock, "SB" },\r
+  { XZ_ID_Delta, "Delta" },\r
+  { XZ_ID_X86, "x86" },\r
+  { XZ_ID_PPC, "PPC" },\r
+  { XZ_ID_IA64, "IA64" },\r
+  { XZ_ID_ARM, "ARM" },\r
+  { XZ_ID_ARMT, "ARMT" },\r
+  { XZ_ID_SPARC, "SPARC" },\r
+  { XZ_ID_LZMA2, "LZMA2" }\r
+};\r
+\r
+static AString GetMethodString(const CXzFilter &f)\r
+{\r
+  AString s;\r
+\r
+  for (int i = 0; i < sizeof(g_NamePairs) / sizeof(g_NamePairs[i]); i++)\r
+    if (g_NamePairs[i].Id == f.id)\r
+      s = g_NamePairs[i].Name;\r
+  if (s.IsEmpty())\r
+  {\r
+    char temp[32];\r
+    ::ConvertUInt64ToString(f.id, temp);\r
+    s = temp;\r
+  }\r
+\r
+  if (f.propsSize > 0)\r
+  {\r
+    s += ':';\r
+    if (f.id == XZ_ID_LZMA2 && f.propsSize == 1)\r
+      s += Lzma2PropToString(f.props[0]);\r
+    else if (f.id == XZ_ID_Delta && f.propsSize == 1)\r
+      s += ConvertUInt32ToString((UInt32)f.props[0] + 1);\r
+    else\r
+    {\r
+      s += '[';\r
+      for (UInt32 bi = 0; bi < f.propsSize; bi++)\r
+        AddHexToString(s, f.props[bi]);\r
+      s += ']';\r
+    }\r
+  }\r
+  return s;\r
+}\r
+\r
+static void AddString(AString &dest, const AString &src)\r
+{\r
+  if (!dest.IsEmpty())\r
+    dest += ' ';\r
+  dest += src;\r
+}\r
+\r
+static const char *kChecks[] =\r
+{\r
+  "NoCheck",\r
+  "CRC32",\r
+  NULL,\r
+  NULL,\r
+  "CRC64",\r
+  NULL,\r
+  NULL,\r
+  NULL,\r
+  NULL,\r
+  NULL,\r
+  "SHA256",\r
+  NULL,\r
+  NULL,\r
+  NULL,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+static AString GetCheckString(const CXzs &xzs)\r
+{\r
+  size_t i;\r
+  UInt32 mask = 0;\r
+  for (i = 0; i < xzs.num; i++)\r
+    mask |= ((UInt32)1 << XzFlags_GetCheckType(xzs.streams[i].flags));\r
+  AString s;\r
+  for (i = 0; i <= XZ_CHECK_MASK; i++)\r
+    if (((mask >> i) & 1) != 0)\r
+    {\r
+      AString s2;\r
+      if (kChecks[i])\r
+        s2 = kChecks[i];\r
+      else\r
+        s2 = "Check-" + ConvertUInt32ToString((UInt32)i);\r
+      AddString(s, s2);\r
+    }\r
+  return s;\r
+}\r
+\r
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)\r
+{\r
+  COM_TRY_BEGIN\r
+  NWindows::NCOM::CPropVariant prop;\r
+  switch(propID)\r
+  {\r
+    case kpidNumBlocks: if (!_useSeq) prop = _numBlocks; break;\r
+    case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;\r
+    case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)\r
+{\r
+  *numItems = 1;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID,  PROPVARIANT *value)\r
+{\r
+  COM_TRY_BEGIN\r
+  NWindows::NCOM::CPropVariant prop;\r
+  switch(propID)\r
+  {\r
+    case kpidSize: if (_unpackSizeDefined) prop = _unpackSize; break;\r
+    case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;\r
+    case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+\r
+struct COpenCallbackWrap\r
+{\r
+  ICompressProgress p;\r
+  IArchiveOpenCallback *OpenCallback;\r
+  HRESULT Res;\r
+  COpenCallbackWrap(IArchiveOpenCallback *progress);\r
+};\r
+\r
+static SRes OpenCallbackProgress(void *pp, UInt64 inSize, UInt64 /* outSize */)\r
+{\r
+  COpenCallbackWrap *p = (COpenCallbackWrap *)pp;\r
+  p->Res = p->OpenCallback->SetCompleted(NULL, &inSize);\r
+  return (SRes)p->Res;\r
+}\r
+\r
+COpenCallbackWrap::COpenCallbackWrap(IArchiveOpenCallback *callback)\r
+{\r
+  p.Progress = OpenCallbackProgress;\r
+  OpenCallback = callback;\r
+  Res = SZ_OK;\r
+}\r
+\r
+struct CXzsCPP\r
+{\r
+  CXzs p;\r
+  CXzsCPP() { Xzs_Construct(&p); }\r
+  ~CXzsCPP() { Xzs_Free(&p, &g_Alloc); }\r
+};\r
+\r
+HRESULT CHandler::Open2(IInStream *inStream, IArchiveOpenCallback *callback)\r
+{\r
+  CSeekInStreamWrap inStreamImp(inStream);\r
+\r
+  CLookToRead lookStream;\r
+  LookToRead_CreateVTable(&lookStream, True);\r
+  lookStream.realStream = &inStreamImp.p;\r
+  LookToRead_Init(&lookStream);\r
+\r
+  COpenCallbackWrap openWrap(callback);\r
+  RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));\r
+  RINOK(callback->SetTotal(NULL, &_packSize));\r
+\r
+  CXzsCPP xzs;\r
+  SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &_startPosition, &openWrap.p, &g_Alloc);\r
+  if (res == SZ_ERROR_NO_ARCHIVE && xzs.p.num > 0)\r
+    res = SZ_OK;\r
+  if (res == SZ_OK)\r
+  {\r
+    _packSize -= _startPosition;\r
+    _unpackSize = Xzs_GetUnpackSize(&xzs.p);\r
+    _unpackSizeDefined = _packSizeDefined = true;\r
+    _numBlocks = (UInt64)Xzs_GetNumBlocks(&xzs.p);\r
+\r
+    RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));\r
+    CXzStreamFlags st;\r
+    CSeqInStreamWrap inStreamWrap(inStream);\r
+    SRes res2 = Xz_ReadHeader(&st, &inStreamWrap.p);\r
+\r
+    if (res2 == SZ_OK)\r
+    {\r
+      CXzBlock block;\r
+      Bool isIndex;\r
+      UInt32 headerSizeRes;\r
+      res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);\r
+      if (res2 == SZ_OK && !isIndex)\r
+      {\r
+        int numFilters = XzBlock_GetNumFilters(&block);\r
+        for (int i = 0; i < numFilters; i++)\r
+          AddString(_methodsString, GetMethodString(block.filters[i]));\r
+      }\r
+    }\r
+    AddString(_methodsString, GetCheckString(xzs.p));\r
+  }\r
+\r
+  if (res != SZ_OK || _startPosition != 0)\r
+  {\r
+    RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));\r
+    CXzStreamFlags st;\r
+    CSeqInStreamWrap inStreamWrap(inStream);\r
+    SRes res2 = Xz_ReadHeader(&st, &inStreamWrap.p);\r
+    if (res2 == SZ_OK)\r
+    {\r
+      res = res2;\r
+      _startPosition = 0;\r
+      _useSeq = True;\r
+      _unpackSizeDefined = _packSizeDefined = false;\r
+    }\r
+  }\r
+  if (res == SZ_ERROR_NO_ARCHIVE)\r
+    return S_FALSE;\r
+  RINOK(SResToHRESULT(res));\r
+  _stream = inStream;\r
+  _seqStream = inStream;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)\r
+{\r
+  COM_TRY_BEGIN\r
+  try\r
+  {\r
+    Close();\r
+    return Open2(inStream, callback);\r
+  }\r
+  catch(...) { return S_FALSE; }\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)\r
+{\r
+  Close();\r
+  _seqStream = stream;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::Close()\r
+{\r
+  _numBlocks = 0;\r
+  _useSeq = true;\r
+  _unpackSizeDefined = _packSizeDefined = false;\r
+  _methodsString.Empty();\r
+  _stream.Release();\r
+  _seqStream.Release();\r
+  return S_OK;\r
+}\r
+\r
+class CSeekToSeqStream:\r
+  public IInStream,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  CMyComPtr<ISequentialInStream> Stream;\r
+  MY_UNKNOWN_IMP1(IInStream)\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+};\r
+\r
+STDMETHODIMP CSeekToSeqStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  return Stream->Read(data, size, processedSize);\r
+}\r
+\r
+STDMETHODIMP CSeekToSeqStream::Seek(Int64, UInt32, UInt64 *) { return E_NOTIMPL; }\r
+\r
+struct CXzUnpackerCPP\r
+{\r
+  Byte *InBuf;\r
+  Byte *OutBuf;\r
+  CXzUnpacker p;\r
+  CXzUnpackerCPP(): InBuf(0), OutBuf(0) {}\r
+  ~CXzUnpackerCPP()\r
+  {\r
+    XzUnpacker_Free(&p);\r
+    MyFree(InBuf);\r
+    MyFree(OutBuf);\r
+  }\r
+};\r
+\r
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,\r
+    Int32 testMode, IArchiveExtractCallback *extractCallback)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (numItems == 0)\r
+    return S_OK;\r
+  if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0))\r
+    return E_INVALIDARG;\r
+\r
+  extractCallback->SetTotal(_packSize);\r
+  UInt64 currentTotalPacked = 0;\r
+  RINOK(extractCallback->SetCompleted(&currentTotalPacked));\r
+  CMyComPtr<ISequentialOutStream> realOutStream;\r
+  Int32 askMode = testMode ?\r
+      NExtract::NAskMode::kTest :\r
+      NExtract::NAskMode::kExtract;\r
+  \r
+  RINOK(extractCallback->GetStream(0, &realOutStream, askMode));\r
+  \r
+  if (!testMode && !realOutStream)\r
+    return S_OK;\r
+\r
+  extractCallback->PrepareOperation(askMode);\r
+\r
+  if (_stream)\r
+  {\r
+    RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));\r
+  }\r
+\r
+  CLocalProgress *lps = new CLocalProgress;\r
+  CMyComPtr<ICompressProgressInfo> progress = lps;\r
+  lps->Init(extractCallback, true);\r
+\r
+  CCompressProgressWrap progressWrap(progress);\r
+\r
+  SRes res;\r
+\r
+  const UInt32 kInBufSize = 1 << 15;\r
+  const UInt32 kOutBufSize = 1 << 21;\r
+\r
+  UInt32 inPos = 0;\r
+  UInt32 inSize = 0;\r
+  UInt32 outPos = 0;\r
+  CXzUnpackerCPP xzu;\r
+  res = XzUnpacker_Create(&xzu.p, &g_Alloc);\r
+  if (res == SZ_OK)\r
+  {\r
+    xzu.InBuf = (Byte *)MyAlloc(kInBufSize);\r
+    xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize);\r
+    if (xzu.InBuf == 0 || xzu.OutBuf == 0)\r
+      res = SZ_ERROR_MEM;\r
+  }\r
+  if (res == SZ_OK)\r
+  for (;;)\r
+  {\r
+    if (inPos == inSize)\r
+    {\r
+      inPos = inSize = 0;\r
+      RINOK(_seqStream->Read(xzu.InBuf, kInBufSize, &inSize));\r
+    }\r
+\r
+    SizeT inLen = inSize - inPos;\r
+    SizeT outLen = kOutBufSize - outPos;\r
+    ECoderStatus status;\r
+    res = XzUnpacker_Code(&xzu.p,\r
+        xzu.OutBuf + outPos, &outLen,\r
+        xzu.InBuf + inPos, &inLen,\r
+        (inSize == 0 ? CODER_FINISH_END : CODER_FINISH_ANY), &status);\r
+\r
+    // printf("\n_inPos = %6d  inLen = %5d, outLen = %5d", inPos, inLen, outLen);\r
+\r
+    inPos += (UInt32)inLen;\r
+    outPos += (UInt32)outLen;\r
+    lps->InSize += inLen;\r
+    lps->OutSize += outLen;\r
+\r
+    bool finished = (((inLen == 0) && (outLen == 0)) || res != SZ_OK);\r
+\r
+    if (outPos == kOutBufSize || finished)\r
+    {\r
+      if (realOutStream && outPos > 0)\r
+      {\r
+        RINOK(WriteStream(realOutStream, xzu.OutBuf, outPos));\r
+      }\r
+      outPos = 0;\r
+    }\r
+    if (finished)\r
+    {\r
+      _packSize = lps->InSize;\r
+      _unpackSize = lps->OutSize;\r
+      _packSizeDefined = _unpackSizeDefined = true;\r
+      if (res == SZ_OK)\r
+      {\r
+        if (status == CODER_STATUS_NEEDS_MORE_INPUT)\r
+        {\r
+          if (XzUnpacker_IsStreamWasFinished(&xzu.p))\r
+            _packSize -= xzu.p.padSize;\r
+          else\r
+            res = SZ_ERROR_DATA;\r
+        }\r
+        else\r
+          res = SZ_ERROR_DATA;\r
+      }\r
+      break;\r
+    }\r
+    RINOK(lps->SetCur());\r
+  }\r
+\r
+  Int32 opRes;\r
+  switch(res)\r
+  {\r
+    case SZ_OK:\r
+      opRes = NExtract::NOperationResult::kOK; break;\r
+    case SZ_ERROR_UNSUPPORTED:\r
+      opRes = NExtract::NOperationResult::kUnSupportedMethod; break;\r
+    case SZ_ERROR_CRC:\r
+      opRes = NExtract::NOperationResult::kCRCError; break;\r
+    case SZ_ERROR_DATA:\r
+    case SZ_ERROR_ARCHIVE:\r
+    case SZ_ERROR_NO_ARCHIVE:\r
+      opRes = NExtract::NOperationResult::kDataError; break;\r
+    default:\r
+      return SResToHRESULT(res);\r
+  }\r
+  realOutStream.Release();\r
+  RINOK(extractCallback->SetOperationResult(opRes));\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+#ifndef EXTRACT_ONLY\r
+\r
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)\r
+{\r
+  *timeType = NFileTimeType::kUnix;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,\r
+    IArchiveUpdateCallback *updateCallback)\r
+{\r
+  CSeqOutStreamWrap seqOutStream(outStream);\r
+  \r
+  if (numItems == 0)\r
+  {\r
+    SRes res = Xz_EncodeEmpty(&seqOutStream.p);\r
+    return SResToHRESULT(res);\r
+  }\r
+  \r
+  if (numItems != 1)\r
+    return E_INVALIDARG;\r
+\r
+  Int32 newData, newProps;\r
+  UInt32 indexInArchive;\r
+  if (!updateCallback)\r
+    return E_FAIL;\r
+  RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));\r
+\r
+  if (IntToBool(newProps))\r
+  {\r
+    {\r
+      NCOM::CPropVariant prop;\r
+      RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));\r
+      if (prop.vt != VT_EMPTY)\r
+        if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)\r
+          return E_INVALIDARG;\r
+    }\r
+  }\r
+\r
+  if (IntToBool(newData))\r
+  {\r
+    {\r
+      UInt64 size;\r
+      NCOM::CPropVariant prop;\r
+      RINOK(updateCallback->GetProperty(0, kpidSize, &prop));\r
+      if (prop.vt != VT_UI8)\r
+        return E_INVALIDARG;\r
+      size = prop.uhVal.QuadPart;\r
+      RINOK(updateCallback->SetTotal(size));\r
+    }\r
+\r
+    CLzma2EncProps lzma2Props;\r
+    Lzma2EncProps_Init(&lzma2Props);\r
+\r
+    lzma2Props.lzmaProps.level = _level;\r
+\r
+    CMyComPtr<ISequentialInStream> fileInStream;\r
+    RINOK(updateCallback->GetStream(0, &fileInStream));\r
+\r
+    CSeqInStreamWrap seqInStream(fileInStream);\r
+\r
+    for (int i = 0; i < _methods.Size(); i++)\r
+    {\r
+      COneMethodInfo &m = _methods[i];\r
+      SetCompressionMethod2(m\r
+      #ifndef _7ZIP_ST\r
+      , _numThreads\r
+      #endif\r
+      );\r
+      if (m.IsLzma())\r
+      {\r
+        for (int j = 0; j < m.Props.Size(); j++)\r
+        {\r
+          const CProp &prop = m.Props[j];\r
+          RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));\r
+        }\r
+      }\r
+    }\r
+\r
+    #ifndef _7ZIP_ST\r
+    lzma2Props.numTotalThreads = _numThreads;\r
+    #endif\r
+\r
+    CLocalProgress *lps = new CLocalProgress;\r
+    CMyComPtr<ICompressProgressInfo> progress = lps;\r
+    lps->Init(updateCallback, true);\r
+\r
+    CCompressProgressWrap progressWrap(progress);\r
+    SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &lzma2Props, False, &progressWrap.p);\r
+    if (res == SZ_OK)\r
+      return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);\r
+    return SResToHRESULT(res);\r
+  }\r
+  if (indexInArchive != 0)\r
+    return E_INVALIDARG;\r
+  if (_stream)\r
+    RINOK(_stream->Seek(_startPosition, STREAM_SEEK_SET, NULL));\r
+  return NCompress::CopyStream(_stream, outStream, 0);\r
+}\r
+\r
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)\r
+{\r
+  COM_TRY_BEGIN\r
+  BeforeSetProperty();\r
+  for (int i = 0; i < numProps; i++)\r
+  {\r
+    RINOK(SetProperty(names[i], values[i]));\r
+  }\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+#endif\r
+\r
+static IInArchive *CreateArc() { return new NArchive::NXz::CHandler; }\r
+#ifndef EXTRACT_ONLY\r
+static IOutArchive *CreateArcOut() { return new NArchive::NXz::CHandler; }\r
+#else\r
+#define CreateArcOut 0\r
+#endif\r
+\r
+static CArcInfo g_ArcInfo =\r
+  { L"xz", L"xz txz", L"* .tar", 0xC, {0xFD, '7' , 'z', 'X', 'Z', '\0'}, 6, true, CreateArc, CreateArcOut };\r
+\r
+REGISTER_ARC(xz)\r
+\r
+}}\r
diff --git a/CPP/7zip/Asm.mak b/CPP/7zip/Asm.mak
new file mode 100755 (executable)
index 0000000..0284903
--- /dev/null
@@ -0,0 +1,7 @@
+!IF "$(CPU)" == "ARM"\r
+$(ASM_OBJS): ../../../../Asm/Arm/$(*B).asm\r
+       $(COMPL_ASM)\r
+!ELSEIF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS"\r
+$(ASM_OBJS): ../../../../Asm/x86/$(*B).asm\r
+       $(COMPL_ASM)\r
+!ENDIF\r
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp
new file mode 100755 (executable)
index 0000000..2b9543f
--- /dev/null
@@ -0,0 +1,1664 @@
+# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=Alone - Win32 DebugU\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "Alone.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c\r
+# ADD BASE RSC /l 0x419 /d "NDEBUG"\r
+# ADD RSC /l 0x419 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c\r
+# ADD BASE RSC /l 0x419 /d "_DEBUG"\r
+# ADD RSC /l 0x419 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "ReleaseU"\r
+# PROP BASE Intermediate_Dir "ReleaseU"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "ReleaseU"\r
+# PROP Intermediate_Dir "ReleaseU"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c\r
+# ADD CPP /nologo /Gz /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c\r
+# ADD BASE RSC /l 0x419 /d "NDEBUG"\r
+# ADD RSC /l 0x419 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98\r
+# SUBTRACT BASE LINK32 /pdb:none\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "DebugU"\r
+# PROP BASE Intermediate_Dir "DebugU"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "DebugU"\r
+# PROP Intermediate_Dir "DebugU"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c\r
+# ADD CPP /nologo /Gz /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c\r
+# ADD BASE RSC /l 0x419 /d "_DEBUG"\r
+# ADD RSC /l 0x419 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "Alone - Win32 Release"\r
+# Name "Alone - Win32 Debug"\r
+# Name "Alone - Win32 ReleaseU"\r
+# Name "Alone - Win32 DebugU"\r
+# Begin Group "Console"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\ArError.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\BenchCon.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\BenchCon.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\CompressionMode.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\ConsoleClose.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\ConsoleClose.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\List.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\List.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\Main.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\MainAr.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\OpenCallbackConsole.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\PercentPrinter.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\PercentPrinter.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\UserInputUtils.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\UserInputUtils.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Spec"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\resource.rc\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\StdAfx.cpp\r
+# ADD CPP /Yc"StdAfx.h"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\StdAfx.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\AutoPtr.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Buffer.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\CommandLineParser.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\CommandLineParser.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\ComTry.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\CRC.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Defs.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\DynamicBuffer.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\IntToString.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\IntToString.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\ListFileUtils.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\ListFileUtils.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyCom.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyException.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyGuidDef.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyInitGuid.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyString.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyString.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyUnknown.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyVector.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyVector.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\NewHandler.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\NewHandler.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StdInStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StdInStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StdOutStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StdOutStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringConvert.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringConvert.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringToInt.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringToInt.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Types.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\UTFConvert.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\UTFConvert.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Wildcard.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Wildcard.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Windows"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Defs.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Device.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\DLL.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\DLL.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Error.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Error.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileDir.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileDir.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileFind.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileFind.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileIO.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileIO.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileMapping.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileName.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileName.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Handle.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\MemoryLock.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\MemoryLock.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\PropVariant.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\PropVariant.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\PropVariantConversions.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Synchronization.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Synchronization.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\System.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\System.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Thread.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Time.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Time.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "7zip Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\CreateCoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\CreateCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\CWrappers.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\CWrappers.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FilePathAutoRename.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FilePathAutoRename.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FileStreams.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FileStreams.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FilterCoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FilterCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\InBuffer.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\InBuffer.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\InOutTempBuffer.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\InOutTempBuffer.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\LimitedStreams.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\LimitedStreams.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\LockedStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\LockedStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\MethodId.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\MethodId.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\MethodProps.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\MethodProps.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\OffsetStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\OffsetStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\OutBuffer.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\OutBuffer.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\ProgressUtils.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\ProgressUtils.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\RegisterArc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\RegisterCodec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\StreamBinder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\StreamBinder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\StreamObjects.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\StreamObjects.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\StreamUtils.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\StreamUtils.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\VirtThread.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\VirtThread.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Compress"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\Bcj2Coder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\Bcj2Coder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\Bcj2Register.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\BcjCoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\BcjCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\BcjRegister.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\BranchCoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\BranchCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\BranchMisc.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\BranchMisc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\BranchRegister.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\ByteSwap.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\ByteSwap.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\CopyCoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\CopyCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\CopyRegister.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\DeltaFilter.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\Lzma2Decoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\Lzma2Decoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\Lzma2Encoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\Lzma2Encoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\Lzma2Register.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaDecoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaDecoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaEncoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaEncoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaRegister.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\RangeCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\RangeCoderBit.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\RangeCoderBitTree.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\RangeCoderOpt.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Archive"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Group "7z"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zCompressionMode.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zCompressionMode.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zDecode.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zDecode.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zEncode.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zEncode.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zExtract.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zFolderInStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zFolderInStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zHandler.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zHandler.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zHandlerOut.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zHeader.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zHeader.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zIn.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zIn.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zItem.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zOut.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zOut.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zProperties.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zProperties.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zRegister.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zSpecStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zSpecStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zUpdate.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\7z\7zUpdate.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Archive Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\CoderMixer2.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\DummyOutStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\DummyOutStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\HandlerOut.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\HandlerOut.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\InStreamWithCRC.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\ItemNameUtils.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\MultiStream.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\MultiStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\ParseProperties.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\Common\ParseProperties.h\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\LzmaHandler.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\SplitHandler.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Archive\XzHandler.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "UI Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\ArchiveCommandLine.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Bench.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Bench.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\DefaultName.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\DefaultName.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\EnumDirItems.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\EnumDirItems.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Extract.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Extract.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\ExtractingFilePath.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\LoadCodecs.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\LoadCodecs.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\OpenArchive.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\OpenArchive.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Property.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\PropIDUtils.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\PropIDUtils.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\SetProperties.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\SetProperties.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\SortUtils.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\SortUtils.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\TempFiles.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\TempFiles.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Update.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Update.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\UpdateAction.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\UpdateAction.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\UpdateCallback.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\UpdateCallback.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\UpdatePair.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\UpdatePair.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\UpdateProduce.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\UpdateProduce.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\WorkDir.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\WorkDir.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "7-zip"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\ICoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\IMyUnknown.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\IPassword.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\IProgress.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\IStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\PropID.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "C"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Group "Xz"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Sha256.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Sha256.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Xz.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Xz.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\XzCrc64.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\XzCrc64.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\XzDec.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\XzEnc.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\XzEnc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\XzIn.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\7zCrc.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\7zCrc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\7zCrcOpt.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\7zStream.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Alloc.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Alloc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Bra.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Bra.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Bra86.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\BraIA64.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\CpuArch.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\CpuArch.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Delta.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Delta.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\IStream.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzFind.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzFind.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzFindMt.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzFindMt.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzHash.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Lzma2Dec.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Lzma2Dec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Lzma2Enc.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Lzma2Enc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzmaDec.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzmaDec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzmaEnc.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzmaEnc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\MtCoder.c\r
+\r
+!IF  "$(CFG)" == "Alone - Win32 Release"\r
+\r
+# ADD CPP /O2\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"\r
+\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\MtCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Threads.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Threads.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Types.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsw b/CPP/7zip/Bundles/Alone7z/Alone.dsw
new file mode 100755 (executable)
index 0000000..036aab4
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "Alone"=.\Alone.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.cpp b/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
new file mode 100755 (executable)
index 0000000..c6d3b1f
--- /dev/null
@@ -0,0 +1,3 @@
+// StdAfx.cpp\r
+\r
+#include "StdAfx.h"\r
diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.h b/CPP/7zip/Bundles/Alone7z/StdAfx.h
new file mode 100755 (executable)
index 0000000..a4e6173
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../../Common/MyWindows.h"\r
+#include "../../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile
new file mode 100755 (executable)
index 0000000..3132895
--- /dev/null
@@ -0,0 +1,213 @@
+PROG = 7zr.exe\r
+MY_CONSOLE = 1\r
+CFLAGS = $(CFLAGS) -I ../../../ \\r
+  -D_NO_CRYPTO \\r
+\r
+!IFNDEF UNDER_CE\r
+CFLAGS = $(CFLAGS) -DWIN_LONG_PATH\r
+!ENDIF\r
+\r
+CONSOLE_OBJS = \\r
+  $O\BenchCon.obj \\r
+  $O\ConsoleClose.obj \\r
+  $O\ExtractCallbackConsole.obj \\r
+  $O\List.obj \\r
+  $O\Main.obj \\r
+  $O\MainAr.obj \\r
+  $O\OpenCallbackConsole.obj \\r
+  $O\PercentPrinter.obj \\r
+  $O\UpdateCallbackConsole.obj \\r
+  $O\UserInputUtils.obj \\r
+\r
+COMMON_OBJS = \\r
+  $O\CommandLineParser.obj \\r
+  $O\CRC.obj \\r
+  $O\IntToString.obj \\r
+  $O\ListFileUtils.obj \\r
+  $O\NewHandler.obj \\r
+  $O\StdInStream.obj \\r
+  $O\StdOutStream.obj \\r
+  $O\MyString.obj \\r
+  $O\StringConvert.obj \\r
+  $O\StringToInt.obj \\r
+  $O\UTFConvert.obj \\r
+  $O\MyVector.obj \\r
+  $O\Wildcard.obj \\r
+\r
+WIN_OBJS = \\r
+  $O\DLL.obj \\r
+  $O\Error.obj \\r
+  $O\FileDir.obj \\r
+  $O\FileFind.obj \\r
+  $O\FileIO.obj \\r
+  $O\FileName.obj \\r
+  $O\MemoryLock.obj \\r
+  $O\PropVariant.obj \\r
+  $O\PropVariantConversions.obj \\r
+  $O\Synchronization.obj \\r
+  $O\System.obj \\r
+  $O\Time.obj \\r
+\r
+7ZIP_COMMON_OBJS = \\r
+  $O\CreateCoder.obj \\r
+  $O\CWrappers.obj \\r
+  $O\FilePathAutoRename.obj \\r
+  $O\FileStreams.obj \\r
+  $O\InBuffer.obj \\r
+  $O\InOutTempBuffer.obj \\r
+  $O\FilterCoder.obj \\r
+  $O\LimitedStreams.obj \\r
+  $O\LockedStream.obj \\r
+  $O\MethodId.obj \\r
+  $O\MethodProps.obj \\r
+  $O\OffsetStream.obj \\r
+  $O\OutBuffer.obj \\r
+  $O\ProgressUtils.obj \\r
+  $O\StreamBinder.obj \\r
+  $O\StreamObjects.obj \\r
+  $O\StreamUtils.obj \\r
+  $O\VirtThread.obj \\r
+\r
+UI_COMMON_OBJS = \\r
+  $O\ArchiveCommandLine.obj \\r
+  $O\ArchiveExtractCallback.obj \\r
+  $O\ArchiveOpenCallback.obj \\r
+  $O\Bench.obj \\r
+  $O\DefaultName.obj \\r
+  $O\EnumDirItems.obj \\r
+  $O\Extract.obj \\r
+  $O\ExtractingFilePath.obj \\r
+  $O\LoadCodecs.obj \\r
+  $O\OpenArchive.obj \\r
+  $O\PropIDUtils.obj \\r
+  $O\SetProperties.obj \\r
+  $O\SortUtils.obj \\r
+  $O\TempFiles.obj \\r
+  $O\Update.obj \\r
+  $O\UpdateAction.obj \\r
+  $O\UpdateCallback.obj \\r
+  $O\UpdatePair.obj \\r
+  $O\UpdateProduce.obj \\r
+  $O\WorkDir.obj \\r
+\r
+AR_OBJS = \\r
+  $O\LzmaHandler.obj \\r
+  $O\SplitHandler.obj \\r
+  $O\XzHandler.obj \\r
+\r
+AR_COMMON_OBJS = \\r
+  $O\CoderMixer2.obj \\r
+  $O\CoderMixer2MT.obj \\r
+  $O\CrossThreadProgress.obj \\r
+  $O\DummyOutStream.obj \\r
+  $O\HandlerOut.obj \\r
+  $O\InStreamWithCRC.obj \\r
+  $O\ItemNameUtils.obj \\r
+  $O\MultiStream.obj \\r
+  $O\OutStreamWithCRC.obj \\r
+  $O\ParseProperties.obj \\r
+\r
+\r
+7Z_OBJS = \\r
+  $O\7zCompressionMode.obj \\r
+  $O\7zDecode.obj \\r
+  $O\7zEncode.obj \\r
+  $O\7zExtract.obj \\r
+  $O\7zFolderInStream.obj \\r
+  $O\7zFolderOutStream.obj \\r
+  $O\7zHandler.obj \\r
+  $O\7zHandlerOut.obj \\r
+  $O\7zHeader.obj \\r
+  $O\7zIn.obj \\r
+  $O\7zOut.obj \\r
+  $O\7zProperties.obj \\r
+  $O\7zRegister.obj \\r
+  $O\7zSpecStream.obj \\r
+  $O\7zUpdate.obj \\r
+\r
+COMPRESS_OBJS = \\r
+  $O\Bcj2Coder.obj \\r
+  $O\Bcj2Register.obj \\r
+  $O\BcjCoder.obj \\r
+  $O\BcjRegister.obj \\r
+  $O\BranchCoder.obj \\r
+  $O\BranchMisc.obj \\r
+  $O\BranchRegister.obj \\r
+  $O\ByteSwap.obj \\r
+  $O\CopyCoder.obj \\r
+  $O\CopyRegister.obj \\r
+  $O\DeltaFilter.obj \\r
+  $O\Lzma2Decoder.obj \\r
+  $O\Lzma2Encoder.obj \\r
+  $O\Lzma2Register.obj \\r
+  $O\LzmaDecoder.obj \\r
+  $O\LzmaEncoder.obj \\r
+  $O\LzmaRegister.obj \\r
+\r
+C_OBJS = \\r
+  $O\7zStream.obj \\r
+  $O\Alloc.obj \\r
+  $O\Bra.obj \\r
+  $O\Bra86.obj \\r
+  $O\BraIA64.obj \\r
+  $O\CpuArch.obj \\r
+  $O\Delta.obj \\r
+  $O\LzFind.obj \\r
+  $O\LzFindMt.obj \\r
+  $O\Lzma2Dec.obj \\r
+  $O\Lzma2Enc.obj \\r
+  $O\LzmaDec.obj \\r
+  $O\LzmaEnc.obj \\r
+  $O\MtCoder.obj \\r
+  $O\Sha256.obj \\r
+  $O\Threads.obj \\r
+  $O\Xz.obj \\r
+  $O\XzCrc64.obj \\r
+  $O\XzDec.obj \\r
+  $O\XzEnc.obj \\r
+  $O\XzIn.obj \\r
+\r
+!include "../../Crc.mak"\r
+\r
+OBJS = \\r
+  $O\StdAfx.obj \\r
+  $(CONSOLE_OBJS) \\r
+  $(COMMON_OBJS) \\r
+  $(WIN_OBJS) \\r
+  $(7ZIP_COMMON_OBJS) \\r
+  $(UI_COMMON_OBJS) \\r
+  $(AR_OBJS) \\r
+  $(AR_COMMON_OBJS) \\r
+  $(7Z_OBJS) \\r
+  $(COMPRESS_OBJS) \\r
+  $(C_OBJS) \\r
+  $(ASM_OBJS) \\r
+  $O\resource.res\r
+\r
+\r
+!include "../../../Build.mak"\r
+\r
+$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp\r
+       $(COMPL)\r
+\r
+$(COMMON_OBJS): ../../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(WIN_OBJS): ../../../Windows/$(*B).cpp\r
+       $(COMPL)\r
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp\r
+       $(COMPL)\r
+$(AR_OBJS): ../../Archive/$(*B).cpp\r
+       $(COMPL)\r
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp\r
+       $(COMPL)\r
+\r
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp\r
+       $(COMPL)\r
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp\r
+       $(COMPL_O2)\r
+$(C_OBJS): ../../../../C/$(*B).c\r
+       $(COMPL_O2)\r
+\r
+!include "../../Asm.mak"\r
diff --git a/CPP/7zip/Bundles/Alone7z/resource.rc b/CPP/7zip/Bundles/Alone7z/resource.rc
new file mode 100755 (executable)
index 0000000..0f90dfb
--- /dev/null
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"\r
+\r
+MY_VERSION_INFO_APP("7-Zip Standalone Console", "7zr")\r
diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
new file mode 100755 (executable)
index 0000000..c6d3b1f
--- /dev/null
@@ -0,0 +1,3 @@
+// StdAfx.cpp\r
+\r
+#include "StdAfx.h"\r
diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
new file mode 100755 (executable)
index 0000000..a4e6173
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../../Common/MyWindows.h"\r
+#include "../../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Bundles/Format7zExtractR/makefile b/CPP/7zip/Bundles/Format7zExtractR/makefile
new file mode 100755 (executable)
index 0000000..34a9bb3
--- /dev/null
@@ -0,0 +1,132 @@
+PROG = 7zxr.dll\r
+DEF_FILE = ../../Archive/Archive2.def\r
+CFLAGS = $(CFLAGS) -I ../../../ \\r
+  -DEXTRACT_ONLY \\r
+  -D_NO_CRYPTO\r
+\r
+COMMON_OBJS = \\r
+  $O\CRC.obj \\r
+  $O\IntToString.obj \\r
+  $O\NewHandler.obj \\r
+  $O\MyString.obj \\r
+  $O\StringConvert.obj \\r
+  $O\StringToInt.obj \\r
+  $O\MyVector.obj \\r
+  $O\Wildcard.obj \\r
+\r
+WIN_OBJS = \\r
+  $O\PropVariant.obj \\r
+  $O\Synchronization.obj \\r
+  $O\System.obj \\r
+\r
+7ZIP_COMMON_OBJS = \\r
+  $O\CreateCoder.obj \\r
+  $O\CWrappers.obj \\r
+  $O\InBuffer.obj \\r
+  $O\FilterCoder.obj \\r
+  $O\LimitedStreams.obj \\r
+  $O\LockedStream.obj \\r
+  $O\MethodId.obj \\r
+  $O\MethodProps.obj \\r
+  $O\OutBuffer.obj \\r
+  $O\ProgressUtils.obj \\r
+  $O\StreamBinder.obj \\r
+  $O\StreamObjects.obj \\r
+  $O\StreamUtils.obj \\r
+  $O\VirtThread.obj \\r
+\r
+AR_OBJS = \\r
+  $O\ArchiveExports.obj \\r
+  $O\DllExports2.obj \\r
+\r
+AR_COMMON_OBJS = \\r
+  $O\CoderMixer2.obj \\r
+  $O\CoderMixer2MT.obj \\r
+  $O\CrossThreadProgress.obj \\r
+  $O\HandlerOut.obj \\r
+  $O\ItemNameUtils.obj \\r
+  $O\OutStreamWithCRC.obj \\r
+  $O\ParseProperties.obj \\r
+\r
+\r
+7Z_OBJS = \\r
+  $O\7zCompressionMode.obj \\r
+  $O\7zDecode.obj \\r
+  $O\7zExtract.obj \\r
+  $O\7zFolderOutStream.obj \\r
+  $O\7zHandler.obj \\r
+  $O\7zHeader.obj \\r
+  $O\7zIn.obj \\r
+  $O\7zProperties.obj \\r
+  $O\7zRegister.obj \\r
+\r
+\r
+COMPRESS_OBJS = \\r
+  $O\CodecExports.obj \\r
+  $O\Bcj2Coder.obj \\r
+  $O\Bcj2Register.obj \\r
+  $O\BcjCoder.obj \\r
+  $O\BcjRegister.obj \\r
+  $O\BranchCoder.obj \\r
+  $O\BranchMisc.obj \\r
+  $O\BranchRegister.obj \\r
+  $O\ByteSwap.obj \\r
+  $O\CopyCoder.obj \\r
+  $O\CopyRegister.obj \\r
+  $O\DeltaFilter.obj \\r
+  $O\Lzma2Decoder.obj \\r
+  $O\Lzma2Register.obj \\r
+  $O\LzmaDecoder.obj \\r
+  $O\LzmaRegister.obj \\r
+\r
+C_OBJS = \\r
+  $O\Alloc.obj \\r
+  $O\Bra.obj \\r
+  $O\Bra86.obj \\r
+  $O\BraIA64.obj \\r
+  $O\CpuArch.obj \\r
+  $O\Delta.obj \\r
+  $O\Lzma2Dec.obj \\r
+  $O\LzmaDec.obj \\r
+  $O\Threads.obj \\r
+\r
+!include "../../Crc.mak"\r
+\r
+OBJS = \\r
+  $O\StdAfx.obj \\r
+  $(CONSOLE_OBJS) \\r
+  $(COMMON_OBJS) \\r
+  $(WIN_OBJS) \\r
+  $(7ZIP_COMMON_OBJS) \\r
+  $(AR_OBJS) \\r
+  $(AR_COMMON_OBJS) \\r
+  $(7Z_OBJS) \\r
+  $(COMPRESS_OBJS) \\r
+  $(C_OBJS) \\r
+  $(ASM_OBJS) \\r
+  $O\resource.res\r
+\r
+\r
+!include "../../../Build.mak"\r
+\r
+$(COMMON_OBJS): ../../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(WIN_OBJS): ../../../Windows/$(*B).cpp\r
+       $(COMPL)\r
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(AR_OBJS): ../../Archive/$(*B).cpp\r
+       $(COMPL)\r
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp\r
+       $(COMPL)\r
+\r
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp\r
+       $(COMPL)\r
+\r
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp\r
+       $(COMPL_O2)\r
+\r
+$(C_OBJS): ../../../../C/$(*B).c\r
+       $(COMPL_O2)\r
+\r
+!include "../../Asm.mak"\r
diff --git a/CPP/7zip/Bundles/Format7zExtractR/resource.rc b/CPP/7zip/Bundles/Format7zExtractR/resource.rc
new file mode 100755 (executable)
index 0000000..652c4a1
--- /dev/null
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"\r
+\r
+MY_VERSION_INFO_DLL("7z Standalone Extracting Plugin", "7zxr")\r
+\r
+101  ICON  "../../Archive/Icons/7z.ico"\r
diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
new file mode 100755 (executable)
index 0000000..c6d3b1f
--- /dev/null
@@ -0,0 +1,3 @@
+// StdAfx.cpp\r
+\r
+#include "StdAfx.h"\r
diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.h b/CPP/7zip/Bundles/Format7zR/StdAfx.h
new file mode 100755 (executable)
index 0000000..a4e6173
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../../Common/MyWindows.h"\r
+#include "../../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Bundles/Format7zR/makefile b/CPP/7zip/Bundles/Format7zR/makefile
new file mode 100755 (executable)
index 0000000..65d1f65
--- /dev/null
@@ -0,0 +1,149 @@
+PROG = 7zra.dll\r
+DEF_FILE = ../../Archive/Archive2.def\r
+CFLAGS = $(CFLAGS) -I ../../../ \\r
+  -D_NO_CRYPTO\r
+\r
+COMMON_OBJS = \\r
+  $O\CRC.obj \\r
+  $O\IntToString.obj \\r
+  $O\NewHandler.obj \\r
+  $O\MyString.obj \\r
+  $O\StringConvert.obj \\r
+  $O\StringToInt.obj \\r
+  $O\MyVector.obj \\r
+  $O\Wildcard.obj \\r
+\r
+WIN_OBJS = \\r
+  $O\FileDir.obj \\r
+  $O\FileFind.obj \\r
+  $O\FileIO.obj \\r
+  $O\PropVariant.obj \\r
+  $O\Synchronization.obj \\r
+  $O\System.obj \\r
+\r
+7ZIP_COMMON_OBJS = \\r
+  $O\CreateCoder.obj \\r
+  $O\CWrappers.obj \\r
+  $O\InBuffer.obj \\r
+  $O\InOutTempBuffer.obj \\r
+  $O\FilterCoder.obj \\r
+  $O\LimitedStreams.obj \\r
+  $O\LockedStream.obj \\r
+  $O\MethodId.obj \\r
+  $O\MethodProps.obj \\r
+  $O\OutBuffer.obj \\r
+  $O\ProgressUtils.obj \\r
+  $O\StreamBinder.obj \\r
+  $O\StreamObjects.obj \\r
+  $O\StreamUtils.obj \\r
+  $O\VirtThread.obj \\r
+\r
+AR_OBJS = \\r
+  $O\ArchiveExports.obj \\r
+  $O\DllExports2.obj \\r
+\r
+AR_COMMON_OBJS = \\r
+  $O\CoderMixer2.obj \\r
+  $O\CoderMixer2MT.obj \\r
+  $O\CrossThreadProgress.obj \\r
+  $O\HandlerOut.obj \\r
+  $O\InStreamWithCRC.obj \\r
+  $O\ItemNameUtils.obj \\r
+  $O\OutStreamWithCRC.obj \\r
+  $O\ParseProperties.obj \\r
+\r
+\r
+7Z_OBJS = \\r
+  $O\7zCompressionMode.obj \\r
+  $O\7zDecode.obj \\r
+  $O\7zEncode.obj \\r
+  $O\7zExtract.obj \\r
+  $O\7zFolderInStream.obj \\r
+  $O\7zFolderOutStream.obj \\r
+  $O\7zHandler.obj \\r
+  $O\7zHandlerOut.obj \\r
+  $O\7zHeader.obj \\r
+  $O\7zIn.obj \\r
+  $O\7zOut.obj \\r
+  $O\7zProperties.obj \\r
+  $O\7zSpecStream.obj \\r
+  $O\7zUpdate.obj \\r
+  $O\7zRegister.obj \\r
+\r
+\r
+COMPRESS_OBJS = \\r
+  $O\CodecExports.obj \\r
+  $O\Bcj2Coder.obj \\r
+  $O\Bcj2Register.obj \\r
+  $O\BcjCoder.obj \\r
+  $O\BcjRegister.obj \\r
+  $O\BranchCoder.obj \\r
+  $O\BranchMisc.obj \\r
+  $O\BranchRegister.obj \\r
+  $O\ByteSwap.obj \\r
+  $O\CopyCoder.obj \\r
+  $O\CopyRegister.obj \\r
+  $O\DeltaFilter.obj \\r
+  $O\Lzma2Decoder.obj \\r
+  $O\Lzma2Encoder.obj \\r
+  $O\Lzma2Register.obj \\r
+  $O\LzmaDecoder.obj \\r
+  $O\LzmaEncoder.obj \\r
+  $O\LzmaRegister.obj \\r
+\r
+C_OBJS = \\r
+  $O\Alloc.obj \\r
+  $O\Bra.obj \\r
+  $O\Bra86.obj \\r
+  $O\BraIA64.obj \\r
+  $O\CpuArch.obj \\r
+  $O\Delta.obj \\r
+  $O\LzFind.obj \\r
+  $O\LzFindMt.obj \\r
+  $O\Lzma2Dec.obj \\r
+  $O\Lzma2Enc.obj \\r
+  $O\LzmaDec.obj \\r
+  $O\LzmaEnc.obj \\r
+  $O\MtCoder.obj \\r
+  $O\Threads.obj \\r
+\r
+!include "../../Crc.mak"\r
+\r
+OBJS = \\r
+  $O\StdAfx.obj \\r
+  $(CONSOLE_OBJS) \\r
+  $(COMMON_OBJS) \\r
+  $(WIN_OBJS) \\r
+  $(7ZIP_COMMON_OBJS) \\r
+  $(AR_OBJS) \\r
+  $(AR_COMMON_OBJS) \\r
+  $(7Z_OBJS) \\r
+  $(COMPRESS_OBJS) \\r
+  $(C_OBJS) \\r
+  $(ASM_OBJS) \\r
+  $O\resource.res\r
+\r
+\r
+!include "../../../Build.mak"\r
+\r
+$(COMMON_OBJS): ../../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(WIN_OBJS): ../../../Windows/$(*B).cpp\r
+       $(COMPL)\r
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(AR_OBJS): ../../Archive/$(*B).cpp\r
+       $(COMPL)\r
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp\r
+       $(COMPL)\r
+\r
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp\r
+       $(COMPL)\r
+\r
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp\r
+       $(COMPL_O2)\r
+\r
+$(C_OBJS): ../../../../C/$(*B).c\r
+       $(COMPL_O2)\r
+\r
+!include "../../Asm.mak"\r
diff --git a/CPP/7zip/Bundles/Format7zR/resource.rc b/CPP/7zip/Bundles/Format7zR/resource.rc
new file mode 100755 (executable)
index 0000000..b67ef0c
--- /dev/null
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"\r
+\r
+MY_VERSION_INFO_DLL("7z Standalone Plugin", "7zr")\r
+\r
+101  ICON  "../../Archive/Icons/7z.ico"\r
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
new file mode 100755 (executable)
index 0000000..1f759b4
--- /dev/null
@@ -0,0 +1,525 @@
+// LzmaAlone.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include <stdio.h>\r
+\r
+#if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE)\r
+#include <fcntl.h>\r
+#include <io.h>\r
+#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY)\r
+#else\r
+#define MY_SET_BINARY_MODE(file)\r
+#endif\r
+\r
+// #include "../../../Common/MyWindows.h"\r
+#include "../../../Common/MyInitGuid.h"\r
+\r
+#include "../../../../C/7zVersion.h"\r
+#include "../../../../C/Alloc.h"\r
+#include "../../../../C/Lzma86.h"\r
+\r
+#include "../../../Windows/NtCheck.h"\r
+\r
+#ifndef _7ZIP_ST\r
+#include "../../../Windows/System.h"\r
+#endif\r
+\r
+#include "../../../Common/CommandLineParser.h"\r
+#include "../../../Common/StringConvert.h"\r
+#include "../../../Common/StringToInt.h"\r
+\r
+#include "../../Common/FileStreams.h"\r
+#include "../../Common/StreamUtils.h"\r
+\r
+#include "../../Compress/LzmaDecoder.h"\r
+#include "../../Compress/LzmaEncoder.h"\r
+\r
+#include "../../UI/Console/BenchCon.h"\r
+\r
+\r
+using namespace NCommandLineParser;\r
+\r
+static const char *kCantAllocate = "Can not allocate memory";\r
+static const char *kReadError = "Read error";\r
+static const char *kWriteError = "Write error";\r
+\r
+namespace NKey {\r
+enum Enum\r
+{\r
+  kHelp1 = 0,\r
+  kHelp2,\r
+  kAlgo,\r
+  kDict,\r
+  kFb,\r
+  kMc,\r
+  kLc,\r
+  kLp,\r
+  kPb,\r
+  kMatchFinder,\r
+  kMultiThread,\r
+  kEOS,\r
+  kStdIn,\r
+  kStdOut,\r
+  kFilter86\r
+};\r
+}\r
+\r
+static const CSwitchForm kSwitchForms[] =\r
+{\r
+  { L"?",  NSwitchType::kSimple, false },\r
+  { L"H",  NSwitchType::kSimple, false },\r
+  { L"A", NSwitchType::kUnLimitedPostString, false, 1 },\r
+  { L"D", NSwitchType::kUnLimitedPostString, false, 1 },\r
+  { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },\r
+  { L"MC", NSwitchType::kUnLimitedPostString, false, 1 },\r
+  { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },\r
+  { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },\r
+  { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },\r
+  { L"MF", NSwitchType::kUnLimitedPostString, false, 1 },\r
+  { L"MT", NSwitchType::kUnLimitedPostString, false, 0 },\r
+  { L"EOS", NSwitchType::kSimple, false },\r
+  { L"SI",  NSwitchType::kSimple, false },\r
+  { L"SO",  NSwitchType::kSimple, false },\r
+  { L"F86",  NSwitchType::kPostChar, false, 0, 0, L"+" }\r
+};\r
+\r
+static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);\r
+\r
+static void PrintMessage(const char *s)\r
+{\r
+  fputs(s, stderr);\r
+}\r
+\r
+static void PrintHelp()\r
+{\r
+  PrintMessage("\nUsage:  LZMA <e|d> inputFile outputFile [<switches>...]\n"\r
+             "  e: encode file\n"\r
+             "  d: decode file\n"\r
+             "  b: Benchmark\n"\r
+    "<Switches>\n"\r
+    "  -a{N}:  set compression mode - [0, 1], default: 1 (max)\n"\r
+    "  -d{N}:  set dictionary size - [12, 30], default: 23 (8MB)\n"\r
+    "  -fb{N}: set number of fast bytes - [5, 273], default: 128\n"\r
+    "  -mc{N}: set number of cycles for match finder\n"\r
+    "  -lc{N}: set number of literal context bits - [0, 8], default: 3\n"\r
+    "  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"\r
+    "  -pb{N}: set number of pos bits - [0, 4], default: 2\n"\r
+    "  -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4\n"\r
+    "  -mt{N}: set number of CPU threads\n"\r
+    "  -eos:   write End Of Stream marker\n"\r
+    "  -si:    read data from stdin\n"\r
+    "  -so:    write data to stdout\n"\r
+    );\r
+}\r
+\r
+static void PrintHelpAndExit(const char *s)\r
+{\r
+  fprintf(stderr, "\nError: %s\n\n", s);\r
+  PrintHelp();\r
+  throw -1;\r
+}\r
+\r
+static void IncorrectCommand()\r
+{\r
+  PrintHelpAndExit("Incorrect command");\r
+}\r
+\r
+static void WriteArgumentsToStringList(int numArgs, const char *args[], UStringVector &strings)\r
+{\r
+  for (int i = 1; i < numArgs; i++)\r
+    strings.Add(MultiByteToUnicodeString(args[i]));\r
+}\r
+\r
+static bool GetNumber(const wchar_t *s, UInt32 &value)\r
+{\r
+  value = 0;\r
+  if (MyStringLen(s) == 0)\r
+    return false;\r
+  const wchar_t *end;\r
+  UInt64 res = ConvertStringToUInt64(s, &end);\r
+  if (*end != L'\0')\r
+    return false;\r
+  if (res > 0xFFFFFFFF)\r
+    return false;\r
+  value = UInt32(res);\r
+  return true;\r
+}\r
+\r
+static void ParseUInt32(const CParser &parser, int index, UInt32 &res)\r
+{\r
+  if (parser[index].ThereIs)\r
+    if (!GetNumber(parser[index].PostStrings[0], res))\r
+      IncorrectCommand();\r
+}\r
+\r
+#define NT_CHECK_FAIL_ACTION PrintMessage("Unsupported Windows version"); return 1;\r
+\r
+int main2(int numArgs, const char *args[])\r
+{\r
+  NT_CHECK\r
+\r
+  PrintMessage("\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");\r
+\r
+  if (numArgs == 1)\r
+  {\r
+    PrintHelp();\r
+    return 0;\r
+  }\r
+\r
+  bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);\r
+  if (unsupportedTypes)\r
+  {\r
+    PrintMessage("Unsupported base types. Edit Common/Types.h and recompile");\r
+    return 1;\r
+  }\r
+\r
+  UStringVector commandStrings;\r
+  WriteArgumentsToStringList(numArgs, args, commandStrings);\r
+  CParser parser(kNumSwitches);\r
+  try\r
+  {\r
+    parser.ParseStrings(kSwitchForms, commandStrings);\r
+  }\r
+  catch(...)\r
+  {\r
+    IncorrectCommand();\r
+  }\r
+\r
+  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)\r
+  {\r
+    PrintHelp();\r
+    return 0;\r
+  }\r
+  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;\r
+\r
+  int paramIndex = 0;\r
+  if (paramIndex >= nonSwitchStrings.Size())\r
+    IncorrectCommand();\r
+  const UString &command = nonSwitchStrings[paramIndex++];\r
+\r
+  bool dictDefined = false;\r
+  UInt32 dict = (UInt32)-1;\r
+  if(parser[NKey::kDict].ThereIs)\r
+  {\r
+    UInt32 dicLog;\r
+    if (!GetNumber(parser[NKey::kDict].PostStrings[0], dicLog))\r
+      IncorrectCommand();\r
+    dict = 1 << dicLog;\r
+    dictDefined = true;\r
+  }\r
+  UString mf = L"BT4";\r
+  if (parser[NKey::kMatchFinder].ThereIs)\r
+    mf = parser[NKey::kMatchFinder].PostStrings[0];\r
+\r
+  UInt32 numThreads = (UInt32)-1;\r
+\r
+  #ifndef _7ZIP_ST\r
+  if (parser[NKey::kMultiThread].ThereIs)\r
+  {\r
+    UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();\r
+    const UString &s = parser[NKey::kMultiThread].PostStrings[0];\r
+    if (s.IsEmpty())\r
+      numThreads = numCPUs;\r
+    else\r
+      if (!GetNumber(s, numThreads))\r
+        IncorrectCommand();\r
+  }\r
+  #endif\r
+\r
+  if (command.CompareNoCase(L"b") == 0)\r
+  {\r
+    const UInt32 kNumDefaultItereations = 1;\r
+    UInt32 numIterations = kNumDefaultItereations;\r
+    {\r
+      if (paramIndex < nonSwitchStrings.Size())\r
+        if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))\r
+          numIterations = kNumDefaultItereations;\r
+    }\r
+    return LzmaBenchCon(stderr, numIterations, numThreads, dict);\r
+  }\r
+\r
+  if (numThreads == (UInt32)-1)\r
+    numThreads = 1;\r
+\r
+  bool encodeMode = false;\r
+  if (command.CompareNoCase(L"e") == 0)\r
+    encodeMode = true;\r
+  else if (command.CompareNoCase(L"d") == 0)\r
+    encodeMode = false;\r
+  else\r
+    IncorrectCommand();\r
+\r
+  bool stdInMode = parser[NKey::kStdIn].ThereIs;\r
+  bool stdOutMode = parser[NKey::kStdOut].ThereIs;\r
+\r
+  CMyComPtr<ISequentialInStream> inStream;\r
+  CInFileStream *inStreamSpec = 0;\r
+  if (stdInMode)\r
+  {\r
+    inStream = new CStdInFileStream;\r
+    MY_SET_BINARY_MODE(stdin);\r
+  }\r
+  else\r
+  {\r
+    if (paramIndex >= nonSwitchStrings.Size())\r
+      IncorrectCommand();\r
+    const UString &inputName = nonSwitchStrings[paramIndex++];\r
+    inStreamSpec = new CInFileStream;\r
+    inStream = inStreamSpec;\r
+    if (!inStreamSpec->Open(GetSystemString(inputName)))\r
+    {\r
+      fprintf(stderr, "\nError: can not open input file %s\n",\r
+          (const char *)GetOemString(inputName));\r
+      return 1;\r
+    }\r
+  }\r
+\r
+  CMyComPtr<ISequentialOutStream> outStream;\r
+  COutFileStream *outStreamSpec = NULL;\r
+  if (stdOutMode)\r
+  {\r
+    outStream = new CStdOutFileStream;\r
+    MY_SET_BINARY_MODE(stdout);\r
+  }\r
+  else\r
+  {\r
+    if (paramIndex >= nonSwitchStrings.Size())\r
+      IncorrectCommand();\r
+    const UString &outputName = nonSwitchStrings[paramIndex++];\r
+    outStreamSpec = new COutFileStream;\r
+    outStream = outStreamSpec;\r
+    if (!outStreamSpec->Create(GetSystemString(outputName), true))\r
+    {\r
+      fprintf(stderr, "\nError: can not open output file %s\n",\r
+        (const char *)GetOemString(outputName));\r
+      return 1;\r
+    }\r
+  }\r
+\r
+  if (parser[NKey::kFilter86].ThereIs)\r
+  {\r
+    // -f86 switch is for x86 filtered mode: BCJ + LZMA.\r
+    if (parser[NKey::kEOS].ThereIs || stdInMode)\r
+      throw "Can not use stdin in this mode";\r
+    UInt64 fileSize;\r
+    inStreamSpec->File.GetLength(fileSize);\r
+    if (fileSize > 0xF0000000)\r
+      throw "File is too big";\r
+    size_t inSize = (size_t)fileSize;\r
+    Byte *inBuffer = 0;\r
+    if (inSize != 0)\r
+    {\r
+      inBuffer = (Byte *)MyAlloc((size_t)inSize);\r
+      if (inBuffer == 0)\r
+        throw kCantAllocate;\r
+    }\r
+    \r
+    if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK)\r
+      throw "Can not read";\r
+\r
+    Byte *outBuffer = 0;\r
+    size_t outSize;\r
+    if (encodeMode)\r
+    {\r
+      // we allocate 105% of original size for output buffer\r
+      outSize = (size_t)fileSize / 20 * 21 + (1 << 16);\r
+      if (outSize != 0)\r
+      {\r
+        outBuffer = (Byte *)MyAlloc((size_t)outSize);\r
+        if (outBuffer == 0)\r
+          throw kCantAllocate;\r
+      }\r
+      if (!dictDefined)\r
+        dict = 1 << 23;\r
+      int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize,\r
+          5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);\r
+      if (res != 0)\r
+      {\r
+        fprintf(stderr, "\nEncoder error = %d\n", (int)res);\r
+        return 1;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      UInt64 outSize64;\r
+      if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0)\r
+        throw "data error";\r
+      outSize = (size_t)outSize64;\r
+      if (outSize != outSize64)\r
+        throw "too big";\r
+      if (outSize != 0)\r
+      {\r
+        outBuffer = (Byte *)MyAlloc(outSize);\r
+        if (outBuffer == 0)\r
+          throw kCantAllocate;\r
+      }\r
+      int res = Lzma86_Decode(outBuffer, &outSize, inBuffer, &inSize);\r
+      if (inSize != (size_t)fileSize)\r
+        throw "incorrect processed size";\r
+      if (res != 0)\r
+        throw "LzmaDecoder error";\r
+    }\r
+    if (WriteStream(outStream, outBuffer, outSize) != S_OK)\r
+      throw kWriteError;\r
+    MyFree(outBuffer);\r
+    MyFree(inBuffer);\r
+    return 0;\r
+  }\r
+\r
+\r
+  UInt64 fileSize;\r
+  if (encodeMode)\r
+  {\r
+    NCompress::NLzma::CEncoder *encoderSpec = new NCompress::NLzma::CEncoder;\r
+    CMyComPtr<ICompressCoder> encoder = encoderSpec;\r
+\r
+    if (!dictDefined)\r
+      dict = 1 << 23;\r
+\r
+    UInt32 pb = 2;\r
+    UInt32 lc = 3; // = 0; for 32-bit data\r
+    UInt32 lp = 0; // = 2; for 32-bit data\r
+    UInt32 algo = 1;\r
+    UInt32 fb = 128;\r
+    UInt32 mc = 16 + fb / 2;\r
+    bool mcDefined = false;\r
+\r
+    bool eos = parser[NKey::kEOS].ThereIs || stdInMode;\r
\r
+    ParseUInt32(parser, NKey::kAlgo, algo);\r
+    ParseUInt32(parser, NKey::kFb, fb);\r
+    ParseUInt32(parser, NKey::kLc, lc);\r
+    ParseUInt32(parser, NKey::kLp, lp);\r
+    ParseUInt32(parser, NKey::kPb, pb);\r
+\r
+    mcDefined = parser[NKey::kMc].ThereIs;\r
+    if (mcDefined)\r
+      if (!GetNumber(parser[NKey::kMc].PostStrings[0], mc))\r
+        IncorrectCommand();\r
+    \r
+    PROPID propIDs[] =\r
+    {\r
+      NCoderPropID::kDictionarySize,\r
+      NCoderPropID::kPosStateBits,\r
+      NCoderPropID::kLitContextBits,\r
+      NCoderPropID::kLitPosBits,\r
+      NCoderPropID::kAlgorithm,\r
+      NCoderPropID::kNumFastBytes,\r
+      NCoderPropID::kMatchFinder,\r
+      NCoderPropID::kEndMarker,\r
+      NCoderPropID::kNumThreads,\r
+      NCoderPropID::kMatchFinderCycles,\r
+    };\r
+    const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);\r
+\r
+    PROPVARIANT props[kNumPropsMax];\r
+    for (int p = 0; p < 6; p++)\r
+      props[p].vt = VT_UI4;\r
+\r
+    props[0].ulVal = (UInt32)dict;\r
+    props[1].ulVal = (UInt32)pb;\r
+    props[2].ulVal = (UInt32)lc;\r
+    props[3].ulVal = (UInt32)lp;\r
+    props[4].ulVal = (UInt32)algo;\r
+    props[5].ulVal = (UInt32)fb;\r
+\r
+    props[6].vt = VT_BSTR;\r
+    props[6].bstrVal = const_cast<BSTR>((const wchar_t *)mf);\r
+\r
+    props[7].vt = VT_BOOL;\r
+    props[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;\r
+\r
+    props[8].vt = VT_UI4;\r
+    props[8].ulVal = (UInt32)numThreads;\r
+\r
+    // it must be last in property list\r
+    props[9].vt = VT_UI4;\r
+    props[9].ulVal = (UInt32)mc;\r
+\r
+    int numProps = kNumPropsMax;\r
+    if (!mcDefined)\r
+      numProps--;\r
+\r
+    if (encoderSpec->SetCoderProperties(propIDs, props, numProps) != S_OK)\r
+      IncorrectCommand();\r
+    encoderSpec->WriteCoderProperties(outStream);\r
+\r
+    if (eos || stdInMode)\r
+      fileSize = (UInt64)(Int64)-1;\r
+    else\r
+      inStreamSpec->File.GetLength(fileSize);\r
+\r
+    for (int i = 0; i < 8; i++)\r
+    {\r
+      Byte b = Byte(fileSize >> (8 * i));\r
+      if (outStream->Write(&b, 1, 0) != S_OK)\r
+      {\r
+        PrintMessage(kWriteError);\r
+        return 1;\r
+      }\r
+    }\r
+    HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);\r
+    if (result == E_OUTOFMEMORY)\r
+    {\r
+      PrintMessage("\nError: Can not allocate memory\n");\r
+      return 1;\r
+    }\r
+    else if (result != S_OK)\r
+    {\r
+      fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);\r
+      return 1;\r
+    }\r
+  }\r
+  else\r
+  {\r
+    NCompress::NLzma::CDecoder *decoderSpec = new NCompress::NLzma::CDecoder;\r
+    CMyComPtr<ICompressCoder> decoder = decoderSpec;\r
+    decoderSpec->FinishStream = true;\r
+    const UInt32 kPropertiesSize = 5;\r
+    Byte header[kPropertiesSize + 8];\r
+    if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK)\r
+    {\r
+      PrintMessage(kReadError);\r
+      return 1;\r
+    }\r
+    if (decoderSpec->SetDecoderProperties2(header, kPropertiesSize) != S_OK)\r
+    {\r
+      PrintMessage("SetDecoderProperties error");\r
+      return 1;\r
+    }\r
+    fileSize = 0;\r
+    for (int i = 0; i < 8; i++)\r
+      fileSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i);\r
+\r
+    if (decoder->Code(inStream, outStream, 0, (fileSize == (UInt64)(Int64)-1) ? 0 : &fileSize, 0) != S_OK)\r
+    {\r
+      PrintMessage("Decoder error");\r
+      return 1;\r
+    }\r
+  }\r
+  if (outStreamSpec != NULL)\r
+  {\r
+    if (outStreamSpec->Close() != S_OK)\r
+    {\r
+      PrintMessage("File closing error");\r
+      return 1;\r
+    }\r
+  }\r
+  return 0;\r
+}\r
+\r
+int MY_CDECL main(int numArgs, const char *args[])\r
+{\r
+  try { return main2(numArgs, args); }\r
+  catch(const char *s)\r
+  {\r
+    fprintf(stderr, "\nError: %s\n", s);\r
+    return 1;\r
+  }\r
+  catch(...)\r
+  {\r
+    PrintMessage("\nError\n");\r
+    return 1;\r
+  }\r
+}\r
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
new file mode 100755 (executable)
index 0000000..edac514
--- /dev/null
@@ -0,0 +1,457 @@
+# Microsoft Developer Studio Project File - Name="LzmaCon" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=LzmaCon - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "LzmaCon.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "LzmaCon.mak" CFG="LzmaCon - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "LzmaCon - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "LzmaCon - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "LzmaCon - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /Gr /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c\r
+# ADD BASE RSC /l 0x419 /d "NDEBUG"\r
+# ADD RSC /l 0x419 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\Util\lzma.exe"\r
+\r
+!ELSEIF  "$(CFG)" == "LzmaCon - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c\r
+# ADD BASE RSC /l 0x419 /d "_DEBUG"\r
+# ADD RSC /l 0x419 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\Util\lzma.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "LzmaCon - Win32 Release"\r
+# Name "LzmaCon - Win32 Debug"\r
+# Begin Group "Spec"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\StdAfx.cpp\r
+# ADD CPP /Yc"StdAfx.h"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\StdAfx.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Compress"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaDecoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaDecoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaEncoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaEncoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Compress\LzmaRegister.cpp\r
+# End Source File\r
+# End Group\r
+# Begin Group "Windows"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileIO.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileIO.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Synchronization.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Synchronization.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\System.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\System.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\Thread.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\CommandLineParser.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\CommandLineParser.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\ComTry.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\CRC.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Defs.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\IntToString.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\IntToString.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyCom.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyString.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyString.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyUnknown.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyVector.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyVector.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyWindows.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyWindows.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\NewHandler.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\NewHandler.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringConvert.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringConvert.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringToInt.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringToInt.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Types.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "7zip Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\CreateCoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\CreateCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\CWrappers.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\CWrappers.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FileStreams.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FileStreams.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FilterCoder.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FilterCoder.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\StreamUtils.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\StreamUtils.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "UI Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Bench.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\Bench.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\LoadCodecs.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Common\LoadCodecs.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Console"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\BenchCon.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\BenchCon.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\ConsoleClose.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\UI\Console\ConsoleClose.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "C"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\7zCrc.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\7zCrc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\7zCrcOpt.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Alloc.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Alloc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Bra.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Bra.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Bra86.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\BraIA64.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\CpuArch.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\CpuArch.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzFind.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzFind.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzFindMt.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzFindMt.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzHash.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Lzma86.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Lzma86Dec.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Lzma86Enc.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzmaDec.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzmaDec.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzmaEnc.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\LzmaEnc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Threads.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Threads.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\..\C\Types.h\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=.\LzmaAlone.cpp\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw
new file mode 100755 (executable)
index 0000000..c6a6662
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "LzmaCon"=.\LzmaCon.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp b/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp
new file mode 100755 (executable)
index 0000000..c6d3b1f
--- /dev/null
@@ -0,0 +1,3 @@
+// StdAfx.cpp\r
+\r
+#include "StdAfx.h"\r
diff --git a/CPP/7zip/Bundles/LzmaCon/StdAfx.h b/CPP/7zip/Bundles/LzmaCon/StdAfx.h
new file mode 100755 (executable)
index 0000000..83fdd22
--- /dev/null
@@ -0,0 +1,8 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../../Common/MyWindows.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Bundles/LzmaCon/makefile b/CPP/7zip/Bundles/LzmaCon/makefile
new file mode 100755 (executable)
index 0000000..b0b84f1
--- /dev/null
@@ -0,0 +1,87 @@
+PROG = lzma.exe\r
+MY_CONSOLE = 1\r
+CFLAGS = $(CFLAGS)\r
+\r
+LZMA_OBJS = \\r
+  $O\LzmaAlone.obj \\r
+\r
+COMPRESS_OBJS = \\r
+  $O\LzmaDecoder.obj \\r
+  $O\LzmaEncoder.obj \\r
+  $O\LzmaRegister.obj \\r
+\r
+COMMON_OBJS = \\r
+  $O\CommandLineParser.obj \\r
+  $O\CRC.obj \\r
+  $O\IntToString.obj \\r
+  $O\MyString.obj \\r
+  $O\StringConvert.obj \\r
+  $O\StringToInt.obj \\r
+  $O\MyVector.obj\r
+\r
+WIN_OBJS = \\r
+  $O\FileIO.obj \\r
+  $O\System.obj\r
+\r
+7ZIP_COMMON_OBJS = \\r
+  $O\CWrappers.obj \\r
+  $O\CreateCoder.obj \\r
+  $O\FileStreams.obj \\r
+  $O\FilterCoder.obj \\r
+  $O\OutBuffer.obj \\r
+  $O\StreamUtils.obj \\r
+\r
+UI_COMMON_OBJS = \\r
+  $O\Bench.obj \\r
+\r
+CONSOLE_OBJS = \\r
+  $O\ConsoleClose.obj \\r
+  $O\BenchCon.obj \\r
+\r
+C_OBJS = \\r
+  $O\Alloc.obj \\r
+  $O\Bra86.obj \\r
+  $O\CpuArch.obj \\r
+  $O\LzFind.obj \\r
+  $O\LzFindMt.obj \\r
+  $O\Lzma86Dec.obj \\r
+  $O\Lzma86Enc.obj \\r
+  $O\LzmaDec.obj \\r
+  $O\LzmaEnc.obj \\r
+  $O\Threads.obj \\r
+\r
+!include "../../Crc.mak"\r
+\r
+OBJS = \\r
+  $O\StdAfx.obj \\r
+  $(LZMA_OBJS) \\r
+  $(COMPRESS_OBJS) \\r
+  $(COMMON_OBJS) \\r
+  $(WIN_OBJS) \\r
+  $(7ZIP_COMMON_OBJS) \\r
+  $(UI_COMMON_OBJS) \\r
+  $(CONSOLE_OBJS) \\r
+  $(C_OBJS) \\r
+  $(ASM_OBJS) \\r
+\r
+!include "../../../Build.mak"\r
+\r
+\r
+$(LZMA_OBJS): $(*B).cpp\r
+       $(COMPL)\r
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp\r
+       $(COMPL_O2)\r
+$(COMMON_OBJS): ../../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(WIN_OBJS): ../../../Windows/$(*B).cpp\r
+       $(COMPL)\r
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp\r
+       $(COMPL)\r
+$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp\r
+       $(COMPL)\r
+$(C_OBJS): ../../../../C/$(*B).c\r
+       $(COMPL_O2)\r
+\r
+!include "../../Asm.mak"\r
diff --git a/CPP/7zip/Bundles/LzmaCon/makefile.gcc b/CPP/7zip/Bundles/LzmaCon/makefile.gcc
new file mode 100755 (executable)
index 0000000..59a70de
--- /dev/null
@@ -0,0 +1,155 @@
+PROG = lzma\r
+CXX = g++ -O2 -Wall\r
+CXX_C = gcc -O2 -Wall\r
+LIB = -lm\r
+RM = rm -f\r
+CFLAGS = -c -D_7ZIP_ST\r
+\r
+ifdef SystemDrive\r
+IS_MINGW = 1\r
+endif\r
+\r
+ifdef IS_MINGW\r
+FILE_IO =FileIO\r
+FILE_IO_2 =Windows/$(FILE_IO)\r
+LIB2 = -luuid\r
+else\r
+FILE_IO =C_FileIO\r
+FILE_IO_2 =Common/$(FILE_IO)\r
+endif\r
+\r
+OBJS = \\r
+  LzmaAlone.o \\r
+  Bench.o \\r
+  BenchCon.o \\r
+  ConsoleClose.o \\r
+  LzmaDecoder.o \\r
+  LzmaEncoder.o \\r
+  LzmaRegister.o \\r
+  CreateCoder.o \\r
+  CWrappers.o \\r
+  FileStreams.o \\r
+  FilterCoder.o \\r
+  StreamUtils.o \\r
+  $(FILE_IO).o \\r
+  CommandLineParser.o \\r
+  CRC.o \\r
+  IntToString.o \\r
+  MyString.o \\r
+  StringConvert.o \\r
+  StringToInt.o \\r
+  MyVector.o \\r
+  7zCrc.o \\r
+  7zCrcOpt.o \\r
+  Alloc.o \\r
+  Bra86.o \\r
+  CpuArch.o \\r
+  LzFind.o \\r
+  LzmaDec.o \\r
+  LzmaEnc.o \\r
+  Lzma86Dec.o \\r
+  Lzma86Enc.o \\r
+\r
+\r
+all: $(PROG)\r
+\r
+$(PROG): $(OBJS)\r
+       $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)\r
+\r
+LzmaAlone.o: LzmaAlone.cpp\r
+       $(CXX) $(CFLAGS) LzmaAlone.cpp\r
+\r
+Bench.o: ../../UI/Common/Bench.cpp\r
+       $(CXX) $(CFLAGS) ../../UI/Common/Bench.cpp\r
+\r
+BenchCon.o: ../../UI/Console/BenchCon.cpp\r
+       $(CXX) $(CFLAGS) ../../UI/Console/BenchCon.cpp\r
+\r
+ConsoleClose.o: ../../UI/Console/ConsoleClose.cpp\r
+       $(CXX) $(CFLAGS) ../../UI/Console/ConsoleClose.cpp\r
+\r
+LzmaDecoder.o: ../../Compress/LzmaDecoder.cpp\r
+       $(CXX) $(CFLAGS) ../../Compress/LzmaDecoder.cpp\r
+\r
+LzmaEncoder.o: ../../Compress/LzmaEncoder.cpp\r
+       $(CXX) $(CFLAGS) ../../Compress/LzmaEncoder.cpp\r
+\r
+LzmaRegister.o: ../../Compress/LzmaRegister.cpp\r
+       $(CXX) $(CFLAGS) ../../Compress/LzmaRegister.cpp\r
+\r
+CreateCoder.o: ../../Common/CreateCoder.cpp\r
+       $(CXX) $(CFLAGS) ../../Common/CreateCoder.cpp\r
+\r
+CWrappers.o: ../../Common/CWrappers.cpp\r
+       $(CXX) $(CFLAGS) ../../Common/CWrappers.cpp\r
+\r
+FileStreams.o: ../../Common/FileStreams.cpp\r
+       $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp\r
+\r
+FilterCoder.o: ../../Common/FilterCoder.cpp\r
+       $(CXX) $(CFLAGS) ../../Common/FilterCoder.cpp\r
+\r
+StreamUtils.o: ../../Common/StreamUtils.cpp\r
+       $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp\r
+\r
+$(FILE_IO).o: ../../../$(FILE_IO_2).cpp\r
+       $(CXX) $(CFLAGS) ../../../$(FILE_IO_2).cpp\r
+\r
+\r
+CommandLineParser.o: ../../../Common/CommandLineParser.cpp\r
+       $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp\r
+\r
+CRC.o: ../../../Common/CRC.cpp\r
+       $(CXX) $(CFLAGS) ../../../Common/CRC.cpp\r
+\r
+MyWindows.o: ../../../Common/MyWindows.cpp\r
+       $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp\r
+\r
+IntToString.o: ../../../Common/IntToString.cpp\r
+       $(CXX) $(CFLAGS) ../../../Common/IntToString.cpp\r
+\r
+MyString.o: ../../../Common/MyString.cpp\r
+       $(CXX) $(CFLAGS) ../../../Common/MyString.cpp\r
+\r
+StringConvert.o: ../../../Common/StringConvert.cpp\r
+       $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp\r
+\r
+StringToInt.o: ../../../Common/StringToInt.cpp\r
+       $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp\r
+\r
+MyVector.o: ../../../Common/MyVector.cpp\r
+       $(CXX) $(CFLAGS) ../../../Common/MyVector.cpp\r
+\r
+7zCrc.o: ../../../../C/7zCrc.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c\r
+\r
+7zCrcOpt.o: ../../../../C/7zCrcOpt.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/7zCrcOpt.c\r
+\r
+Alloc.o: ../../../../C/Alloc.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/Alloc.c\r
+\r
+Bra86.o: ../../../../C/Bra86.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/Bra86.c\r
+\r
+CpuArch.o: ../../../../C/CpuArch.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/CpuArch.c\r
+\r
+LzFind.o: ../../../../C/LzFind.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/LzFind.c\r
+\r
+LzmaDec.o: ../../../../C/LzmaDec.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/LzmaDec.c\r
+\r
+LzmaEnc.o: ../../../../C/LzmaEnc.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/LzmaEnc.c\r
+\r
+Lzma86Dec.o: ../../../../C/Lzma86Dec.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/Lzma86Dec.c\r
+\r
+Lzma86Enc.o: ../../../../C/Lzma86Enc.c\r
+       $(CXX_C) $(CFLAGS) ../../../../C/Lzma86Enc.c\r
+\r
+clean:\r
+       -$(RM) $(PROG) $(OBJS)\r
+\r
diff --git a/CPP/7zip/Common/CWrappers.cpp b/CPP/7zip/Common/CWrappers.cpp
new file mode 100755 (executable)
index 0000000..66b8449
--- /dev/null
@@ -0,0 +1,226 @@
+// CWrappers.h\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "CWrappers.h"\r
+\r
+#include "StreamUtils.h"\r
+\r
+#define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1)\r
+\r
+#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)\r
+\r
+static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize)\r
+{\r
+  CCompressProgressWrap *p = (CCompressProgressWrap *)pp;\r
+  p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));\r
+  return (SRes)p->Res;\r
+}\r
+\r
+CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress)\r
+{\r
+  p.Progress = CompressProgress;\r
+  Progress = progress;\r
+  Res = SZ_OK;\r
+}\r
+\r
+static const UInt32 kStreamStepSize = (UInt32)1 << 31;\r
+\r
+SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)\r
+{\r
+  switch(res)\r
+  {\r
+    case S_OK: return SZ_OK;\r
+    case E_OUTOFMEMORY: return SZ_ERROR_MEM;\r
+    case E_INVALIDARG: return SZ_ERROR_PARAM;\r
+    case E_ABORT: return SZ_ERROR_PROGRESS;\r
+    case S_FALSE: return SZ_ERROR_DATA;\r
+  }\r
+  return defaultRes;\r
+}\r
+\r
+static SRes MyRead(void *object, void *data, size_t *size)\r
+{\r
+  CSeqInStreamWrap *p = (CSeqInStreamWrap *)object;\r
+  UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);\r
+  p->Res = (p->Stream->Read(data, curSize, &curSize));\r
+  *size = curSize;\r
+  if (p->Res == S_OK)\r
+    return SZ_OK;\r
+  return HRESULT_To_SRes(p->Res, SZ_ERROR_READ);\r
+}\r
+\r
+static size_t MyWrite(void *object, const void *data, size_t size)\r
+{\r
+  CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object;\r
+  if (p->Stream)\r
+  {\r
+    p->Res = WriteStream(p->Stream, data, size);\r
+    if (p->Res != 0)\r
+      return 0;\r
+  }\r
+  else\r
+    p->Res = S_OK;\r
+  p->Processed += size;\r
+  return size;\r
+}\r
+\r
+CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream)\r
+{\r
+  p.Read = MyRead;\r
+  Stream = stream;\r
+}\r
+\r
+CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)\r
+{\r
+  p.Write = MyWrite;\r
+  Stream = stream;\r
+  Res = SZ_OK;\r
+  Processed = 0;\r
+}\r
+\r
+HRESULT SResToHRESULT(SRes res)\r
+{\r
+  switch(res)\r
+  {\r
+    case SZ_OK: return S_OK;\r
+    case SZ_ERROR_MEM: return E_OUTOFMEMORY;\r
+    case SZ_ERROR_PARAM: return E_INVALIDARG;\r
+    case SZ_ERROR_PROGRESS: return E_ABORT;\r
+    case SZ_ERROR_DATA: return S_FALSE;\r
+  }\r
+  return E_FAIL;\r
+}\r
+\r
+static SRes InStreamWrap_Read(void *pp, void *data, size_t *size)\r
+{\r
+  CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;\r
+  UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);\r
+  p->Res = p->Stream->Read(data, curSize, &curSize);\r
+  *size = curSize;\r
+  return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;\r
+}\r
+\r
+static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin)\r
+{\r
+  CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;\r
+  UInt32 moveMethod;\r
+  switch(origin)\r
+  {\r
+    case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break;\r
+    case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break;\r
+    case SZ_SEEK_END: moveMethod = STREAM_SEEK_END; break;\r
+    default: return SZ_ERROR_PARAM;\r
+  }\r
+  UInt64 newPosition;\r
+  p->Res = p->Stream->Seek(*offset, moveMethod, &newPosition);\r
+  *offset = (Int64)newPosition;\r
+  return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;\r
+}\r
+\r
+CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream)\r
+{\r
+  Stream = stream;\r
+  p.Read = InStreamWrap_Read;\r
+  p.Seek = InStreamWrap_Seek;\r
+  Res = S_OK;\r
+}\r
+\r
+\r
+/* ---------- CByteInBufWrap ---------- */\r
+\r
+void CByteInBufWrap::Free()\r
+{\r
+  ::MidFree(Buf);\r
+  Buf = 0;\r
+}\r
+\r
+bool CByteInBufWrap::Alloc(UInt32 size)\r
+{\r
+  if (Buf == 0 || size != Size)\r
+  {\r
+    Free();\r
+    Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size);\r
+    Size = size;\r
+  }\r
+  return (Buf != 0);\r
+}\r
+\r
+Byte CByteInBufWrap::ReadByteFromNewBlock()\r
+{\r
+  if (Res == S_OK)\r
+  {\r
+    UInt32 avail;\r
+    Processed += (Cur - Buf);\r
+    Res = Stream->Read(Buf, Size, &avail);\r
+    Cur = Buf;\r
+    Lim = Buf + avail;\r
+    if (avail != 0)\r
+      return *Cur++;\r
+  }\r
+  Extra = true;\r
+  return 0;\r
+}\r
+\r
+static Byte Wrap_ReadByte(void *pp)\r
+{\r
+  CByteInBufWrap *p = (CByteInBufWrap *)pp;\r
+  if (p->Cur != p->Lim)\r
+    return *p->Cur++;\r
+  return p->ReadByteFromNewBlock();\r
+}\r
+\r
+CByteInBufWrap::CByteInBufWrap(): Buf(0)\r
+{\r
+  p.Read = Wrap_ReadByte;\r
+}\r
+\r
+\r
+/* ---------- CByteOutBufWrap ---------- */\r
+\r
+void CByteOutBufWrap::Free()\r
+{\r
+  ::MidFree(Buf);\r
+  Buf = 0;\r
+}\r
+\r
+bool CByteOutBufWrap::Alloc(size_t size)\r
+{\r
+  if (Buf == 0 || size != Size)\r
+  {\r
+    Free();\r
+    Buf = (Byte *)::MidAlloc(size);\r
+    Size = size;\r
+  }\r
+  return (Buf != 0);\r
+}\r
+\r
+HRESULT CByteOutBufWrap::Flush()\r
+{\r
+  if (Res == S_OK)\r
+  {\r
+    size_t size = (Cur - Buf);\r
+    Res = WriteStream(Stream, Buf, size);\r
+    if (Res == S_OK)\r
+      Processed += size;\r
+    Cur = Buf;\r
+  }\r
+  return Res;\r
+}\r
+\r
+static void Wrap_WriteByte(void *pp, Byte b)\r
+{\r
+  CByteOutBufWrap *p = (CByteOutBufWrap *)pp;\r
+  Byte *dest = p->Cur;\r
+  *dest = b;\r
+  p->Cur = ++dest;\r
+  if (dest == p->Lim)\r
+    p->Flush();\r
+}\r
+\r
+CByteOutBufWrap::CByteOutBufWrap(): Buf(0)\r
+{\r
+  p.Write = Wrap_WriteByte;\r
+}\r
diff --git a/CPP/7zip/Common/CWrappers.h b/CPP/7zip/Common/CWrappers.h
new file mode 100755 (executable)
index 0000000..dd4197c
--- /dev/null
@@ -0,0 +1,109 @@
+// CWrappers.h\r
+\r
+#ifndef __C_WRAPPERS_H\r
+#define __C_WRAPPERS_H\r
+\r
+#include "../ICoder.h"\r
+#include "../../Common/MyCom.h"\r
+\r
+struct CCompressProgressWrap\r
+{\r
+  ICompressProgress p;\r
+  ICompressProgressInfo *Progress;\r
+  HRESULT Res;\r
+  CCompressProgressWrap(ICompressProgressInfo *progress);\r
+};\r
+\r
+struct CSeqInStreamWrap\r
+{\r
+  ISeqInStream p;\r
+  ISequentialInStream *Stream;\r
+  HRESULT Res;\r
+  CSeqInStreamWrap(ISequentialInStream *stream);\r
+};\r
+\r
+struct CSeekInStreamWrap\r
+{\r
+  ISeekInStream p;\r
+  IInStream *Stream;\r
+  HRESULT Res;\r
+  CSeekInStreamWrap(IInStream *stream);\r
+};\r
+\r
+struct CSeqOutStreamWrap\r
+{\r
+  ISeqOutStream p;\r
+  ISequentialOutStream *Stream;\r
+  HRESULT Res;\r
+  UInt64 Processed;\r
+  CSeqOutStreamWrap(ISequentialOutStream *stream);\r
+};\r
+\r
+HRESULT SResToHRESULT(SRes res);\r
+\r
+struct CByteInBufWrap\r
+{\r
+  IByteIn p;\r
+  const Byte *Cur;\r
+  const Byte *Lim;\r
+  Byte *Buf;\r
+  UInt32 Size;\r
+  ISequentialInStream *Stream;\r
+  UInt64 Processed;\r
+  bool Extra;\r
+  HRESULT Res;\r
+  \r
+  CByteInBufWrap();\r
+  ~CByteInBufWrap() { Free();  }\r
+  void Free();\r
+  bool Alloc(UInt32 size);\r
+  void Init()\r
+  {\r
+    Lim = Cur = Buf;\r
+    Processed = 0;\r
+    Extra = false;\r
+    Res = S_OK;\r
+  }\r
+  UInt64 GetProcessed() const { return Processed + (Cur - Buf); }\r
+  Byte ReadByteFromNewBlock();\r
+  Byte ReadByte()\r
+  {\r
+    if (Cur != Lim)\r
+      return *Cur++;\r
+    return ReadByteFromNewBlock();\r
+  }\r
+};\r
+\r
+struct CByteOutBufWrap\r
+{\r
+  IByteOut p;\r
+  Byte *Cur;\r
+  const Byte *Lim;\r
+  Byte *Buf;\r
+  size_t Size;\r
+  ISequentialOutStream *Stream;\r
+  UInt64 Processed;\r
+  HRESULT Res;\r
+  \r
+  CByteOutBufWrap();\r
+  ~CByteOutBufWrap() { Free();  }\r
+  void Free();\r
+  bool Alloc(size_t size);\r
+  void Init()\r
+  {\r
+    Cur = Buf;\r
+    Lim = Buf + Size;\r
+    Processed = 0;\r
+    Res = S_OK;\r
+  }\r
+  UInt64 GetProcessed() const { return Processed + (Cur - Buf); }\r
+  HRESULT Flush();\r
+  void WriteByte(Byte b)\r
+  {\r
+    *Cur++ = b;\r
+    if (Cur == Lim)\r
+      Flush();\r
+  }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/CreateCoder.cpp b/CPP/7zip/Common/CreateCoder.cpp
new file mode 100755 (executable)
index 0000000..55bad3c
--- /dev/null
@@ -0,0 +1,293 @@
+// CreateCoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Windows/Defs.h"\r
+#include "../../Windows/PropVariant.h"\r
+\r
+#include "CreateCoder.h"\r
+\r
+#include "FilterCoder.h"\r
+#include "RegisterCodec.h"\r
+\r
+static const unsigned int kNumCodecsMax = 64;\r
+unsigned int g_NumCodecs = 0;\r
+const CCodecInfo *g_Codecs[kNumCodecsMax];\r
+void RegisterCodec(const CCodecInfo *codecInfo)\r
+{\r
+  if (g_NumCodecs < kNumCodecsMax)\r
+    g_Codecs[g_NumCodecs++] = codecInfo;\r
+}\r
+\r
+#ifdef EXTERNAL_CODECS\r
+static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)\r
+{\r
+  NWindows::NCOM::CPropVariant prop;\r
+  RINOK(codecsInfo->GetProperty(index, propID, &prop));\r
+  if (prop.vt == VT_EMPTY)\r
+    res = 1;\r
+  else if (prop.vt == VT_UI4)\r
+    res = prop.ulVal;\r
+  else\r
+    return E_INVALIDARG;\r
+  return S_OK;\r
+}\r
+\r
+static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res)\r
+{\r
+  NWindows::NCOM::CPropVariant prop;\r
+  RINOK(codecsInfo->GetProperty(index, propID, &prop));\r
+  if (prop.vt == VT_EMPTY)\r
+    res = true;\r
+  else if (prop.vt == VT_BOOL)\r
+    res = VARIANT_BOOLToBool(prop.boolVal);\r
+  else\r
+    return E_INVALIDARG;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)\r
+{\r
+  UInt32 num;\r
+  RINOK(codecsInfo->GetNumberOfMethods(&num));\r
+  for (UInt32 i = 0; i < num; i++)\r
+  {\r
+    CCodecInfoEx info;\r
+    NWindows::NCOM::CPropVariant prop;\r
+    RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));\r
+    // if (prop.vt != VT_BSTR)\r
+    // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);\r
+    // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);\r
+    if (prop.vt != VT_UI8)\r
+    {\r
+      continue; // old Interface\r
+      // return E_INVALIDARG;\r
+    }\r
+    info.Id = prop.uhVal.QuadPart;\r
+    prop.Clear();\r
+    \r
+    RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));\r
+    if (prop.vt == VT_BSTR)\r
+      info.Name = prop.bstrVal;\r
+    else if (prop.vt != VT_EMPTY)\r
+      return E_INVALIDARG;;\r
+    \r
+    RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));\r
+    RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));\r
+    RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));\r
+    RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));\r
+    \r
+    externalCodecs.Add(info);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+#endif\r
+\r
+bool FindMethod(\r
+  #ifdef EXTERNAL_CODECS\r
+  ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,\r
+  #endif\r
+  const UString &name,\r
+  CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < g_NumCodecs; i++)\r
+  {\r
+    const CCodecInfo &codec = *g_Codecs[i];\r
+    if (name.CompareNoCase(codec.Name) == 0)\r
+    {\r
+      methodId = codec.Id;\r
+      numInStreams = codec.NumInStreams;\r
+      numOutStreams = 1;\r
+      return true;\r
+    }\r
+  }\r
+  #ifdef EXTERNAL_CODECS\r
+  if (externalCodecs)\r
+    for (i = 0; i < (UInt32)externalCodecs->Size(); i++)\r
+    {\r
+      const CCodecInfoEx &codec = (*externalCodecs)[i];\r
+      if (codec.Name.CompareNoCase(name) == 0)\r
+      {\r
+        methodId = codec.Id;\r
+        numInStreams = codec.NumInStreams;\r
+        numOutStreams = codec.NumOutStreams;\r
+        return true;\r
+      }\r
+    }\r
+  #endif\r
+  return false;\r
+}\r
+\r
+bool FindMethod(\r
+  #ifdef EXTERNAL_CODECS\r
+  ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,\r
+  #endif\r
+  CMethodId methodId, UString &name)\r
+{\r
+  UInt32 i;\r
+  for (i = 0; i < g_NumCodecs; i++)\r
+  {\r
+    const CCodecInfo &codec = *g_Codecs[i];\r
+    if (methodId == codec.Id)\r
+    {\r
+      name = codec.Name;\r
+      return true;\r
+    }\r
+  }\r
+  #ifdef EXTERNAL_CODECS\r
+  if (externalCodecs)\r
+    for (i = 0; i < (UInt32)externalCodecs->Size(); i++)\r
+    {\r
+      const CCodecInfoEx &codec = (*externalCodecs)[i];\r
+      if (methodId == codec.Id)\r
+      {\r
+        name = codec.Name;\r
+        return true;\r
+      }\r
+    }\r
+  #endif\r
+  return false;\r
+}\r
+\r
+HRESULT CreateCoder(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId,\r
+  CMyComPtr<ICompressFilter> &filter,\r
+  CMyComPtr<ICompressCoder> &coder,\r
+  CMyComPtr<ICompressCoder2> &coder2,\r
+  bool encode, bool onlyCoder)\r
+{\r
+  bool created = false;\r
+  UInt32 i;\r
+  for (i = 0; i < g_NumCodecs; i++)\r
+  {\r
+    const CCodecInfo &codec = *g_Codecs[i];\r
+    if (codec.Id == methodId)\r
+    {\r
+      if (encode)\r
+      {\r
+        if (codec.CreateEncoder)\r
+        {\r
+          void *p = codec.CreateEncoder();\r
+          if (codec.IsFilter) filter = (ICompressFilter *)p;\r
+          else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;\r
+          else coder2 = (ICompressCoder2 *)p;\r
+          created = (p != 0);\r
+          break;\r
+        }\r
+      }\r
+      else\r
+        if (codec.CreateDecoder)\r
+        {\r
+          void *p = codec.CreateDecoder();\r
+          if (codec.IsFilter) filter = (ICompressFilter *)p;\r
+          else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;\r
+          else coder2 = (ICompressCoder2 *)p;\r
+          created = (p != 0);\r
+          break;\r
+        }\r
+    }\r
+  }\r
+\r
+  #ifdef EXTERNAL_CODECS\r
+  if (!created && externalCodecs)\r
+    for (i = 0; i < (UInt32)externalCodecs->Size(); i++)\r
+    {\r
+      const CCodecInfoEx &codec = (*externalCodecs)[i];\r
+      if (codec.Id == methodId)\r
+      {\r
+        if (encode)\r
+        {\r
+          if (codec.EncoderIsAssigned)\r
+          {\r
+            if (codec.IsSimpleCodec())\r
+            {\r
+              HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);\r
+              if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)\r
+                return result;\r
+              if (!coder)\r
+              {\r
+                RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));\r
+              }\r
+            }\r
+            else\r
+            {\r
+              RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));\r
+            }\r
+            break;\r
+          }\r
+        }\r
+        else\r
+          if (codec.DecoderIsAssigned)\r
+          {\r
+            if (codec.IsSimpleCodec())\r
+            {\r
+              HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);\r
+              if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)\r
+                return result;\r
+              if (!coder)\r
+              {\r
+                RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));\r
+              }\r
+            }\r
+            else\r
+            {\r
+              RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));\r
+            }\r
+            break;\r
+          }\r
+      }\r
+    }\r
+  #endif\r
+\r
+  if (onlyCoder && filter)\r
+  {\r
+    CFilterCoder *coderSpec = new CFilterCoder;\r
+    coder = coderSpec;\r
+    coderSpec->Filter = filter;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CreateCoder(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId,\r
+  CMyComPtr<ICompressCoder> &coder,\r
+  CMyComPtr<ICompressCoder2> &coder2,\r
+  bool encode)\r
+{\r
+  CMyComPtr<ICompressFilter> filter;\r
+  return CreateCoder(\r
+    EXTERNAL_CODECS_LOC_VARS\r
+    methodId,\r
+    filter, coder, coder2, encode, true);\r
+}\r
+\r
+HRESULT CreateCoder(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId,\r
+  CMyComPtr<ICompressCoder> &coder, bool encode)\r
+{\r
+  CMyComPtr<ICompressFilter> filter;\r
+  CMyComPtr<ICompressCoder2> coder2;\r
+  return CreateCoder(\r
+    EXTERNAL_CODECS_LOC_VARS\r
+    methodId,\r
+    coder, coder2, encode);\r
+}\r
+\r
+HRESULT CreateFilter(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId,\r
+  CMyComPtr<ICompressFilter> &filter,\r
+  bool encode)\r
+{\r
+  CMyComPtr<ICompressCoder> coder;\r
+  CMyComPtr<ICompressCoder2> coder2;\r
+  return CreateCoder(\r
+    EXTERNAL_CODECS_LOC_VARS\r
+    methodId,\r
+    filter, coder, coder2, encode, false);\r
+}\r
diff --git a/CPP/7zip/Common/CreateCoder.h b/CPP/7zip/Common/CreateCoder.h
new file mode 100755 (executable)
index 0000000..9a59d45
--- /dev/null
@@ -0,0 +1,98 @@
+// CreateCoder.h\r
+\r
+#ifndef __CREATE_CODER_H\r
+#define __CREATE_CODER_H\r
+\r
+#include "../../Common/MyCom.h"\r
+#include "../../Common/MyString.h"\r
+#include "../ICoder.h"\r
+\r
+#include "MethodId.h"\r
+\r
+#ifdef EXTERNAL_CODECS\r
+\r
+struct CCodecInfoEx\r
+{\r
+  UString Name;\r
+  CMethodId Id;\r
+  UInt32 NumInStreams;\r
+  UInt32 NumOutStreams;\r
+  bool EncoderIsAssigned;\r
+  bool DecoderIsAssigned;\r
+  bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; }\r
+  CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {}\r
+};\r
+\r
+HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs);\r
+\r
+#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo,\r
+#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo)\r
+#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo);\r
+#define IMPL_ISetCompressCodecsInfo2(x) \\r
+STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \\r
+  COM_TRY_BEGIN _codecsInfo = compressCodecsInfo;  return LoadExternalCodecs(_codecsInfo, _externalCodecs); COM_TRY_END }\r
+#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler)\r
+\r
+#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs\r
+\r
+#define DECL_EXTERNAL_CODECS_VARS CMyComPtr<ICompressCodecsInfo> _codecsInfo; CObjectVector<CCodecInfoEx> _externalCodecs;\r
+#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,\r
+\r
+#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector<CCodecInfoEx> *externalCodecs\r
+#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs\r
+\r
+#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2,\r
+#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2,\r
+\r
+#else\r
+\r
+#define PUBLIC_ISetCompressCodecsInfo\r
+#define QUERY_ENTRY_ISetCompressCodecsInfo\r
+#define DECL_ISetCompressCodecsInfo\r
+#define IMPL_ISetCompressCodecsInfo\r
+#define EXTERNAL_CODECS_VARS2\r
+#define DECL_EXTERNAL_CODECS_VARS\r
+#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2\r
+#define DECL_EXTERNAL_CODECS_LOC_VARS2\r
+#define EXTERNAL_CODECS_LOC_VARS2\r
+#define DECL_EXTERNAL_CODECS_LOC_VARS\r
+#define EXTERNAL_CODECS_LOC_VARS\r
+\r
+#endif\r
+\r
+bool FindMethod(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams);\r
+\r
+bool FindMethod(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId, UString &name);\r
+\r
+\r
+HRESULT CreateCoder(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId,\r
+  CMyComPtr<ICompressFilter> &filter,\r
+  CMyComPtr<ICompressCoder> &coder,\r
+  CMyComPtr<ICompressCoder2> &coder2,\r
+  bool encode, bool onlyCoder);\r
+\r
+HRESULT CreateCoder(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId,\r
+  CMyComPtr<ICompressCoder> &coder,\r
+  CMyComPtr<ICompressCoder2> &coder2,\r
+  bool encode);\r
+\r
+HRESULT CreateCoder(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId,\r
+  CMyComPtr<ICompressCoder> &coder, bool encode);\r
+\r
+HRESULT CreateFilter(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  CMethodId methodId,\r
+  CMyComPtr<ICompressFilter> &filter,\r
+  bool encode);\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/FilePathAutoRename.cpp b/CPP/7zip/Common/FilePathAutoRename.cpp
new file mode 100755 (executable)
index 0000000..d357c5b
--- /dev/null
@@ -0,0 +1,55 @@
+// FilePathAutoRename.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/Defs.h"\r
+#include "Common/IntToString.h"\r
+\r
+#include "Windows/FileFind.h"\r
+\r
+#include "FilePathAutoRename.h"\r
+\r
+using namespace NWindows;\r
+\r
+static bool MakeAutoName(const UString &name,\r
+    const UString &extension, unsigned value, UString &path)\r
+{\r
+  wchar_t number[16];\r
+  ConvertUInt32ToString(value, number);\r
+  path = name;\r
+  path += number;\r
+  path += extension;\r
+  return NFile::NFind::DoesFileOrDirExist(path);\r
+}\r
+\r
+bool AutoRenamePath(UString &fullProcessedPath)\r
+{\r
+  UString path;\r
+  int dotPos = fullProcessedPath.ReverseFind(L'.');\r
+\r
+  int slashPos = fullProcessedPath.ReverseFind(L'/');\r
+  #ifdef _WIN32\r
+  int slash1Pos = fullProcessedPath.ReverseFind(L'\\');\r
+  slashPos = MyMax(slashPos, slash1Pos);\r
+  #endif\r
+\r
+  UString name, extension;\r
+  if (dotPos > slashPos && dotPos > 0)\r
+  {\r
+    name = fullProcessedPath.Left(dotPos);\r
+    extension = fullProcessedPath.Mid(dotPos);\r
+  }\r
+  else\r
+    name = fullProcessedPath;\r
+  name += L'_';\r
+  unsigned left = 1, right = (1 << 30);\r
+  while (left != right)\r
+  {\r
+    unsigned mid = (left + right) / 2;\r
+    if (MakeAutoName(name, extension, mid, path))\r
+      left = mid + 1;\r
+    else\r
+      right = mid;\r
+  }\r
+  return !MakeAutoName(name, extension, right, fullProcessedPath);\r
+}\r
diff --git a/CPP/7zip/Common/FilePathAutoRename.h b/CPP/7zip/Common/FilePathAutoRename.h
new file mode 100755 (executable)
index 0000000..4303962
--- /dev/null
@@ -0,0 +1,10 @@
+// Util/FilePathAutoRename.h\r
+\r
+#ifndef __FILEPATHAUTORENAME_H\r
+#define __FILEPATHAUTORENAME_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+bool AutoRenamePath(UString &fullProcessedPath);\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/FileStreams.cpp b/CPP/7zip/Common/FileStreams.cpp
new file mode 100755 (executable)
index 0000000..de49911
--- /dev/null
@@ -0,0 +1,422 @@
+// FileStreams.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#ifndef _WIN32\r
+#include <fcntl.h>\r
+#include <unistd.h>\r
+#include <errno.h>\r
+#endif\r
+\r
+#ifdef SUPPORT_DEVICE_FILE\r
+#include "../../../C/Alloc.h"\r
+#include "../../Common/Defs.h"\r
+#endif\r
+\r
+#include "FileStreams.h"\r
+\r
+static inline HRESULT ConvertBoolToHRESULT(bool result)\r
+{\r
+  #ifdef _WIN32\r
+  if (result)\r
+    return S_OK;\r
+  DWORD lastError = ::GetLastError();\r
+  if (lastError == 0)\r
+    return E_FAIL;\r
+  return HRESULT_FROM_WIN32(lastError);\r
+  #else\r
+  return result ? S_OK: E_FAIL;\r
+  #endif\r
+}\r
+\r
+bool CInFileStream::Open(LPCTSTR fileName)\r
+{\r
+  return File.Open(fileName);\r
+}\r
+\r
+#ifdef USE_WIN_FILE\r
+#ifndef _UNICODE\r
+bool CInFileStream::Open(LPCWSTR fileName)\r
+{\r
+  return File.Open(fileName);\r
+}\r
+#endif\r
+#endif\r
+\r
+bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)\r
+{\r
+  return File.OpenShared(fileName, shareForWrite);\r
+}\r
+\r
+#ifdef USE_WIN_FILE\r
+#ifndef _UNICODE\r
+bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)\r
+{\r
+  return File.OpenShared(fileName, shareForWrite);\r
+}\r
+#endif\r
+#endif\r
+\r
+#ifdef SUPPORT_DEVICE_FILE\r
+\r
+static const UInt32 kClusterSize = 1 << 18;\r
+CInFileStream::CInFileStream():\r
+  VirtPos(0),\r
+  PhyPos(0),\r
+  Buffer(0),\r
+  BufferSize(0)\r
+{\r
+}\r
+\r
+#endif\r
+\r
+CInFileStream::~CInFileStream()\r
+{\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  MidFree(Buffer);\r
+  #endif\r
+}\r
+\r
+STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  #ifdef USE_WIN_FILE\r
+  \r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  if (size == 0)\r
+    return S_OK;\r
+  if (File.IsDeviceFile)\r
+  {\r
+    if (File.LengthDefined)\r
+    {\r
+      if (VirtPos >= File.Length)\r
+        return VirtPos == File.Length ? S_OK : E_FAIL;\r
+      UInt64 rem = File.Length - VirtPos;\r
+      if (size > rem)\r
+        size = (UInt32)rem;\r
+    }\r
+    for (;;)\r
+    {\r
+      const UInt32 mask = kClusterSize - 1;\r
+      UInt64 mask2 = ~(UInt64)mask;\r
+      UInt64 alignedPos = VirtPos & mask2;\r
+      if (BufferSize > 0 && BufferStartPos == alignedPos)\r
+      {\r
+        UInt32 pos = (UInt32)VirtPos & mask;\r
+        if (pos >= BufferSize)\r
+          return S_OK;\r
+        UInt32 rem = MyMin(BufferSize - pos, size);\r
+        memcpy(data, Buffer + pos, rem);\r
+        VirtPos += rem;\r
+        if (processedSize != NULL)\r
+          *processedSize += rem;\r
+        return S_OK;\r
+      }\r
+      \r
+      bool useBuffer = false;\r
+      if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 )\r
+        useBuffer = true;\r
+      else\r
+      {\r
+        UInt64 end = VirtPos + size;\r
+        if ((end & mask) != 0)\r
+        {\r
+          end &= mask2;\r
+          if (end <= VirtPos)\r
+            useBuffer = true;\r
+          else\r
+            size = (UInt32)(end - VirtPos);\r
+        }\r
+      }\r
+      if (!useBuffer)\r
+        break;\r
+      if (alignedPos != PhyPos)\r
+      {\r
+        UInt64 realNewPosition;\r
+        bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition);\r
+        if (!result)\r
+          return ConvertBoolToHRESULT(result);\r
+        PhyPos = realNewPosition;\r
+      }\r
+\r
+      BufferStartPos = alignedPos;\r
+      UInt32 readSize = kClusterSize;\r
+      if (File.LengthDefined)\r
+        readSize = (UInt32)MyMin(File.Length - PhyPos, (UInt64)kClusterSize);\r
+\r
+      if (Buffer == 0)\r
+      {\r
+        Buffer = (Byte *)MidAlloc(kClusterSize);\r
+        if (Buffer == 0)\r
+          return E_OUTOFMEMORY;\r
+      }\r
+      bool result = File.Read1(Buffer, readSize, BufferSize);\r
+      if (!result)\r
+        return ConvertBoolToHRESULT(result);\r
+\r
+      if (BufferSize == 0)\r
+        return S_OK;\r
+      PhyPos += BufferSize;\r
+    }\r
+\r
+    if (VirtPos != PhyPos)\r
+    {\r
+      UInt64 realNewPosition;\r
+      bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition);\r
+      if (!result)\r
+        return ConvertBoolToHRESULT(result);\r
+      PhyPos = VirtPos = realNewPosition;\r
+    }\r
+  }\r
+  #endif\r
+\r
+  UInt32 realProcessedSize;\r
+  bool result = File.ReadPart(data, size, realProcessedSize);\r
+  if (processedSize != NULL)\r
+    *processedSize = realProcessedSize;\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  VirtPos += realProcessedSize;\r
+  PhyPos += realProcessedSize;\r
+  #endif\r
+  return ConvertBoolToHRESULT(result);\r
+  \r
+  #else\r
+  \r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  ssize_t res = File.Read(data, (size_t)size);\r
+  if (res == -1)\r
+    return E_FAIL;\r
+  if (processedSize != NULL)\r
+    *processedSize = (UInt32)res;\r
+  return S_OK;\r
+\r
+  #endif\r
+}\r
+\r
+#ifdef UNDER_CE\r
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  size_t s2 = fread(data, 1, size, stdout);\r
+  if (processedSize != 0)\r
+    *processedSize = s2;\r
+  return (s2 = size) ? S_OK : E_FAIL;\r
+}\r
+#else\r
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  #ifdef _WIN32\r
+  \r
+  DWORD realProcessedSize;\r
+  UInt32 sizeTemp = (1 << 20);\r
+  if (sizeTemp > size)\r
+    sizeTemp = size;\r
+  BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL);\r
+  if (processedSize != NULL)\r
+    *processedSize = realProcessedSize;\r
+  if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)\r
+    return S_OK;\r
+  return ConvertBoolToHRESULT(res != FALSE);\r
+  \r
+  #else\r
+\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  ssize_t res;\r
+  do\r
+  {\r
+    res = read(0, data, (size_t)size);\r
+  }\r
+  while (res < 0 && (errno == EINTR));\r
+  if (res == -1)\r
+    return E_FAIL;\r
+  if (processedSize != NULL)\r
+    *processedSize = (UInt32)res;\r
+  return S_OK;\r
+  \r
+  #endif\r
+}\r
+  \r
+#endif\r
+\r
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,\r
+    UInt64 *newPosition)\r
+{\r
+  if (seekOrigin >= 3)\r
+    return STG_E_INVALIDFUNCTION;\r
+\r
+  #ifdef USE_WIN_FILE\r
+\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  if (File.IsDeviceFile)\r
+  {\r
+    UInt64 newVirtPos = offset;\r
+    switch(seekOrigin)\r
+    {\r
+      case STREAM_SEEK_SET: break;\r
+      case STREAM_SEEK_CUR: newVirtPos += VirtPos; break;\r
+      case STREAM_SEEK_END: newVirtPos += File.Length; break;\r
+      default: return STG_E_INVALIDFUNCTION;\r
+    }\r
+    VirtPos = newVirtPos;\r
+    if (newPosition)\r
+      *newPosition = newVirtPos;\r
+    return S_OK;\r
+  }\r
+  #endif\r
+  \r
+  UInt64 realNewPosition;\r
+  bool result = File.Seek(offset, seekOrigin, realNewPosition);\r
+  \r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  PhyPos = VirtPos = realNewPosition;\r
+  #endif\r
+\r
+  if (newPosition != NULL)\r
+    *newPosition = realNewPosition;\r
+  return ConvertBoolToHRESULT(result);\r
+  \r
+  #else\r
+  \r
+  off_t res = File.Seek(offset, seekOrigin);\r
+  if (res == -1)\r
+    return E_FAIL;\r
+  if (newPosition != NULL)\r
+    *newPosition = (UInt64)res;\r
+  return S_OK;\r
+  \r
+  #endif\r
+}\r
+\r
+STDMETHODIMP CInFileStream::GetSize(UInt64 *size)\r
+{\r
+  return ConvertBoolToHRESULT(File.GetLength(*size));\r
+}\r
+\r
+\r
+//////////////////////////\r
+// COutFileStream\r
+\r
+HRESULT COutFileStream::Close()\r
+{\r
+  return ConvertBoolToHRESULT(File.Close());\r
+}\r
+\r
+STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  #ifdef USE_WIN_FILE\r
+\r
+  UInt32 realProcessedSize;\r
+  bool result = File.WritePart(data, size, realProcessedSize);\r
+  ProcessedSize += realProcessedSize;\r
+  if (processedSize != NULL)\r
+    *processedSize = realProcessedSize;\r
+  return ConvertBoolToHRESULT(result);\r
+  \r
+  #else\r
+  \r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  ssize_t res = File.Write(data, (size_t)size);\r
+  if (res == -1)\r
+    return E_FAIL;\r
+  if (processedSize != NULL)\r
+    *processedSize = (UInt32)res;\r
+  ProcessedSize += res;\r
+  return S_OK;\r
+  \r
+  #endif\r
+}\r
+  \r
+STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  if (seekOrigin >= 3)\r
+    return STG_E_INVALIDFUNCTION;\r
+  #ifdef USE_WIN_FILE\r
+\r
+  UInt64 realNewPosition;\r
+  bool result = File.Seek(offset, seekOrigin, realNewPosition);\r
+  if (newPosition != NULL)\r
+    *newPosition = realNewPosition;\r
+  return ConvertBoolToHRESULT(result);\r
+  \r
+  #else\r
+  \r
+  off_t res = File.Seek(offset, seekOrigin);\r
+  if (res == -1)\r
+    return E_FAIL;\r
+  if (newPosition != NULL)\r
+    *newPosition = (UInt64)res;\r
+  return S_OK;\r
+  \r
+  #endif\r
+}\r
+\r
+STDMETHODIMP COutFileStream::SetSize(UInt64 newSize)\r
+{\r
+  #ifdef USE_WIN_FILE\r
+  UInt64 currentPos;\r
+  if (!File.Seek(0, FILE_CURRENT, currentPos))\r
+    return E_FAIL;\r
+  bool result = File.SetLength(newSize);\r
+  UInt64 currentPos2;\r
+  result = result && File.Seek(currentPos, currentPos2);\r
+  return result ? S_OK : E_FAIL;\r
+  #else\r
+  return E_FAIL;\r
+  #endif\r
+}\r
+\r
+#ifdef UNDER_CE\r
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  size_t s2 = fwrite(data, 1, size, stdout);\r
+  if (processedSize != 0)\r
+    *processedSize = s2;\r
+  return (s2 = size) ? S_OK : E_FAIL;\r
+}\r
+#else\r
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+\r
+  #ifdef _WIN32\r
+  UInt32 realProcessedSize;\r
+  BOOL res = TRUE;\r
+  if (size > 0)\r
+  {\r
+    // Seems that Windows doesn't like big amounts writing to stdout.\r
+    // So we limit portions by 32KB.\r
+    UInt32 sizeTemp = (1 << 15);\r
+    if (sizeTemp > size)\r
+      sizeTemp = size;\r
+    res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),\r
+        data, sizeTemp, (DWORD *)&realProcessedSize, NULL);\r
+    size -= realProcessedSize;\r
+    data = (const void *)((const Byte *)data + realProcessedSize);\r
+    if (processedSize != NULL)\r
+      *processedSize += realProcessedSize;\r
+  }\r
+  return ConvertBoolToHRESULT(res != FALSE);\r
+\r
+  #else\r
+  \r
+  ssize_t res;\r
+  do\r
+  {\r
+    res = write(1, data, (size_t)size);\r
+  }\r
+  while (res < 0 && (errno == EINTR));\r
+  if (res == -1)\r
+    return E_FAIL;\r
+  if (processedSize != NULL)\r
+    *processedSize = (UInt32)res;\r
+  return S_OK;\r
+  \r
+  return S_OK;\r
+  #endif\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/FileStreams.h b/CPP/7zip/Common/FileStreams.h
new file mode 100755 (executable)
index 0000000..f979294
--- /dev/null
@@ -0,0 +1,144 @@
+// FileStreams.h\r
+\r
+#ifndef __FILESTREAMS_H\r
+#define __FILESTREAMS_H\r
+\r
+#ifdef _WIN32\r
+#define USE_WIN_FILE\r
+#endif\r
+\r
+#ifdef USE_WIN_FILE\r
+#include "../../Windows/FileIO.h"\r
+#else\r
+#include "../../Common/C_FileIO.h"\r
+#endif\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../IStream.h"\r
+\r
+class CInFileStream:\r
+  public IInStream,\r
+  public IStreamGetSize,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  #ifdef USE_WIN_FILE\r
+  NWindows::NFile::NIO::CInFile File;\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  UInt64 VirtPos;\r
+  UInt64 PhyPos;\r
+  UInt64 BufferStartPos;\r
+  Byte *Buffer;\r
+  UInt32 BufferSize;\r
+  #endif\r
+  #else\r
+  NC::NFile::NIO::CInFile File;\r
+  #endif\r
+  virtual ~CInFileStream();\r
+\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  CInFileStream();\r
+  #endif\r
+  \r
+  bool Open(LPCTSTR fileName);\r
+  #ifdef USE_WIN_FILE\r
+  #ifndef _UNICODE\r
+  bool Open(LPCWSTR fileName);\r
+  #endif\r
+  #endif\r
+\r
+  bool OpenShared(LPCTSTR fileName, bool shareForWrite);\r
+  #ifdef USE_WIN_FILE\r
+  #ifndef _UNICODE\r
+  bool OpenShared(LPCWSTR fileName, bool shareForWrite);\r
+  #endif\r
+  #endif\r
+\r
+  MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+\r
+  STDMETHOD(GetSize)(UInt64 *size);\r
+};\r
+\r
+class CStdInFileStream:\r
+  public ISequentialInStream,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP\r
+\r
+  virtual ~CStdInFileStream() {}\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+class COutFileStream:\r
+  public IOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  #ifdef USE_WIN_FILE\r
+  NWindows::NFile::NIO::COutFile File;\r
+  #else\r
+  NC::NFile::NIO::COutFile File;\r
+  #endif\r
+public:\r
+  virtual ~COutFileStream() {}\r
+  bool Create(LPCTSTR fileName, bool createAlways)\r
+  {\r
+    ProcessedSize = 0;\r
+    return File.Create(fileName, createAlways);\r
+  }\r
+  bool Open(LPCTSTR fileName, DWORD creationDisposition)\r
+  {\r
+    ProcessedSize = 0;\r
+    return File.Open(fileName, creationDisposition);\r
+  }\r
+  #ifdef USE_WIN_FILE\r
+  #ifndef _UNICODE\r
+  bool Create(LPCWSTR fileName, bool createAlways)\r
+  {\r
+    ProcessedSize = 0;\r
+    return File.Create(fileName, createAlways);\r
+  }\r
+  bool Open(LPCWSTR fileName, DWORD creationDisposition)\r
+  {\r
+    ProcessedSize = 0;\r
+    return File.Open(fileName, creationDisposition);\r
+  }\r
+  #endif\r
+  #endif\r
+\r
+  HRESULT Close();\r
+  \r
+  UInt64 ProcessedSize;\r
+\r
+  #ifdef USE_WIN_FILE\r
+  bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)\r
+  {\r
+    return File.SetTime(cTime, aTime, mTime);\r
+  }\r
+  bool SetMTime(const FILETIME *mTime) {  return File.SetMTime(mTime); }\r
+  #endif\r
+\r
+\r
+  MY_UNKNOWN_IMP1(IOutStream)\r
+\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+  STDMETHOD(SetSize)(UInt64 newSize);\r
+};\r
+\r
+class CStdOutFileStream:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP\r
+\r
+  virtual ~CStdOutFileStream() {}\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/FilterCoder.cpp b/CPP/7zip/Common/FilterCoder.cpp
new file mode 100755 (executable)
index 0000000..03a2aa0
--- /dev/null
@@ -0,0 +1,247 @@
+// FilterCoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "../../Common/Defs.h"\r
+\r
+#include "FilterCoder.h"\r
+#include "StreamUtils.h"\r
+\r
+static const UInt32 kBufferSize = 1 << 17;\r
+\r
+CFilterCoder::CFilterCoder()\r
+{\r
+  _buffer = (Byte *)::MidAlloc(kBufferSize);\r
+  if (_buffer == 0)\r
+    throw 1;\r
+}\r
+\r
+CFilterCoder::~CFilterCoder()\r
+{\r
+  ::MidFree(_buffer);\r
+}\r
+\r
+HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)\r
+{\r
+  if (_outSizeIsDefined)\r
+  {\r
+    UInt64 remSize = _outSize - _nowPos64;\r
+    if (size > remSize)\r
+      size = (UInt32)remSize;\r
+  }\r
+  RINOK(WriteStream(outStream, _buffer, size));\r
+  _nowPos64 += size;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+    const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)\r
+{\r
+  RINOK(Init());\r
+  UInt32 bufferPos = 0;\r
+  _outSizeIsDefined = (outSize != 0);\r
+  if (_outSizeIsDefined)\r
+    _outSize = *outSize;\r
+\r
+  while (!_outSizeIsDefined || _nowPos64 < _outSize)\r
+  {\r
+    size_t processedSize = kBufferSize - bufferPos;\r
+    \r
+    // Change it: It can be optimized using ReadPart\r
+    RINOK(ReadStream(inStream, _buffer + bufferPos, &processedSize));\r
+    \r
+    UInt32 endPos = bufferPos + (UInt32)processedSize;\r
+\r
+    bufferPos = Filter->Filter(_buffer, endPos);\r
+    if (bufferPos > endPos)\r
+    {\r
+      for (; endPos < bufferPos; endPos++)\r
+        _buffer[endPos] = 0;\r
+      bufferPos = Filter->Filter(_buffer, endPos);\r
+    }\r
+\r
+    if (bufferPos == 0)\r
+    {\r
+      if (endPos == 0)\r
+        return S_OK;\r
+      return WriteWithLimit(outStream, endPos);\r
+    }\r
+    RINOK(WriteWithLimit(outStream, bufferPos));\r
+    if (progress != NULL)\r
+    {\r
+      RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));\r
+    }\r
+    UInt32 i = 0;\r
+    while (bufferPos < endPos)\r
+      _buffer[i++] = _buffer[bufferPos++];\r
+    bufferPos = i;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)\r
+{\r
+  _bufferPos = 0;\r
+  _outStream = outStream;\r
+  return Init();\r
+}\r
+\r
+STDMETHODIMP CFilterCoder::ReleaseOutStream()\r
+{\r
+  _outStream.Release();\r
+  return S_OK;\r
+}\r
+\r
+\r
+STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  while (size > 0)\r
+  {\r
+    UInt32 sizeTemp = MyMin(size, kBufferSize - _bufferPos);\r
+    memcpy(_buffer + _bufferPos, data, sizeTemp);\r
+    size -= sizeTemp;\r
+    if (processedSize != NULL)\r
+      *processedSize += sizeTemp;\r
+    data = (const Byte *)data + sizeTemp;\r
+    UInt32 endPos = _bufferPos + sizeTemp;\r
+    _bufferPos = Filter->Filter(_buffer, endPos);\r
+    if (_bufferPos == 0)\r
+    {\r
+      _bufferPos = endPos;\r
+      break;\r
+    }\r
+    if (_bufferPos > endPos)\r
+    {\r
+      if (size != 0)\r
+        return E_FAIL;\r
+      break;\r
+    }\r
+    RINOK(WriteWithLimit(_outStream, _bufferPos));\r
+    UInt32 i = 0;\r
+    while (_bufferPos < endPos)\r
+      _buffer[i++] = _buffer[_bufferPos++];\r
+    _bufferPos = i;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFilterCoder::Flush()\r
+{\r
+  if (_bufferPos != 0)\r
+  {\r
+    // _buffer contains only data refused by previous Filter->Filter call.\r
+    UInt32 endPos = Filter->Filter(_buffer, _bufferPos);\r
+    if (endPos > _bufferPos)\r
+    {\r
+      for (; _bufferPos < endPos; _bufferPos++)\r
+        _buffer[_bufferPos] = 0;\r
+      if (Filter->Filter(_buffer, endPos) != endPos)\r
+        return E_FAIL;\r
+    }\r
+    RINOK(WriteWithLimit(_outStream, _bufferPos));\r
+    _bufferPos = 0;\r
+  }\r
+  CMyComPtr<IOutStreamFlush> flush;\r
+  _outStream.QueryInterface(IID_IOutStreamFlush, &flush);\r
+  if (flush)\r
+    return flush->Flush();\r
+  return S_OK;\r
+}\r
+\r
+\r
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)\r
+{\r
+  _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;\r
+  _inStream = inStream;\r
+  return Init();\r
+}\r
+\r
+STDMETHODIMP CFilterCoder::ReleaseInStream()\r
+{\r
+  _inStream.Release();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  while (size > 0)\r
+  {\r
+    if (_convertedPosBegin != _convertedPosEnd)\r
+    {\r
+      UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);\r
+      memcpy(data, _buffer + _convertedPosBegin, sizeTemp);\r
+      _convertedPosBegin += sizeTemp;\r
+      data = (void *)((Byte *)data + sizeTemp);\r
+      size -= sizeTemp;\r
+      if (processedSize != NULL)\r
+        *processedSize += sizeTemp;\r
+      break;\r
+    }\r
+    UInt32 i;\r
+    for (i = 0; _convertedPosEnd + i < _bufferPos; i++)\r
+      _buffer[i] = _buffer[_convertedPosEnd + i];\r
+    _bufferPos = i;\r
+    _convertedPosBegin = _convertedPosEnd = 0;\r
+    size_t processedSizeTemp = kBufferSize - _bufferPos;\r
+    RINOK(ReadStream(_inStream, _buffer + _bufferPos, &processedSizeTemp));\r
+    _bufferPos += (UInt32)processedSizeTemp;\r
+    _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);\r
+    if (_convertedPosEnd == 0)\r
+    {\r
+      if (_bufferPos == 0)\r
+        break;\r
+      _convertedPosEnd = _bufferPos; // check it\r
+      continue;\r
+    }\r
+    if (_convertedPosEnd > _bufferPos)\r
+    {\r
+      for (; _bufferPos < _convertedPosEnd; _bufferPos++)\r
+        _buffer[_bufferPos] = 0;\r
+      _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+#ifndef _NO_CRYPTO\r
+STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)\r
+{\r
+  return _setPassword->CryptoSetPassword(data, size);\r
+}\r
+#endif\r
+\r
+#ifndef EXTRACT_ONLY\r
+STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs,\r
+      const PROPVARIANT *properties, UInt32 numProperties)\r
+{\r
+  return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties);\r
+}\r
+\r
+STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)\r
+{\r
+  return _writeCoderProperties->WriteCoderProperties(outStream);\r
+}\r
+\r
+/*\r
+STDMETHODIMP CFilterCoder::ResetSalt()\r
+{\r
+  return _CryptoResetSalt->ResetSalt();\r
+}\r
+*/\r
+\r
+STDMETHODIMP CFilterCoder::ResetInitVector()\r
+{\r
+  return _CryptoResetInitVector->ResetInitVector();\r
+}\r
+#endif\r
+\r
+STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)\r
+{\r
+  return _setDecoderProperties->SetDecoderProperties2(data, size);\r
+}\r
diff --git a/CPP/7zip/Common/FilterCoder.h b/CPP/7zip/Common/FilterCoder.h
new file mode 100755 (executable)
index 0000000..1b0125d
--- /dev/null
@@ -0,0 +1,128 @@
+// FilterCoder.h\r
+\r
+#ifndef __FILTER_CODER_H\r
+#define __FILTER_CODER_H\r
+\r
+#include "../../Common/MyCom.h"\r
+#include "../ICoder.h"\r
+#include "../IPassword.h"\r
+\r
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \\r
+{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \\r
+*outObject = (void *)(i *)this; AddRef(); return S_OK; }\r
+\r
+class CFilterCoder:\r
+  public ICompressCoder,\r
+  public ICompressSetInStream,\r
+  public ISequentialInStream,\r
+  public ICompressSetOutStream,\r
+  public ISequentialOutStream,\r
+  public IOutStreamFlush,\r
+\r
+  #ifndef _NO_CRYPTO\r
+  public ICryptoSetPassword,\r
+  #endif\r
+  #ifndef EXTRACT_ONLY\r
+  public ICompressSetCoderProperties,\r
+  public ICompressWriteCoderProperties,\r
+  // public ICryptoResetSalt,\r
+  public ICryptoResetInitVector,\r
+  #endif\r
+  public ICompressSetDecoderProperties2,\r
+  public CMyUnknownImp\r
+{\r
+protected:\r
+  Byte *_buffer;\r
+  CMyComPtr<ISequentialInStream> _inStream;\r
+  CMyComPtr<ISequentialOutStream> _outStream;\r
+  UInt32 _bufferPos;\r
+  UInt32 _convertedPosBegin;\r
+  UInt32 _convertedPosEnd;\r
+  bool _outSizeIsDefined;\r
+  UInt64 _outSize;\r
+  UInt64 _nowPos64;\r
+\r
+  HRESULT Init()\r
+  {\r
+    _nowPos64 = 0;\r
+    _outSizeIsDefined = false;\r
+    return Filter->Init();\r
+  }\r
+\r
+  CMyComPtr<ICryptoSetPassword> _setPassword;\r
+  #ifndef EXTRACT_ONLY\r
+  CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties;\r
+  CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;\r
+  // CMyComPtr<ICryptoResetSalt> _CryptoResetSalt;\r
+  CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector;\r
+  #endif\r
+  CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;\r
+public:\r
+  CMyComPtr<ICompressFilter> Filter;\r
+\r
+  CFilterCoder();\r
+  ~CFilterCoder();\r
+  HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);\r
+\r
+public:\r
+  MY_QUERYINTERFACE_BEGIN2(ICompressCoder)\r
+    MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)\r
+    MY_QUERYINTERFACE_ENTRY(ISequentialInStream)\r
+    MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)\r
+    MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)\r
+    MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)\r
+\r
+    #ifndef _NO_CRYPTO\r
+    MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)\r
+    #endif\r
+\r
+    #ifndef EXTRACT_ONLY\r
+    MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties)\r
+    MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)\r
+    // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt)\r
+    MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector)\r
+    #endif\r
+\r
+    MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties)\r
+  MY_QUERYINTERFACE_END\r
+  MY_ADDREF_RELEASE\r
+  STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+      const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);\r
+  STDMETHOD(ReleaseInStream)();\r
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream);\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \\r
+  STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);\r
+  STDMETHOD(ReleaseOutStream)();\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Flush)();\r
+\r
+  #ifndef _NO_CRYPTO\r
+  STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);\r
+  #endif\r
+  #ifndef EXTRACT_ONLY\r
+  STDMETHOD(SetCoderProperties)(const PROPID *propIDs,\r
+      const PROPVARIANT *properties, UInt32 numProperties);\r
+  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);\r
+  // STDMETHOD(ResetSalt)();\r
+  STDMETHOD(ResetInitVector)();\r
+  #endif\r
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);\r
+};\r
+\r
+class CInStreamReleaser\r
+{\r
+public:\r
+  CFilterCoder *FilterCoder;\r
+  CInStreamReleaser(): FilterCoder(0) {}\r
+  ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }\r
+};\r
+\r
+class COutStreamReleaser\r
+{\r
+public:\r
+  CFilterCoder *FilterCoder;\r
+  COutStreamReleaser(): FilterCoder(0) {}\r
+  ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/InBuffer.cpp b/CPP/7zip/Common/InBuffer.cpp
new file mode 100755 (executable)
index 0000000..3f84f48
--- /dev/null
@@ -0,0 +1,83 @@
+// InBuffer.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "InBuffer.h"\r
+\r
+CInBuffer::CInBuffer():\r
+  _buffer(0),\r
+  _bufferLimit(0),\r
+  _bufferBase(0),\r
+  _stream(0),\r
+  _bufferSize(0)\r
+{}\r
+\r
+bool CInBuffer::Create(UInt32 bufferSize)\r
+{\r
+  const UInt32 kMinBlockSize = 1;\r
+  if (bufferSize < kMinBlockSize)\r
+    bufferSize = kMinBlockSize;\r
+  if (_bufferBase != 0 && _bufferSize == bufferSize)\r
+    return true;\r
+  Free();\r
+  _bufferSize = bufferSize;\r
+  _bufferBase = (Byte *)::MidAlloc(bufferSize);\r
+  return (_bufferBase != 0);\r
+}\r
+\r
+void CInBuffer::Free()\r
+{\r
+  ::MidFree(_bufferBase);\r
+  _bufferBase = 0;\r
+}\r
+\r
+void CInBuffer::SetStream(ISequentialInStream *stream)\r
+{\r
+  _stream = stream;\r
+}\r
+\r
+void CInBuffer::Init()\r
+{\r
+  _processedSize = 0;\r
+  _buffer = _bufferBase;\r
+  _bufferLimit = _buffer;\r
+  _wasFinished = false;\r
+  #ifdef _NO_EXCEPTIONS\r
+  ErrorCode = S_OK;\r
+  #endif\r
+}\r
+\r
+bool CInBuffer::ReadBlock()\r
+{\r
+  #ifdef _NO_EXCEPTIONS\r
+  if (ErrorCode != S_OK)\r
+    return false;\r
+  #endif\r
+  if (_wasFinished)\r
+    return false;\r
+  _processedSize += (_buffer - _bufferBase);\r
+  UInt32 numProcessedBytes;\r
+  HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);\r
+  #ifdef _NO_EXCEPTIONS\r
+  ErrorCode = result;\r
+  #else\r
+  if (result != S_OK)\r
+    throw CInBufferException(result);\r
+  #endif\r
+  _buffer = _bufferBase;\r
+  _bufferLimit = _buffer + numProcessedBytes;\r
+  _wasFinished = (numProcessedBytes == 0);\r
+  return (!_wasFinished);\r
+}\r
+\r
+Byte CInBuffer::ReadBlock2()\r
+{\r
+  if (!ReadBlock())\r
+  {\r
+    _processedSize++;\r
+    return 0xFF;\r
+  }\r
+  return *_buffer++;\r
+}\r
diff --git a/CPP/7zip/Common/InBuffer.h b/CPP/7zip/Common/InBuffer.h
new file mode 100755 (executable)
index 0000000..cdd50f1
--- /dev/null
@@ -0,0 +1,81 @@
+// InBuffer.h\r
+\r
+#ifndef __INBUFFER_H\r
+#define __INBUFFER_H\r
+\r
+#include "../IStream.h"\r
+#include "../../Common/MyCom.h"\r
+#include "../../Common/MyException.h"\r
+\r
+#ifndef _NO_EXCEPTIONS\r
+struct CInBufferException: public CSystemException\r
+{\r
+  CInBufferException(HRESULT errorCode): CSystemException(errorCode) {}\r
+};\r
+#endif\r
+\r
+class CInBuffer\r
+{\r
+  Byte *_buffer;\r
+  Byte *_bufferLimit;\r
+  Byte *_bufferBase;\r
+  CMyComPtr<ISequentialInStream> _stream;\r
+  UInt64 _processedSize;\r
+  UInt32 _bufferSize;\r
+  bool _wasFinished;\r
+\r
+  bool ReadBlock();\r
+  Byte ReadBlock2();\r
+\r
+public:\r
+  #ifdef _NO_EXCEPTIONS\r
+  HRESULT ErrorCode;\r
+  #endif\r
+\r
+  CInBuffer();\r
+  ~CInBuffer() { Free(); }\r
+\r
+  bool Create(UInt32 bufferSize);\r
+  void Free();\r
+  \r
+  void SetStream(ISequentialInStream *stream);\r
+  void Init();\r
+  void ReleaseStream() { _stream.Release(); }\r
+\r
+  bool ReadByte(Byte &b)\r
+  {\r
+    if (_buffer >= _bufferLimit)\r
+      if (!ReadBlock())\r
+        return false;\r
+    b = *_buffer++;\r
+    return true;\r
+  }\r
+  Byte ReadByte()\r
+  {\r
+    if (_buffer >= _bufferLimit)\r
+      return ReadBlock2();\r
+    return *_buffer++;\r
+  }\r
+  UInt32 ReadBytes(Byte *buf, UInt32 size)\r
+  {\r
+    if ((UInt32)(_bufferLimit - _buffer) >= size)\r
+    {\r
+      for (UInt32 i = 0; i < size; i++)\r
+        buf[i] = _buffer[i];\r
+      _buffer += size;\r
+      return size;\r
+    }\r
+    for (UInt32 i = 0; i < size; i++)\r
+    {\r
+      if (_buffer >= _bufferLimit)\r
+        if (!ReadBlock())\r
+          return i;\r
+      buf[i] = *_buffer++;\r
+    }\r
+    return size;\r
+  }\r
+  UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }\r
+  bool WasFinished() const { return _wasFinished; }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/InOutTempBuffer.cpp b/CPP/7zip/Common/InOutTempBuffer.cpp
new file mode 100755 (executable)
index 0000000..13a7696
--- /dev/null
@@ -0,0 +1,122 @@
+// InOutTempBuffer.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/7zCrc.h"\r
+\r
+#include "InOutTempBuffer.h"\r
+#include "StreamUtils.h"\r
+\r
+using namespace NWindows;\r
+using namespace NFile;\r
+using namespace NDirectory;\r
+\r
+static const UInt32 kTempBufSize = (1 << 20);\r
+\r
+static LPCTSTR kTempFilePrefixString = TEXT("7zt");\r
+\r
+CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }\r
+\r
+void CInOutTempBuffer::Create()\r
+{\r
+  if (!_buf)\r
+    _buf = new Byte[kTempBufSize];\r
+}\r
+\r
+CInOutTempBuffer::~CInOutTempBuffer()\r
+{\r
+  delete []_buf;\r
+}\r
+\r
+void CInOutTempBuffer::InitWriting()\r
+{\r
+  _bufPos = 0;\r
+  _tempFileCreated = false;\r
+  _size = 0;\r
+  _crc = CRC_INIT_VAL;\r
+}\r
+\r
+bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)\r
+{\r
+  if (size == 0)\r
+    return true;\r
+  if (!_tempFileCreated)\r
+  {\r
+    CSysString tempDirPath;\r
+    if (!MyGetTempPath(tempDirPath))\r
+      return false;\r
+    if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tempFileName) == 0)\r
+      return false;\r
+    if (!_outFile.Create(_tempFileName, true))\r
+      return false;\r
+    _tempFileCreated = true;\r
+  }\r
+  UInt32 processed;\r
+  if (!_outFile.Write(data, size, processed))\r
+    return false;\r
+  _crc = CrcUpdate(_crc, data, processed);\r
+  _size += processed;\r
+  return (processed == size);\r
+}\r
+\r
+bool CInOutTempBuffer::Write(const void *data, UInt32 size)\r
+{\r
+  if (_bufPos < kTempBufSize)\r
+  {\r
+    UInt32 cur = MyMin(kTempBufSize - _bufPos, size);\r
+    memcpy(_buf + _bufPos, data, cur);\r
+    _crc = CrcUpdate(_crc, data, cur);\r
+    _bufPos += cur;\r
+    size -= cur;\r
+    data = ((const Byte *)data) + cur;\r
+    _size += cur;\r
+  }\r
+  return WriteToFile(data, size);\r
+}\r
+\r
+HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)\r
+{\r
+  if (!_outFile.Close())\r
+    return E_FAIL;\r
+\r
+  UInt64 size = 0;\r
+  UInt32 crc = CRC_INIT_VAL;\r
+\r
+  if (_bufPos > 0)\r
+  {\r
+    RINOK(WriteStream(stream, _buf, _bufPos));\r
+    crc = CrcUpdate(crc, _buf, _bufPos);\r
+    size += _bufPos;\r
+  }\r
+  if (_tempFileCreated)\r
+  {\r
+    NIO::CInFile inFile;\r
+    if (!inFile.Open(_tempFileName))\r
+      return E_FAIL;\r
+    while (size < _size)\r
+    {\r
+      UInt32 processed;\r
+      if (!inFile.ReadPart(_buf, kTempBufSize, processed))\r
+        return E_FAIL;\r
+      if (processed == 0)\r
+        break;\r
+      RINOK(WriteStream(stream, _buf, processed));\r
+      crc = CrcUpdate(crc, _buf, processed);\r
+      size += processed;\r
+    }\r
+  }\r
+  return (_crc == crc && size == _size) ? S_OK : E_FAIL;\r
+}\r
+\r
+STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed)\r
+{\r
+  if (!_buf->Write(data, size))\r
+  {\r
+    if (processed != NULL)\r
+      *processed = 0;\r
+    return E_FAIL;\r
+  }\r
+  if (processed != NULL)\r
+    *processed = size;\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/Common/InOutTempBuffer.h b/CPP/7zip/Common/InOutTempBuffer.h
new file mode 100755 (executable)
index 0000000..a69bc85
--- /dev/null
@@ -0,0 +1,48 @@
+// InOutTempBuffer.h\r
+\r
+#ifndef __IN_OUT_TEMP_BUFFER_H\r
+#define __IN_OUT_TEMP_BUFFER_H\r
+\r
+#include "../../Common/MyCom.h"\r
+#include "../../Windows/FileDir.h"\r
+#include "../../Windows/FileIO.h"\r
+\r
+#include "../IStream.h"\r
+\r
+class CInOutTempBuffer\r
+{\r
+  NWindows::NFile::NDirectory::CTempFile _tempFile;\r
+  NWindows::NFile::NIO::COutFile _outFile;\r
+  Byte *_buf;\r
+  UInt32 _bufPos;\r
+  CSysString _tempFileName;\r
+  bool _tempFileCreated;\r
+  UInt64 _size;\r
+  UInt32 _crc;\r
+\r
+  bool WriteToFile(const void *data, UInt32 size);\r
+public:\r
+  CInOutTempBuffer();\r
+  ~CInOutTempBuffer();\r
+  void Create();\r
+\r
+  void InitWriting();\r
+  bool Write(const void *data, UInt32 size);\r
+\r
+  HRESULT WriteToStream(ISequentialOutStream *stream);\r
+  UInt64 GetDataSize() const { return _size; }\r
+};\r
+\r
+class CSequentialOutTempBufferImp:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  CInOutTempBuffer *_buf;\r
+public:\r
+  void Init(CInOutTempBuffer *buffer)  { _buf = buffer; }\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/LimitedStreams.cpp b/CPP/7zip/Common/LimitedStreams.cpp
new file mode 100755 (executable)
index 0000000..dd2d2d5
--- /dev/null
@@ -0,0 +1,154 @@
+// LimitedStreams.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "LimitedStreams.h"\r
+#include "../../Common/Defs.h"\r
+\r
+STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  UInt32 realProcessedSize = 0;\r
+  UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size);\r
+  HRESULT result = S_OK;\r
+  if (sizeToRead > 0)\r
+  {\r
+    result = _stream->Read(data, sizeToRead, &realProcessedSize);\r
+    _pos += realProcessedSize;\r
+    if (realProcessedSize == 0)\r
+      _wasFinished = true;\r
+  }\r
+  if (processedSize != NULL)\r
+    *processedSize = realProcessedSize;\r
+  return result;\r
+}\r
+\r
+STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  if (_virtPos >= _size)\r
+    return (_virtPos == _size) ? S_OK: E_FAIL;\r
+  UInt64 rem = _size - _virtPos;\r
+  if (rem < size)\r
+    size = (UInt32)rem;\r
+  UInt64 newPos = _startOffset + _virtPos;\r
+  if (newPos != _physPos)\r
+  {\r
+    _physPos = newPos;\r
+    RINOK(SeekToPhys());\r
+  }\r
+  HRESULT res = _stream->Read(data, size, &size);\r
+  if (processedSize != NULL)\r
+    *processedSize = size;\r
+  _physPos += size;\r
+  _virtPos += size;\r
+  return res;\r
+}\r
+\r
+STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  switch(seekOrigin)\r
+  {\r
+    case STREAM_SEEK_SET: _virtPos = offset; break;\r
+    case STREAM_SEEK_CUR: _virtPos += offset; break;\r
+    case STREAM_SEEK_END: _virtPos = _size + offset; break;\r
+    default: return STG_E_INVALIDFUNCTION;\r
+  }\r
+  if (newPosition)\r
+    *newPosition = _virtPos;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  if (_virtPos >= Size)\r
+    return (_virtPos == Size) ? S_OK: E_FAIL;\r
+\r
+  if (_curRem == 0)\r
+  {\r
+    UInt32 blockSize = (UInt32)1 << BlockSizeLog;\r
+    UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog);\r
+    UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1);\r
+    UInt32 phyBlock = Vector[virtBlock];\r
+    UInt64 newPos = StartOffset + ((UInt64)phyBlock << BlockSizeLog) + offsetInBlock;\r
+    if (newPos != _physPos)\r
+    {\r
+      _physPos = newPos;\r
+      RINOK(SeekToPhys());\r
+    }\r
+    _curRem = blockSize - offsetInBlock;\r
+    for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++)\r
+      _curRem += (UInt32)1 << BlockSizeLog;\r
+    UInt64 rem = Size - _virtPos;\r
+    if (_curRem > rem)\r
+      _curRem = (UInt32)rem;\r
+  }\r
+  if (size > _curRem)\r
+    size = _curRem;\r
+  HRESULT res = Stream->Read(data, size, &size);\r
+  if (processedSize != NULL)\r
+    *processedSize = size;\r
+  _physPos += size;\r
+  _virtPos += size;\r
+  _curRem -= size;\r
+  return res;\r
+}\r
\r
+STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  UInt64 newVirtPos = offset;\r
+  switch(seekOrigin)\r
+  {\r
+    case STREAM_SEEK_SET: break;\r
+    case STREAM_SEEK_CUR: newVirtPos += _virtPos; break;\r
+    case STREAM_SEEK_END: newVirtPos += Size; break;\r
+    default: return STG_E_INVALIDFUNCTION;\r
+  }\r
+  if (_virtPos != newVirtPos)\r
+    _curRem = 0;\r
+  _virtPos = newVirtPos;\r
+  if (newPosition)\r
+    *newPosition = newVirtPos;\r
+  return S_OK;\r
+}\r
+\r
+\r
+HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream)\r
+{\r
+  *resStream = 0;\r
+  CLimitedInStream *streamSpec = new CLimitedInStream;\r
+  CMyComPtr<ISequentialInStream> streamTemp = streamSpec;\r
+  streamSpec->SetStream(inStream);\r
+  RINOK(streamSpec->InitAndSeek(pos, size));\r
+  streamSpec->SeekToStart();\r
+  *resStream = streamTemp.Detach();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  HRESULT result = S_OK;\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  if (size > _size)\r
+  {\r
+    if (_size == 0)\r
+    {\r
+      _overflow = true;\r
+      if (!_overflowIsAllowed)\r
+        return E_FAIL;\r
+      if (processedSize != NULL)\r
+        *processedSize = size;\r
+      return S_OK;\r
+    }\r
+    size = (UInt32)_size;\r
+  }\r
+  if (_stream)\r
+    result = _stream->Write(data, size, &size);\r
+  _size -= size;\r
+  if (processedSize != NULL)\r
+    *processedSize = size;\r
+  return result;\r
+}\r
diff --git a/CPP/7zip/Common/LimitedStreams.h b/CPP/7zip/Common/LimitedStreams.h
new file mode 100755 (executable)
index 0000000..caec98f
--- /dev/null
@@ -0,0 +1,125 @@
+// LimitedStreams.h\r
+\r
+#ifndef __LIMITED_STREAMS_H\r
+#define __LIMITED_STREAMS_H\r
+\r
+#include "../../Common/MyCom.h"\r
+#include "../../Common/MyVector.h"\r
+#include "../IStream.h"\r
+\r
+class CLimitedSequentialInStream:\r
+  public ISequentialInStream,\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<ISequentialInStream> _stream;\r
+  UInt64 _size;\r
+  UInt64 _pos;\r
+  bool _wasFinished;\r
+public:\r
+  void SetStream(ISequentialInStream *stream) { _stream = stream; }\r
+  void ReleaseStream() { _stream.Release(); }\r
+  void Init(UInt64 streamSize)\r
+  {\r
+    _size = streamSize;\r
+    _pos = 0;\r
+    _wasFinished = false;\r
+  }\r
\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  UInt64 GetSize() const { return _pos; }\r
+  bool WasFinished() const { return _wasFinished; }\r
+};\r
+\r
+class CLimitedInStream:\r
+  public IInStream,\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<IInStream> _stream;\r
+  UInt64 _virtPos;\r
+  UInt64 _physPos;\r
+  UInt64 _size;\r
+  UInt64 _startOffset;\r
+\r
+  HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }\r
+public:\r
+  void SetStream(IInStream *stream) { _stream = stream; }\r
+  HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)\r
+  {\r
+    _startOffset = startOffset;\r
+    _physPos = startOffset;\r
+    _virtPos = 0;\r
+    _size = size;\r
+    return SeekToPhys();\r
+  }\r
\r
+  MY_UNKNOWN_IMP1(IInStream)\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+\r
+  HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }\r
+};\r
+\r
+class CClusterInStream:\r
+  public IInStream,\r
+  public CMyUnknownImp\r
+{\r
+  UInt64 _virtPos;\r
+  UInt64 _physPos;\r
+  UInt32 _curRem;\r
+public:\r
+  CMyComPtr<IInStream> Stream;\r
+  UInt64 StartOffset;\r
+  UInt64 Size;\r
+  int BlockSizeLog;\r
+  CRecordVector<UInt32> Vector;\r
+\r
+  HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }\r
+\r
+  HRESULT InitAndSeek()\r
+  {\r
+    _curRem = 0;\r
+    _virtPos = 0;\r
+    _physPos = StartOffset;\r
+    if (Vector.Size() > 0)\r
+    {\r
+      _physPos = StartOffset + (Vector[0] << BlockSizeLog);\r
+      return SeekToPhys();\r
+    }\r
+    return S_OK;\r
+  }\r
+\r
+  MY_UNKNOWN_IMP1(IInStream)\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+};\r
+\r
+HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);\r
+\r
+class CLimitedSequentialOutStream:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<ISequentialOutStream> _stream;\r
+  UInt64 _size;\r
+  bool _overflow;\r
+  bool _overflowIsAllowed;\r
+public:\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  void SetStream(ISequentialOutStream *stream) { _stream = stream; }\r
+  void ReleaseStream() { _stream.Release(); }\r
+  void Init(UInt64 size, bool overflowIsAllowed = false)\r
+  {\r
+    _size = size;\r
+    _overflow = false;\r
+    _overflowIsAllowed = overflowIsAllowed;\r
+  }\r
+  bool IsFinishedOK() const { return (_size == 0 && !_overflow); }\r
+  UInt64 GetRem() const { return _size; }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/LockedStream.cpp b/CPP/7zip/Common/LockedStream.cpp
new file mode 100755 (executable)
index 0000000..d1bbf6d
--- /dev/null
@@ -0,0 +1,23 @@
+// LockedStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "LockedStream.h"\r
+\r
+HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size,\r
+  UInt32 *processedSize)\r
+{\r
+  NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);\r
+  RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));\r
+  return _stream->Read(data, size, processedSize);\r
+}\r
+\r
+STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  UInt32 realProcessedSize = 0;\r
+  HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize);\r
+  _pos += realProcessedSize;\r
+  if (processedSize != NULL)\r
+    *processedSize = realProcessedSize;\r
+  return result;\r
+}\r
diff --git a/CPP/7zip/Common/LockedStream.h b/CPP/7zip/Common/LockedStream.h
new file mode 100755 (executable)
index 0000000..e12e22a
--- /dev/null
@@ -0,0 +1,38 @@
+// LockedStream.h\r
+\r
+#ifndef __LOCKEDSTREAM_H\r
+#define __LOCKEDSTREAM_H\r
+\r
+#include "../../Windows/Synchronization.h"\r
+#include "../../Common/MyCom.h"\r
+#include "../IStream.h"\r
+\r
+class CLockedInStream\r
+{\r
+  CMyComPtr<IInStream> _stream;\r
+  NWindows::NSynchronization::CCriticalSection _criticalSection;\r
+public:\r
+  void Init(IInStream *stream)\r
+    { _stream = stream; }\r
+  HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+class CLockedSequentialInStreamImp:\r
+  public ISequentialInStream,\r
+  public CMyUnknownImp\r
+{\r
+  CLockedInStream *_lockedInStream;\r
+  UInt64 _pos;\r
+public:\r
+  void Init(CLockedInStream *lockedInStream, UInt64 startPos)\r
+  {\r
+    _lockedInStream = lockedInStream;\r
+    _pos = startPos;\r
+  }\r
+\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/MethodId.cpp b/CPP/7zip/Common/MethodId.cpp
new file mode 100755 (executable)
index 0000000..705cc4d
--- /dev/null
@@ -0,0 +1,27 @@
+// MethodId.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "MethodId.h"\r
+#include "../../Common/MyString.h"\r
+\r
+static inline wchar_t GetHex(Byte value)\r
+{\r
+  return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));\r
+}\r
+\r
+UString ConvertMethodIdToString(UInt64 id)\r
+{\r
+  wchar_t s[32];\r
+  int len = 32;\r
+  s[--len] = 0;\r
+  do\r
+  {\r
+    s[--len] = GetHex((Byte)id & 0xF);\r
+    id >>= 4;\r
+    s[--len] = GetHex((Byte)id & 0xF);\r
+    id >>= 4;\r
+  }\r
+  while (id != 0);\r
+  return s + len;\r
+}\r
diff --git a/CPP/7zip/Common/MethodId.h b/CPP/7zip/Common/MethodId.h
new file mode 100755 (executable)
index 0000000..9551723
--- /dev/null
@@ -0,0 +1,10 @@
+// MethodId.h\r
+\r
+#ifndef __7Z_METHOD_ID_H\r
+#define __7Z_METHOD_ID_H\r
+\r
+#include "../../Common/Types.h"\r
+\r
+typedef UInt64 CMethodId;\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/MethodProps.cpp b/CPP/7zip/Common/MethodProps.cpp
new file mode 100755 (executable)
index 0000000..937708e
--- /dev/null
@@ -0,0 +1,99 @@
+// MethodProps.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+#include "MethodProps.h"\r
+\r
+static const UInt64 k_LZMA = 0x030101;\r
+static const UInt64 k_LZMA2 = 0x21;\r
+\r
+HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)\r
+{\r
+  bool tryReduce = false;\r
+  UInt32 reducedDictionarySize = 1 << 10;\r
+  if (inSizeForReduce != 0 && (method.Id == k_LZMA || method.Id == k_LZMA2))\r
+  {\r
+    for (;;)\r
+    {\r
+      const UInt32 step = (reducedDictionarySize >> 1);\r
+      if (reducedDictionarySize >= *inSizeForReduce)\r
+      {\r
+        tryReduce = true;\r
+        break;\r
+      }\r
+      reducedDictionarySize += step;\r
+      if (reducedDictionarySize >= *inSizeForReduce)\r
+      {\r
+        tryReduce = true;\r
+        break;\r
+      }\r
+      if (reducedDictionarySize >= ((UInt32)3 << 30))\r
+        break;\r
+      reducedDictionarySize += step;\r
+    }\r
+  }\r
+\r
+  {\r
+    int numProps = method.Props.Size();\r
+    CMyComPtr<ICompressSetCoderProperties> setCoderProperties;\r
+    coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);\r
+    if (setCoderProperties == NULL)\r
+    {\r
+      if (numProps != 0)\r
+        return E_INVALIDARG;\r
+    }\r
+    else\r
+    {\r
+      CRecordVector<PROPID> propIDs;\r
+      NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProps];\r
+      HRESULT res = S_OK;\r
+      try\r
+      {\r
+        for (int i = 0; i < numProps; i++)\r
+        {\r
+          const CProp &prop = method.Props[i];\r
+          propIDs.Add(prop.Id);\r
+          NWindows::NCOM::CPropVariant &value = values[i];\r
+          value = prop.Value;\r
+          // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)\r
+          if (tryReduce)\r
+            if (prop.Id == NCoderPropID::kDictionarySize)\r
+              if (value.vt == VT_UI4)\r
+                if (reducedDictionarySize < value.ulVal)\r
+            value.ulVal = reducedDictionarySize;\r
+        }\r
+        CMyComPtr<ICompressSetCoderProperties> setCoderProperties;\r
+        coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);\r
+        res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProps);\r
+      }\r
+      catch(...)\r
+      {\r
+        delete []values;\r
+        throw;\r
+      }\r
+      delete []values;\r
+      RINOK(res);\r
+    }\r
+  }\r
\r
+  /*\r
+  CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;\r
+  coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);\r
+  if (writeCoderProperties != NULL)\r
+  {\r
+    CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;\r
+    CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);\r
+    outStreamSpec->Init();\r
+    RINOK(writeCoderProperties->WriteCoderProperties(outStream));\r
+    size_t size = outStreamSpec->GetSize();\r
+    filterProps.SetCapacity(size);\r
+    memmove(filterProps, outStreamSpec->GetBuffer(), size);\r
+  }\r
+  */\r
+  return S_OK;\r
+}\r
+\r
diff --git a/CPP/7zip/Common/MethodProps.h b/CPP/7zip/Common/MethodProps.h
new file mode 100755 (executable)
index 0000000..75b87f1
--- /dev/null
@@ -0,0 +1,41 @@
+// MethodProps.h\r
+\r
+#ifndef __7Z_METHOD_PROPS_H\r
+#define __7Z_METHOD_PROPS_H\r
+\r
+#include "../../Common/MyVector.h"\r
+\r
+#include "../../Windows/PropVariant.h"\r
+\r
+#include "MethodId.h"\r
+\r
+struct CProp\r
+{\r
+  PROPID Id;\r
+  NWindows::NCOM::CPropVariant Value;\r
+};\r
+\r
+struct CMethod\r
+{\r
+  CMethodId Id;\r
+  CObjectVector<CProp> Props;\r
+};\r
+\r
+struct CMethodsMode\r
+{\r
+  CObjectVector<CMethod> Methods;\r
+  #ifndef _7ZIP_ST\r
+  UInt32 NumThreads;\r
+  #endif\r
+\r
+  CMethodsMode()\r
+      #ifndef _7ZIP_ST\r
+      : NumThreads(1)\r
+      #endif\r
+  {}\r
+  bool IsEmpty() const { return Methods.IsEmpty() ; }\r
+};\r
+\r
+HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder);\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/OffsetStream.cpp b/CPP/7zip/Common/OffsetStream.cpp
new file mode 100755 (executable)
index 0000000..f10f54c
--- /dev/null
@@ -0,0 +1,35 @@
+// OffsetStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/Defs.h"\r
+#include "OffsetStream.h"\r
+\r
+HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)\r
+{\r
+  _offset = offset;\r
+  _stream = stream;\r
+  return _stream->Seek(offset, STREAM_SEEK_SET, NULL);\r
+}\r
+\r
+STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  return _stream->Write(data, size, processedSize);\r
+}\r
+\r
+STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,\r
+    UInt64 *newPosition)\r
+{\r
+  UInt64 absoluteNewPosition;\r
+  if (seekOrigin == STREAM_SEEK_SET)\r
+    offset += _offset;\r
+  HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);\r
+  if (newPosition != NULL)\r
+    *newPosition = absoluteNewPosition - _offset;\r
+  return result;\r
+}\r
+\r
+STDMETHODIMP COffsetOutStream::SetSize(UInt64 newSize)\r
+{\r
+  return _stream->SetSize(_offset + newSize);\r
+}\r
diff --git a/CPP/7zip/Common/OffsetStream.h b/CPP/7zip/Common/OffsetStream.h
new file mode 100755 (executable)
index 0000000..972a8ce
--- /dev/null
@@ -0,0 +1,25 @@
+// OffsetStream.h\r
+\r
+#ifndef __OFFSETSTREAM_H\r
+#define __OFFSETSTREAM_H\r
+\r
+#include "Common/MyCom.h"\r
+#include "../IStream.h"\r
+\r
+class COffsetOutStream:\r
+  public IOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  UInt64 _offset;\r
+  CMyComPtr<IOutStream> _stream;\r
+public:\r
+  HRESULT Init(IOutStream *stream, UInt64 offset);\r
+  \r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+  STDMETHOD(SetSize)(UInt64 newSize);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/OutBuffer.cpp b/CPP/7zip/Common/OutBuffer.cpp
new file mode 100755 (executable)
index 0000000..4e55f55
--- /dev/null
@@ -0,0 +1,116 @@
+// OutBuffer.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "OutBuffer.h"\r
+\r
+bool COutBuffer::Create(UInt32 bufferSize)\r
+{\r
+  const UInt32 kMinBlockSize = 1;\r
+  if (bufferSize < kMinBlockSize)\r
+    bufferSize = kMinBlockSize;\r
+  if (_buffer != 0 && _bufferSize == bufferSize)\r
+    return true;\r
+  Free();\r
+  _bufferSize = bufferSize;\r
+  _buffer = (Byte *)::MidAlloc(bufferSize);\r
+  return (_buffer != 0);\r
+}\r
+\r
+void COutBuffer::Free()\r
+{\r
+  ::MidFree(_buffer);\r
+  _buffer = 0;\r
+}\r
+\r
+void COutBuffer::SetStream(ISequentialOutStream *stream)\r
+{\r
+  _stream = stream;\r
+}\r
+\r
+void COutBuffer::Init()\r
+{\r
+  _streamPos = 0;\r
+  _limitPos = _bufferSize;\r
+  _pos = 0;\r
+  _processedSize = 0;\r
+  _overDict = false;\r
+  #ifdef _NO_EXCEPTIONS\r
+  ErrorCode = S_OK;\r
+  #endif\r
+}\r
+\r
+UInt64 COutBuffer::GetProcessedSize() const\r
+{\r
+  UInt64 res = _processedSize + _pos - _streamPos;\r
+  if (_streamPos > _pos)\r
+    res += _bufferSize;\r
+  return res;\r
+}\r
+\r
+\r
+HRESULT COutBuffer::FlushPart()\r
+{\r
+  // _streamPos < _bufferSize\r
+  UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);\r
+  HRESULT result = S_OK;\r
+  #ifdef _NO_EXCEPTIONS\r
+  result = ErrorCode;\r
+  #endif\r
+  if (_buffer2 != 0)\r
+  {\r
+    memmove(_buffer2, _buffer + _streamPos, size);\r
+    _buffer2 += size;\r
+  }\r
+\r
+  if (_stream != 0\r
+      #ifdef _NO_EXCEPTIONS\r
+      && (ErrorCode == S_OK)\r
+      #endif\r
+     )\r
+  {\r
+    UInt32 processedSize = 0;\r
+    result = _stream->Write(_buffer + _streamPos, size, &processedSize);\r
+    size = processedSize;\r
+  }\r
+  _streamPos += size;\r
+  if (_streamPos == _bufferSize)\r
+    _streamPos = 0;\r
+  if (_pos == _bufferSize)\r
+  {\r
+    _overDict = true;\r
+    _pos = 0;\r
+  }\r
+  _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;\r
+  _processedSize += size;\r
+  return result;\r
+}\r
+\r
+HRESULT COutBuffer::Flush()\r
+{\r
+  #ifdef _NO_EXCEPTIONS\r
+  if (ErrorCode != S_OK)\r
+    return ErrorCode;\r
+  #endif\r
+\r
+  while(_streamPos != _pos)\r
+  {\r
+    HRESULT result = FlushPart();\r
+    if (result != S_OK)\r
+      return result;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+void COutBuffer::FlushWithCheck()\r
+{\r
+  HRESULT result = Flush();\r
+  #ifdef _NO_EXCEPTIONS\r
+  ErrorCode = result;\r
+  #else\r
+  if (result != S_OK)\r
+    throw COutBufferException(result);\r
+  #endif\r
+}\r
diff --git a/CPP/7zip/Common/OutBuffer.h b/CPP/7zip/Common/OutBuffer.h
new file mode 100755 (executable)
index 0000000..e2e76ad
--- /dev/null
@@ -0,0 +1,64 @@
+// OutBuffer.h\r
+\r
+#ifndef __OUTBUFFER_H\r
+#define __OUTBUFFER_H\r
+\r
+#include "../IStream.h"\r
+#include "../../Common/MyCom.h"\r
+#include "../../Common/MyException.h"\r
+\r
+#ifndef _NO_EXCEPTIONS\r
+struct COutBufferException: public CSystemException\r
+{\r
+  COutBufferException(HRESULT errorCode): CSystemException(errorCode) {}\r
+};\r
+#endif\r
+\r
+class COutBuffer\r
+{\r
+protected:\r
+  Byte *_buffer;\r
+  UInt32 _pos;\r
+  UInt32 _limitPos;\r
+  UInt32 _streamPos;\r
+  UInt32 _bufferSize;\r
+  CMyComPtr<ISequentialOutStream> _stream;\r
+  UInt64 _processedSize;\r
+  Byte  *_buffer2;\r
+  bool _overDict;\r
+\r
+  HRESULT FlushPart();\r
+public:\r
+  #ifdef _NO_EXCEPTIONS\r
+  HRESULT ErrorCode;\r
+  #endif\r
+\r
+  COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}\r
+  ~COutBuffer() { Free(); }\r
+  \r
+  bool Create(UInt32 bufferSize);\r
+  void Free();\r
+\r
+  void SetMemStream(Byte *buffer) { _buffer2 = buffer; }\r
+  void SetStream(ISequentialOutStream *stream);\r
+  void Init();\r
+  HRESULT Flush();\r
+  void FlushWithCheck();\r
+  void ReleaseStream() {  _stream.Release(); }\r
+\r
+  void WriteByte(Byte b)\r
+  {\r
+    _buffer[_pos++] = b;\r
+    if(_pos == _limitPos)\r
+      FlushWithCheck();\r
+  }\r
+  void WriteBytes(const void *data, size_t size)\r
+  {\r
+    for (size_t i = 0; i < size; i++)\r
+      WriteByte(((const Byte *)data)[i]);\r
+  }\r
+\r
+  UInt64 GetProcessedSize() const;\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/ProgressUtils.cpp b/CPP/7zip/Common/ProgressUtils.cpp
new file mode 100755 (executable)
index 0000000..84a3eaf
--- /dev/null
@@ -0,0 +1,42 @@
+// ProgressUtils.h\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "ProgressUtils.h"\r
+\r
+CLocalProgress::CLocalProgress()\r
+{\r
+  ProgressOffset = InSize = OutSize = 0;\r
+  SendRatio = SendProgress = true;\r
+}\r
+\r
+void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)\r
+{\r
+  _ratioProgress.Release();\r
+  _progress = progress;\r
+  _progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress);\r
+  _inSizeIsMain = inSizeIsMain;\r
+}\r
+\r
+STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)\r
+{\r
+  UInt64 inSizeNew = InSize, outSizeNew = OutSize;\r
+  if (inSize)\r
+    inSizeNew += (*inSize);\r
+  if (outSize)\r
+    outSizeNew += (*outSize);\r
+  if (SendRatio && _ratioProgress)\r
+  {\r
+    RINOK(_ratioProgress->SetRatioInfo(&inSizeNew, &outSizeNew));\r
+  }\r
+  inSizeNew += ProgressOffset;\r
+  outSizeNew += ProgressOffset;\r
+  if (SendProgress)\r
+    return _progress->SetCompleted(_inSizeIsMain ? &inSizeNew : &outSizeNew);\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CLocalProgress::SetCur()\r
+{\r
+  return SetRatioInfo(NULL, NULL);\r
+}\r
diff --git a/CPP/7zip/Common/ProgressUtils.h b/CPP/7zip/Common/ProgressUtils.h
new file mode 100755 (executable)
index 0000000..c620484
--- /dev/null
@@ -0,0 +1,34 @@
+// ProgressUtils.h\r
+\r
+#ifndef __PROGRESSUTILS_H\r
+#define __PROGRESSUTILS_H\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+#include "../IProgress.h"\r
+\r
+class CLocalProgress:\r
+  public ICompressProgressInfo,\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<IProgress> _progress;\r
+  CMyComPtr<ICompressProgressInfo> _ratioProgress;\r
+  bool _inSizeIsMain;\r
+public:\r
+  UInt64 ProgressOffset;\r
+  UInt64 InSize;\r
+  UInt64 OutSize;\r
+  bool SendRatio;\r
+  bool SendProgress;\r
+\r
+  CLocalProgress();\r
+  void Init(IProgress *progress, bool inSizeIsMain);\r
+  HRESULT SetCur();\r
+\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/RegisterArc.h b/CPP/7zip/Common/RegisterArc.h
new file mode 100755 (executable)
index 0000000..7066325
--- /dev/null
@@ -0,0 +1,32 @@
+// RegisterArc.h\r
+\r
+#ifndef __REGISTER_ARC_H\r
+#define __REGISTER_ARC_H\r
+\r
+#include "../Archive/IArchive.h"\r
+\r
+typedef IInArchive * (*CreateInArchiveP)();\r
+typedef IOutArchive * (*CreateOutArchiveP)();\r
+\r
+struct CArcInfo\r
+{\r
+  const wchar_t *Name;\r
+  const wchar_t *Ext;\r
+  const wchar_t *AddExt;\r
+  Byte ClassId;\r
+  Byte Signature[16];\r
+  int SignatureSize;\r
+  bool KeepName;\r
+  CreateInArchiveP CreateInArchive;\r
+  CreateOutArchiveP CreateOutArchive;\r
+};\r
+\r
+void RegisterArc(const CArcInfo *arcInfo);\r
+\r
+#define REGISTER_ARC_NAME(x) CRegister ## x\r
+\r
+#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) { \\r
+    REGISTER_ARC_NAME(x)() { RegisterArc(&g_ArcInfo); }}; \\r
+    static REGISTER_ARC_NAME(x) g_RegisterArc;\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/RegisterCodec.h b/CPP/7zip/Common/RegisterCodec.h
new file mode 100755 (executable)
index 0000000..c59ab66
--- /dev/null
@@ -0,0 +1,33 @@
+// RegisterCodec.h\r
+\r
+#ifndef __REGISTERCODEC_H\r
+#define __REGISTERCODEC_H\r
+\r
+#include "../Common/MethodId.h"\r
+\r
+typedef void * (*CreateCodecP)();\r
+struct CCodecInfo\r
+{\r
+  CreateCodecP CreateDecoder;\r
+  CreateCodecP CreateEncoder;\r
+  CMethodId Id;\r
+  const wchar_t *Name;\r
+  UInt32 NumInStreams;\r
+  bool IsFilter;\r
+};\r
+\r
+void RegisterCodec(const CCodecInfo *codecInfo);\r
+\r
+#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x\r
+\r
+#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \\r
+    REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \\r
+    static REGISTER_CODEC_NAME(x) g_RegisterCodec;\r
+\r
+#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x\r
+#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \\r
+    REGISTER_CODECS_NAME(x)() { for (int i = 0; i < sizeof(g_CodecsInfo) / sizeof(g_CodecsInfo[0]); i++) \\r
+    RegisterCodec(&g_CodecsInfo[i]); }}; \\r
+    static REGISTER_CODECS_NAME(x) g_RegisterCodecs;\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/StdAfx.h b/CPP/7zip/Common/StdAfx.h
new file mode 100755 (executable)
index 0000000..f56e92f
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../Common/MyWindows.h"\r
+#include "../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/StreamBinder.cpp b/CPP/7zip/Common/StreamBinder.cpp
new file mode 100755 (executable)
index 0000000..cb3bf99
--- /dev/null
@@ -0,0 +1,150 @@
+// StreamBinder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "StreamBinder.h"\r
+#include "../../Common/Defs.h"\r
+#include "../../Common/MyCom.h"\r
+\r
+using namespace NWindows;\r
+using namespace NSynchronization;\r
+\r
+class CSequentialInStreamForBinder:\r
+  public ISequentialInStream,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+private:\r
+  CStreamBinder *m_StreamBinder;\r
+public:\r
+  ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }\r
+  void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }\r
+};\r
+\r
+STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+  { return m_StreamBinder->Read(data, size, processedSize); }\r
+\r
+class CSequentialOutStreamForBinder:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP\r
+\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+\r
+private:\r
+  CStreamBinder *m_StreamBinder;\r
+public:\r
+  ~CSequentialOutStreamForBinder() {  m_StreamBinder->CloseWrite(); }\r
+  void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }\r
+};\r
+\r
+STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+  { return m_StreamBinder->Write(data, size, processedSize); }\r
+\r
+\r
+//////////////////////////\r
+// CStreamBinder\r
+// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.\r
+\r
+HRes CStreamBinder::CreateEvents()\r
+{\r
+  RINOK(_allBytesAreWritenEvent.Create(true));\r
+  RINOK(_thereAreBytesToReadEvent.Create());\r
+  return _readStreamIsClosedEvent.Create();\r
+}\r
+\r
+void CStreamBinder::ReInit()\r
+{\r
+  _thereAreBytesToReadEvent.Reset();\r
+  _readStreamIsClosedEvent.Reset();\r
+  ProcessedSize = 0;\r
+}\r
+\r
+\r
+  \r
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream,\r
+      ISequentialOutStream **outStream)\r
+{\r
+  CSequentialInStreamForBinder *inStreamSpec = new\r
+      CSequentialInStreamForBinder;\r
+  CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);\r
+  inStreamSpec->SetBinder(this);\r
+  *inStream = inStreamLoc.Detach();\r
+\r
+  CSequentialOutStreamForBinder *outStreamSpec = new\r
+      CSequentialOutStreamForBinder;\r
+  CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);\r
+  outStreamSpec->SetBinder(this);\r
+  *outStream = outStreamLoc.Detach();\r
+\r
+  _buffer = NULL;\r
+  _bufferSize= 0;\r
+  ProcessedSize = 0;\r
+}\r
+\r
+HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  UInt32 sizeToRead = size;\r
+  if (size > 0)\r
+  {\r
+    RINOK(_thereAreBytesToReadEvent.Lock());\r
+    sizeToRead = MyMin(_bufferSize, size);\r
+    if (_bufferSize > 0)\r
+    {\r
+      memcpy(data, _buffer, sizeToRead);\r
+      _buffer = ((const Byte *)_buffer) + sizeToRead;\r
+      _bufferSize -= sizeToRead;\r
+      if (_bufferSize == 0)\r
+      {\r
+        _thereAreBytesToReadEvent.Reset();\r
+        _allBytesAreWritenEvent.Set();\r
+      }\r
+    }\r
+  }\r
+  if (processedSize != NULL)\r
+    *processedSize = sizeToRead;\r
+  ProcessedSize += sizeToRead;\r
+  return S_OK;\r
+}\r
+\r
+void CStreamBinder::CloseRead()\r
+{\r
+  _readStreamIsClosedEvent.Set();\r
+}\r
+\r
+HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (size > 0)\r
+  {\r
+    _buffer = data;\r
+    _bufferSize = size;\r
+    _allBytesAreWritenEvent.Reset();\r
+    _thereAreBytesToReadEvent.Set();\r
+\r
+    HANDLE events[2];\r
+    events[0] = _allBytesAreWritenEvent;\r
+    events[1] = _readStreamIsClosedEvent;\r
+    DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);\r
+    if (waitResult != WAIT_OBJECT_0 + 0)\r
+    {\r
+      // ReadingWasClosed = true;\r
+      return S_FALSE;\r
+    }\r
+    // if(!_allBytesAreWritenEvent.Lock())\r
+    //   return E_FAIL;\r
+  }\r
+  if (processedSize != NULL)\r
+    *processedSize = size;\r
+  return S_OK;\r
+}\r
+\r
+void CStreamBinder::CloseWrite()\r
+{\r
+  // _bufferSize must be = 0\r
+  _thereAreBytesToReadEvent.Set();\r
+}\r
diff --git a/CPP/7zip/Common/StreamBinder.h b/CPP/7zip/Common/StreamBinder.h
new file mode 100755 (executable)
index 0000000..b5d6c0d
--- /dev/null
@@ -0,0 +1,32 @@
+// StreamBinder.h\r
+\r
+#ifndef __STREAMBINDER_H\r
+#define __STREAMBINDER_H\r
+\r
+#include "../IStream.h"\r
+#include "../../Windows/Synchronization.h"\r
+\r
+class CStreamBinder\r
+{\r
+  NWindows::NSynchronization::CManualResetEvent _allBytesAreWritenEvent;\r
+  NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent;\r
+  NWindows::NSynchronization::CManualResetEvent _readStreamIsClosedEvent;\r
+  UInt32 _bufferSize;\r
+  const void *_buffer;\r
+public:\r
+  // bool ReadingWasClosed;\r
+  UInt64 ProcessedSize;\r
+  CStreamBinder() {}\r
+  HRes CreateEvents();\r
+\r
+  void CreateStreams(ISequentialInStream **inStream,\r
+      ISequentialOutStream **outStream);\r
+  HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);\r
+  void CloseRead();\r
+\r
+  HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);\r
+  void CloseWrite();\r
+  void ReInit();\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/StreamObjects.cpp b/CPP/7zip/Common/StreamObjects.cpp
new file mode 100755 (executable)
index 0000000..a18f1bc
--- /dev/null
@@ -0,0 +1,221 @@
+// StreamObjects.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "StreamObjects.h"\r
+\r
+STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize)\r
+    *processedSize = 0;\r
+  if (size == 0)\r
+    return S_OK;\r
+  if (_pos > _size)\r
+    return E_FAIL;\r
+  size_t rem = _size - (size_t)_pos;\r
+  if (rem > size)\r
+    rem = (size_t)size;\r
+  memcpy(data, _data + (size_t)_pos, rem);\r
+  _pos += rem;\r
+  if (processedSize)\r
+    *processedSize = (UInt32)rem;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  switch(seekOrigin)\r
+  {\r
+    case STREAM_SEEK_SET: _pos = offset; break;\r
+    case STREAM_SEEK_CUR: _pos += offset; break;\r
+    case STREAM_SEEK_END: _pos = _size + offset; break;\r
+    default: return STG_E_INVALIDFUNCTION;\r
+  }\r
+  if (newPosition)\r
+    *newPosition = _pos;\r
+  return S_OK;\r
+}\r
+\r
+void CByteDynBuffer::Free()\r
+{\r
+  free(_buf);\r
+  _buf = 0;\r
+  _capacity = 0;\r
+}\r
+\r
+bool CByteDynBuffer::EnsureCapacity(size_t cap)\r
+{\r
+  if (cap <= _capacity)\r
+    return true;\r
+  size_t delta;\r
+  if (_capacity > 64)\r
+    delta = _capacity / 4;\r
+  else if (_capacity > 8)\r
+    delta = 16;\r
+  else\r
+    delta = 4;\r
+  cap = MyMax(_capacity + delta, cap);\r
+  Byte *buf = (Byte *)realloc(_buf, cap);\r
+  if (!buf)\r
+    return false;\r
+  _buf = buf;\r
+  _capacity = cap;\r
+  return true;\r
+}\r
+\r
+Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize)\r
+{\r
+  addSize += _size;\r
+  if (addSize < _size)\r
+    return NULL;\r
+  if (!_buffer.EnsureCapacity(addSize))\r
+    return NULL;\r
+  return (Byte *)_buffer + _size;\r
+}\r
+\r
+void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const\r
+{\r
+  dest.SetCapacity(_size);\r
+  memcpy(dest, _buffer, _size);\r
+}\r
+\r
+STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize)\r
+    *processedSize = 0;\r
+  if (size == 0)\r
+    return S_OK;\r
+  Byte *buf = GetBufPtrForWriting(size);\r
+  if (!buf)\r
+    return E_OUTOFMEMORY;\r
+  memcpy(buf, data, size);\r
+  UpdateSize(size);\r
+  if (processedSize)\r
+    *processedSize = size;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  size_t rem = _size - _pos;\r
+  if (rem > size)\r
+    rem = (size_t)size;\r
+  memcpy(_buffer + _pos, data, rem);\r
+  _pos += rem;\r
+  if (processedSize)\r
+    *processedSize = (UInt32)rem;\r
+  return (rem != 0 || size == 0) ? S_OK : E_FAIL;\r
+}\r
+\r
+STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  UInt32 realProcessedSize;\r
+  HRESULT result = _stream->Write(data, size, &realProcessedSize);\r
+  _size += realProcessedSize;\r
+  if (processedSize)\r
+    *processedSize = realProcessedSize;\r
+  return result;\r
+}\r
+\r
+static const UInt64 kEmptyTag = (UInt64)(Int64)-1;\r
+\r
+void CCachedInStream::Free()\r
+{\r
+  MyFree(_tags);\r
+  _tags = 0;\r
+  MidFree(_data);\r
+  _data = 0;\r
+}\r
+\r
+bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog)\r
+{\r
+  unsigned sizeLog = blockSizeLog + numBlocksLog;\r
+  if (sizeLog >= sizeof(size_t) * 8)\r
+    return false;\r
+  size_t dataSize = (size_t)1 << sizeLog;\r
+  if (_data == 0 || dataSize != _dataSize)\r
+  {\r
+    MidFree(_data);\r
+    _data = (Byte *)MidAlloc(dataSize);\r
+    if (_data == 0)\r
+      return false;\r
+    _dataSize = dataSize;\r
+  }\r
+  if (_tags == 0 || numBlocksLog != _numBlocksLog)\r
+  {\r
+    MyFree(_tags);\r
+    _tags = (UInt64 *)MyAlloc(sizeof(UInt64) << numBlocksLog);\r
+    if (_tags == 0)\r
+      return false;\r
+    _numBlocksLog = numBlocksLog;\r
+  }\r
+  _blockSizeLog = blockSizeLog;\r
+  return true;\r
+}\r
+\r
+void CCachedInStream::Init(UInt64 size)\r
+{\r
+  _size = size;\r
+  _pos = 0;\r
+  size_t numBlocks = (size_t)1 << _numBlocksLog;\r
+  for (size_t i = 0; i < numBlocks; i++)\r
+    _tags[i] = kEmptyTag;\r
+}\r
+\r
+STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize)\r
+    *processedSize = 0;\r
+  if (size == 0)\r
+    return S_OK;\r
+  if (_pos > _size)\r
+    return E_FAIL;\r
+\r
+  {\r
+    UInt64 rem = _size - _pos;\r
+    if (size > rem)\r
+      size = (UInt32)rem;\r
+  }\r
+\r
+  while (size != 0)\r
+  {\r
+    UInt64 cacheTag = _pos >> _blockSizeLog;\r
+    size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1);\r
+    Byte *p = _data + (cacheIndex << _blockSizeLog);\r
+    if (_tags[cacheIndex] != cacheTag)\r
+    {\r
+      UInt64 remInBlock = _size - (cacheTag << _blockSizeLog);\r
+      size_t blockSize = (size_t)1 << _blockSizeLog;\r
+      if (blockSize > remInBlock)\r
+        blockSize = (size_t)remInBlock;\r
+      RINOK(ReadBlock(cacheTag, p, blockSize));\r
+      _tags[cacheIndex] = cacheTag;\r
+    }\r
+    size_t offset = (size_t)_pos & (((size_t)1 << _blockSizeLog) - 1);\r
+    UInt32 cur = (UInt32)MyMin(((size_t)1 << _blockSizeLog) - offset, (size_t)size);\r
+    memcpy(data, p + offset, cur);\r
+    if (processedSize)\r
+      *processedSize += cur;\r
+    data = (void *)((const Byte *)data + cur);\r
+    _pos += cur;\r
+    size -= cur;\r
+  }\r
+\r
+  return S_OK;\r
+}\r
\r
+STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  switch(seekOrigin)\r
+  {\r
+    case STREAM_SEEK_SET: _pos = offset; break;\r
+    case STREAM_SEEK_CUR: _pos = _pos + offset; break;\r
+    case STREAM_SEEK_END: _pos = _size + offset; break;\r
+    default: return STG_E_INVALIDFUNCTION;\r
+  }\r
+  if (newPosition != 0)\r
+    *newPosition = _pos;\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/Common/StreamObjects.h b/CPP/7zip/Common/StreamObjects.h
new file mode 100755 (executable)
index 0000000..ed1532c
--- /dev/null
@@ -0,0 +1,135 @@
+// StreamObjects.h\r
+\r
+#ifndef __STREAM_OBJECTS_H\r
+#define __STREAM_OBJECTS_H\r
+\r
+#include "../../Common/Buffer.h"\r
+#include "../../Common/MyCom.h"\r
+#include "../IStream.h"\r
+\r
+struct CReferenceBuf:\r
+  public IUnknown,\r
+  public CMyUnknownImp\r
+{\r
+  CByteBuffer Buf;\r
+  MY_UNKNOWN_IMP\r
+};\r
+\r
+class CBufInStream:\r
+  public IInStream,\r
+  public CMyUnknownImp\r
+{\r
+  const Byte *_data;\r
+  UInt64 _pos;\r
+  size_t _size;\r
+  CMyComPtr<IUnknown> _ref;\r
+public:\r
+  void Init(const Byte *data, size_t size, IUnknown *ref = 0)\r
+  {\r
+    _data = data;\r
+    _size = size;\r
+    _pos = 0;\r
+    _ref = ref;\r
+  }\r
+  void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.GetCapacity(), ref); }\r
+\r
+  MY_UNKNOWN_IMP1(IInStream)\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+};\r
+\r
+class CByteDynBuffer\r
+{\r
+  size_t _capacity;\r
+  Byte *_buf;\r
+public:\r
+  CByteDynBuffer(): _capacity(0), _buf(0) {};\r
+  // there is no copy constructor. So don't copy this object.\r
+  ~CByteDynBuffer() { Free(); }\r
+  void Free();\r
+  size_t GetCapacity() const { return  _capacity; }\r
+  operator Byte*() const { return _buf; };\r
+  operator const Byte*() const { return _buf; };\r
+  bool EnsureCapacity(size_t capacity);\r
+};\r
+\r
+class CDynBufSeqOutStream:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  CByteDynBuffer _buffer;\r
+  size_t _size;\r
+public:\r
+  CDynBufSeqOutStream(): _size(0) {}\r
+  void Init() { _size = 0;  }\r
+  size_t GetSize() const { return _size; }\r
+  const Byte *GetBuffer() const { return _buffer; }\r
+  void CopyToBuffer(CByteBuffer &dest) const;\r
+  Byte *GetBufPtrForWriting(size_t addSize);\r
+  void UpdateSize(size_t addSize) { _size += addSize; }\r
+\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+class CBufPtrSeqOutStream:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  Byte *_buffer;\r
+  size_t _size;\r
+  size_t _pos;\r
+public:\r
+  void Init(Byte *buffer, size_t size)\r
+  {\r
+    _buffer = buffer;\r
+    _pos = 0;\r
+    _size = size;\r
+  }\r
+  size_t GetPos() const { return _pos; }\r
+\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+class CSequentialOutStreamSizeCount:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<ISequentialOutStream> _stream;\r
+  UInt64 _size;\r
+public:\r
+  void SetStream(ISequentialOutStream *stream) { _stream = stream; }\r
+  void Init() { _size = 0; }\r
+  UInt64 GetSize() const { return _size; }\r
+\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+class CCachedInStream:\r
+  public IInStream,\r
+  public CMyUnknownImp\r
+{\r
+  UInt64 *_tags;\r
+  Byte *_data;\r
+  size_t _dataSize;\r
+  unsigned _blockSizeLog;\r
+  unsigned _numBlocksLog;\r
+  UInt64 _size;\r
+  UInt64 _pos;\r
+protected:\r
+  virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0;\r
+public:\r
+  CCachedInStream(): _tags(0), _data(0) {}\r
+  virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!!\r
+  void Free();\r
+  bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog);\r
+  void Init(UInt64 size);\r
+\r
+  MY_UNKNOWN_IMP2(ISequentialInStream, IInStream)\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/StreamUtils.cpp b/CPP/7zip/Common/StreamUtils.cpp
new file mode 100755 (executable)
index 0000000..57ff4ee
--- /dev/null
@@ -0,0 +1,56 @@
+// StreamUtils.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "StreamUtils.h"\r
+\r
+static const UInt32 kBlockSize = ((UInt32)1 << 31);\r
+\r
+HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize)\r
+{\r
+  size_t size = *processedSize;\r
+  *processedSize = 0;\r
+  while (size != 0)\r
+  {\r
+    UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize;\r
+    UInt32 processedSizeLoc;\r
+    HRESULT res = stream->Read(data, curSize, &processedSizeLoc);\r
+    *processedSize += processedSizeLoc;\r
+    data = (void *)((Byte *)data + processedSizeLoc);\r
+    size -= processedSizeLoc;\r
+    RINOK(res);\r
+    if (processedSizeLoc == 0)\r
+      return S_OK;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size)\r
+{\r
+  size_t processedSize = size;\r
+  RINOK(ReadStream(stream, data, &processedSize));\r
+  return (size == processedSize) ? S_OK : S_FALSE;\r
+}\r
+\r
+HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size)\r
+{\r
+  size_t processedSize = size;\r
+  RINOK(ReadStream(stream, data, &processedSize));\r
+  return (size == processedSize) ? S_OK : E_FAIL;\r
+}\r
+\r
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size)\r
+{\r
+  while (size != 0)\r
+  {\r
+    UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize;\r
+    UInt32 processedSizeLoc;\r
+    HRESULT res = stream->Write(data, curSize, &processedSizeLoc);\r
+    data = (const void *)((const Byte *)data + processedSizeLoc);\r
+    size -= processedSizeLoc;\r
+    RINOK(res);\r
+    if (processedSizeLoc == 0)\r
+      return E_FAIL;\r
+  }\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/Common/StreamUtils.h b/CPP/7zip/Common/StreamUtils.h
new file mode 100755 (executable)
index 0000000..30535ab
--- /dev/null
@@ -0,0 +1,13 @@
+// StreamUtils.h\r
+\r
+#ifndef __STREAMUTILS_H\r
+#define __STREAMUTILS_H\r
+\r
+#include "../IStream.h"\r
+\r
+HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size);\r
+HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size);\r
+HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size);\r
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size);\r
+\r
+#endif\r
diff --git a/CPP/7zip/Common/VirtThread.cpp b/CPP/7zip/Common/VirtThread.cpp
new file mode 100755 (executable)
index 0000000..c07caba
--- /dev/null
@@ -0,0 +1,46 @@
+// VirtThread.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "VirtThread.h"\r
+\r
+static THREAD_FUNC_DECL CoderThread(void *p)\r
+{\r
+  for (;;)\r
+  {\r
+    CVirtThread *t = (CVirtThread *)p;\r
+    t->StartEvent.Lock();\r
+    if (t->ExitEvent)\r
+      return 0;\r
+    t->Execute();\r
+    t->FinishedEvent.Set();\r
+  }\r
+}\r
+\r
+WRes CVirtThread::Create()\r
+{\r
+  RINOK(StartEvent.CreateIfNotCreated());\r
+  RINOK(FinishedEvent.CreateIfNotCreated());\r
+  StartEvent.Reset();\r
+  FinishedEvent.Reset();\r
+  ExitEvent = false;\r
+  if (Thread.IsCreated())\r
+    return S_OK;\r
+  return Thread.Create(CoderThread, this);\r
+}\r
+\r
+void CVirtThread::Start()\r
+{\r
+  ExitEvent = false;\r
+  StartEvent.Set();\r
+}\r
+\r
+CVirtThread::~CVirtThread()\r
+{\r
+  ExitEvent = true;\r
+  if (StartEvent.IsCreated())\r
+    StartEvent.Set();\r
+  if (Thread.IsCreated())\r
+    Thread.Wait();\r
+}\r
+\r
diff --git a/CPP/7zip/Common/VirtThread.h b/CPP/7zip/Common/VirtThread.h
new file mode 100755 (executable)
index 0000000..bfc10dc
--- /dev/null
@@ -0,0 +1,23 @@
+// VirtThread.h\r
+\r
+#ifndef __VIRTTHREAD_H\r
+#define __VIRTTHREAD_H\r
+\r
+#include "../../Windows/Synchronization.h"\r
+#include "../../Windows/Thread.h"\r
+\r
+struct CVirtThread\r
+{\r
+  NWindows::NSynchronization::CAutoResetEvent StartEvent;\r
+  NWindows::NSynchronization::CAutoResetEvent FinishedEvent;\r
+  NWindows::CThread Thread;\r
+  bool ExitEvent;\r
+\r
+  ~CVirtThread();\r
+  WRes Create();\r
+  void Start();\r
+  void WaitFinish() { FinishedEvent.Lock(); }\r
+  virtual void Execute() = 0;\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/Bcj2Coder.cpp b/CPP/7zip/Compress/Bcj2Coder.cpp
new file mode 100755 (executable)
index 0000000..05590e7
--- /dev/null
@@ -0,0 +1,386 @@
+// Bcj2Coder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "Bcj2Coder.h"\r
+\r
+namespace NCompress {\r
+namespace NBcj2 {\r
+\r
+inline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); }\r
+inline bool IsJ(Byte b0, Byte b1) { return ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)); }\r
+inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == 0xE9) ? 256 : 257)); }\r
+\r
+#ifndef EXTRACT_ONLY\r
+\r
+static const int kBufferSize = 1 << 17;\r
+\r
+static bool inline Test86MSByte(Byte b)\r
+{\r
+  return (b == 0 || b == 0xFF);\r
+}\r
+\r
+bool CEncoder::Create()\r
+{\r
+  if (!_mainStream.Create(1 << 18))\r
+    return false;\r
+  if (!_callStream.Create(1 << 18))\r
+    return false;\r
+  if (!_jumpStream.Create(1 << 18))\r
+    return false;\r
+  if (!_rangeEncoder.Create(1 << 20))\r
+    return false;\r
+  if (_buffer == 0)\r
+  {\r
+    _buffer = (Byte *)MidAlloc(kBufferSize);\r
+    if (_buffer == 0)\r
+      return false;\r
+  }\r
+  return true;\r
+}\r
+\r
+CEncoder::~CEncoder()\r
+{\r
+  ::MidFree(_buffer);\r
+}\r
+\r
+HRESULT CEncoder::Flush()\r
+{\r
+  RINOK(_mainStream.Flush());\r
+  RINOK(_callStream.Flush());\r
+  RINOK(_jumpStream.Flush());\r
+  _rangeEncoder.FlushData();\r
+  return _rangeEncoder.FlushStream();\r
+}\r
+\r
+const UInt32 kDefaultLimit = (1 << 24);\r
+\r
+HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,\r
+    ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams,\r
+    ICompressProgressInfo *progress)\r
+{\r
+  if (numInStreams != 1 || numOutStreams != 4)\r
+    return E_INVALIDARG;\r
+\r
+  if (!Create())\r
+    return E_OUTOFMEMORY;\r
+\r
+  bool sizeIsDefined = false;\r
+  UInt64 inSize = 0;\r
+  if (inSizes != NULL)\r
+    if (inSizes[0] != NULL)\r
+    {\r
+      inSize = *inSizes[0];\r
+      if (inSize <= kDefaultLimit)\r
+        sizeIsDefined = true;\r
+    }\r
+\r
+  CCoderReleaser releaser(this);\r
+\r
+  ISequentialInStream *inStream = inStreams[0];\r
+\r
+  _mainStream.SetStream(outStreams[0]);\r
+  _mainStream.Init();\r
+  _callStream.SetStream(outStreams[1]);\r
+  _callStream.Init();\r
+  _jumpStream.SetStream(outStreams[2]);\r
+  _jumpStream.Init();\r
+  _rangeEncoder.SetStream(outStreams[3]);\r
+  _rangeEncoder.Init();\r
+  for (int i = 0; i < 256 + 2; i++)\r
+    _statusEncoder[i].Init();\r
+\r
+  CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;\r
+  {\r
+    inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);\r
+  }\r
+\r
+  UInt32 nowPos = 0;\r
+  UInt64 nowPos64 = 0;\r
+  UInt32 bufferPos = 0;\r
+\r
+  Byte prevByte = 0;\r
+\r
+  UInt64 subStreamIndex = 0;\r
+  UInt64 subStreamStartPos  = 0;\r
+  UInt64 subStreamEndPos = 0;\r
+\r
+  for (;;)\r
+  {\r
+    UInt32 processedSize = 0;\r
+    for (;;)\r
+    {\r
+      UInt32 size = kBufferSize - (bufferPos + processedSize);\r
+      UInt32 processedSizeLoc;\r
+      if (size == 0)\r
+        break;\r
+      RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));\r
+      if (processedSizeLoc == 0)\r
+        break;\r
+      processedSize += processedSizeLoc;\r
+    }\r
+    UInt32 endPos = bufferPos + processedSize;\r
+    \r
+    if (endPos < 5)\r
+    {\r
+      // change it\r
+      for (bufferPos = 0; bufferPos < endPos; bufferPos++)\r
+      {\r
+        Byte b = _buffer[bufferPos];\r
+        _mainStream.WriteByte(b);\r
+        UInt32 index;\r
+        if (b == 0xE8)\r
+          index = prevByte;\r
+        else if (b == 0xE9)\r
+          index = 256;\r
+        else if (IsJcc(prevByte, b))\r
+          index = 257;\r
+        else\r
+        {\r
+          prevByte = b;\r
+          continue;\r
+        }\r
+        _statusEncoder[index].Encode(&_rangeEncoder, 0);\r
+        prevByte = b;\r
+      }\r
+      return Flush();\r
+    }\r
+\r
+    bufferPos = 0;\r
+\r
+    UInt32 limit = endPos - 5;\r
+    while(bufferPos <= limit)\r
+    {\r
+      Byte b = _buffer[bufferPos];\r
+      _mainStream.WriteByte(b);\r
+      if (!IsJ(prevByte, b))\r
+      {\r
+        bufferPos++;\r
+        prevByte = b;\r
+        continue;\r
+      }\r
+      Byte nextByte = _buffer[bufferPos + 4];\r
+      UInt32 src =\r
+        (UInt32(nextByte) << 24) |\r
+        (UInt32(_buffer[bufferPos + 3]) << 16) |\r
+        (UInt32(_buffer[bufferPos + 2]) << 8) |\r
+        (_buffer[bufferPos + 1]);\r
+      UInt32 dest = (nowPos + bufferPos + 5) + src;\r
+      // if (Test86MSByte(nextByte))\r
+      bool convert;\r
+      if (getSubStreamSize != NULL)\r
+      {\r
+        UInt64 currentPos = (nowPos64 + bufferPos);\r
+        while (subStreamEndPos < currentPos)\r
+        {\r
+          UInt64 subStreamSize;\r
+          HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);\r
+          if (result == S_OK)\r
+          {\r
+            subStreamStartPos = subStreamEndPos;\r
+            subStreamEndPos += subStreamSize;\r
+            subStreamIndex++;\r
+          }\r
+          else if (result == S_FALSE || result == E_NOTIMPL)\r
+          {\r
+            getSubStreamSize.Release();\r
+            subStreamStartPos = 0;\r
+            subStreamEndPos = subStreamStartPos - 1;\r
+          }\r
+          else\r
+            return result;\r
+        }\r
+        if (getSubStreamSize == NULL)\r
+        {\r
+          if (sizeIsDefined)\r
+            convert = (dest < inSize);\r
+          else\r
+            convert = Test86MSByte(nextByte);\r
+        }\r
+        else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)\r
+          convert = Test86MSByte(nextByte);\r
+        else\r
+        {\r
+          UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));\r
+          convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);\r
+        }\r
+      }\r
+      else if (sizeIsDefined)\r
+        convert = (dest < inSize);\r
+      else\r
+        convert = Test86MSByte(nextByte);\r
+      unsigned index = GetIndex(prevByte, b);\r
+      if (convert)\r
+      {\r
+        _statusEncoder[index].Encode(&_rangeEncoder, 1);\r
+        bufferPos += 5;\r
+        COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;\r
+        for (int i = 24; i >= 0; i -= 8)\r
+          s.WriteByte((Byte)(dest >> i));\r
+        prevByte = nextByte;\r
+      }\r
+      else\r
+      {\r
+        _statusEncoder[index].Encode(&_rangeEncoder, 0);\r
+        bufferPos++;\r
+        prevByte = b;\r
+      }\r
+    }\r
+    nowPos += bufferPos;\r
+    nowPos64 += bufferPos;\r
+\r
+    if (progress != NULL)\r
+    {\r
+      /*\r
+      const UInt64 compressedSize =\r
+        _mainStream.GetProcessedSize() +\r
+        _callStream.GetProcessedSize() +\r
+        _jumpStream.GetProcessedSize() +\r
+        _rangeEncoder.GetProcessedSize();\r
+      */\r
+      RINOK(progress->SetRatioInfo(&nowPos64, NULL));\r
+    }\r
\r
+    UInt32 i = 0;\r
+    while(bufferPos < endPos)\r
+      _buffer[i++] = _buffer[bufferPos++];\r
+    bufferPos = i;\r
+  }\r
+}\r
+\r
+STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,\r
+    ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,\r
+    ICompressProgressInfo *progress)\r
+{\r
+  try\r
+  {\r
+    return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress);\r
+  }\r
+  catch(const COutBufferException &e) { return e.ErrorCode; }\r
+  catch(...) { return S_FALSE; }\r
+}\r
+\r
+#endif\r
+\r
+\r
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _inBufSizes[streamIndex] = size; return S_OK; }\r
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }\r
+\r
+CDecoder::CDecoder():\r
+  _outBufSize(1 << 16)\r
+{\r
+  _inBufSizes[0] = 1 << 20;\r
+  _inBufSizes[1] = 1 << 20;\r
+  _inBufSizes[2] = 1 << 20;\r
+  _inBufSizes[3] = 1 << 20;\r
+}\r
+\r
+HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* inSizes */, UInt32 numInStreams,\r
+    ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams,\r
+    ICompressProgressInfo *progress)\r
+{\r
+  if (numInStreams != 4 || numOutStreams != 1)\r
+    return E_INVALIDARG;\r
+\r
+  if (!_mainInStream.Create(_inBufSizes[0]))\r
+    return E_OUTOFMEMORY;\r
+  if (!_callStream.Create(_inBufSizes[1]))\r
+    return E_OUTOFMEMORY;\r
+  if (!_jumpStream.Create(_inBufSizes[2]))\r
+    return E_OUTOFMEMORY;\r
+  if (!_rangeDecoder.Create(_inBufSizes[3]))\r
+    return E_OUTOFMEMORY;\r
+  if (!_outStream.Create(_outBufSize))\r
+    return E_OUTOFMEMORY;\r
+\r
+  CCoderReleaser releaser(this);\r
+\r
+  _mainInStream.SetStream(inStreams[0]);\r
+  _callStream.SetStream(inStreams[1]);\r
+  _jumpStream.SetStream(inStreams[2]);\r
+  _rangeDecoder.SetStream(inStreams[3]);\r
+  _outStream.SetStream(outStreams[0]);\r
+\r
+  _mainInStream.Init();\r
+  _callStream.Init();\r
+  _jumpStream.Init();\r
+  _rangeDecoder.Init();\r
+  _outStream.Init();\r
+\r
+  for (int i = 0; i < 256 + 2; i++)\r
+    _statusDecoder[i].Init();\r
+\r
+  Byte prevByte = 0;\r
+  UInt32 processedBytes = 0;\r
+  for (;;)\r
+  {\r
+    if (processedBytes >= (1 << 20) && progress != NULL)\r
+    {\r
+      /*\r
+      const UInt64 compressedSize =\r
+        _mainInStream.GetProcessedSize() +\r
+        _callStream.GetProcessedSize() +\r
+        _jumpStream.GetProcessedSize() +\r
+        _rangeDecoder.GetProcessedSize();\r
+      */\r
+      const UInt64 nowPos64 = _outStream.GetProcessedSize();\r
+      RINOK(progress->SetRatioInfo(NULL, &nowPos64));\r
+      processedBytes = 0;\r
+    }\r
+    UInt32 i;\r
+    Byte b = 0;\r
+    const UInt32 kBurstSize = (1 << 18);\r
+    for (i = 0; i < kBurstSize; i++)\r
+    {\r
+      if (!_mainInStream.ReadByte(b))\r
+        return Flush();\r
+      _outStream.WriteByte(b);\r
+      if (IsJ(prevByte, b))\r
+        break;\r
+      prevByte = b;\r
+    }\r
+    processedBytes += i;\r
+    if (i == kBurstSize)\r
+      continue;\r
+    unsigned index = GetIndex(prevByte, b);\r
+    if (_statusDecoder[index].Decode(&_rangeDecoder) == 1)\r
+    {\r
+      UInt32 src = 0;\r
+      CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;\r
+      for (int i = 0; i < 4; i++)\r
+      {\r
+        Byte b0;\r
+        if(!s.ReadByte(b0))\r
+          return S_FALSE;\r
+        src <<= 8;\r
+        src |= ((UInt32)b0);\r
+      }\r
+      UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;\r
+      _outStream.WriteByte((Byte)(dest));\r
+      _outStream.WriteByte((Byte)(dest >> 8));\r
+      _outStream.WriteByte((Byte)(dest >> 16));\r
+      _outStream.WriteByte((Byte)(dest >> 24));\r
+      prevByte = (Byte)(dest >> 24);\r
+      processedBytes += 4;\r
+    }\r
+    else\r
+      prevByte = b;\r
+  }\r
+}\r
+\r
+STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,\r
+    ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,\r
+    ICompressProgressInfo *progress)\r
+{\r
+  try\r
+  {\r
+    return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress);\r
+  }\r
+  catch(const CInBufferException &e) { return e.ErrorCode; }\r
+  catch(const COutBufferException &e) { return e.ErrorCode; }\r
+  catch(...) { return S_FALSE; }\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Compress/Bcj2Coder.h b/CPP/7zip/Compress/Bcj2Coder.h
new file mode 100755 (executable)
index 0000000..c8f0893
--- /dev/null
@@ -0,0 +1,115 @@
+// Bcj2Coder.h\r
+\r
+#ifndef __COMPRESS_BCJ2_CODER_H\r
+#define __COMPRESS_BCJ2_CODER_H\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+#include "RangeCoderBit.h"\r
+\r
+namespace NCompress {\r
+namespace NBcj2 {\r
+\r
+const int kNumMoveBits = 5;\r
+\r
+#ifndef EXTRACT_ONLY\r
+\r
+class CEncoder:\r
+  public ICompressCoder2,\r
+  public CMyUnknownImp\r
+{\r
+  Byte *_buffer;\r
+  bool Create();\r
+\r
+  COutBuffer _mainStream;\r
+  COutBuffer _callStream;\r
+  COutBuffer _jumpStream;\r
+  NCompress::NRangeCoder::CEncoder _rangeEncoder;\r
+  NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];\r
+\r
+  HRESULT Flush();\r
+public:\r
+  void ReleaseStreams()\r
+  {\r
+    _mainStream.ReleaseStream();\r
+    _callStream.ReleaseStream();\r
+    _jumpStream.ReleaseStream();\r
+    _rangeEncoder.ReleaseStream();\r
+  }\r
+\r
+  class CCoderReleaser\r
+  {\r
+    CEncoder *_coder;\r
+  public:\r
+    CCoderReleaser(CEncoder *coder): _coder(coder) {}\r
+    ~CCoderReleaser() {  _coder->ReleaseStreams(); }\r
+  };\r
+\r
+public:\r
+  MY_UNKNOWN_IMP\r
+\r
+  HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,\r
+      ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,\r
+      ICompressProgressInfo *progress);\r
+  STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,\r
+      ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,\r
+      ICompressProgressInfo *progress);\r
+  CEncoder(): _buffer(0) {};\r
+  ~CEncoder();\r
+};\r
+\r
+#endif\r
+\r
+class CDecoder:\r
+  public ICompressCoder2,\r
+  public ICompressSetBufSize,\r
+  public CMyUnknownImp\r
+{\r
+  CInBuffer _mainInStream;\r
+  CInBuffer _callStream;\r
+  CInBuffer _jumpStream;\r
+  NCompress::NRangeCoder::CDecoder _rangeDecoder;\r
+  NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];\r
+\r
+  COutBuffer _outStream;\r
+  UInt32 _inBufSizes[4];\r
+  UInt32 _outBufSize;\r
+\r
+public:\r
+  void ReleaseStreams()\r
+  {\r
+    _mainInStream.ReleaseStream();\r
+    _callStream.ReleaseStream();\r
+    _jumpStream.ReleaseStream();\r
+    _rangeDecoder.ReleaseStream();\r
+    _outStream.ReleaseStream();\r
+  }\r
+\r
+  HRESULT Flush() { return _outStream.Flush(); }\r
+  class CCoderReleaser\r
+  {\r
+    CDecoder *_coder;\r
+  public:\r
+    CCoderReleaser(CDecoder *coder): _coder(coder) {}\r
+    ~CCoderReleaser()  { _coder->ReleaseStreams(); }\r
+  };\r
+\r
+public:\r
+  MY_UNKNOWN_IMP1(ICompressSetBufSize);\r
+  HRESULT CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,\r
+      ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,\r
+      ICompressProgressInfo *progress);\r
+  STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,\r
+      ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,\r
+      ICompressProgressInfo *progress);\r
+\r
+  STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);\r
+  STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);\r
+  CDecoder();\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/Bcj2Register.cpp b/CPP/7zip/Compress/Bcj2Register.cpp
new file mode 100755 (executable)
index 0000000..b063f3f
--- /dev/null
@@ -0,0 +1,19 @@
+// Bcj2Register.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+#include "Bcj2Coder.h"\r
+\r
+static void *CreateCodec() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CDecoder()); }\r
+#ifndef EXTRACT_ONLY\r
+static void *CreateCodecOut() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CEncoder());  }\r
+#else\r
+#define CreateCodecOut 0\r
+#endif\r
+\r
+static CCodecInfo g_CodecInfo =\r
+  { CreateCodec, CreateCodecOut, 0x0303011B, L"BCJ2", 4, false };\r
+\r
+REGISTER_CODEC(BCJ2)\r
diff --git a/CPP/7zip/Compress/BcjCoder.cpp b/CPP/7zip/Compress/BcjCoder.cpp
new file mode 100755 (executable)
index 0000000..108c573
--- /dev/null
@@ -0,0 +1,15 @@
+// BcjCoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "BcjCoder.h"\r
+\r
+UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)\r
+{\r
+  return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 1);\r
+}\r
+\r
+UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)\r
+{\r
+  return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 0);\r
+}\r
diff --git a/CPP/7zip/Compress/BcjCoder.h b/CPP/7zip/Compress/BcjCoder.h
new file mode 100755 (executable)
index 0000000..c86d5fc
--- /dev/null
@@ -0,0 +1,19 @@
+// BcjCoder.h\r
+\r
+#ifndef __COMPRESS_BCJ_CODER_H\r
+#define __COMPRESS_BCJ_CODER_H\r
+\r
+#include "../../../C/Bra.h"\r
+\r
+#include "BranchCoder.h"\r
+\r
+struct CBranch86\r
+{\r
+  UInt32 _prevMask;\r
+  void x86Init() { x86_Convert_Init(_prevMask); }\r
+};\r
+\r
+MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,\r
+    virtual void SubInit() { x86Init(); })\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/BcjRegister.cpp b/CPP/7zip/Compress/BcjRegister.cpp
new file mode 100755 (executable)
index 0000000..09e53c6
--- /dev/null
@@ -0,0 +1,19 @@
+// BcjRegister.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+#include "BcjCoder.h"\r
+\r
+static void *CreateCodec() { return (void *)(ICompressFilter *)(new CBCJ_x86_Decoder()); }\r
+#ifndef EXTRACT_ONLY\r
+static void *CreateCodecOut() { return (void *)(ICompressFilter *)(new CBCJ_x86_Encoder());  }\r
+#else\r
+#define CreateCodecOut 0\r
+#endif\r
+\r
+static CCodecInfo g_CodecInfo =\r
+  { CreateCodec, CreateCodecOut, 0x03030103, L"BCJ", 1, true };\r
+\r
+REGISTER_CODEC(BCJ)\r
diff --git a/CPP/7zip/Compress/BranchCoder.cpp b/CPP/7zip/Compress/BranchCoder.cpp
new file mode 100755 (executable)
index 0000000..6cacc66
--- /dev/null
@@ -0,0 +1,19 @@
+// BranchCoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "BranchCoder.h"\r
+\r
+STDMETHODIMP CBranchConverter::Init()\r
+{\r
+  _bufferPos = 0;\r
+  SubInit();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)\r
+{\r
+  UInt32 processedSize = SubFilter(data, size);\r
+  _bufferPos += processedSize;\r
+  return processedSize;\r
+}\r
diff --git a/CPP/7zip/Compress/BranchCoder.h b/CPP/7zip/Compress/BranchCoder.h
new file mode 100755 (executable)
index 0000000..473286a
--- /dev/null
@@ -0,0 +1,44 @@
+// BranchCoder.h\r
+\r
+#ifndef __COMPRESS_BRANCH_CODER_H\r
+#define __COMPRESS_BRANCH_CODER_H\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+class CBranchConverter:\r
+  public ICompressFilter,\r
+  public CMyUnknownImp\r
+{\r
+protected:\r
+  UInt32 _bufferPos;\r
+  virtual void SubInit() {}\r
+  virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;\r
+public:\r
+  MY_UNKNOWN_IMP;\r
+  STDMETHOD(Init)();\r
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);\r
+};\r
+\r
+#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \\r
+  { public: UInt32 SubFilter(Byte *data, UInt32 size); };\r
+\r
+#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \\r
+  { public: UInt32 SubFilter(Byte *data, UInt32 size); };\r
+\r
+#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \\r
+  { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};\r
+\r
+#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \\r
+  { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};\r
+\r
+#define MyClassA(Name, id, subId)  \\r
+MyClassEncoderA(Name ## _Encoder) \\r
+MyClassDecoderA(Name ## _Decoder)\r
+\r
+#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT)  \\r
+MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \\r
+MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/BranchMisc.cpp b/CPP/7zip/Compress/BranchMisc.cpp
new file mode 100755 (executable)
index 0000000..1a46bb1
--- /dev/null
@@ -0,0 +1,37 @@
+// BranchMisc.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Bra.h"\r
+\r
+#include "BranchMisc.h"\r
+\r
+UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::ARM_Convert(data, size, _bufferPos, 1); }\r
+\r
+UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::ARM_Convert(data, size, _bufferPos, 0); }\r
+\r
+UInt32 CBC_ARMT_Encoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 1); }\r
+\r
+UInt32 CBC_ARMT_Decoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::ARMT_Convert(data, size, _bufferPos, 0); }\r
+\r
+UInt32 CBC_PPC_Encoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::PPC_Convert(data, size, _bufferPos, 1); }\r
+\r
+UInt32 CBC_PPC_Decoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::PPC_Convert(data, size, _bufferPos, 0); }\r
+\r
+UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 1); }\r
+\r
+UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::SPARC_Convert(data, size, _bufferPos, 0); }\r
+\r
+UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)\r
+  { return (UInt32)::IA64_Convert(data, size, _bufferPos, 1); }\r
+\r
+UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)\r
+  {  return (UInt32)::IA64_Convert(data, size, _bufferPos, 0); }\r
diff --git a/CPP/7zip/Compress/BranchMisc.h b/CPP/7zip/Compress/BranchMisc.h
new file mode 100755 (executable)
index 0000000..053e923
--- /dev/null
@@ -0,0 +1,14 @@
+// BranchMisc.h\r
+\r
+#ifndef __COMPRESS_BRANCH_MISC_H\r
+#define __COMPRESS_BRANCH_MISC_H\r
+\r
+#include "BranchCoder.h"\r
+\r
+MyClassA(BC_ARM,   0x05, 1)\r
+MyClassA(BC_ARMT,  0x07, 1)\r
+MyClassA(BC_PPC,   0x02, 5)\r
+MyClassA(BC_SPARC, 0x08, 5)\r
+MyClassA(BC_IA64,  0x04, 1)\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/BranchRegister.cpp b/CPP/7zip/Compress/BranchRegister.cpp
new file mode 100755 (executable)
index 0000000..bc55dd6
--- /dev/null
@@ -0,0 +1,30 @@
+// BranchRegister.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+#include "BranchMisc.h"\r
+\r
+#define CREATE_CODEC(x) \\r
+  static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## _Decoder); } \\r
+  static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## _Encoder); }\r
+\r
+CREATE_CODEC(BC_PPC)\r
+CREATE_CODEC(BC_IA64)\r
+CREATE_CODEC(BC_ARM)\r
+CREATE_CODEC(BC_ARMT)\r
+CREATE_CODEC(BC_SPARC)\r
+\r
+#define METHOD_ITEM(x, id1, id2, name) { CreateCodec ## x, CreateCodec ## x ## Out, 0x03030000 + (id1 * 256) + id2, name, 1, true  }\r
+\r
+static CCodecInfo g_CodecsInfo[] =\r
+{\r
+  METHOD_ITEM(BC_PPC,   0x02, 0x05, L"PPC"),\r
+  METHOD_ITEM(BC_IA64,  0x04, 1, L"IA64"),\r
+  METHOD_ITEM(BC_ARM,   0x05, 1, L"ARM"),\r
+  METHOD_ITEM(BC_ARMT,  0x07, 1, L"ARMT"),\r
+  METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"SPARC")\r
+};\r
+\r
+REGISTER_CODECS(Branch)\r
diff --git a/CPP/7zip/Compress/ByteSwap.cpp b/CPP/7zip/Compress/ByteSwap.cpp
new file mode 100755 (executable)
index 0000000..7f028fb
--- /dev/null
@@ -0,0 +1,73 @@
+// ByteSwap.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+class CByteSwap2:\r
+  public ICompressFilter,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Init)();\r
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);\r
+};\r
+\r
+class CByteSwap4:\r
+  public ICompressFilter,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Init)();\r
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);\r
+};\r
+\r
+STDMETHODIMP CByteSwap2::Init() { return S_OK; }\r
+\r
+STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size)\r
+{\r
+  const UInt32 kStep = 2;\r
+  UInt32 i;\r
+  for (i = 0; i + kStep <= size; i += kStep)\r
+  {\r
+    Byte b = data[i];\r
+    data[i] = data[i + 1];\r
+    data[i + 1] = b;\r
+  }\r
+  return i;\r
+}\r
+\r
+STDMETHODIMP CByteSwap4::Init() { return S_OK; }\r
+\r
+STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)\r
+{\r
+  const UInt32 kStep = 4;\r
+  UInt32 i;\r
+  for (i = 0; i + kStep <= size; i += kStep)\r
+  {\r
+    Byte b0 = data[i];\r
+    Byte b1 = data[i + 1];\r
+    data[i] = data[i + 3];\r
+    data[i + 1] = data[i + 2];\r
+    data[i + 2] = b1;\r
+    data[i + 3] = b0;\r
+  }\r
+  return i;\r
+}\r
+\r
+static void *CreateCodec2() { return (void *)(ICompressFilter *)(new CByteSwap2); }\r
+static void *CreateCodec4() { return (void *)(ICompressFilter *)(new CByteSwap4); }\r
+\r
+static CCodecInfo g_CodecsInfo[] =\r
+{\r
+  { CreateCodec2, CreateCodec2, 0x020302, L"Swap2", 1, true },\r
+  { CreateCodec4, CreateCodec4, 0x020304, L"Swap4", 1, true }\r
+};\r
+\r
+REGISTER_CODECS(ByteSwap)\r
diff --git a/CPP/7zip/Compress/CodecExports.cpp b/CPP/7zip/Compress/CodecExports.cpp
new file mode 100755 (executable)
index 0000000..84a27cf
--- /dev/null
@@ -0,0 +1,160 @@
+// CodecExports.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../Common/ComTry.h"\r
+\r
+#include "../../Windows/PropVariant.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+extern unsigned int g_NumCodecs;\r
+extern const CCodecInfo *g_Codecs[];\r
+\r
+static const UInt16 kDecodeId = 0x2790;\r
+\r
+DEFINE_GUID(CLSID_CCodec,\r
+0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\r
+\r
+static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)\r
+{\r
+  if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)\r
+    value->vt = VT_BSTR;\r
+  return S_OK;\r
+}\r
+\r
+static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)\r
+{\r
+  return SetPropString((const char *)&guid, sizeof(GUID), value);\r
+}\r
+\r
+static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value)\r
+{\r
+  GUID clsId = CLSID_CCodec;\r
+  for (int i = 0; i < sizeof(id); i++, id >>= 8)\r
+    clsId.Data4[i] = (Byte)(id & 0xFF);\r
+  if (encode)\r
+    clsId.Data3++;\r
+  return SetPropGUID(clsId, value);\r
+}\r
+\r
+static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index)\r
+{\r
+  index = -1;\r
+  if (clsID->Data1 != CLSID_CCodec.Data1 ||\r
+      clsID->Data2 != CLSID_CCodec.Data2 ||\r
+      (clsID->Data3 & ~1) != kDecodeId)\r
+    return S_OK;\r
+  encode = (clsID->Data3 != kDecodeId);\r
+  UInt64 id = 0;\r
+  for (int j = 0; j < 8; j++)\r
+    id |= ((UInt64)clsID->Data4[j]) << (8 * j);\r
+  for (unsigned i = 0; i < g_NumCodecs; i++)\r
+  {\r
+    const CCodecInfo &codec = *g_Codecs[i];\r
+    if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder)\r
+      continue;\r
+    if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||\r
+        codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)\r
+      return E_NOINTERFACE;\r
+    index = i;\r
+    return S_OK;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject)\r
+{\r
+  COM_TRY_BEGIN\r
+  *outObject = 0;\r
+  bool isCoder = (*iid == IID_ICompressCoder) != 0;\r
+  bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;\r
+  bool isFilter = (*iid == IID_ICompressFilter) != 0;\r
+  const CCodecInfo &codec = *g_Codecs[index];\r
+  if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||\r
+      codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)\r
+    return E_NOINTERFACE;\r
+  if (encode)\r
+  {\r
+    if (!codec.CreateEncoder)\r
+      return CLASS_E_CLASSNOTAVAILABLE;\r
+    *outObject = codec.CreateEncoder();\r
+  }\r
+  else\r
+  {\r
+    if (!codec.CreateDecoder)\r
+      return CLASS_E_CLASSNOTAVAILABLE;\r
+    *outObject = codec.CreateDecoder();\r
+  }\r
+  if (isCoder)\r
+    ((ICompressCoder *)*outObject)->AddRef();\r
+  else if (isCoder2)\r
+    ((ICompressCoder2 *)*outObject)->AddRef();\r
+  else\r
+    ((ICompressFilter *)*outObject)->AddRef();\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)\r
+{\r
+  *outObject = 0;\r
+  bool isCoder = (*iid == IID_ICompressCoder) != 0;\r
+  bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;\r
+  bool isFilter = (*iid == IID_ICompressFilter) != 0;\r
+  if (!isCoder && !isCoder2 && !isFilter)\r
+    return E_NOINTERFACE;\r
+  bool encode;\r
+  int codecIndex;\r
+  HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex);\r
+  if (res != S_OK)\r
+    return res;\r
+  if (codecIndex < 0)\r
+    return CLASS_E_CLASSNOTAVAILABLE;\r
+  return CreateCoder2(encode, codecIndex, iid, outObject);\r
+}\r
+\r
+STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)\r
+{\r
+  ::VariantClear((VARIANTARG *)value);\r
+  const CCodecInfo &codec = *g_Codecs[codecIndex];\r
+  switch(propID)\r
+  {\r
+    case NMethodPropID::kID:\r
+    {\r
+      value->uhVal.QuadPart = (UInt64)codec.Id;\r
+      value->vt = VT_UI8;\r
+      break;\r
+    }\r
+    case NMethodPropID::kName:\r
+      if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0)\r
+        value->vt = VT_BSTR;\r
+      break;\r
+    case NMethodPropID::kDecoder:\r
+      if (codec.CreateDecoder)\r
+        return SetClassID(codec.Id, false, value);\r
+      break;\r
+    case NMethodPropID::kEncoder:\r
+      if (codec.CreateEncoder)\r
+        return SetClassID(codec.Id, true, value);\r
+      break;\r
+    case NMethodPropID::kInStreams:\r
+    {\r
+      if (codec.NumInStreams != 1)\r
+      {\r
+        value->vt = VT_UI4;\r
+        value->ulVal = (ULONG)codec.NumInStreams;\r
+      }\r
+      break;\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDAPI GetNumberOfMethods(UINT32 *numCodecs)\r
+{\r
+  *numCodecs = g_NumCodecs;\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/Compress/CopyCoder.cpp b/CPP/7zip/Compress/CopyCoder.cpp
new file mode 100755 (executable)
index 0000000..da15d04
--- /dev/null
@@ -0,0 +1,67 @@
+// Compress/CopyCoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "../Common/StreamUtils.h"\r
+\r
+#include "CopyCoder.h"\r
+\r
+namespace NCompress {\r
+\r
+static const UInt32 kBufferSize = 1 << 17;\r
+\r
+CCopyCoder::~CCopyCoder()\r
+{\r
+  ::MidFree(_buffer);\r
+}\r
+\r
+STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,\r
+    ISequentialOutStream *outStream,\r
+    const UInt64 * /* inSize */, const UInt64 *outSize,\r
+    ICompressProgressInfo *progress)\r
+{\r
+  if (_buffer == 0)\r
+  {\r
+    _buffer = (Byte *)::MidAlloc(kBufferSize);\r
+    if (_buffer == 0)\r
+      return E_OUTOFMEMORY;\r
+  }\r
+\r
+  TotalSize = 0;\r
+  for (;;)\r
+  {\r
+    UInt32 size = kBufferSize;\r
+    if (outSize != 0)\r
+      if (size > *outSize - TotalSize)\r
+        size = (UInt32)(*outSize - TotalSize);\r
+    RINOK(inStream->Read(_buffer, size, &size));\r
+    if (size == 0)\r
+      break;\r
+    if (outStream)\r
+    {\r
+      RINOK(WriteStream(outStream, _buffer, size));\r
+    }\r
+    TotalSize += size;\r
+    if (progress != NULL)\r
+    {\r
+      RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)\r
+{\r
+  *value = TotalSize;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)\r
+{\r
+  CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;\r
+  return copyCoder->Code(inStream, outStream, NULL, NULL, progress);\r
+}\r
+\r
+}\r
diff --git a/CPP/7zip/Compress/CopyCoder.h b/CPP/7zip/Compress/CopyCoder.h
new file mode 100755 (executable)
index 0000000..16c42ee
--- /dev/null
@@ -0,0 +1,34 @@
+// Compress/CopyCoder.h\r
+\r
+#ifndef __COMPRESS_COPY_CODER_H\r
+#define __COMPRESS_COPY_CODER_H\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+namespace NCompress {\r
+\r
+class CCopyCoder:\r
+  public ICompressCoder,\r
+  public ICompressGetInStreamProcessedSize,\r
+  public CMyUnknownImp\r
+{\r
+  Byte *_buffer;\r
+public:\r
+  UInt64 TotalSize;\r
+  CCopyCoder(): TotalSize(0), _buffer(0) {};\r
+  ~CCopyCoder();\r
+\r
+  MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)\r
+\r
+  STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+      const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);\r
+  STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);\r
+};\r
+\r
+HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/CopyRegister.cpp b/CPP/7zip/Compress/CopyRegister.cpp
new file mode 100755 (executable)
index 0000000..3ef2459
--- /dev/null
@@ -0,0 +1,14 @@
+// CopyRegister.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+#include "CopyCoder.h"\r
+\r
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::CCopyCoder); }\r
+\r
+static CCodecInfo g_CodecInfo =\r
+{ CreateCodec, CreateCodec, 0x00, L"Copy", 1, false };\r
+\r
+REGISTER_CODEC(Copy)\r
diff --git a/CPP/7zip/Compress/DeltaFilter.cpp b/CPP/7zip/Compress/DeltaFilter.cpp
new file mode 100755 (executable)
index 0000000..e7e3822
--- /dev/null
@@ -0,0 +1,112 @@
+// DeltaFilter.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Delta.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+#include "BranchCoder.h"\r
+\r
+struct CDelta\r
+{\r
+  unsigned _delta;\r
+  Byte _state[DELTA_STATE_SIZE];\r
+  CDelta(): _delta(1) {}\r
+  void DeltaInit() { Delta_Init(_state); }\r
+};\r
+\r
+class CDeltaEncoder:\r
+  public ICompressFilter,\r
+  public ICompressSetCoderProperties,\r
+  public ICompressWriteCoderProperties,\r
+  CDelta,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)\r
+  STDMETHOD(Init)();\r
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);\r
+  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);\r
+  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);\r
+};\r
+\r
+class CDeltaDecoder:\r
+  public ICompressFilter,\r
+  public ICompressSetDecoderProperties2,\r
+  CDelta,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)\r
+  STDMETHOD(Init)();\r
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);\r
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);\r
+};\r
+\r
+STDMETHODIMP CDeltaEncoder::Init()\r
+{\r
+  DeltaInit();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP_(UInt32) CDeltaEncoder::Filter(Byte *data, UInt32 size)\r
+{\r
+  Delta_Encode(_state, _delta, data, size);\r
+  return size;\r
+}\r
+\r
+STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)\r
+{\r
+  UInt32 delta = _delta;\r
+  for (UInt32 i = 0; i < numProps; i++)\r
+  {\r
+    const PROPVARIANT &prop = props[i];\r
+    if (propIDs[i] != NCoderPropID::kDefaultProp || prop.vt != VT_UI4 || prop.ulVal < 1 || prop.ulVal > 256)\r
+      return E_INVALIDARG;\r
+    delta = prop.ulVal;\r
+  }\r
+  _delta = delta;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream)\r
+{\r
+  Byte prop = (Byte)(_delta - 1);\r
+  return outStream->Write(&prop, 1, NULL);\r
+}\r
+\r
+STDMETHODIMP CDeltaDecoder::Init()\r
+{\r
+  DeltaInit();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size)\r
+{\r
+  Delta_Decode(_state, _delta, data, size);\r
+  return size;\r
+}\r
+\r
+STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)\r
+{\r
+  if (size != 1)\r
+    return E_INVALIDARG;\r
+  _delta = (unsigned)props[0] + 1;\r
+  return S_OK;\r
+}\r
+\r
+#define CREATE_CODEC(x) \\r
+  static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## Decoder); } \\r
+  static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## Encoder); }\r
+\r
+CREATE_CODEC(Delta)\r
+\r
+#define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true  }\r
+\r
+static CCodecInfo g_CodecsInfo[] =\r
+{\r
+  METHOD_ITEM(Delta, 3, L"Delta")\r
+};\r
+\r
+REGISTER_CODECS(Delta)\r
diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp
new file mode 100755 (executable)
index 0000000..8d3d830
--- /dev/null
@@ -0,0 +1,189 @@
+// Lzma2Decoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "../Common/StreamUtils.h"\r
+\r
+#include "Lzma2Decoder.h"\r
+\r
+static HRESULT SResToHRESULT(SRes res)\r
+{\r
+  switch(res)\r
+  {\r
+    case SZ_OK: return S_OK;\r
+    case SZ_ERROR_MEM: return E_OUTOFMEMORY;\r
+    case SZ_ERROR_PARAM: return E_INVALIDARG;\r
+    // case SZ_ERROR_PROGRESS: return E_ABORT;\r
+    case SZ_ERROR_DATA: return S_FALSE;\r
+  }\r
+  return E_FAIL;\r
+}\r
+\r
+namespace NCompress {\r
+namespace NLzma2 {\r
+\r
+static const UInt32 kInBufSize = 1 << 20;\r
+\r
+CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false)\r
+{\r
+  Lzma2Dec_Construct(&_state);\r
+}\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+CDecoder::~CDecoder()\r
+{\r
+  Lzma2Dec_Free(&_state, &g_Alloc);\r
+  MyFree(_inBuf);\r
+}\r
+\r
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)\r
+{\r
+  if (size != 1) return SZ_ERROR_UNSUPPORTED;\r
+  RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc)));\r
+  if (_inBuf == 0)\r
+  {\r
+    _inBuf = (Byte *)MyAlloc(kInBufSize);\r
+    if (_inBuf == 0)\r
+      return E_OUTOFMEMORY;\r
+  }\r
+\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; }\r
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }\r
+STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }\r
+\r
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)\r
+{\r
+  _outSizeDefined = (outSize != NULL);\r
+  if (_outSizeDefined)\r
+    _outSize = *outSize;\r
+\r
+  Lzma2Dec_Init(&_state);\r
+  \r
+  _inPos = _inSize = 0;\r
+  _inSizeProcessed = _outSizeProcessed = 0;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,\r
+    ISequentialOutStream *outStream, const UInt64 * /* inSize */,\r
+    const UInt64 *outSize, ICompressProgressInfo *progress)\r
+{\r
+  if (_inBuf == 0)\r
+    return S_FALSE;\r
+  SetOutStreamSize(outSize);\r
+\r
+  for (;;)\r
+  {\r
+    if (_inPos == _inSize)\r
+    {\r
+      _inPos = _inSize = 0;\r
+      RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize));\r
+    }\r
+\r
+    SizeT dicPos = _state.decoder.dicPos;\r
+    SizeT curSize = _state.decoder.dicBufSize - dicPos;\r
+    const UInt32 kStepSize = ((UInt32)1 << 22);\r
+    if (curSize > kStepSize)\r
+      curSize = (SizeT)kStepSize;\r
+    \r
+    ELzmaFinishMode finishMode = LZMA_FINISH_ANY;\r
+    if (_outSizeDefined)\r
+    {\r
+      const UInt64 rem = _outSize - _outSizeProcessed;\r
+      if (rem < curSize)\r
+      {\r
+        curSize = (SizeT)rem;\r
+        /*\r
+        // finishMode = LZMA_FINISH_END;\r
+        we can't use LZMA_FINISH_END here to allow partial decoding\r
+        */\r
+      }\r
+    }\r
+\r
+    SizeT inSizeProcessed = _inSize - _inPos;\r
+    ELzmaStatus status;\r
+    SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status);\r
+\r
+    _inPos += (UInt32)inSizeProcessed;\r
+    _inSizeProcessed += inSizeProcessed;\r
+    SizeT outSizeProcessed = _state.decoder.dicPos - dicPos;\r
+    _outSizeProcessed += outSizeProcessed;\r
+\r
+    bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);\r
+    bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);\r
+\r
+    if (res != 0 || _state.decoder.dicPos == _state.decoder.dicBufSize || finished || stopDecoding)\r
+    {\r
+      HRESULT res2 = WriteStream(outStream, _state.decoder.dic, _state.decoder.dicPos);\r
+      if (res != 0)\r
+        return S_FALSE;\r
+      RINOK(res2);\r
+      if (stopDecoding)\r
+        return S_OK;\r
+      if (finished)\r
+        return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);\r
+    }\r
+    if (_state.decoder.dicPos == _state.decoder.dicBufSize)\r
+      _state.decoder.dicPos = 0;\r
+\r
+    if (progress != NULL)\r
+    {\r
+      RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed));\r
+    }\r
+  }\r
+}\r
+\r
+#ifndef NO_READ_FROM_CODER\r
+\r
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize)\r
+    *processedSize = 0;\r
+  do\r
+  {\r
+    if (_inPos == _inSize)\r
+    {\r
+      _inPos = _inSize = 0;\r
+      RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));\r
+    }\r
+    {\r
+      SizeT inProcessed = _inSize - _inPos;\r
+\r
+      if (_outSizeDefined)\r
+      {\r
+        const UInt64 rem = _outSize - _outSizeProcessed;\r
+        if (rem < size)\r
+          size = (UInt32)rem;\r
+      }\r
+\r
+      SizeT outProcessed = size;\r
+      ELzmaStatus status;\r
+      SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,\r
+          _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status);\r
+      _inPos += (UInt32)inProcessed;\r
+      _inSizeProcessed += inProcessed;\r
+      _outSizeProcessed += outProcessed;\r
+      size -= (UInt32)outProcessed;\r
+      data = (Byte *)data + outProcessed;\r
+      if (processedSize)\r
+        *processedSize += (UInt32)outProcessed;\r
+      RINOK(SResToHRESULT(res));\r
+      if (inProcessed == 0 && outProcessed == 0)\r
+        return S_OK;\r
+    }\r
+  }\r
+  while (size != 0);\r
+  return S_OK;\r
+}\r
+\r
+#endif\r
+\r
+}}\r
diff --git a/CPP/7zip/Compress/Lzma2Decoder.h b/CPP/7zip/Compress/Lzma2Decoder.h
new file mode 100755 (executable)
index 0000000..3540097
--- /dev/null
@@ -0,0 +1,73 @@
+// Lzma2Decoder.h\r
+\r
+#ifndef __LZMA2_DECODER_H\r
+#define __LZMA2_DECODER_H\r
+\r
+#include "../../../C/Lzma2Dec.h"\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+namespace NCompress {\r
+namespace NLzma2 {\r
+\r
+class CDecoder:\r
+  public ICompressCoder,\r
+  public ICompressSetDecoderProperties2,\r
+  public ICompressGetInStreamProcessedSize,\r
+  #ifndef NO_READ_FROM_CODER\r
+  public ICompressSetInStream,\r
+  public ICompressSetOutStreamSize,\r
+  public ISequentialInStream,\r
+  #endif\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<ISequentialInStream> _inStream;\r
+  Byte *_inBuf;\r
+  UInt32 _inPos;\r
+  UInt32 _inSize;\r
+  CLzma2Dec _state;\r
+  bool _outSizeDefined;\r
+  UInt64 _outSize;\r
+  UInt64 _inSizeProcessed;\r
+  UInt64 _outSizeProcessed;\r
+public:\r
+\r
+  #ifndef NO_READ_FROM_CODER\r
+  MY_UNKNOWN_IMP5(\r
+      ICompressSetDecoderProperties2,\r
+      ICompressGetInStreamProcessedSize,\r
+      ICompressSetInStream,\r
+      ICompressSetOutStreamSize,\r
+      ISequentialInStream)\r
+  #else\r
+  MY_UNKNOWN_IMP2(\r
+      ICompressSetDecoderProperties2,\r
+      ICompressGetInStreamProcessedSize)\r
+  #endif\r
+\r
+  STDMETHOD(Code)(ISequentialInStream *inStream,\r
+      ISequentialOutStream *outStream, const UInt64 *_inSize, const UInt64 *outSize,\r
+      ICompressProgressInfo *progress);\r
+\r
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);\r
+\r
+  STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);\r
+\r
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream);\r
+  STDMETHOD(ReleaseInStream)();\r
+  STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);\r
+\r
+  #ifndef NO_READ_FROM_CODER\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  #endif\r
+\r
+  CDecoder();\r
+  virtual ~CDecoder();\r
+\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp
new file mode 100755 (executable)
index 0000000..871f146
--- /dev/null
@@ -0,0 +1,94 @@
+// Lzma2Encoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "../Common/CWrappers.h"\r
+#include "../Common/StreamUtils.h"\r
+\r
+#include "Lzma2Encoder.h"\r
+\r
+namespace NCompress {\r
+\r
+namespace NLzma {\r
+\r
+HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep);\r
+\r
+}\r
+\r
+namespace NLzma2 {\r
+\r
+static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }\r
+static void SzBigFree(void *, void *address) { BigFree(address); }\r
+static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };\r
+\r
+static void *SzAlloc(void *, size_t size) { return MyAlloc(size); }\r
+static void SzFree(void *, void *address) { MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+CEncoder::CEncoder()\r
+{\r
+  _encoder = 0;\r
+  _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc);\r
+  if (_encoder == 0)\r
+    throw 1;\r
+}\r
+\r
+CEncoder::~CEncoder()\r
+{\r
+  if (_encoder != 0)\r
+    Lzma2Enc_Destroy(_encoder);\r
+}\r
+\r
+HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props)\r
+{\r
+  switch (propID)\r
+  {\r
+    case NCoderPropID::kBlockSize:\r
+      if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.blockSize = prop.ulVal; break;\r
+    case NCoderPropID::kNumThreads:\r
+      if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break;\r
+    default:\r
+      RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps));\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,\r
+    const PROPVARIANT *coderProps, UInt32 numProps)\r
+{\r
+  CLzma2EncProps lzma2Props;\r
+  Lzma2EncProps_Init(&lzma2Props);\r
+\r
+  for (UInt32 i = 0; i < numProps; i++)\r
+  {\r
+    RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props));\r
+  }\r
+  return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props));\r
+}\r
+\r
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)\r
+{\r
+  Byte prop = Lzma2Enc_WriteProperties(_encoder);\r
+  return WriteStream(outStream, &prop, 1);\r
+}\r
+\r
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+    const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)\r
+{\r
+  CSeqInStreamWrap inWrap(inStream);\r
+  CSeqOutStreamWrap outWrap(outStream);\r
+  CCompressProgressWrap progressWrap(progress);\r
+\r
+  SRes res = Lzma2Enc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL);\r
+  if (res == SZ_ERROR_READ && inWrap.Res != S_OK)\r
+    return inWrap.Res;\r
+  if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)\r
+    return outWrap.Res;\r
+  if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK)\r
+    return progressWrap.Res;\r
+  return SResToHRESULT(res);\r
+}\r
+  \r
+}}\r
diff --git a/CPP/7zip/Compress/Lzma2Encoder.h b/CPP/7zip/Compress/Lzma2Encoder.h
new file mode 100755 (executable)
index 0000000..fc43702
--- /dev/null
@@ -0,0 +1,36 @@
+// Lzma2Encoder.h\r
+\r
+#ifndef __LZMA2_ENCODER_H\r
+#define __LZMA2_ENCODER_H\r
+\r
+#include "../../../C/Lzma2Enc.h"\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+namespace NCompress {\r
+namespace NLzma2 {\r
+\r
+class CEncoder:\r
+  public ICompressCoder,\r
+  public ICompressSetCoderProperties,\r
+  public ICompressWriteCoderProperties,\r
+  public CMyUnknownImp\r
+{\r
+  CLzma2EncHandle _encoder;\r
+public:\r
+  MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)\r
\r
+  STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+      const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);\r
+  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);\r
+  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);\r
+\r
+  CEncoder();\r
+  virtual ~CEncoder();\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/Lzma2Register.cpp b/CPP/7zip/Compress/Lzma2Register.cpp
new file mode 100755 (executable)
index 0000000..28430b4
--- /dev/null
@@ -0,0 +1,20 @@
+// Lzma2Register.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+#include "Lzma2Decoder.h"\r
+\r
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CDecoder); }\r
+#ifndef EXTRACT_ONLY\r
+#include "Lzma2Encoder.h"\r
+static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CEncoder);  }\r
+#else\r
+#define CreateCodecOut 0\r
+#endif\r
+\r
+static CCodecInfo g_CodecInfo =\r
+  { CreateCodec, CreateCodecOut, 0x21, L"LZMA2", 1, false };\r
+\r
+REGISTER_CODEC(LZMA2)\r
diff --git a/CPP/7zip/Compress/LzmaDecoder.cpp b/CPP/7zip/Compress/LzmaDecoder.cpp
new file mode 100755 (executable)
index 0000000..9f15fdb
--- /dev/null
@@ -0,0 +1,252 @@
+// LzmaDecoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "../Common/StreamUtils.h"\r
+\r
+#include "LzmaDecoder.h"\r
+\r
+static HRESULT SResToHRESULT(SRes res)\r
+{\r
+  switch(res)\r
+  {\r
+    case SZ_OK: return S_OK;\r
+    case SZ_ERROR_MEM: return E_OUTOFMEMORY;\r
+    case SZ_ERROR_PARAM: return E_INVALIDARG;\r
+    case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;\r
+    case SZ_ERROR_DATA: return S_FALSE;\r
+  }\r
+  return E_FAIL;\r
+}\r
+\r
+namespace NCompress {\r
+namespace NLzma {\r
+\r
+CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false),\r
+  _inBufSize(1 << 20),\r
+  _outBufSize(1 << 22),\r
+  FinishStream(false)\r
+{\r
+  _inSizeProcessed = 0;\r
+  _inPos = _inSize = 0;\r
+  LzmaDec_Construct(&_state);\r
+}\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+CDecoder::~CDecoder()\r
+{\r
+  LzmaDec_Free(&_state, &g_Alloc);\r
+  MyFree(_inBuf);\r
+}\r
+\r
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }\r
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }\r
+\r
+HRESULT CDecoder::CreateInputBuffer()\r
+{\r
+  if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)\r
+  {\r
+    MyFree(_inBuf);\r
+    _inBuf = (Byte *)MyAlloc(_inBufSize);\r
+    if (_inBuf == 0)\r
+      return E_OUTOFMEMORY;\r
+    _inBufSizeAllocated = _inBufSize;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)\r
+{\r
+  RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc)));\r
+  _propsWereSet = true;\r
+  return CreateInputBuffer();\r
+}\r
+\r
+void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize)\r
+{\r
+  _outSizeDefined = (outSize != NULL);\r
+  if (_outSizeDefined)\r
+    _outSize = *outSize;\r
+  _outSizeProcessed = 0;\r
+  _wrPos = 0;\r
+  LzmaDec_Init(&_state);\r
+}\r
+\r
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)\r
+{\r
+  _inSizeProcessed = 0;\r
+  _inPos = _inSize = 0;\r
+  SetOutStreamSizeResume(outSize);\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)\r
+{\r
+  if (_inBuf == 0 || !_propsWereSet)\r
+    return S_FALSE;\r
+\r
+  UInt64 startInProgress = _inSizeProcessed;\r
+\r
+  SizeT next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);\r
+  for (;;)\r
+  {\r
+    if (_inPos == _inSize)\r
+    {\r
+      _inPos = _inSize = 0;\r
+      RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));\r
+    }\r
+\r
+    SizeT dicPos = _state.dicPos;\r
+    SizeT curSize = next - dicPos;\r
+    \r
+    ELzmaFinishMode finishMode = LZMA_FINISH_ANY;\r
+    if (_outSizeDefined)\r
+    {\r
+      const UInt64 rem = _outSize - _outSizeProcessed;\r
+      if (rem <= curSize)\r
+      {\r
+        curSize = (SizeT)rem;\r
+        if (FinishStream)\r
+          finishMode = LZMA_FINISH_END;\r
+      }\r
+    }\r
+\r
+    SizeT inSizeProcessed = _inSize - _inPos;\r
+    ELzmaStatus status;\r
+    SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status);\r
+\r
+    _inPos += (UInt32)inSizeProcessed;\r
+    _inSizeProcessed += inSizeProcessed;\r
+    SizeT outSizeProcessed = _state.dicPos - dicPos;\r
+    _outSizeProcessed += outSizeProcessed;\r
+\r
+    bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);\r
+    bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);\r
+\r
+    if (res != 0 || _state.dicPos == next || finished || stopDecoding)\r
+    {\r
+      HRESULT res2 = WriteStream(outStream, _state.dic + _wrPos, _state.dicPos - _wrPos);\r
+\r
+      _wrPos = _state.dicPos;\r
+      if (_state.dicPos == _state.dicBufSize)\r
+      {\r
+        _state.dicPos = 0;\r
+        _wrPos = 0;\r
+      }\r
+      next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);\r
+\r
+      if (res != 0)\r
+        return S_FALSE;\r
+      RINOK(res2);\r
+      if (stopDecoding)\r
+        return S_OK;\r
+      if (finished)\r
+        return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);\r
+    }\r
+    if (progress)\r
+    {\r
+      UInt64 inSize = _inSizeProcessed - startInProgress;\r
+      RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed));\r
+    }\r
+  }\r
+}\r
+\r
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+    const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)\r
+{\r
+  if (_inBuf == 0)\r
+    return E_INVALIDARG;\r
+  SetOutStreamSize(outSize);\r
+  return CodeSpec(inStream, outStream, progress);\r
+}\r
+\r
+#ifndef NO_READ_FROM_CODER\r
+\r
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }\r
+STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }\r
+\r
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize)\r
+    *processedSize = 0;\r
+  do\r
+  {\r
+    if (_inPos == _inSize)\r
+    {\r
+      _inPos = _inSize = 0;\r
+      RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));\r
+    }\r
+    {\r
+      SizeT inProcessed = _inSize - _inPos;\r
+\r
+      if (_outSizeDefined)\r
+      {\r
+        const UInt64 rem = _outSize - _outSizeProcessed;\r
+        if (rem < size)\r
+          size = (UInt32)rem;\r
+      }\r
+\r
+      SizeT outProcessed = size;\r
+      ELzmaStatus status;\r
+      SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,\r
+          _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status);\r
+      _inPos += (UInt32)inProcessed;\r
+      _inSizeProcessed += inProcessed;\r
+      _outSizeProcessed += outProcessed;\r
+      size -= (UInt32)outProcessed;\r
+      data = (Byte *)data + outProcessed;\r
+      if (processedSize)\r
+        *processedSize += (UInt32)outProcessed;\r
+      RINOK(SResToHRESULT(res));\r
+      if (inProcessed == 0 && outProcessed == 0)\r
+        return S_OK;\r
+    }\r
+  }\r
+  while (size != 0);\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress)\r
+{\r
+  SetOutStreamSizeResume(outSize);\r
+  return CodeSpec(_inStream, outStream, progress);\r
+}\r
+\r
+HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  RINOK(CreateInputBuffer());\r
+  if (processedSize)\r
+    *processedSize = 0;\r
+  while (size > 0)\r
+  {\r
+    if (_inPos == _inSize)\r
+    {\r
+      _inPos = _inSize = 0;\r
+      RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));\r
+      if (_inSize == 0)\r
+        break;\r
+    }\r
+    {\r
+      UInt32 curSize = _inSize - _inPos;\r
+      if (curSize > size)\r
+        curSize = size;\r
+      memcpy(data, _inBuf + _inPos, curSize);\r
+      _inPos += curSize;\r
+      _inSizeProcessed += curSize;\r
+      size -= curSize;\r
+      data = (Byte *)data + curSize;\r
+      if (processedSize)\r
+        *processedSize += curSize;\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+#endif\r
+\r
+}}\r
diff --git a/CPP/7zip/Compress/LzmaDecoder.h b/CPP/7zip/Compress/LzmaDecoder.h
new file mode 100755 (executable)
index 0000000..801a77b
--- /dev/null
@@ -0,0 +1,84 @@
+// LzmaDecoder.h\r
+\r
+#ifndef __LZMA_DECODER_H\r
+#define __LZMA_DECODER_H\r
+\r
+#include "../../../C/LzmaDec.h"\r
+\r
+#include "../../Common/MyCom.h"\r
+#include "../ICoder.h"\r
+\r
+namespace NCompress {\r
+namespace NLzma {\r
+\r
+class CDecoder:\r
+  public ICompressCoder,\r
+  public ICompressSetDecoderProperties2,\r
+  public ICompressSetBufSize,\r
+  #ifndef NO_READ_FROM_CODER\r
+  public ICompressSetInStream,\r
+  public ICompressSetOutStreamSize,\r
+  public ISequentialInStream,\r
+  #endif\r
+  public CMyUnknownImp\r
+{\r
+  CMyComPtr<ISequentialInStream> _inStream;\r
+  Byte *_inBuf;\r
+  UInt32 _inPos;\r
+  UInt32 _inSize;\r
+  CLzmaDec _state;\r
+  bool _propsWereSet;\r
+  bool _outSizeDefined;\r
+  UInt64 _outSize;\r
+  UInt64 _inSizeProcessed;\r
+  UInt64 _outSizeProcessed;\r
+\r
+  UInt32 _inBufSizeAllocated;\r
+  UInt32 _inBufSize;\r
+  UInt32 _outBufSize;\r
+  SizeT _wrPos;\r
+\r
+  HRESULT CreateInputBuffer();\r
+  HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);\r
+  void SetOutStreamSizeResume(const UInt64 *outSize);\r
+\r
+public:\r
+  MY_QUERYINTERFACE_BEGIN2(ICompressCoder)\r
+  MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)\r
+  MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)\r
+  #ifndef NO_READ_FROM_CODER\r
+  MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)\r
+  MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)\r
+  MY_QUERYINTERFACE_ENTRY(ISequentialInStream)\r
+  #endif\r
+  MY_QUERYINTERFACE_END\r
+  MY_ADDREF_RELEASE\r
+\r
+  STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+      const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);\r
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);\r
+  STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);\r
+  STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);\r
+  STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);\r
+\r
+  #ifndef NO_READ_FROM_CODER\r
+  \r
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream);\r
+  STDMETHOD(ReleaseInStream)();\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+\r
+  HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);\r
+  HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize);\r
+  UInt64 GetInputProcessedSize() const { return _inSizeProcessed; }\r
+\r
+  #endif\r
+\r
+  bool FinishStream;\r
+\r
+  CDecoder();\r
+  virtual ~CDecoder();\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp
new file mode 100755 (executable)
index 0000000..aa96c0e
--- /dev/null
@@ -0,0 +1,149 @@
+// LzmaEncoder.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+\r
+#include "../Common/CWrappers.h"\r
+#include "../Common/StreamUtils.h"\r
+\r
+#include "LzmaEncoder.h"\r
+\r
+namespace NCompress {\r
+namespace NLzma {\r
+\r
+static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }\r
+static void SzBigFree(void *, void *address) { BigFree(address); }\r
+static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };\r
+\r
+static void *SzAlloc(void *, size_t size) { return MyAlloc(size); }\r
+static void SzFree(void *, void *address) { MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+CEncoder::CEncoder()\r
+{\r
+  _encoder = 0;\r
+  _encoder = LzmaEnc_Create(&g_Alloc);\r
+  if (_encoder == 0)\r
+    throw 1;\r
+}\r
+\r
+CEncoder::~CEncoder()\r
+{\r
+  if (_encoder != 0)\r
+    LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc);\r
+}\r
+\r
+inline wchar_t GetUpperChar(wchar_t c)\r
+{\r
+  if (c >= 'a' && c <= 'z')\r
+    c -= 0x20;\r
+  return c;\r
+}\r
+\r
+static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)\r
+{\r
+  wchar_t c = GetUpperChar(*s++);\r
+  if (c == L'H')\r
+  {\r
+    if (GetUpperChar(*s++) != L'C')\r
+      return 0;\r
+    int numHashBytesLoc = (int)(*s++ - L'0');\r
+    if (numHashBytesLoc < 4 || numHashBytesLoc > 4)\r
+      return 0;\r
+    if (*s++ != 0)\r
+      return 0;\r
+    *btMode = 0;\r
+    *numHashBytes = numHashBytesLoc;\r
+    return 1;\r
+  }\r
+  if (c != L'B')\r
+    return 0;\r
+\r
+  if (GetUpperChar(*s++) != L'T')\r
+    return 0;\r
+  int numHashBytesLoc = (int)(*s++ - L'0');\r
+  if (numHashBytesLoc < 2 || numHashBytesLoc > 4)\r
+    return 0;\r
+  c = GetUpperChar(*s++);\r
+  if (c != L'\0')\r
+    return 0;\r
+  *btMode = 1;\r
+  *numHashBytes = numHashBytesLoc;\r
+  return 1;\r
+}\r
+\r
+HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)\r
+{\r
+  if (propID == NCoderPropID::kMatchFinder)\r
+  {\r
+    if (prop.vt != VT_BSTR)\r
+      return E_INVALIDARG;\r
+    return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;\r
+  }\r
+  if (prop.vt != VT_UI4)\r
+    return E_INVALIDARG;\r
+  UInt32 v = prop.ulVal;\r
+  switch (propID)\r
+  {\r
+    case NCoderPropID::kNumFastBytes: ep.fb = v; break;\r
+    case NCoderPropID::kMatchFinderCycles: ep.mc = v; break;\r
+    case NCoderPropID::kAlgorithm: ep.algo = v; break;\r
+    case NCoderPropID::kDictionarySize: ep.dictSize = v; break;\r
+    case NCoderPropID::kPosStateBits: ep.pb = v; break;\r
+    case NCoderPropID::kLitPosBits: ep.lp = v; break;\r
+    case NCoderPropID::kLitContextBits: ep.lc = v; break;\r
+    default: return E_INVALIDARG;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,\r
+    const PROPVARIANT *coderProps, UInt32 numProps)\r
+{\r
+  CLzmaEncProps props;\r
+  LzmaEncProps_Init(&props);\r
+\r
+  for (UInt32 i = 0; i < numProps; i++)\r
+  {\r
+    const PROPVARIANT &prop = coderProps[i];\r
+    PROPID propID = propIDs[i];\r
+    switch (propID)\r
+    {\r
+      case NCoderPropID::kEndMarker:\r
+        if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break;\r
+      case NCoderPropID::kNumThreads:\r
+        if (prop.vt != VT_UI4) return E_INVALIDARG; props.numThreads = prop.ulVal; break;\r
+      default:\r
+        RINOK(SetLzmaProp(propID, prop, props));\r
+    }\r
+  }\r
+  return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props));\r
+}\r
+\r
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)\r
+{\r
+  Byte props[LZMA_PROPS_SIZE];\r
+  size_t size = LZMA_PROPS_SIZE;\r
+  RINOK(LzmaEnc_WriteProperties(_encoder, props, &size));\r
+  return WriteStream(outStream, props, size);\r
+}\r
+\r
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+    const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)\r
+{\r
+  CSeqInStreamWrap inWrap(inStream);\r
+  CSeqOutStreamWrap outWrap(outStream);\r
+  CCompressProgressWrap progressWrap(progress);\r
+\r
+  SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc);\r
+  if (res == SZ_ERROR_READ && inWrap.Res != S_OK)\r
+    return inWrap.Res;\r
+  if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)\r
+    return outWrap.Res;\r
+  if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK)\r
+    return progressWrap.Res;\r
+  return SResToHRESULT(res);\r
+}\r
+  \r
+}}\r
diff --git a/CPP/7zip/Compress/LzmaEncoder.h b/CPP/7zip/Compress/LzmaEncoder.h
new file mode 100755 (executable)
index 0000000..c3e8961
--- /dev/null
@@ -0,0 +1,36 @@
+// LzmaEncoder.h\r
+\r
+#ifndef __LZMA_ENCODER_H\r
+#define __LZMA_ENCODER_H\r
+\r
+#include "../../../C/LzmaEnc.h"\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+namespace NCompress {\r
+namespace NLzma {\r
+\r
+class CEncoder:\r
+  public ICompressCoder,\r
+  public ICompressSetCoderProperties,\r
+  public ICompressWriteCoderProperties,\r
+  public CMyUnknownImp\r
+{\r
+  CLzmaEncHandle _encoder;\r
+public:\r
+  MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)\r
+    \r
+  STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+      const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);\r
+  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);\r
+  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);\r
+\r
+  CEncoder();\r
+  virtual ~CEncoder();\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/LzmaRegister.cpp b/CPP/7zip/Compress/LzmaRegister.cpp
new file mode 100755 (executable)
index 0000000..9c67eaf
--- /dev/null
@@ -0,0 +1,20 @@
+// LzmaRegister.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+#include "LzmaDecoder.h"\r
+\r
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CDecoder); }\r
+#ifndef EXTRACT_ONLY\r
+#include "LzmaEncoder.h"\r
+static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CEncoder);  }\r
+#else\r
+#define CreateCodecOut 0\r
+#endif\r
+\r
+static CCodecInfo g_CodecInfo =\r
+  { CreateCodec, CreateCodecOut, 0x030101, L"LZMA", 1, false };\r
+\r
+REGISTER_CODEC(LZMA)\r
diff --git a/CPP/7zip/Compress/PpmdDecoder.h b/CPP/7zip/Compress/PpmdDecoder.h
new file mode 100755 (executable)
index 0000000..c61d1d0
--- /dev/null
@@ -0,0 +1,78 @@
+// PpmdDecoder.h\r
+// 2009-03-11 : Igor Pavlov : Public domain\r
+\r
+#ifndef __COMPRESS_PPMD_DECODER_H\r
+#define __COMPRESS_PPMD_DECODER_H\r
+\r
+#include "../../../C/Ppmd7.h"\r
+\r
+#include "../../Common/MyCom.h"\r
+\r
+#include "../Common/CWrappers.h"\r
+\r
+#include "../ICoder.h"\r
+\r
+namespace NCompress {\r
+namespace NPpmd {\r
+\r
+class CDecoder :\r
+  public ICompressCoder,\r
+  public ICompressSetDecoderProperties2,\r
+  #ifndef NO_READ_FROM_CODER\r
+  public ICompressSetInStream,\r
+  public ICompressSetOutStreamSize,\r
+  public ISequentialInStream,\r
+  #endif\r
+  public CMyUnknownImp\r
+{\r
+  Byte *_outBuf;\r
+  CPpmd7z_RangeDec _rangeDec;\r
+  CByteInBufWrap _inStream;\r
+  CPpmd7 _ppmd;\r
+\r
+  Byte _order;\r
+  bool _outSizeDefined;\r
+  int _status;\r
+  UInt64 _outSize;\r
+  UInt64 _processedSize;\r
+\r
+  HRESULT CodeSpec(Byte *memStream, UInt32 size);\r
+\r
+public:\r
+\r
+  #ifndef NO_READ_FROM_CODER\r
+  CMyComPtr<ISequentialInStream> InSeqStream;\r
+  MY_UNKNOWN_IMP4(\r
+      ICompressSetDecoderProperties2,\r
+      ICompressSetInStream,\r
+      ICompressSetOutStreamSize,\r
+      ISequentialInStream)\r
+  #else\r
+  MY_UNKNOWN_IMP1(\r
+      ICompressSetDecoderProperties2)\r
+  #endif\r
+\r
+  STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+      const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);\r
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);\r
+  STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);\r
+\r
+  #ifndef NO_READ_FROM_CODER\r
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream);\r
+  STDMETHOD(ReleaseInStream)();\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+  #endif\r
+\r
+  CDecoder(): _outBuf(NULL), _outSizeDefined(false)\r
+  {\r
+    Ppmd7z_RangeDec_CreateVTable(&_rangeDec);\r
+    _rangeDec.Stream = &_inStream.p;\r
+    Ppmd7_Construct(&_ppmd);\r
+  }\r
+\r
+  ~CDecoder();\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp
new file mode 100755 (executable)
index 0000000..3a8df78
--- /dev/null
@@ -0,0 +1,119 @@
+// PpmdEncoder.cpp\r
+// 2009-03-11 : Igor Pavlov : Public domain\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../C/Alloc.h"\r
+#include "../../../C/CpuArch.h"\r
+\r
+#include "../Common/StreamUtils.h"\r
+\r
+#include "PpmdEncoder.h"\r
+\r
+namespace NCompress {\r
+namespace NPpmd {\r
+\r
+static const UInt32 kBufSize = (1 << 20);\r
+\r
+static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }\r
+static void SzBigFree(void *, void *address) { BigFree(address); }\r
+static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };\r
+\r
+CEncoder::CEncoder():\r
+  _inBuf(NULL),\r
+  _usedMemSize(1 << 24),\r
+  _order(6)\r
+{\r
+  _rangeEnc.Stream = &_outStream.p;\r
+  Ppmd7_Construct(&_ppmd);\r
+}\r
+\r
+CEncoder::~CEncoder()\r
+{\r
+  ::MidFree(_inBuf);\r
+  Ppmd7_Free(&_ppmd, &g_BigAlloc);\r
+}\r
+\r
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)\r
+{\r
+  for (UInt32 i = 0; i < numProps; i++)\r
+  {\r
+    const PROPVARIANT &prop = props[i];\r
+    if (prop.vt != VT_UI4)\r
+      return E_INVALIDARG;\r
+    UInt32 v = (UInt32)prop.ulVal;\r
+    switch(propIDs[i])\r
+    {\r
+      case NCoderPropID::kUsedMemorySize:\r
+        if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0)\r
+          return E_INVALIDARG;\r
+        _usedMemSize = v;\r
+        break;\r
+      case NCoderPropID::kOrder:\r
+        if (v < 2 || v > 32)\r
+          return E_INVALIDARG;\r
+        _order = (Byte)v;\r
+        break;\r
+      default:\r
+        return E_INVALIDARG;\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)\r
+{\r
+  const UInt32 kPropSize = 5;\r
+  Byte props[kPropSize];\r
+  props[0] = _order;\r
+  SetUi32(props + 1, _usedMemSize);\r
+  return WriteStream(outStream, props, kPropSize);\r
+}\r
+\r
+HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+    const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)\r
+{\r
+  if (!_inBuf)\r
+  {\r
+    _inBuf = (Byte *)::MidAlloc(kBufSize);\r
+    if (!_inBuf)\r
+      return E_OUTOFMEMORY;\r
+  }\r
+  if (!_outStream.Alloc(1 << 20))\r
+    return E_OUTOFMEMORY;\r
+  if (!Ppmd7_Alloc(&_ppmd, _usedMemSize, &g_BigAlloc))\r
+    return E_OUTOFMEMORY;\r
+\r
+  _outStream.Stream = outStream;\r
+  _outStream.Init();\r
+\r
+  Ppmd7z_RangeEnc_Init(&_rangeEnc);\r
+  Ppmd7_Init(&_ppmd, _order);\r
+\r
+  UInt64 processed = 0;\r
+  for (;;)\r
+  {\r
+    UInt32 size;\r
+    RINOK(inStream->Read(_inBuf, kBufSize, &size));\r
+    if (size == 0)\r
+    {\r
+      // We don't write EndMark in PPMD-7z.\r
+      // Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, -1);\r
+      Ppmd7z_RangeEnc_FlushData(&_rangeEnc);\r
+      return _outStream.Flush();\r
+    }\r
+    for (UInt32 i = 0; i < size; i++)\r
+    {\r
+      Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, _inBuf[i]);\r
+      RINOK(_outStream.Res);\r
+    }\r
+    processed += size;\r
+    if (progress)\r
+    {\r
+      UInt64 outSize = _outStream.GetProcessed();\r
+      RINOK(progress->SetRatioInfo(&processed, &outSize));\r
+    }\r
+  }\r
+}\r
+\r
+}}\r
diff --git a/CPP/7zip/Compress/PpmdRegister.cpp b/CPP/7zip/Compress/PpmdRegister.cpp
new file mode 100755 (executable)
index 0000000..e2fd007
--- /dev/null
@@ -0,0 +1,21 @@
+// PpmdRegister.cpp\r
+// 2009-05-30 : Igor Pavlov : Public domain\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../Common/RegisterCodec.h"\r
+\r
+#include "PpmdDecoder.h"\r
+\r
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NPpmd::CDecoder); }\r
+#ifndef EXTRACT_ONLY\r
+#include "PpmdEncoder.h"\r
+static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NPpmd::CEncoder);  }\r
+#else\r
+#define CreateCodecOut 0\r
+#endif\r
+\r
+static CCodecInfo g_CodecInfo =\r
+  { CreateCodec, CreateCodecOut, 0x030401, L"PPMD", 1, false };\r
+\r
+REGISTER_CODEC(PPMD)\r
diff --git a/CPP/7zip/Compress/RangeCoder.h b/CPP/7zip/Compress/RangeCoder.h
new file mode 100755 (executable)
index 0000000..e9e8e32
--- /dev/null
@@ -0,0 +1,205 @@
+// Compress/RangeCoder.h\r
+// 2009-05-30 : Igor Pavlov : Public domain\r
+\r
+#ifndef __COMPRESS_RANGE_CODER_H\r
+#define __COMPRESS_RANGE_CODER_H\r
+\r
+#include "../Common/InBuffer.h"\r
+#include "../Common/OutBuffer.h"\r
+\r
+namespace NCompress {\r
+namespace NRangeCoder {\r
+\r
+const int kNumTopBits = 24;\r
+const UInt32 kTopValue = (1 << kNumTopBits);\r
+\r
+class CEncoder\r
+{\r
+  UInt32 _cacheSize;\r
+  Byte _cache;\r
+public:\r
+  UInt64 Low;\r
+  UInt32 Range;\r
+  COutBuffer Stream;\r
+  bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }\r
+\r
+  void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }\r
+  void Init()\r
+  {\r
+    Stream.Init();\r
+    Low = 0;\r
+    Range = 0xFFFFFFFF;\r
+    _cacheSize = 1;\r
+    _cache = 0;\r
+  }\r
+\r
+  void FlushData()\r
+  {\r
+    // Low += 1;\r
+    for(int i = 0; i < 5; i++)\r
+      ShiftLow();\r
+  }\r
+\r
+  HRESULT FlushStream() { return Stream.Flush();  }\r
+\r
+  void ReleaseStream() { Stream.ReleaseStream(); }\r
+\r
+  void Encode(UInt32 start, UInt32 size, UInt32 total)\r
+  {\r
+    Low += start * (Range /= total);\r
+    Range *= size;\r
+    while (Range < kTopValue)\r
+    {\r
+      Range <<= 8;\r
+      ShiftLow();\r
+    }\r
+  }\r
+\r
+  void ShiftLow()\r
+  {\r
+    if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)\r
+    {\r
+      Byte temp = _cache;\r
+      do\r
+      {\r
+        Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));\r
+        temp = 0xFF;\r
+      }\r
+      while(--_cacheSize != 0);\r
+      _cache = (Byte)((UInt32)Low >> 24);\r
+    }\r
+    _cacheSize++;\r
+    Low = (UInt32)Low << 8;\r
+  }\r
+  \r
+  void EncodeDirectBits(UInt32 value, int numBits)\r
+  {\r
+    for (numBits--; numBits >= 0; numBits--)\r
+    {\r
+      Range >>= 1;\r
+      Low += Range & (0 - ((value >> numBits) & 1));\r
+      if (Range < kTopValue)\r
+      {\r
+        Range <<= 8;\r
+        ShiftLow();\r
+      }\r
+    }\r
+  }\r
+\r
+  void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)\r
+  {\r
+    UInt32 newBound = (Range >> numTotalBits) * size0;\r
+    if (symbol == 0)\r
+      Range = newBound;\r
+    else\r
+    {\r
+      Low += newBound;\r
+      Range -= newBound;\r
+    }\r
+    while (Range < kTopValue)\r
+    {\r
+      Range <<= 8;\r
+      ShiftLow();\r
+    }\r
+  }\r
+\r
+  UInt64 GetProcessedSize() {  return Stream.GetProcessedSize() + _cacheSize + 4; }\r
+};\r
+\r
+class CDecoder\r
+{\r
+public:\r
+  CInBuffer Stream;\r
+  UInt32 Range;\r
+  UInt32 Code;\r
+  bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }\r
+\r
+  void Normalize()\r
+  {\r
+    while (Range < kTopValue)\r
+    {\r
+      Code = (Code << 8) | Stream.ReadByte();\r
+      Range <<= 8;\r
+    }\r
+  }\r
+  \r
+  void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }\r
+  void Init()\r
+  {\r
+    Stream.Init();\r
+    Code = 0;\r
+    Range = 0xFFFFFFFF;\r
+    for(int i = 0; i < 5; i++)\r
+      Code = (Code << 8) | Stream.ReadByte();\r
+  }\r
+\r
+  void ReleaseStream() { Stream.ReleaseStream(); }\r
+\r
+  UInt32 GetThreshold(UInt32 total)\r
+  {\r
+    return (Code) / ( Range /= total);\r
+  }\r
+\r
+  void Decode(UInt32 start, UInt32 size)\r
+  {\r
+    Code -= start * Range;\r
+    Range *= size;\r
+    Normalize();\r
+  }\r
+\r
+  UInt32 DecodeDirectBits(int numTotalBits)\r
+  {\r
+    UInt32 range = Range;\r
+    UInt32 code = Code;\r
+    UInt32 result = 0;\r
+    for (int i = numTotalBits; i != 0; i--)\r
+    {\r
+      range >>= 1;\r
+      /*\r
+      result <<= 1;\r
+      if (code >= range)\r
+      {\r
+        code -= range;\r
+        result |= 1;\r
+      }\r
+      */\r
+      UInt32 t = (code - range) >> 31;\r
+      code -= range & (t - 1);\r
+      result = (result << 1) | (1 - t);\r
+\r
+      if (range < kTopValue)\r
+      {\r
+        code = (code << 8) | Stream.ReadByte();\r
+        range <<= 8;\r
+      }\r
+    }\r
+    Range = range;\r
+    Code = code;\r
+    return result;\r
+  }\r
+\r
+  UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)\r
+  {\r
+    UInt32 newBound = (Range >> numTotalBits) * size0;\r
+    UInt32 symbol;\r
+    if (Code < newBound)\r
+    {\r
+      symbol = 0;\r
+      Range = newBound;\r
+    }\r
+    else\r
+    {\r
+      symbol = 1;\r
+      Code -= newBound;\r
+      Range -= newBound;\r
+    }\r
+    Normalize();\r
+    return symbol;\r
+  }\r
+\r
+  UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/RangeCoderBit.h b/CPP/7zip/Compress/RangeCoderBit.h
new file mode 100755 (executable)
index 0000000..f06408c
--- /dev/null
@@ -0,0 +1,114 @@
+// Compress/RangeCoderBit.h\r
+// 2009-05-30 : Igor Pavlov : Public domain\r
+\r
+#ifndef __COMPRESS_RANGE_CODER_BIT_H\r
+#define __COMPRESS_RANGE_CODER_BIT_H\r
+\r
+#include "RangeCoder.h"\r
+\r
+namespace NCompress {\r
+namespace NRangeCoder {\r
+\r
+const int kNumBitModelTotalBits  = 11;\r
+const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);\r
+\r
+const int kNumMoveReducingBits = 4;\r
+\r
+const int kNumBitPriceShiftBits = 4;\r
+const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;\r
+\r
+extern UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];\r
+\r
+template <int numMoveBits>\r
+class CBitModel\r
+{\r
+public:\r
+  UInt32 Prob;\r
+  void UpdateModel(UInt32 symbol)\r
+  {\r
+    /*\r
+    Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;\r
+    Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);\r
+    */\r
+    if (symbol == 0)\r
+      Prob += (kBitModelTotal - Prob) >> numMoveBits;\r
+    else\r
+      Prob -= (Prob) >> numMoveBits;\r
+  }\r
+public:\r
+  void Init() { Prob = kBitModelTotal / 2; }\r
+};\r
+\r
+template <int numMoveBits>\r
+class CBitEncoder: public CBitModel<numMoveBits>\r
+{\r
+public:\r
+  void Encode(CEncoder *encoder, UInt32 symbol)\r
+  {\r
+    /*\r
+    encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);\r
+    this->UpdateModel(symbol);\r
+    */\r
+    UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;\r
+    if (symbol == 0)\r
+    {\r
+      encoder->Range = newBound;\r
+      this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;\r
+    }\r
+    else\r
+    {\r
+      encoder->Low += newBound;\r
+      encoder->Range -= newBound;\r
+      this->Prob -= (this->Prob) >> numMoveBits;\r
+    }\r
+    if (encoder->Range < kTopValue)\r
+    {\r
+      encoder->Range <<= 8;\r
+      encoder->ShiftLow();\r
+    }\r
+  }\r
+  UInt32 GetPrice(UInt32 symbol) const\r
+  {\r
+    return ProbPrices[(this->Prob ^ ((-(int)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];\r
+  }\r
+  UInt32 GetPrice0() const { return ProbPrices[this->Prob >> kNumMoveReducingBits]; }\r
+  UInt32 GetPrice1() const { return ProbPrices[(this->Prob ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]; }\r
+};\r
+\r
+\r
+template <int numMoveBits>\r
+class CBitDecoder: public CBitModel<numMoveBits>\r
+{\r
+public:\r
+  UInt32 Decode(CDecoder *decoder)\r
+  {\r
+    UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;\r
+    if (decoder->Code < newBound)\r
+    {\r
+      decoder->Range = newBound;\r
+      this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;\r
+      if (decoder->Range < kTopValue)\r
+      {\r
+        decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();\r
+        decoder->Range <<= 8;\r
+      }\r
+      return 0;\r
+    }\r
+    else\r
+    {\r
+      decoder->Range -= newBound;\r
+      decoder->Code -= newBound;\r
+      this->Prob -= (this->Prob) >> numMoveBits;\r
+      if (decoder->Range < kTopValue)\r
+      {\r
+        decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();\r
+        decoder->Range <<= 8;\r
+      }\r
+      return 1;\r
+    }\r
+  }\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/7zip/Compress/StdAfx.h b/CPP/7zip/Compress/StdAfx.h
new file mode 100755 (executable)
index 0000000..c28ffce
--- /dev/null
@@ -0,0 +1,8 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../Common/MyWindows.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/Crc.mak b/CPP/7zip/Crc.mak
new file mode 100755 (executable)
index 0000000..444f8fe
--- /dev/null
@@ -0,0 +1,8 @@
+C_OBJS = $(C_OBJS) \\r
+  $O\7zCrc.obj\r
+!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS"\r
+C_OBJS = $(C_OBJS) \\r
+!ELSE\r
+ASM_OBJS = $(ASM_OBJS) \\r
+!ENDIF\r
+  $O\7zCrcOpt.obj\r
diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt
new file mode 100755 (executable)
index 0000000..cbd45a4
--- /dev/null
@@ -0,0 +1,170 @@
+{23170F69-40C1-278A-0000-00yy00xx0000}\r
+\r
+00 IProgress.h\r
+\r
+  05  IProgress\r
+\r
+01 IFolderArchive.h\r
+\r
+  05  IArchiveFolder\r
+  // 06  IInFolderArchive // old\r
+  07  IFileExtractCallback.h::IFolderArchiveExtractCallback\r
+  0A  IOutFolderArchive\r
+  0B  IFolderArchiveUpdateCallback\r
+  0C  Agent.h::IArchiveFolderInternal\r
+  0D\r
+  0E  IInFolderArchive\r
+\r
+03 IStream.h\r
+\r
+  01  ISequentialInStream\r
+  02  ISequentialOutStream\r
+  03  IInStream\r
+  04  IOutStream\r
+  06  IStreamGetSize\r
+  07  IOutStreamFlush\r
+\r
+\r
+04 ICoder.h\r
+\r
+  04  ICompressProgressInfo\r
+  05  ICompressCoder\r
+  18  ICompressCoder2\r
+  20  ICompressSetCoderProperties\r
+  21  ICompressSetDecoderProperties //\r
+  22  ICompressSetDecoderProperties2\r
+  23  ICompressWriteCoderProperties\r
+  24  ICompressGetInStreamProcessedSize\r
+  25  ICompressSetCoderMt\r
+  30  ICompressGetSubStreamSize\r
+  31  ICompressSetInStream\r
+  32  ICompressSetOutStream\r
+  33  ICompressSetInStreamSize\r
+  34  ICompressSetOutStreamSize\r
+  35  ICompressSetBufSize\r
+  40  ICompressFilter\r
+  60  ICompressCodecsInfo\r
+  61  ISetCompressCodecsInfo\r
+  80  ICryptoProperties\r
+  88  ICryptoResetSalt\r
+  8C  ICryptoResetInitVector\r
+  90  ICryptoSetPassword\r
+  A0  ICryptoSetCRC\r
+\r
+\r
+05 IPassword.h\r
+\r
+  10 ICryptoGetTextPassword\r
+  11 ICryptoGetTextPassword2\r
+\r
+\r
+06 IArchive.h\r
+\r
+  03  ISetProperties\r
+\r
+  10  IArchiveOpenCallback\r
+  20  IArchiveExtractCallback\r
+  30  IArchiveOpenVolumeCallback\r
+  40  IInArchiveGetStream\r
+  50  IArchiveOpenSetSubArchiveName\r
+  60  IInArchive\r
+  61  IArchiveOpenSeq\r
+\r
+  80  IArchiveUpdateCallback\r
+  82  IArchiveUpdateCallback2\r
+  A0  IOutArchive\r
+\r
+\r
+\r
+08 IFolder.h\r
+\r
+  00 IFolderFolder\r
+  01 IEnumProperties\r
+  02 IFolderGetTypeID\r
+  03 IFolderGetPath\r
+  04 IFolderWasChanged\r
+  05 // IFolderReload\r
+  06 IFolderOperations\r
+  07 IFolderGetSystemIconIndex\r
+  08 IFolderGetItemFullSize\r
+  09 IFolderClone\r
+  0A IFolderSetFlatMode\r
+  0B IFolderOperationsExtractCallback\r
+  0C // \r
+  0D // \r
+  0E IFolderProperties\r
+  0F \r
+  10 IFolderArcProps\r
+  11 IGetFolderArcProps\r
+\r
+\r
+09 IFolder.h :: FOLDER_MANAGER_INTERFACE\r
+\r
+  00 - 04 // old IFolderManager\r
+  05 IFolderManager\r
+\r
+\r
+// 0A PluginInterface.h\r
+  00 IInitContextMenu\r
+  01 IPluginOptionsCallback\r
+  02 IPluginOptions\r
+\r
+\r
+Handler GUIDs:\r
+\r
+{23170F69-40C1-278A-1000-000110xx0000}\r
+\r
+  01 Zip\r
+  02 BZip2\r
+  03 Rar\r
+  04 Arj\r
+  05 Z\r
+  06 Lzh\r
+  07 7z\r
+  08 Cab\r
+  09 Nsis\r
+  0A lzma\r
+  0B lzma86\r
+  0C xz\r
+  0D ppmd\r
+\r
+  D2 SquashFS\r
+  D3 CramFS\r
+  D4 APM\r
+  D5 Mslz\r
+  D6 Flv\r
+  D7 Swf\r
+  D8 Swfc\r
+  D9 Ntfs\r
+  DA Fat\r
+  DB Mbr\r
+  DC Vhd\r
+  DD Pe\r
+  DE Elf\r
+  DF Mach-O\r
+  E0 Udf\r
+  E1 Xar\r
+  E2 Mub\r
+  E3 Hfs\r
+  E4 Dmg\r
+  E5 Compound\r
+  E6 Wim\r
+  E7 Iso\r
+  E8 Bkf\r
+  E9 Chm\r
+  EA Split\r
+  EB Rpm\r
+  EC Deb\r
+  ED Cpio\r
+  EE Tar\r
+  EF GZip\r
+\r
+{23170F69-40C1-278A-1000-000100030000} CAgentArchiveHandle\r
+{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu\r
+\r
+{23170F69-40C1-278B- old codecs clsids\r
+\r
+{23170F69-40C1-278D-1000-000100020000} OptionsDialog.h::CLSID_CSevenZipOptions\r
+\r
+{23170F69-40C1-2790-id} Codec Decoders\r
+{23170F69-40C1-2791-id} Codec Encoders\r
diff --git a/CPP/7zip/ICoder.h b/CPP/7zip/ICoder.h
new file mode 100755 (executable)
index 0000000..cb74f98
--- /dev/null
@@ -0,0 +1,186 @@
+// ICoder.h\r
+\r
+#ifndef __ICODER_H\r
+#define __ICODER_H\r
+\r
+#include "IStream.h"\r
+\r
+#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x)\r
+\r
+CODER_INTERFACE(ICompressProgressInfo, 0x04)\r
+{\r
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressCoder, 0x05)\r
+{\r
+  STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
+      const UInt64 *inSize, const UInt64 *outSize,\r
+      ICompressProgressInfo *progress) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressCoder2, 0x18)\r
+{\r
+  STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,\r
+      ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,\r
+      ICompressProgressInfo *progress) PURE;\r
+};\r
+\r
+namespace NCoderPropID\r
+{\r
+  enum EEnum\r
+  {\r
+    kDefaultProp = 0,\r
+    kDictionarySize,\r
+    kUsedMemorySize,\r
+    kOrder,\r
+    kBlockSize,\r
+    kPosStateBits,\r
+    kLitContextBits,\r
+    kLitPosBits,\r
+    kNumFastBytes,\r
+    kMatchFinder,\r
+    kMatchFinderCycles,\r
+    kNumPasses,\r
+    kAlgorithm,\r
+    kNumThreads,\r
+    kEndMarker\r
+  };\r
+}\r
+\r
+CODER_INTERFACE(ICompressSetCoderProperties, 0x20)\r
+{\r
+  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE;\r
+};\r
+\r
+/*\r
+CODER_INTERFACE(ICompressSetCoderProperties, 0x21)\r
+{\r
+  STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;\r
+};\r
+*/\r
+\r
+CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)\r
+{\r
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)\r
+{\r
+  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)\r
+{\r
+  STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressSetCoderMt, 0x25)\r
+{\r
+  STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)\r
+{\r
+  STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressSetInStream, 0x31)\r
+{\r
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;\r
+  STDMETHOD(ReleaseInStream)() PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressSetOutStream, 0x32)\r
+{\r
+  STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;\r
+  STDMETHOD(ReleaseOutStream)() PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressSetInStreamSize, 0x33)\r
+{\r
+  STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)\r
+{\r
+  STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressSetBufSize, 0x35)\r
+{\r
+  STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size) PURE;\r
+  STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICompressFilter, 0x40)\r
+{\r
+  STDMETHOD(Init)() PURE;\r
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;\r
+  // Filter converts as most as possible bytes\r
+  // Filter return outSize (UInt32)\r
+  // if (outSize <= size): Filter have converted outSize bytes\r
+  // if (outSize > size): Filter have not converted anything.\r
+  //      and it needs at least outSize bytes to convert one block\r
+  //      (it's for crypto block algorithms).\r
+};\r
+\r
+CODER_INTERFACE(ICompressCodecsInfo, 0x60)\r
+{\r
+  STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods) PURE;\r
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;\r
+  STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE;\r
+  STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE;\r
+};\r
+CODER_INTERFACE(ISetCompressCodecsInfo, 0x61)\r
+{\r
+  STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICryptoProperties, 0x80)\r
+{\r
+  STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;\r
+  STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;\r
+};\r
+\r
+/*\r
+CODER_INTERFACE(ICryptoResetSalt, 0x88)\r
+{\r
+  STDMETHOD(ResetSalt)() PURE;\r
+};\r
+*/\r
+\r
+CODER_INTERFACE(ICryptoResetInitVector, 0x8C)\r
+{\r
+  STDMETHOD(ResetInitVector)() PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICryptoSetPassword, 0x90)\r
+{\r
+  STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;\r
+};\r
+\r
+CODER_INTERFACE(ICryptoSetCRC, 0xA0)\r
+{\r
+  STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;\r
+};\r
+\r
+//////////////////////\r
+// It's for DLL file\r
+namespace NMethodPropID\r
+{\r
+  enum EEnum\r
+  {\r
+    kID,\r
+    kName,\r
+    kDecoder,\r
+    kEncoder,\r
+    kInStreams,\r
+    kOutStreams,\r
+    kDescription,\r
+    kDecoderIsAssigned,\r
+    kEncoderIsAssigned\r
+  };\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/IDecl.h b/CPP/7zip/IDecl.h
new file mode 100755 (executable)
index 0000000..768bbe7
--- /dev/null
@@ -0,0 +1,15 @@
+// IDecl.h\r
+\r
+#ifndef __IDECL_H\r
+#define __IDECL_H\r
+\r
+#include "../Common/MyUnknown.h"\r
+\r
+#define DECL_INTERFACE_SUB(i, base, groupId, subId) \\r
+DEFINE_GUID(IID_ ## i, \\r
+0x23170F69, 0x40C1, 0x278A, 0, 0, 0, (groupId), 0, (subId), 0, 0); \\r
+struct i: public base\r
+\r
+#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId)\r
+\r
+#endif\r
diff --git a/CPP/7zip/IPassword.h b/CPP/7zip/IPassword.h
new file mode 100755 (executable)
index 0000000..5679d84
--- /dev/null
@@ -0,0 +1,24 @@
+// IPassword.h\r
+\r
+#ifndef __IPASSWORD_H\r
+#define __IPASSWORD_H\r
+\r
+#include "../Common/MyUnknown.h"\r
+#include "../Common/Types.h"\r
+\r
+#include "IDecl.h"\r
+\r
+#define PASSWORD_INTERFACE(i, x) DECL_INTERFACE(i, 5, x)\r
+\r
+PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10)\r
+{\r
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE;\r
+};\r
+\r
+PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)\r
+{\r
+  STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE;\r
+};\r
+\r
+#endif\r
+\r
diff --git a/CPP/7zip/IProgress.h b/CPP/7zip/IProgress.h
new file mode 100755 (executable)
index 0000000..09486ba
--- /dev/null
@@ -0,0 +1,33 @@
+// Interface/IProgress.h\r
+\r
+#ifndef __IPROGRESS_H\r
+#define __IPROGRESS_H\r
+\r
+#include "../Common/MyUnknown.h"\r
+#include "../Common/Types.h"\r
+\r
+#include "IDecl.h"\r
+\r
+#define INTERFACE_IProgress(x) \\r
+  STDMETHOD(SetTotal)(UInt64 total) x; \\r
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \\r
+\r
+DECL_INTERFACE(IProgress, 0, 5)\r
+{\r
+  INTERFACE_IProgress(PURE)\r
+};\r
+\r
+/*\r
+// {23170F69-40C1-278A-0000-000000050002}\r
+DEFINE_GUID(IID_IProgress2,\r
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02);\r
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002")\r
+IProgress2: public IUnknown\r
+{\r
+public:\r
+  STDMETHOD(SetTotal)(const UInt64 *total) PURE;\r
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;\r
+};\r
+*/\r
+\r
+#endif\r
diff --git a/CPP/7zip/IStream.h b/CPP/7zip/IStream.h
new file mode 100755 (executable)
index 0000000..89f02f5
--- /dev/null
@@ -0,0 +1,58 @@
+// IStream.h\r
+\r
+#ifndef __ISTREAM_H\r
+#define __ISTREAM_H\r
+\r
+#include "../Common/MyUnknown.h"\r
+#include "../Common/Types.h"\r
+\r
+#include "IDecl.h"\r
+\r
+#define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x)\r
+#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)\r
+\r
+STREAM_INTERFACE(ISequentialInStream, 0x01)\r
+{\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;\r
+  /*\r
+  Out: if size != 0, return_value = S_OK and (*processedSize == 0),\r
+    then there are no more bytes in stream.\r
+  if (size > 0) && there are bytes in stream,\r
+  this function must read at least 1 byte.\r
+  This function is allowed to read less than number of remaining bytes in stream.\r
+  You must call Read function in loop, if you need exact amount of data\r
+  */\r
+};\r
+\r
+STREAM_INTERFACE(ISequentialOutStream, 0x02)\r
+{\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;\r
+  /*\r
+  if (size > 0) this function must write at least 1 byte.\r
+  This function is allowed to write less than "size".\r
+  You must call Write function in loop, if you need to write exact amount of data\r
+  */\r
+};\r
+\r
+STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)\r
+{\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;\r
+};\r
+\r
+STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)\r
+{\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;\r
+  STDMETHOD(SetSize)(UInt64 newSize) PURE;\r
+};\r
+\r
+STREAM_INTERFACE(IStreamGetSize, 0x06)\r
+{\r
+  STDMETHOD(GetSize)(UInt64 *size) PURE;\r
+};\r
+\r
+STREAM_INTERFACE(IOutStreamFlush, 0x07)\r
+{\r
+  STDMETHOD(Flush)() PURE;\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h
new file mode 100755 (executable)
index 0000000..f549249
--- /dev/null
@@ -0,0 +1,8 @@
+#define MY_VER_MAJOR 9\r
+#define MY_VER_MINOR 20\r
+#define MY_VER_BUILD 0\r
+#define MY_VERSION "9.20"\r
+#define MY_7ZIP_VERSION "7-Zip 9.20"\r
+#define MY_DATE "2010-11-18"\r
+#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov"\r
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION "  " MY_COPYRIGHT "  " MY_DATE\r
diff --git a/CPP/7zip/MyVersionInfo.rc b/CPP/7zip/MyVersionInfo.rc
new file mode 100755 (executable)
index 0000000..84e4ac3
--- /dev/null
@@ -0,0 +1,52 @@
+#define MY_VS_FFI_FILEFLAGSMASK  0x0000003FL\r
+#define MY_VOS_NT_WINDOWS32  0x00040004L\r
+#define MY_VOS_CE_WINDOWS32  0x00050004L\r
+\r
+#define MY_VFT_APP  0x00000001L\r
+#define MY_VFT_DLL  0x00000002L\r
+\r
+// #include <WinVer.h>\r
+#include "MyVersion.h"\r
+\r
+#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0\r
+\r
+#ifdef DEBUG\r
+#define DBG_FL VS_FF_DEBUG\r
+#else\r
+#define DBG_FL 0\r
+#endif\r
+\r
+#define MY_VERSION_INFO(fileType, descr, intName, origName)  \\r
+LANGUAGE 9, 1 \\r
+1 VERSIONINFO \\r
+  FILEVERSION MY_VER \\r
+  PRODUCTVERSION MY_VER \\r
+  FILEFLAGSMASK MY_VS_FFI_FILEFLAGSMASK \\r
+  FILEFLAGS DBG_FL \\r
+  FILEOS MY_VOS_NT_WINDOWS32 \\r
+  FILETYPE fileType \\r
+  FILESUBTYPE 0x0L \\r
+BEGIN \\r
+    BLOCK "StringFileInfo" \\r
+    BEGIN  \\r
+        BLOCK "040904b0" \\r
+        BEGIN \\r
+            VALUE "CompanyName", "Igor Pavlov" \\r
+            VALUE "FileDescription", descr \\r
+            VALUE "FileVersion", MY_VERSION  \\r
+            VALUE "InternalName", intName \\r
+            VALUE "LegalCopyright", MY_COPYRIGHT \\r
+            VALUE "OriginalFilename", origName \\r
+            VALUE "ProductName", "7-Zip" \\r
+            VALUE "ProductVersion", MY_VERSION \\r
+        END \\r
+    END \\r
+    BLOCK "VarFileInfo" \\r
+    BEGIN \\r
+        VALUE "Translation", 0x409, 1200 \\r
+    END \\r
+END\r
+\r
+#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(MY_VFT_APP, descr, intName, intName ".exe")\r
+\r
+#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(MY_VFT_DLL, descr, intName, intName ".dll")\r
diff --git a/CPP/7zip/PropID.h b/CPP/7zip/PropID.h
new file mode 100755 (executable)
index 0000000..1aabc65
--- /dev/null
@@ -0,0 +1,76 @@
+// PropID.h\r
+\r
+#ifndef __7ZIP_PROPID_H\r
+#define __7ZIP_PROPID_H\r
+\r
+enum\r
+{\r
+  kpidNoProperty = 0,\r
+  kpidMainSubfile = 1,\r
+  kpidHandlerItemIndex = 2,\r
+  kpidPath,\r
+  kpidName,\r
+  kpidExtension,\r
+  kpidIsDir,\r
+  kpidSize,\r
+  kpidPackSize,\r
+  kpidAttrib,\r
+  kpidCTime,\r
+  kpidATime,\r
+  kpidMTime,\r
+  kpidSolid,\r
+  kpidCommented,\r
+  kpidEncrypted,\r
+  kpidSplitBefore,\r
+  kpidSplitAfter,\r
+  kpidDictionarySize,\r
+  kpidCRC,\r
+  kpidType,\r
+  kpidIsAnti,\r
+  kpidMethod,\r
+  kpidHostOS,\r
+  kpidFileSystem,\r
+  kpidUser,\r
+  kpidGroup,\r
+  kpidBlock,\r
+  kpidComment,\r
+  kpidPosition,\r
+  kpidPrefix,\r
+  kpidNumSubDirs,\r
+  kpidNumSubFiles,\r
+  kpidUnpackVer,\r
+  kpidVolume,\r
+  kpidIsVolume,\r
+  kpidOffset,\r
+  kpidLinks,\r
+  kpidNumBlocks,\r
+  kpidNumVolumes,\r
+  kpidTimeType,\r
+  kpidBit64,\r
+  kpidBigEndian,\r
+  kpidCpu,\r
+  kpidPhySize,\r
+  kpidHeadersSize,\r
+  kpidChecksum,\r
+  kpidCharacts,\r
+  kpidVa,\r
+  kpidId,\r
+  kpidShortName,\r
+  kpidCreatorApp,\r
+  kpidSectorSize,\r
+  kpidPosixAttrib,\r
+  kpidLink,\r
+  kpidError,\r
+\r
+  kpidTotalSize = 0x1100,\r
+  kpidFreeSpace,\r
+  kpidClusterSize,\r
+  kpidVolumeName,\r
+\r
+  kpidLocalName = 0x1200,\r
+  kpidProvider,\r
+\r
+  kpidUserDefined = 0x10000\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/SubBuild.mak b/CPP/7zip/SubBuild.mak
new file mode 100755 (executable)
index 0000000..0c49d3b
--- /dev/null
@@ -0,0 +1,3 @@
+       cd $(@D)\r
+       $(MAKE) -nologo $(TARGETS)\r
+       cd ..\r
diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp
new file mode 100755 (executable)
index 0000000..7001fe8
--- /dev/null
@@ -0,0 +1,871 @@
+// Client7z.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/IntToString.h"\r
+#include "Common/MyInitGuid.h"\r
+#include "Common/StringConvert.h"\r
+\r
+#include "Windows/DLL.h"\r
+#include "Windows/FileDir.h"\r
+#include "Windows/FileFind.h"\r
+#include "Windows/FileName.h"\r
+#include "Windows/NtCheck.h"\r
+#include "Windows/PropVariant.h"\r
+#include "Windows/PropVariantConversions.h"\r
+\r
+#include "../../Common/FileStreams.h"\r
+\r
+#include "../../Archive/IArchive.h"\r
+\r
+#include "../../IPassword.h"\r
+#include "../../MyVersion.h"\r
+\r
+// use another CLSIDs, if you want to support other formats (zip, rar, ...).\r
+// {23170F69-40C1-278A-1000-000110070000}\r
+DEFINE_GUID(CLSID_CFormat7z,\r
+  0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);\r
+\r
+using namespace NWindows;\r
+\r
+#define kDllName "7z.dll"\r
+\r
+static const char *kCopyrightString = MY_7ZIP_VERSION\r
+" ("  kDllName " client) "\r
+MY_COPYRIGHT " " MY_DATE;\r
+\r
+static const char *kHelpString =\r
+"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"\r
+"Examples:\n"\r
+"  Client7z.exe a archive.7z f1.txt f2.txt  : compress two files to archive.7z\n"\r
+"  Client7z.exe l archive.7z   : List contents of archive.7z\n"\r
+"  Client7z.exe x archive.7z   : eXtract files from archive.7z\n";\r
+\r
+\r
+typedef UINT32 (WINAPI * CreateObjectFunc)(\r
+    const GUID *clsID,\r
+    const GUID *interfaceID,\r
+    void **outObject);\r
+\r
+\r
+void PrintString(const UString &s)\r
+{\r
+  printf("%s", (LPCSTR)GetOemString(s));\r
+}\r
+\r
+void PrintString(const AString &s)\r
+{\r
+  printf("%s", (LPCSTR)s);\r
+}\r
+\r
+void PrintNewLine()\r
+{\r
+  PrintString("\n");\r
+}\r
+\r
+void PrintStringLn(const AString &s)\r
+{\r
+  PrintString(s);\r
+  PrintNewLine();\r
+}\r
+\r
+void PrintError(const AString &s)\r
+{\r
+  PrintNewLine();\r
+  PrintString(s);\r
+  PrintNewLine();\r
+}\r
+\r
+static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)\r
+{\r
+  NCOM::CPropVariant prop;\r
+  RINOK(archive->GetProperty(index, propID, &prop));\r
+  if (prop.vt == VT_BOOL)\r
+    result = VARIANT_BOOLToBool(prop.boolVal);\r
+  else if (prop.vt == VT_EMPTY)\r
+    result = false;\r
+  else\r
+    return E_FAIL;\r
+  return S_OK;\r
+}\r
+\r
+static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)\r
+{\r
+  return IsArchiveItemProp(archive, index, kpidIsDir, result);\r
+}\r
+\r
+\r
+static const wchar_t *kEmptyFileAlias = L"[Content]";\r
+\r
+\r
+//////////////////////////////////////////////////////////////\r
+// Archive Open callback class\r
+\r
+\r
+class CArchiveOpenCallback:\r
+  public IArchiveOpenCallback,\r
+  public ICryptoGetTextPassword,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP1(ICryptoGetTextPassword)\r
+\r
+  STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);\r
+  STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);\r
+\r
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);\r
+\r
+  bool PasswordIsDefined;\r
+  UString Password;\r
+\r
+  CArchiveOpenCallback() : PasswordIsDefined(false) {}\r
+};\r
+\r
+STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)\r
+{\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)\r
+{\r
+  return S_OK;\r
+}\r
+  \r
+STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)\r
+{\r
+  if (!PasswordIsDefined)\r
+  {\r
+    // You can ask real password here from user\r
+    // Password = GetPassword(OutStream);\r
+    // PasswordIsDefined = true;\r
+    PrintError("Password is not defined");\r
+    return E_ABORT;\r
+  }\r
+  return StringToBstr(Password, password);\r
+}\r
+\r
+\r
+//////////////////////////////////////////////////////////////\r
+// Archive Extracting callback class\r
+\r
+static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";\r
+\r
+static const char *kTestingString    =  "Testing     ";\r
+static const char *kExtractingString =  "Extracting  ";\r
+static const char *kSkippingString   =  "Skipping    ";\r
+\r
+static const char *kUnsupportedMethod = "Unsupported Method";\r
+static const char *kCRCFailed = "CRC Failed";\r
+static const char *kDataError = "Data Error";\r
+static const char *kUnknownError = "Unknown Error";\r
+\r
+class CArchiveExtractCallback:\r
+  public IArchiveExtractCallback,\r
+  public ICryptoGetTextPassword,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP1(ICryptoGetTextPassword)\r
+\r
+  // IProgress\r
+  STDMETHOD(SetTotal)(UInt64 size);\r
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue);\r
+\r
+  // IArchiveExtractCallback\r
+  STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);\r
+  STDMETHOD(PrepareOperation)(Int32 askExtractMode);\r
+  STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);\r
+\r
+  // ICryptoGetTextPassword\r
+  STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);\r
+\r
+private:\r
+  CMyComPtr<IInArchive> _archiveHandler;\r
+  UString _directoryPath;  // Output directory\r
+  UString _filePath;       // name inside arcvhive\r
+  UString _diskFilePath;   // full path to file on disk\r
+  bool _extractMode;\r
+  struct CProcessedFileInfo\r
+  {\r
+    FILETIME MTime;\r
+    UInt32 Attrib;\r
+    bool isDir;\r
+    bool AttribDefined;\r
+    bool MTimeDefined;\r
+  } _processedFileInfo;\r
+\r
+  COutFileStream *_outFileStreamSpec;\r
+  CMyComPtr<ISequentialOutStream> _outFileStream;\r
+\r
+public:\r
+  void Init(IInArchive *archiveHandler, const UString &directoryPath);\r
+\r
+  UInt64 NumErrors;\r
+  bool PasswordIsDefined;\r
+  UString Password;\r
+\r
+  CArchiveExtractCallback() : PasswordIsDefined(false) {}\r
+};\r
+\r
+void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath)\r
+{\r
+  NumErrors = 0;\r
+  _archiveHandler = archiveHandler;\r
+  _directoryPath = directoryPath;\r
+  NFile::NName::NormalizeDirPathPrefix(_directoryPath);\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */)\r
+{\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)\r
+{\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,\r
+    ISequentialOutStream **outStream, Int32 askExtractMode)\r
+{\r
+  *outStream = 0;\r
+  _outFileStream.Release();\r
+\r
+  {\r
+    // Get Name\r
+    NCOM::CPropVariant prop;\r
+    RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));\r
+    \r
+    UString fullPath;\r
+    if (prop.vt == VT_EMPTY)\r
+      fullPath = kEmptyFileAlias;\r
+    else\r
+    {\r
+      if (prop.vt != VT_BSTR)\r
+        return E_FAIL;\r
+      fullPath = prop.bstrVal;\r
+    }\r
+    _filePath = fullPath;\r
+  }\r
+\r
+  if (askExtractMode != NArchive::NExtract::NAskMode::kExtract)\r
+    return S_OK;\r
+\r
+  {\r
+    // Get Attrib\r
+    NCOM::CPropVariant prop;\r
+    RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));\r
+    if (prop.vt == VT_EMPTY)\r
+    {\r
+      _processedFileInfo.Attrib = 0;\r
+      _processedFileInfo.AttribDefined = false;\r
+    }\r
+    else\r
+    {\r
+      if (prop.vt != VT_UI4)\r
+        return E_FAIL;\r
+      _processedFileInfo.Attrib = prop.ulVal;\r
+      _processedFileInfo.AttribDefined = true;\r
+    }\r
+  }\r
+\r
+  RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir));\r
+\r
+  {\r
+    // Get Modified Time\r
+    NCOM::CPropVariant prop;\r
+    RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));\r
+    _processedFileInfo.MTimeDefined = false;\r
+    switch(prop.vt)\r
+    {\r
+      case VT_EMPTY:\r
+        // _processedFileInfo.MTime = _utcMTimeDefault;\r
+        break;\r
+      case VT_FILETIME:\r
+        _processedFileInfo.MTime = prop.filetime;\r
+        _processedFileInfo.MTimeDefined = true;\r
+        break;\r
+      default:\r
+        return E_FAIL;\r
+    }\r
+\r
+  }\r
+  {\r
+    // Get Size\r
+    NCOM::CPropVariant prop;\r
+    RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));\r
+    bool newFileSizeDefined = (prop.vt != VT_EMPTY);\r
+    UInt64 newFileSize;\r
+    if (newFileSizeDefined)\r
+      newFileSize = ConvertPropVariantToUInt64(prop);\r
+  }\r
+\r
+  \r
+  {\r
+    // Create folders for file\r
+    int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);\r
+    if (slashPos >= 0)\r
+      NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos));\r
+  }\r
+\r
+  UString fullProcessedPath = _directoryPath + _filePath;\r
+  _diskFilePath = fullProcessedPath;\r
+\r
+  if (_processedFileInfo.isDir)\r
+  {\r
+    NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);\r
+  }\r
+  else\r
+  {\r
+    NFile::NFind::CFileInfoW fi;\r
+    if (fi.Find(fullProcessedPath))\r
+    {\r
+      if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))\r
+      {\r
+        PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath);\r
+        return E_ABORT;\r
+      }\r
+    }\r
+    \r
+    _outFileStreamSpec = new COutFileStream;\r
+    CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);\r
+    if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))\r
+    {\r
+      PrintString((UString)L"can not open output file " + fullProcessedPath);\r
+      return E_ABORT;\r
+    }\r
+    _outFileStream = outStreamLoc;\r
+    *outStream = outStreamLoc.Detach();\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)\r
+{\r
+  _extractMode = false;\r
+  switch (askExtractMode)\r
+  {\r
+    case NArchive::NExtract::NAskMode::kExtract:  _extractMode = true; break;\r
+  };\r
+  switch (askExtractMode)\r
+  {\r
+    case NArchive::NExtract::NAskMode::kExtract:  PrintString(kExtractingString); break;\r
+    case NArchive::NExtract::NAskMode::kTest:  PrintString(kTestingString); break;\r
+    case NArchive::NExtract::NAskMode::kSkip:  PrintString(kSkippingString); break;\r
+  };\r
+  PrintString(_filePath);\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)\r
+{\r
+  switch(operationResult)\r
+  {\r
+    case NArchive::NExtract::NOperationResult::kOK:\r
+      break;\r
+    default:\r
+    {\r
+      NumErrors++;\r
+      PrintString("     ");\r
+      switch(operationResult)\r
+      {\r
+        case NArchive::NExtract::NOperationResult::kUnSupportedMethod:\r
+          PrintString(kUnsupportedMethod);\r
+          break;\r
+        case NArchive::NExtract::NOperationResult::kCRCError:\r
+          PrintString(kCRCFailed);\r
+          break;\r
+        case NArchive::NExtract::NOperationResult::kDataError:\r
+          PrintString(kDataError);\r
+          break;\r
+        default:\r
+          PrintString(kUnknownError);\r
+      }\r
+    }\r
+  }\r
+\r
+  if (_outFileStream != NULL)\r
+  {\r
+    if (_processedFileInfo.MTimeDefined)\r
+      _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);\r
+    RINOK(_outFileStreamSpec->Close());\r
+  }\r
+  _outFileStream.Release();\r
+  if (_extractMode && _processedFileInfo.AttribDefined)\r
+    NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib);\r
+  PrintNewLine();\r
+  return S_OK;\r
+}\r
+\r
+\r
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)\r
+{\r
+  if (!PasswordIsDefined)\r
+  {\r
+    // You can ask real password here from user\r
+    // Password = GetPassword(OutStream);\r
+    // PasswordIsDefined = true;\r
+    PrintError("Password is not defined");\r
+    return E_ABORT;\r
+  }\r
+  return StringToBstr(Password, password);\r
+}\r
+\r
+\r
+\r
+//////////////////////////////////////////////////////////////\r
+// Archive Creating callback class\r
+\r
+struct CDirItem\r
+{\r
+  UInt64 Size;\r
+  FILETIME CTime;\r
+  FILETIME ATime;\r
+  FILETIME MTime;\r
+  UString Name;\r
+  UString FullPath;\r
+  UInt32 Attrib;\r
+\r
+  bool isDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }\r
+};\r
+\r
+class CArchiveUpdateCallback:\r
+  public IArchiveUpdateCallback2,\r
+  public ICryptoGetTextPassword2,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)\r
+\r
+  // IProgress\r
+  STDMETHOD(SetTotal)(UInt64 size);\r
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue);\r
+\r
+  // IUpdateCallback2\r
+  STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);\r
+  STDMETHOD(GetUpdateItemInfo)(UInt32 index,\r
+      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);\r
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);\r
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);\r
+  STDMETHOD(SetOperationResult)(Int32 operationResult);\r
+  STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);\r
+  STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);\r
+\r
+  STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);\r
+\r
+public:\r
+  CRecordVector<UInt64> VolumesSizes;\r
+  UString VolName;\r
+  UString VolExt;\r
+\r
+  UString DirPrefix;\r
+  const CObjectVector<CDirItem> *DirItems;\r
+\r
+  bool PasswordIsDefined;\r
+  UString Password;\r
+  bool AskPassword;\r
+\r
+  bool m_NeedBeClosed;\r
+\r
+  UStringVector FailedFiles;\r
+  CRecordVector<HRESULT> FailedCodes;\r
+\r
+  CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};\r
+\r
+  ~CArchiveUpdateCallback() { Finilize(); }\r
+  HRESULT Finilize();\r
+\r
+  void Init(const CObjectVector<CDirItem> *dirItems)\r
+  {\r
+    DirItems = dirItems;\r
+    m_NeedBeClosed = false;\r
+    FailedFiles.Clear();\r
+    FailedCodes.Clear();\r
+  }\r
+};\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */)\r
+{\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)\r
+{\r
+  return S_OK;\r
+}\r
+\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)\r
+{\r
+  return E_NOTIMPL;\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,\r
+      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)\r
+{\r
+  if (newData != NULL)\r
+    *newData = BoolToInt(true);\r
+  if (newProperties != NULL)\r
+    *newProperties = BoolToInt(true);\r
+  if (indexInArchive != NULL)\r
+    *indexInArchive = (UInt32)-1;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)\r
+{\r
+  NWindows::NCOM::CPropVariant prop;\r
+  \r
+  if (propID == kpidIsAnti)\r
+  {\r
+    prop = false;\r
+    prop.Detach(value);\r
+    return S_OK;\r
+  }\r
+\r
+  {\r
+    const CDirItem &dirItem = (*DirItems)[index];\r
+    switch(propID)\r
+    {\r
+      case kpidPath:  prop = dirItem.Name; break;\r
+      case kpidIsDir:  prop = dirItem.isDir(); break;\r
+      case kpidSize:  prop = dirItem.Size; break;\r
+      case kpidAttrib:  prop = dirItem.Attrib; break;\r
+      case kpidCTime:  prop = dirItem.CTime; break;\r
+      case kpidATime:  prop = dirItem.ATime; break;\r
+      case kpidMTime:  prop = dirItem.MTime; break;\r
+    }\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CArchiveUpdateCallback::Finilize()\r
+{\r
+  if (m_NeedBeClosed)\r
+  {\r
+    PrintNewLine();\r
+    m_NeedBeClosed = false;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+static void GetStream2(const wchar_t *name)\r
+{\r
+  PrintString("Compressing  ");\r
+  if (name[0] == 0)\r
+    name = kEmptyFileAlias;\r
+  PrintString(name);\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)\r
+{\r
+  RINOK(Finilize());\r
+\r
+  const CDirItem &dirItem = (*DirItems)[index];\r
+  GetStream2(dirItem.Name);\r
\r
+  if (dirItem.isDir())\r
+    return S_OK;\r
+\r
+  {\r
+    CInFileStream *inStreamSpec = new CInFileStream;\r
+    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);\r
+    UString path = DirPrefix + dirItem.FullPath;\r
+    if (!inStreamSpec->Open(path))\r
+    {\r
+      DWORD sysError = ::GetLastError();\r
+      FailedCodes.Add(sysError);\r
+      FailedFiles.Add(path);\r
+      // if (systemError == ERROR_SHARING_VIOLATION)\r
+      {\r
+        PrintNewLine();\r
+        PrintError("WARNING: can't open file");\r
+        // PrintString(NError::MyFormatMessageW(systemError));\r
+        return S_FALSE;\r
+      }\r
+      // return sysError;\r
+    }\r
+    *inStream = inStreamLoc.Detach();\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)\r
+{\r
+  m_NeedBeClosed = true;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)\r
+{\r
+  if (VolumesSizes.Size() == 0)\r
+    return S_FALSE;\r
+  if (index >= (UInt32)VolumesSizes.Size())\r
+    index = VolumesSizes.Size() - 1;\r
+  *size = VolumesSizes[index];\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)\r
+{\r
+  wchar_t temp[16];\r
+  ConvertUInt32ToString(index + 1, temp);\r
+  UString res = temp;\r
+  while (res.Length() < 2)\r
+    res = UString(L'0') + res;\r
+  UString fileName = VolName;\r
+  fileName += L'.';\r
+  fileName += res;\r
+  fileName += VolExt;\r
+  COutFileStream *streamSpec = new COutFileStream;\r
+  CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);\r
+  if (!streamSpec->Create(fileName, false))\r
+    return ::GetLastError();\r
+  *volumeStream = streamLoc.Detach();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)\r
+{\r
+  if (!PasswordIsDefined)\r
+  {\r
+    if (AskPassword)\r
+    {\r
+      // You can ask real password here from user\r
+      // Password = GetPassword(OutStream);\r
+      // PasswordIsDefined = true;\r
+      PrintError("Password is not defined");\r
+      return E_ABORT;\r
+    }\r
+  }\r
+  *passwordIsDefined = BoolToInt(PasswordIsDefined);\r
+  return StringToBstr(Password, password);\r
+}\r
+\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+// Main function\r
+\r
+#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;\r
+\r
+int MY_CDECL main(int numArgs, const char *args[])\r
+{\r
+  NT_CHECK\r
+\r
+  PrintStringLn(kCopyrightString);\r
+\r
+  if (numArgs < 3)\r
+  {\r
+    PrintStringLn(kHelpString);\r
+    return 1;\r
+  }\r
+  NWindows::NDLL::CLibrary lib;\r
+  if (!lib.Load(TEXT(kDllName)))\r
+  {\r
+    PrintError("Can not load 7-zip library");\r
+    return 1;\r
+  }\r
+  CreateObjectFunc createObjectFunc = (CreateObjectFunc)lib.GetProc("CreateObject");\r
+  if (createObjectFunc == 0)\r
+  {\r
+    PrintError("Can not get CreateObject");\r
+    return 1;\r
+  }\r
+\r
+  char c;\r
+  {\r
+    AString command = args[1];\r
+    if (command.Length() != 1)\r
+    {\r
+      PrintError("incorrect command");\r
+      return 1;\r
+    }\r
+    c = MyCharLower(command[0]);\r
+  }\r
+  UString archiveName = GetUnicodeString(args[2]);\r
+  if (c == 'a')\r
+  {\r
+    // create archive command\r
+    if (numArgs < 4)\r
+    {\r
+      PrintStringLn(kHelpString);\r
+      return 1;\r
+    }\r
+    CObjectVector<CDirItem> dirItems;\r
+    int i;\r
+    for (i = 3; i < numArgs; i++)\r
+    {\r
+      CDirItem di;\r
+      UString name = GetUnicodeString(args[i]);\r
+      \r
+      NFile::NFind::CFileInfoW fi;\r
+      if (!fi.Find(name))\r
+      {\r
+        PrintString(UString(L"Can't find file") + name);\r
+        return 1;\r
+      }\r
+\r
+      di.Attrib = fi.Attrib;\r
+      di.Size = fi.Size;\r
+      di.CTime = fi.CTime;\r
+      di.ATime = fi.ATime;\r
+      di.MTime = fi.MTime;\r
+      di.Name = name;\r
+      di.FullPath = name;\r
+      dirItems.Add(di);\r
+    }\r
+    COutFileStream *outFileStreamSpec = new COutFileStream;\r
+    CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;\r
+    if (!outFileStreamSpec->Create(archiveName, false))\r
+    {\r
+      PrintError("can't create archive file");\r
+      return 1;\r
+    }\r
+\r
+    CMyComPtr<IOutArchive> outArchive;\r
+    if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK)\r
+    {\r
+      PrintError("Can not get class object");\r
+      return 1;\r
+    }\r
+\r
+    CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;\r
+    CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);\r
+    updateCallbackSpec->Init(&dirItems);\r
+    // updateCallbackSpec->PasswordIsDefined = true;\r
+    // updateCallbackSpec->Password = L"1";\r
+\r
+    /*\r
+    {\r
+      const wchar_t *names[] =\r
+      {\r
+        L"s",\r
+        L"x"\r
+      };\r
+      const int kNumProps = sizeof(names) / sizeof(names[0]);\r
+      NWindows::NCOM::CPropVariant values[kNumProps] =\r
+      {\r
+        false,    // solid mode OFF\r
+        (UInt32)9 // compression level = 9 - ultra\r
+      };\r
+      CMyComPtr<ISetProperties> setProperties;\r
+      outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties);\r
+      if (!setProperties)\r
+      {\r
+        PrintError("ISetProperties unsupported");\r
+        return 1;\r
+      }\r
+      RINOK(setProperties->SetProperties(names, values, kNumProps));\r
+    }\r
+    */\r
+    \r
+    HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);\r
+    updateCallbackSpec->Finilize();\r
+    if (result != S_OK)\r
+    {\r
+      PrintError("Update Error");\r
+      return 1;\r
+    }\r
+    for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)\r
+    {\r
+      PrintNewLine();\r
+      PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]);\r
+    }\r
+    if (updateCallbackSpec->FailedFiles.Size() != 0)\r
+      return 1;\r
+  }\r
+  else\r
+  {\r
+    if (numArgs != 3)\r
+    {\r
+      PrintStringLn(kHelpString);\r
+      return 1;\r
+    }\r
+\r
+    bool listCommand;\r
+    if (c == 'l')\r
+      listCommand = true;\r
+    else if (c == 'x')\r
+      listCommand = false;\r
+    else\r
+    {\r
+      PrintError("incorrect command");\r
+      return 1;\r
+    }\r
+  \r
+    CMyComPtr<IInArchive> archive;\r
+    if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK)\r
+    {\r
+      PrintError("Can not get class object");\r
+      return 1;\r
+    }\r
+    \r
+    CInFileStream *fileSpec = new CInFileStream;\r
+    CMyComPtr<IInStream> file = fileSpec;\r
+    \r
+    if (!fileSpec->Open(archiveName))\r
+    {\r
+      PrintError("Can not open archive file");\r
+      return 1;\r
+    }\r
+\r
+    {\r
+      CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;\r
+      CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);\r
+      openCallbackSpec->PasswordIsDefined = false;\r
+      // openCallbackSpec->PasswordIsDefined = true;\r
+      // openCallbackSpec->Password = L"1";\r
+      \r
+      if (archive->Open(file, 0, openCallback) != S_OK)\r
+      {\r
+        PrintError("Can not open archive");\r
+        return 1;\r
+      }\r
+    }\r
+    \r
+    if (listCommand)\r
+    {\r
+      // List command\r
+      UInt32 numItems = 0;\r
+      archive->GetNumberOfItems(&numItems);\r
+      for (UInt32 i = 0; i < numItems; i++)\r
+      {\r
+        {\r
+          // Get uncompressed size of file\r
+          NWindows::NCOM::CPropVariant prop;\r
+          archive->GetProperty(i, kpidSize, &prop);\r
+          UString s = ConvertPropVariantToString(prop);\r
+          PrintString(s);\r
+          PrintString("  ");\r
+        }\r
+        {\r
+          // Get name of file\r
+          NWindows::NCOM::CPropVariant prop;\r
+          archive->GetProperty(i, kpidPath, &prop);\r
+          UString s = ConvertPropVariantToString(prop);\r
+          PrintString(s);\r
+        }\r
+        PrintString("\n");\r
+      }\r
+    }\r
+    else\r
+    {\r
+      // Extract command\r
+      CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;\r
+      CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);\r
+      extractCallbackSpec->Init(archive, L""); // second parameter is output folder path\r
+      extractCallbackSpec->PasswordIsDefined = false;\r
+      // extractCallbackSpec->PasswordIsDefined = true;\r
+      // extractCallbackSpec->Password = L"1";\r
+      HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);\r
+      if (result != S_OK)\r
+      {\r
+        PrintError("Extract Error");\r
+        return 1;\r
+      }\r
+    }\r
+  }\r
+  return 0;\r
+}\r
diff --git a/CPP/7zip/UI/Client7z/Client7z.dsp b/CPP/7zip/UI/Client7z/Client7z.dsp
new file mode 100755 (executable)
index 0000000..34eb42b
--- /dev/null
@@ -0,0 +1,226 @@
+# Microsoft Developer Studio Project File - Name="Client7z" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=Client7z - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "Client7z.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "Client7z.mak" CFG="Client7z - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "Client7z - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "Client7z - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "Client7z - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c\r
+# ADD BASE RSC /l 0x419 /d "NDEBUG"\r
+# ADD RSC /l 0x419 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "Client7z - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c\r
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c\r
+# ADD BASE RSC /l 0x419 /d "_DEBUG"\r
+# ADD RSC /l 0x419 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "Client7z - Win32 Release"\r
+# Name "Client7z - Win32 Debug"\r
+# Begin Group "Spec"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\StdAfx.cpp\r
+# ADD CPP /Yc"stdafx.h"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\StdAfx.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Windows"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\DLL.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\DLL.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileDir.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileDir.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileFind.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileFind.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileIO.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileIO.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileName.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\FileName.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\PropVariant.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\PropVariant.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Windows\PropVariantConversions.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\IntToString.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\IntToString.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyString.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyString.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyVector.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\MyVector.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\NewHandler.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\NewHandler.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringConvert.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\StringConvert.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Wildcard.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\Common\Wildcard.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "7zip Common"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FileStreams.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\Common\FileStreams.h\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=.\Client7z.cpp\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/CPP/7zip/UI/Client7z/Client7z.dsw b/CPP/7zip/UI/Client7z/Client7z.dsw
new file mode 100755 (executable)
index 0000000..4c26851
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "Client7z"=.\Client7z.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/CPP/7zip/UI/Client7z/StdAfx.cpp b/CPP/7zip/UI/Client7z/StdAfx.cpp
new file mode 100755 (executable)
index 0000000..c6d3b1f
--- /dev/null
@@ -0,0 +1,3 @@
+// StdAfx.cpp\r
+\r
+#include "StdAfx.h"\r
diff --git a/CPP/7zip/UI/Client7z/StdAfx.h b/CPP/7zip/UI/Client7z/StdAfx.h
new file mode 100755 (executable)
index 0000000..2edddf4
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include <windows.h>\r
+#include <stdio.h>\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Client7z/makefile b/CPP/7zip/UI/Client7z/makefile
new file mode 100755 (executable)
index 0000000..e3a8239
--- /dev/null
@@ -0,0 +1,45 @@
+PROG = 7z.exe\r
+MY_CONSOLE = 1\r
+CFLAGS = $(CFLAGS) -I ../../../\r
+\r
+CONSOLE_OBJS = \\r
+  $O\Client7z.obj \\r
+\r
+COMMON_OBJS = \\r
+  $O\IntToString.obj \\r
+  $O\NewHandler.obj \\r
+  $O\MyString.obj \\r
+  $O\StringConvert.obj \\r
+  $O\StringToInt.obj \\r
+  $O\MyVector.obj \\r
+  $O\Wildcard.obj \\r
+\r
+WIN_OBJS = \\r
+  $O\DLL.obj \\r
+  $O\FileDir.obj \\r
+  $O\FileFind.obj \\r
+  $O\FileIO.obj \\r
+  $O\FileName.obj \\r
+  $O\PropVariant.obj \\r
+  $O\PropVariantConversions.obj \\r
+\r
+7ZIP_COMMON_OBJS = \\r
+  $O\FileStreams.obj \\r
+\r
+OBJS = \\r
+  $O\StdAfx.obj \\r
+  $(CONSOLE_OBJS) \\r
+  $(COMMON_OBJS) \\r
+  $(WIN_OBJS) \\r
+  $(7ZIP_COMMON_OBJS) \\r
+\r
+!include "../../../Build.mak"\r
+\r
+$(CONSOLE_OBJS): $(*B).cpp\r
+       $(COMPL)\r
+$(COMMON_OBJS): ../../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(WIN_OBJS): ../../../Windows/$(*B).cpp\r
+       $(COMPL)\r
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp\r
+       $(COMPL)\r
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
new file mode 100755 (executable)
index 0000000..7fd012b
--- /dev/null
@@ -0,0 +1,1042 @@
+// ArchiveCommandLine.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#ifdef _WIN32\r
+#ifndef UNDER_CE\r
+#include <io.h>\r
+#endif\r
+#endif\r
+#include <stdio.h>\r
+\r
+#include "Common/ListFileUtils.h"\r
+#include "Common/StringConvert.h"\r
+#include "Common/StringToInt.h"\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/FileName.h"\r
+#ifdef _WIN32\r
+#include "Windows/FileMapping.h"\r
+#include "Windows/Synchronization.h"\r
+#endif\r
+\r
+#include "ArchiveCommandLine.h"\r
+#include "EnumDirItems.h"\r
+#include "SortUtils.h"\r
+#include "Update.h"\r
+#include "UpdateAction.h"\r
+\r
+extern bool g_CaseSensitive;\r
+\r
+#ifdef UNDER_CE\r
+\r
+#define MY_IS_TERMINAL(x) false;\r
+\r
+#else\r
+\r
+#if _MSC_VER >= 1400\r
+#define MY_isatty_fileno(x) _isatty(_fileno(x))\r
+#else\r
+#define MY_isatty_fileno(x) isatty(fileno(x))\r
+#endif\r
+\r
+#define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0);\r
+\r
+#endif\r
+\r
+using namespace NCommandLineParser;\r
+using namespace NWindows;\r
+using namespace NFile;\r
+\r
+int g_CodePage = -1;\r
+\r
+namespace NKey {\r
+enum Enum\r
+{\r
+  kHelp1 = 0,\r
+  kHelp2,\r
+  kHelp3,\r
+  kDisableHeaders,\r
+  kDisablePercents,\r
+  kArchiveType,\r
+  kYes,\r
+  #ifndef _NO_CRYPTO\r
+  kPassword,\r
+  #endif\r
+  kProperty,\r
+  kOutputDir,\r
+  kWorkingDir,\r
+  kInclude,\r
+  kExclude,\r
+  kArInclude,\r
+  kArExclude,\r
+  kNoArName,\r
+  kUpdate,\r
+  kVolume,\r
+  kRecursed,\r
+  kSfx,\r
+  kStdIn,\r
+  kStdOut,\r
+  kOverwrite,\r
+  kEmail,\r
+  kShowDialog,\r
+  kLargePages,\r
+  kListfileCharSet,\r
+  kConsoleCharSet,\r
+  kTechMode,\r
+  kShareForWrite,\r
+  kCaseSensitive,\r
+  kCalcCrc\r
+};\r
+\r
+}\r
+\r
+\r
+static const wchar_t kRecursedIDChar = 'R';\r
+static const wchar_t *kRecursedPostCharSet = L"0-";\r
+\r
+namespace NRecursedPostCharIndex {\r
+  enum EEnum\r
+  {\r
+    kWildCardRecursionOnly = 0,\r
+    kNoRecursion = 1\r
+  };\r
+}\r
+\r
+static const char kImmediateNameID = '!';\r
+static const char kMapNameID = '#';\r
+static const char kFileListID = '@';\r
+\r
+static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be\r
+static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be\r
+\r
+static const wchar_t *kOverwritePostCharSet = L"asut";\r
+\r
+NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =\r
+{\r
+  NExtract::NOverwriteMode::kWithoutPrompt,\r
+  NExtract::NOverwriteMode::kSkipExisting,\r
+  NExtract::NOverwriteMode::kAutoRename,\r
+  NExtract::NOverwriteMode::kAutoRenameExisting\r
+};\r
+\r
+static const CSwitchForm kSwitchForms[] =\r
+  {\r
+    { L"?",  NSwitchType::kSimple, false },\r
+    { L"H",  NSwitchType::kSimple, false },\r
+    { L"-HELP",  NSwitchType::kSimple, false },\r
+    { L"BA", NSwitchType::kSimple, false },\r
+    { L"BD", NSwitchType::kSimple, false },\r
+    { L"T",  NSwitchType::kUnLimitedPostString, false, 1 },\r
+    { L"Y",  NSwitchType::kSimple, false },\r
+    #ifndef _NO_CRYPTO\r
+    { L"P",  NSwitchType::kUnLimitedPostString, false, 0 },\r
+    #endif\r
+    { L"M",  NSwitchType::kUnLimitedPostString, true, 1 },\r
+    { L"O",  NSwitchType::kUnLimitedPostString, false, 1 },\r
+    { L"W",  NSwitchType::kUnLimitedPostString, false, 0 },\r
+    { L"I",  NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},\r
+    { L"X",  NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},\r
+    { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},\r
+    { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},\r
+    { L"AN", NSwitchType::kSimple, false },\r
+    { L"U",  NSwitchType::kUnLimitedPostString, true, 1},\r
+    { L"V",  NSwitchType::kUnLimitedPostString, true, 1},\r
+    { L"R",  NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },\r
+    { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },\r
+    { L"SI", NSwitchType::kUnLimitedPostString, false, 0 },\r
+    { L"SO", NSwitchType::kSimple, false, 0 },\r
+    { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},\r
+    { L"SEML", NSwitchType::kUnLimitedPostString, false, 0},\r
+    { L"AD",  NSwitchType::kSimple, false },\r
+    { L"SLP", NSwitchType::kUnLimitedPostString, false, 0},\r
+    { L"SCS", NSwitchType::kUnLimitedPostString, false, 0},\r
+    { L"SCC", NSwitchType::kUnLimitedPostString, false, 0},\r
+    { L"SLT", NSwitchType::kSimple, false },\r
+    { L"SSW", NSwitchType::kSimple, false },\r
+    { L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" },\r
+    { L"SCRC", NSwitchType::kSimple, false }\r
+  };\r
+\r
+static const CCommandForm g_CommandForms[] =\r
+{\r
+  { L"A", false },\r
+  { L"U", false },\r
+  { L"D", false },\r
+  { L"T", false },\r
+  { L"E", false },\r
+  { L"X", false },\r
+  { L"L", false },\r
+  { L"B", false },\r
+  { L"I", false }\r
+};\r
+\r
+static const int kNumCommandForms = sizeof(g_CommandForms) /  sizeof(g_CommandForms[0]);\r
+\r
+static const wchar_t *kUniversalWildcard = L"*";\r
+static const int kMinNonSwitchWords = 1;\r
+static const int kCommandIndex = 0;\r
+\r
+// ---------------------------\r
+// exception messages\r
+\r
+static const char *kUserErrorMessage  = "Incorrect command line";\r
+static const char *kCannotFindListFile = "Cannot find listfile";\r
+static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";\r
+static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile";\r
+static const char *kIncorrectWildCardInCommandLine  = "Incorrect wildcard in command line";\r
+static const char *kTerminalOutError = "I won't write compressed data to a terminal";\r
+static const char *kSameTerminalError = "I won't write data and program's messages to same terminal";\r
+static const char *kEmptyFilePath = "Empty file path";\r
+\r
+static void ThrowException(const char *errorMessage)\r
+{\r
+  throw CArchiveCommandLineException(errorMessage);\r
+}\r
+\r
+static void ThrowUserErrorException()\r
+{\r
+  ThrowException(kUserErrorMessage);\r
+}\r
+\r
+// ---------------------------\r
+\r
+bool CArchiveCommand::IsFromExtractGroup() const\r
+{\r
+  switch(CommandType)\r
+  {\r
+    case NCommandType::kTest:\r
+    case NCommandType::kExtract:\r
+    case NCommandType::kFullExtract:\r
+      return true;\r
+    default:\r
+      return false;\r
+  }\r
+}\r
+\r
+NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const\r
+{\r
+  switch(CommandType)\r
+  {\r
+    case NCommandType::kTest:\r
+    case NCommandType::kFullExtract:\r
+      return NExtract::NPathMode::kFullPathnames;\r
+    default:\r
+      return NExtract::NPathMode::kNoPathnames;\r
+  }\r
+}\r
+\r
+bool CArchiveCommand::IsFromUpdateGroup() const\r
+{\r
+  return (CommandType == NCommandType::kAdd ||\r
+    CommandType == NCommandType::kUpdate ||\r
+    CommandType == NCommandType::kDelete);\r
+}\r
+\r
+static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)\r
+{\r
+  switch (index)\r
+  {\r
+    case NRecursedPostCharIndex::kWildCardRecursionOnly:\r
+      return NRecursedType::kWildCardOnlyRecursed;\r
+    case NRecursedPostCharIndex::kNoRecursion:\r
+      return NRecursedType::kNonRecursed;\r
+    default:\r
+      return NRecursedType::kRecursed;\r
+  }\r
+}\r
+\r
+static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)\r
+{\r
+  UString commandStringUpper = commandString;\r
+  commandStringUpper.MakeUpper();\r
+  UString postString;\r
+  int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper,\r
+      postString) ;\r
+  if (commandIndex < 0)\r
+    return false;\r
+  command.CommandType = (NCommandType::EEnum)commandIndex;\r
+  return true;\r
+}\r
+\r
+// ------------------------------------------------------------------\r
+// filenames functions\r
+\r
+static void AddNameToCensor(NWildcard::CCensor &wildcardCensor,\r
+    const UString &name, bool include, NRecursedType::EEnum type)\r
+{\r
+  bool recursed = false;\r
+\r
+  switch (type)\r
+  {\r
+    case NRecursedType::kWildCardOnlyRecursed:\r
+      recursed = DoesNameContainWildCard(name);\r
+      break;\r
+    case NRecursedType::kRecursed:\r
+      recursed = true;\r
+      break;\r
+  }\r
+  wildcardCensor.AddItem(include, name, recursed);\r
+}\r
+\r
+static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,\r
+    LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)\r
+{\r
+  UStringVector names;\r
+  if (!NFind::DoesFileExist(fileName))\r
+    throw kCannotFindListFile;\r
+  if (!ReadNamesFromListFile(fileName, names, codePage))\r
+    throw kIncorrectListFile;\r
+  for (int i = 0; i < names.Size(); i++)\r
+    AddNameToCensor(wildcardCensor, names[i], include, type);\r
+}\r
+\r
+static void AddToCensorFromNonSwitchesStrings(\r
+    int startIndex,\r
+    NWildcard::CCensor &wildcardCensor,\r
+    const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,\r
+    bool thereAreSwitchIncludes, UINT codePage)\r
+{\r
+  if (nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))\r
+    AddNameToCensor(wildcardCensor, kUniversalWildcard, true, type);\r
+  for (int i = startIndex; i < nonSwitchStrings.Size(); i++)\r
+  {\r
+    const UString &s = nonSwitchStrings[i];\r
+    if (s.IsEmpty())\r
+      throw kEmptyFilePath;\r
+    if (s[0] == kFileListID)\r
+      AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);\r
+    else\r
+      AddNameToCensor(wildcardCensor, s, true, type);\r
+  }\r
+}\r
+\r
+#ifdef _WIN32\r
+static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,\r
+    const UString &switchParam, bool include,\r
+    NRecursedType::EEnum commonRecursedType)\r
+{\r
+  int splitPos = switchParam.Find(L':');\r
+  if (splitPos < 0)\r
+    ThrowUserErrorException();\r
+  UString mappingName = switchParam.Left(splitPos);\r
+  \r
+  UString switchParam2 = switchParam.Mid(splitPos + 1);\r
+  splitPos = switchParam2.Find(L':');\r
+  if (splitPos < 0)\r
+    ThrowUserErrorException();\r
+  \r
+  UString mappingSize = switchParam2.Left(splitPos);\r
+  UString eventName = switchParam2.Mid(splitPos + 1);\r
+  \r
+  UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL);\r
+  UInt32 dataSize = (UInt32)dataSize64;\r
+  {\r
+    CFileMapping fileMapping;\r
+    if (fileMapping.Open(FILE_MAP_READ, GetSystemString(mappingName)) != 0)\r
+      ThrowException("Can not open mapping");\r
+    LPVOID data = fileMapping.Map(FILE_MAP_READ, 0, dataSize);\r
+    if (data == NULL)\r
+      ThrowException("MapViewOfFile error");\r
+    try\r
+    {\r
+      const wchar_t *curData = (const wchar_t *)data;\r
+      if (*curData != 0)\r
+        ThrowException("Incorrect mapping data");\r
+      UInt32 numChars = dataSize / sizeof(wchar_t);\r
+      UString name;\r
+      for (UInt32 i = 1; i < numChars; i++)\r
+      {\r
+        wchar_t c = curData[i];\r
+        if (c == L'\0')\r
+        {\r
+          AddNameToCensor(wildcardCensor, name, include, commonRecursedType);\r
+          name.Empty();\r
+        }\r
+        else\r
+          name += c;\r
+      }\r
+      if (!name.IsEmpty())\r
+        ThrowException("data error");\r
+    }\r
+    catch(...)\r
+    {\r
+      UnmapViewOfFile(data);\r
+      throw;\r
+    }\r
+    UnmapViewOfFile(data);\r
+  }\r
+  \r
+  {\r
+    NSynchronization::CManualResetEvent event;\r
+    if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)) == S_OK)\r
+      event.Set();\r
+  }\r
+}\r
+#endif\r
+\r
+static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,\r
+    const UStringVector &strings, bool include,\r
+    NRecursedType::EEnum commonRecursedType, UINT codePage)\r
+{\r
+  for (int i = 0; i < strings.Size(); i++)\r
+  {\r
+    const UString &name = strings[i];\r
+    NRecursedType::EEnum recursedType;\r
+    int pos = 0;\r
+    if (name.Length() < kSomeCludePostStringMinSize)\r
+      ThrowUserErrorException();\r
+    if (::MyCharUpper(name[pos]) == kRecursedIDChar)\r
+    {\r
+      pos++;\r
+      int index = UString(kRecursedPostCharSet).Find(name[pos]);\r
+      recursedType = GetRecursedTypeFromIndex(index);\r
+      if (index >= 0)\r
+        pos++;\r
+    }\r
+    else\r
+      recursedType = commonRecursedType;\r
+    if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)\r
+      ThrowUserErrorException();\r
+    UString tail = name.Mid(pos + 1);\r
+    if (name[pos] == kImmediateNameID)\r
+      AddNameToCensor(wildcardCensor, tail, include, recursedType);\r
+    else if (name[pos] == kFileListID)\r
+      AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage);\r
+    #ifdef _WIN32\r
+    else if (name[pos] == kMapNameID)\r
+      ParseMapWithPaths(wildcardCensor, tail, include, recursedType);\r
+    #endif\r
+    else\r
+      ThrowUserErrorException();\r
+  }\r
+}\r
+\r
+#ifdef _WIN32\r
+\r
+// This code converts all short file names to long file names.\r
+\r
+static void ConvertToLongName(const UString &prefix, UString &name)\r
+{\r
+  if (name.IsEmpty() || DoesNameContainWildCard(name))\r
+    return;\r
+  NFind::CFileInfoW fi;\r
+  if (fi.Find(prefix + name))\r
+    name = fi.Name;\r
+}\r
+\r
+static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)\r
+{\r
+  for (int i = 0; i < items.Size(); i++)\r
+  {\r
+    NWildcard::CItem &item = items[i];\r
+    if (item.Recursive || item.PathParts.Size() != 1)\r
+      continue;\r
+    ConvertToLongName(prefix, item.PathParts.Front());\r
+  }\r
+}\r
+\r
+static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)\r
+{\r
+  ConvertToLongNames(prefix, node.IncludeItems);\r
+  ConvertToLongNames(prefix, node.ExcludeItems);\r
+  int i;\r
+  for (i = 0; i < node.SubNodes.Size(); i++)\r
+    ConvertToLongName(prefix, node.SubNodes[i].Name);\r
+  // mix folders with same name\r
+  for (i = 0; i < node.SubNodes.Size(); i++)\r
+  {\r
+    NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];\r
+    for (int j = i + 1; j < node.SubNodes.Size();)\r
+    {\r
+      const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];\r
+      if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0)\r
+      {\r
+        nextNode1.IncludeItems += nextNode2.IncludeItems;\r
+        nextNode1.ExcludeItems += nextNode2.ExcludeItems;\r
+        node.SubNodes.Delete(j);\r
+      }\r
+      else\r
+        j++;\r
+    }\r
+  }\r
+  for (i = 0; i < node.SubNodes.Size(); i++)\r
+  {\r
+    NWildcard::CCensorNode &nextNode = node.SubNodes[i];\r
+    ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode);\r
+  }\r
+}\r
+\r
+static void ConvertToLongNames(NWildcard::CCensor &censor)\r
+{\r
+  for (int i = 0; i < censor.Pairs.Size(); i++)\r
+  {\r
+    NWildcard::CPair &pair = censor.Pairs[i];\r
+    ConvertToLongNames(pair.Prefix, pair.Head);\r
+  }\r
+}\r
+\r
+#endif\r
+\r
+static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)\r
+{\r
+  switch(i)\r
+  {\r
+    case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;\r
+    case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;\r
+    case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress;\r
+    case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti;\r
+  }\r
+  throw 98111603;\r
+}\r
+\r
+const UString kUpdatePairStateIDSet = L"PQRXYZW";\r
+const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};\r
+\r
+const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti\r
+\r
+const wchar_t *kUpdateIgnoreItselfPostStringID = L"-";\r
+const wchar_t kUpdateNewArchivePostCharID = '!';\r
+\r
+\r
+static bool ParseUpdateCommandString2(const UString &command,\r
+    NUpdateArchive::CActionSet &actionSet, UString &postString)\r
+{\r
+  for (int i = 0; i < command.Length();)\r
+  {\r
+    wchar_t c = MyCharUpper(command[i]);\r
+    int statePos = kUpdatePairStateIDSet.Find(c);\r
+    if (statePos < 0)\r
+    {\r
+      postString = command.Mid(i);\r
+      return true;\r
+    }\r
+    i++;\r
+    if (i >= command.Length())\r
+      return false;\r
+    int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));\r
+    if (actionPos < 0)\r
+      return false;\r
+    actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);\r
+    if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)\r
+      return false;\r
+    i++;\r
+  }\r
+  postString.Empty();\r
+  return true;\r
+}\r
+\r
+static void ParseUpdateCommandString(CUpdateOptions &options,\r
+    const UStringVector &updatePostStrings,\r
+    const NUpdateArchive::CActionSet &defaultActionSet)\r
+{\r
+  for (int i = 0; i < updatePostStrings.Size(); i++)\r
+  {\r
+    const UString &updateString = updatePostStrings[i];\r
+    if (updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)\r
+    {\r
+      if (options.UpdateArchiveItself)\r
+      {\r
+        options.UpdateArchiveItself = false;\r
+        options.Commands.Delete(0);\r
+      }\r
+    }\r
+    else\r
+    {\r
+      NUpdateArchive::CActionSet actionSet = defaultActionSet;\r
+\r
+      UString postString;\r
+      if (!ParseUpdateCommandString2(updateString, actionSet, postString))\r
+        ThrowUserErrorException();\r
+      if (postString.IsEmpty())\r
+      {\r
+        if (options.UpdateArchiveItself)\r
+          options.Commands[0].ActionSet = actionSet;\r
+      }\r
+      else\r
+      {\r
+        if (MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)\r
+          ThrowUserErrorException();\r
+        CUpdateArchiveCommand uc;\r
+        UString archivePath = postString.Mid(1);\r
+        if (archivePath.IsEmpty())\r
+          ThrowUserErrorException();\r
+        uc.UserArchivePath = archivePath;\r
+        uc.ActionSet = actionSet;\r
+        options.Commands.Add(uc);\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+static const char kByteSymbol = 'B';\r
+static const char kKiloSymbol = 'K';\r
+static const char kMegaSymbol = 'M';\r
+static const char kGigaSymbol = 'G';\r
+\r
+static bool ParseComplexSize(const UString &src, UInt64 &result)\r
+{\r
+  UString s = src;\r
+  s.MakeUpper();\r
+\r
+  const wchar_t *start = s;\r
+  const wchar_t *end;\r
+  UInt64 number = ConvertStringToUInt64(start, &end);\r
+  int numDigits = (int)(end - start);\r
+  if (numDigits == 0 || s.Length() > numDigits + 1)\r
+    return false;\r
+  if (s.Length() == numDigits)\r
+  {\r
+    result = number;\r
+    return true;\r
+  }\r
+  int numBits;\r
+  switch (s[numDigits])\r
+  {\r
+    case kByteSymbol:\r
+      result = number;\r
+      return true;\r
+    case kKiloSymbol:\r
+      numBits = 10;\r
+      break;\r
+    case kMegaSymbol:\r
+      numBits = 20;\r
+      break;\r
+    case kGigaSymbol:\r
+      numBits = 30;\r
+      break;\r
+    default:\r
+      return false;\r
+  }\r
+  if (number >= ((UInt64)1 << (64 - numBits)))\r
+    return false;\r
+  result = number << numBits;\r
+  return true;\r
+}\r
+\r
+static void SetAddCommandOptions(\r
+    NCommandType::EEnum commandType,\r
+    const CParser &parser,\r
+    CUpdateOptions &options)\r
+{\r
+  NUpdateArchive::CActionSet defaultActionSet;\r
+  switch(commandType)\r
+  {\r
+    case NCommandType::kAdd:\r
+      defaultActionSet = NUpdateArchive::kAddActionSet;\r
+      break;\r
+    case NCommandType::kDelete:\r
+      defaultActionSet = NUpdateArchive::kDeleteActionSet;\r
+      break;\r
+    default:\r
+      defaultActionSet = NUpdateArchive::kUpdateActionSet;\r
+  }\r
+  \r
+  options.UpdateArchiveItself = true;\r
+  \r
+  options.Commands.Clear();\r
+  CUpdateArchiveCommand updateMainCommand;\r
+  updateMainCommand.ActionSet = defaultActionSet;\r
+  options.Commands.Add(updateMainCommand);\r
+  if (parser[NKey::kUpdate].ThereIs)\r
+    ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings,\r
+        defaultActionSet);\r
+  if (parser[NKey::kWorkingDir].ThereIs)\r
+  {\r
+    const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];\r
+    if (postString.IsEmpty())\r
+      NDirectory::MyGetTempPath(options.WorkingDir);\r
+    else\r
+      options.WorkingDir = postString;\r
+  }\r
+  options.SfxMode = parser[NKey::kSfx].ThereIs;\r
+  if (options.SfxMode)\r
+    options.SfxModule = parser[NKey::kSfx].PostStrings[0];\r
+\r
+  if (parser[NKey::kVolume].ThereIs)\r
+  {\r
+    const UStringVector &sv = parser[NKey::kVolume].PostStrings;\r
+    for (int i = 0; i < sv.Size(); i++)\r
+    {\r
+      UInt64 size;\r
+      if (!ParseComplexSize(sv[i], size))\r
+        ThrowException("Incorrect volume size");\r
+      options.VolumesSizes.Add(size);\r
+    }\r
+  }\r
+}\r
+\r
+static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &properties)\r
+{\r
+  if (parser[NKey::kProperty].ThereIs)\r
+  {\r
+    // options.MethodMode.Properties.Clear();\r
+    for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)\r
+    {\r
+      CProperty property;\r
+      const UString &postString = parser[NKey::kProperty].PostStrings[i];\r
+      int index = postString.Find(L'=');\r
+      if (index < 0)\r
+        property.Name = postString;\r
+      else\r
+      {\r
+        property.Name = postString.Left(index);\r
+        property.Value = postString.Mid(index + 1);\r
+      }\r
+      properties.Add(property);\r
+    }\r
+  }\r
+}\r
+\r
+CArchiveCommandLineParser::CArchiveCommandLineParser():\r
+  parser(sizeof(kSwitchForms) / sizeof(kSwitchForms[0])) {}\r
+\r
+void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,\r
+    CArchiveCommandLineOptions &options)\r
+{\r
+  try\r
+  {\r
+    parser.ParseStrings(kSwitchForms, commandStrings);\r
+  }\r
+  catch(...)\r
+  {\r
+    ThrowUserErrorException();\r
+  }\r
+\r
+  options.IsInTerminal = MY_IS_TERMINAL(stdin);\r
+  options.IsStdOutTerminal = MY_IS_TERMINAL(stdout);\r
+  options.IsStdErrTerminal = MY_IS_TERMINAL(stderr);\r
+  options.StdInMode = parser[NKey::kStdIn].ThereIs;\r
+  options.StdOutMode = parser[NKey::kStdOut].ThereIs;\r
+  options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;\r
+  options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs  || parser[NKey::kHelp3].ThereIs;\r
+\r
+  #ifdef _WIN32\r
+  options.LargePages = false;\r
+  if (parser[NKey::kLargePages].ThereIs)\r
+  {\r
+    const UString &postString = parser[NKey::kLargePages].PostStrings.Front();\r
+    if (postString.IsEmpty())\r
+      options.LargePages = true;\r
+  }\r
+  #endif\r
+}\r
+\r
+struct CCodePagePair\r
+{\r
+  const wchar_t *Name;\r
+  UINT CodePage;\r
+};\r
+\r
+static CCodePagePair g_CodePagePairs[] =\r
+{\r
+  { L"UTF-8", CP_UTF8 },\r
+  { L"WIN", CP_ACP },\r
+  { L"DOS", CP_OEMCP }\r
+};\r
+\r
+static int FindCharset(const NCommandLineParser::CParser &parser, int keyIndex, int defaultVal)\r
+{\r
+  if (!parser[keyIndex].ThereIs)\r
+    return defaultVal;\r
+\r
+  UString name = parser[keyIndex].PostStrings.Back();\r
+  name.MakeUpper();\r
+  int i;\r
+  for (i = 0; i < sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]); i++)\r
+  {\r
+    const CCodePagePair &pair = g_CodePagePairs[i];\r
+    if (name.Compare(pair.Name) == 0)\r
+      return pair.CodePage;\r
+  }\r
+  if (i == sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]))\r
+    ThrowUserErrorException();\r
+  return -1;\r
+}\r
+\r
+static bool ConvertStringToUInt32(const wchar_t *s, UInt32 &v)\r
+{\r
+  const wchar_t *end;\r
+  UInt64 number = ConvertStringToUInt64(s, &end);\r
+  if (*end != 0)\r
+    return false;\r
+  if (number > (UInt32)0xFFFFFFFF)\r
+    return false;\r
+  v = (UInt32)number;\r
+  return true;\r
+}\r
+\r
+void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,\r
+    UStringVector &sortedPaths,\r
+    UStringVector &sortedFullPaths)\r
+{\r
+  UStringVector paths;\r
+  {\r
+    CDirItems dirItems;\r
+    {\r
+      UStringVector errorPaths;\r
+      CRecordVector<DWORD> errorCodes;\r
+      HRESULT res = EnumerateItems(wildcardCensor, dirItems, NULL, errorPaths, errorCodes);\r
+      if (res != S_OK || errorPaths.Size() > 0)\r
+        throw "cannot find archive";\r
+    }\r
+    for (int i = 0; i < dirItems.Items.Size(); i++)\r
+    {\r
+      const CDirItem &dirItem = dirItems.Items[i];\r
+      if (!dirItem.IsDir())\r
+        paths.Add(dirItems.GetPhyPath(i));\r
+    }\r
+  }\r
+  \r
+  if (paths.Size() == 0)\r
+    throw "there is no such archive";\r
+  \r
+  UStringVector fullPaths;\r
+  \r
+  int i;\r
+  for (i = 0; i < paths.Size(); i++)\r
+  {\r
+    UString fullPath;\r
+    NFile::NDirectory::MyGetFullPathName(paths[i], fullPath);\r
+    fullPaths.Add(fullPath);\r
+  }\r
+  CIntVector indices;\r
+  SortFileNames(fullPaths, indices);\r
+  sortedPaths.Reserve(indices.Size());\r
+  sortedFullPaths.Reserve(indices.Size());\r
+  for (i = 0; i < indices.Size(); i++)\r
+  {\r
+    int index = indices[i];\r
+    sortedPaths.Add(paths[index]);\r
+    sortedFullPaths.Add(fullPaths[index]);\r
+  }\r
+}\r
+\r
+void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)\r
+{\r
+  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;\r
+  int numNonSwitchStrings = nonSwitchStrings.Size();\r
+  if (numNonSwitchStrings < kMinNonSwitchWords)\r
+    ThrowUserErrorException();\r
+\r
+  if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))\r
+    ThrowUserErrorException();\r
+\r
+  options.TechMode = parser[NKey::kTechMode].ThereIs;\r
+  options.CalcCrc = parser[NKey::kCalcCrc].ThereIs;\r
+\r
+  if (parser[NKey::kCaseSensitive].ThereIs)\r
+    g_CaseSensitive = (parser[NKey::kCaseSensitive].PostCharIndex < 0);\r
+\r
+  NRecursedType::EEnum recursedType;\r
+  if (parser[NKey::kRecursed].ThereIs)\r
+    recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);\r
+  else\r
+    recursedType = NRecursedType::kNonRecursed;\r
+\r
+  g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, -1);\r
+  UINT codePage = FindCharset(parser, NKey::kListfileCharSet, CP_UTF8);\r
+\r
+  bool thereAreSwitchIncludes = false;\r
+  if (parser[NKey::kInclude].ThereIs)\r
+  {\r
+    thereAreSwitchIncludes = true;\r
+    AddSwitchWildCardsToCensor(options.WildcardCensor,\r
+        parser[NKey::kInclude].PostStrings, true, recursedType, codePage);\r
+  }\r
+  if (parser[NKey::kExclude].ThereIs)\r
+    AddSwitchWildCardsToCensor(options.WildcardCensor,\r
+        parser[NKey::kExclude].PostStrings, false, recursedType, codePage);\r
\r
+  int curCommandIndex = kCommandIndex + 1;\r
+  bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs &&\r
+      options.Command.CommandType != NCommandType::kBenchmark &&\r
+      options.Command.CommandType != NCommandType::kInfo;\r
+\r
+  bool isExtractGroupCommand = options.Command.IsFromExtractGroup();\r
+  bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;\r
+\r
+  if (isExtractOrList && options.StdInMode)\r
+    thereIsArchiveName = false;\r
+\r
+  if (thereIsArchiveName)\r
+  {\r
+    if (curCommandIndex >= numNonSwitchStrings)\r
+      ThrowUserErrorException();\r
+    options.ArchiveName = nonSwitchStrings[curCommandIndex++];\r
+    if (options.ArchiveName.IsEmpty())\r
+      ThrowUserErrorException();\r
+  }\r
+\r
+  AddToCensorFromNonSwitchesStrings(\r
+      curCommandIndex, options.WildcardCensor,\r
+      nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage);\r
+\r
+  options.YesToAll = parser[NKey::kYes].ThereIs;\r
+\r
+\r
+  #ifndef _NO_CRYPTO\r
+  options.PasswordEnabled = parser[NKey::kPassword].ThereIs;\r
+  if (options.PasswordEnabled)\r
+    options.Password = parser[NKey::kPassword].PostStrings[0];\r
+  #endif\r
+\r
+  options.ShowDialog = parser[NKey::kShowDialog].ThereIs;\r
+\r
+  if (parser[NKey::kArchiveType].ThereIs)\r
+    options.ArcType = parser[NKey::kArchiveType].PostStrings[0];\r
+\r
+  if (isExtractOrList)\r
+  {\r
+    if (!options.WildcardCensor.AllAreRelative())\r
+      ThrowException("Cannot use absolute pathnames for this command");\r
+\r
+    NWildcard::CCensor archiveWildcardCensor;\r
+\r
+    if (parser[NKey::kArInclude].ThereIs)\r
+      AddSwitchWildCardsToCensor(archiveWildcardCensor,\r
+          parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage);\r
+    if (parser[NKey::kArExclude].ThereIs)\r
+      AddSwitchWildCardsToCensor(archiveWildcardCensor,\r
+          parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage);\r
+\r
+    if (thereIsArchiveName)\r
+      AddNameToCensor(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);\r
+\r
+    #ifdef _WIN32\r
+    ConvertToLongNames(archiveWildcardCensor);\r
+    #endif\r
+\r
+    archiveWildcardCensor.ExtendExclude();\r
+\r
+    if (options.StdInMode)\r
+    {\r
+      UString arcName = parser[NKey::kStdIn].PostStrings.Front();\r
+      options.ArchivePathsSorted.Add(arcName);\r
+      options.ArchivePathsFullSorted.Add(arcName);\r
+    }\r
+    else\r
+    {\r
+      EnumerateDirItemsAndSort(archiveWildcardCensor,\r
+        options.ArchivePathsSorted,\r
+        options.ArchivePathsFullSorted);\r
+    }\r
+    \r
+    if (isExtractGroupCommand)\r
+    {\r
+      SetMethodOptions(parser, options.ExtractProperties);\r
+      if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal)\r
+        throw kSameTerminalError;\r
+      if (parser[NKey::kOutputDir].ThereIs)\r
+      {\r
+        options.OutputDir = parser[NKey::kOutputDir].PostStrings[0];\r
+        NFile::NName::NormalizeDirPathPrefix(options.OutputDir);\r
+      }\r
+\r
+      options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;\r
+      if (parser[NKey::kOverwrite].ThereIs)\r
+        options.OverwriteMode = k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];\r
+      else if (options.YesToAll)\r
+        options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;\r
+    }\r
+  }\r
+  else if (options.Command.IsFromUpdateGroup())\r
+  {\r
+    CUpdateOptions &updateOptions = options.UpdateOptions;\r
+\r
+    SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);\r
+    \r
+    SetMethodOptions(parser, updateOptions.MethodMode.Properties);\r
+\r
+    if (parser[NKey::kShareForWrite].ThereIs)\r
+      updateOptions.OpenShareForWrite = true;\r
+\r
+    options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;\r
+\r
+    if (options.EnablePercents)\r
+    {\r
+      if ((options.StdOutMode && !options.IsStdErrTerminal) ||\r
+         (!options.StdOutMode && !options.IsStdOutTerminal))\r
+        options.EnablePercents = false;\r
+    }\r
+\r
+    updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;\r
+    if (updateOptions.EMailMode)\r
+    {\r
+      updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();\r
+      if (updateOptions.EMailAddress.Length() > 0)\r
+        if (updateOptions.EMailAddress[0] == L'.')\r
+        {\r
+          updateOptions.EMailRemoveAfter = true;\r
+          updateOptions.EMailAddress.Delete(0);\r
+        }\r
+    }\r
+\r
+    updateOptions.StdOutMode = options.StdOutMode;\r
+    updateOptions.StdInMode = options.StdInMode;\r
+\r
+    if (updateOptions.StdOutMode && updateOptions.EMailMode)\r
+      throw "stdout mode and email mode cannot be combined";\r
+    if (updateOptions.StdOutMode && options.IsStdOutTerminal)\r
+      throw kTerminalOutError;\r
+    if (updateOptions.StdInMode)\r
+      updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();\r
+\r
+    #ifdef _WIN32\r
+    ConvertToLongNames(options.WildcardCensor);\r
+    #endif\r
+  }\r
+  else if (options.Command.CommandType == NCommandType::kBenchmark)\r
+  {\r
+    options.NumThreads = (UInt32)-1;\r
+    options.DictionarySize = (UInt32)-1;\r
+    options.NumIterations = 1;\r
+    if (curCommandIndex < numNonSwitchStrings)\r
+    {\r
+      if (!ConvertStringToUInt32(nonSwitchStrings[curCommandIndex++], options.NumIterations))\r
+        ThrowUserErrorException();\r
+    }\r
+    for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)\r
+    {\r
+      UString postString = parser[NKey::kProperty].PostStrings[i];\r
+      postString.MakeUpper();\r
+      if (postString.Length() < 2)\r
+        ThrowUserErrorException();\r
+      if (postString[0] == 'D')\r
+      {\r
+        int pos = 1;\r
+        if (postString[pos] == '=')\r
+          pos++;\r
+        UInt32 logSize;\r
+        if (!ConvertStringToUInt32((const wchar_t *)postString + pos, logSize))\r
+          ThrowUserErrorException();\r
+        if (logSize > 31)\r
+          ThrowUserErrorException();\r
+        options.DictionarySize = 1 << logSize;\r
+      }\r
+      else if (postString[0] == 'M' && postString[1] == 'T' )\r
+      {\r
+        int pos = 2;\r
+        if (postString[pos] == '=')\r
+          pos++;\r
+        if (postString[pos] != 0)\r
+          if (!ConvertStringToUInt32((const wchar_t *)postString + pos, options.NumThreads))\r
+            ThrowUserErrorException();\r
+      }\r
+      else if (postString[0] == 'M' && postString[1] == '=' )\r
+      {\r
+        int pos = 2;\r
+        if (postString[pos] != 0)\r
+          options.Method = postString.Mid(2);\r
+      }\r
+      else\r
+        ThrowUserErrorException();\r
+    }\r
+  }\r
+  else if (options.Command.CommandType == NCommandType::kInfo)\r
+  {\r
+  }\r
+  else\r
+    ThrowUserErrorException();\r
+  options.WildcardCensor.ExtendExclude();\r
+}\r
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h
new file mode 100755 (executable)
index 0000000..491689e
--- /dev/null
@@ -0,0 +1,111 @@
+// ArchiveCommandLine.h\r
+\r
+#ifndef __ARCHIVE_COMMAND_LINE_H\r
+#define __ARCHIVE_COMMAND_LINE_H\r
+\r
+#include "Common/CommandLineParser.h"\r
+#include "Common/Wildcard.h"\r
+\r
+#include "Extract.h"\r
+#include "Update.h"\r
+\r
+struct CArchiveCommandLineException: public AString\r
+{\r
+  CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {}\r
+};\r
+\r
+namespace NCommandType { enum EEnum\r
+{\r
+  kAdd = 0,\r
+  kUpdate,\r
+  kDelete,\r
+  kTest,\r
+  kExtract,\r
+  kFullExtract,\r
+  kList,\r
+  kBenchmark,\r
+  kInfo\r
+};}\r
+\r
+namespace NRecursedType { enum EEnum\r
+{\r
+  kRecursed,\r
+  kWildCardOnlyRecursed,\r
+  kNonRecursed\r
+};}\r
+\r
+struct CArchiveCommand\r
+{\r
+  NCommandType::EEnum CommandType;\r
+  bool IsFromExtractGroup() const;\r
+  bool IsFromUpdateGroup() const;\r
+  bool IsTestMode() const { return CommandType == NCommandType::kTest; }\r
+  NExtract::NPathMode::EEnum GetPathMode() const;\r
+};\r
+\r
+struct CArchiveCommandLineOptions\r
+{\r
+  bool HelpMode;\r
+\r
+  #ifdef _WIN32\r
+  bool LargePages;\r
+  #endif\r
+\r
+  bool IsInTerminal;\r
+  bool IsStdOutTerminal;\r
+  bool IsStdErrTerminal;\r
+  bool StdInMode;\r
+  bool StdOutMode;\r
+  bool EnableHeaders;\r
+\r
+  bool YesToAll;\r
+  bool ShowDialog;\r
+  // NWildcard::CCensor ArchiveWildcardCensor;\r
+  NWildcard::CCensor WildcardCensor;\r
+\r
+  CArchiveCommand Command;\r
+  UString ArchiveName;\r
+\r
+  #ifndef _NO_CRYPTO\r
+  bool PasswordEnabled;\r
+  UString Password;\r
+  #endif\r
+\r
+  bool TechMode;\r
+  // Extract\r
+  bool CalcCrc;\r
+  bool AppendName;\r
+  UString OutputDir;\r
+  NExtract::NOverwriteMode::EEnum OverwriteMode;\r
+  UStringVector ArchivePathsSorted;\r
+  UStringVector ArchivePathsFullSorted;\r
+  CObjectVector<CProperty> ExtractProperties;\r
+\r
+  CUpdateOptions UpdateOptions;\r
+  UString ArcType;\r
+  bool EnablePercents;\r
+\r
+  // Benchmark\r
+  UInt32 NumIterations;\r
+  UInt32 NumThreads;\r
+  UInt32 DictionarySize;\r
+  UString Method;\r
+\r
+\r
+  CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};\r
+};\r
+\r
+class CArchiveCommandLineParser\r
+{\r
+  NCommandLineParser::CParser parser;\r
+public:\r
+  CArchiveCommandLineParser();\r
+  void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options);\r
+  void Parse2(CArchiveCommandLineOptions &options);\r
+};\r
+\r
+void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,\r
+    UStringVector &sortedPaths,\r
+    UStringVector &sortedFullPaths);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
new file mode 100755 (executable)
index 0000000..2a322c5
--- /dev/null
@@ -0,0 +1,488 @@
+// ArchiveExtractCallback.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/ComTry.h"\r
+#include "Common/Wildcard.h"\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/FileFind.h"\r
+#include "Windows/PropVariant.h"\r
+#include "Windows/PropVariantConversions.h"\r
+\r
+#include "../../Common/FilePathAutoRename.h"\r
+\r
+#include "../Common/ExtractingFilePath.h"\r
+\r
+#include "ArchiveExtractCallback.h"\r
+\r
+using namespace NWindows;\r
+\r
+static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name";\r
+static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";\r
+static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";\r
+\r
+void CArchiveExtractCallback::Init(\r
+    const NWildcard::CCensorNode *wildcardCensor,\r
+    const CArc *arc,\r
+    IFolderArchiveExtractCallback *extractCallback2,\r
+    bool stdOutMode, bool testMode, bool crcMode,\r
+    const UString &directoryPath,\r
+    const UStringVector &removePathParts,\r
+    UInt64 packSize)\r
+{\r
+  _wildcardCensor = wildcardCensor;\r
+\r
+  _stdOutMode = stdOutMode;\r
+  _testMode = testMode;\r
+  _crcMode = crcMode;\r
+  _unpTotal = 1;\r
+  _packTotal = packSize;\r
+\r
+  _extractCallback2 = extractCallback2;\r
+  _compressProgress.Release();\r
+  _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);\r
+\r
+  LocalProgressSpec->Init(extractCallback2, true);\r
+  LocalProgressSpec->SendProgress = false;\r
+\r
\r
+  _removePathParts = removePathParts;\r
+  _arc = arc;\r
+  _directoryPath = directoryPath;\r
+  NFile::NName::NormalizeDirPathPrefix(_directoryPath);\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)\r
+{\r
+  COM_TRY_BEGIN\r
+  _unpTotal = size;\r
+  if (!_multiArchives && _extractCallback2)\r
+    return _extractCallback2->SetTotal(size);\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)\r
+{\r
+  const UInt64 kMax = (UInt64)1 << 31;\r
+  while (v1 > kMax)\r
+  {\r
+    v1 >>= 1;\r
+    v2 >>= 1;\r
+  }\r
+}\r
+\r
+static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal)\r
+{\r
+  NormalizeVals(packTotal, unpTotal);\r
+  NormalizeVals(unpCur, unpTotal);\r
+  if (unpTotal == 0)\r
+    unpTotal = 1;\r
+  return unpCur * packTotal / unpTotal;\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (!_extractCallback2)\r
+    return S_OK;\r
+\r
+  if (_multiArchives)\r
+  {\r
+    if (completeValue != NULL)\r
+    {\r
+      UInt64 packCur = LocalProgressSpec->InSize + MyMultDiv64(*completeValue, _unpTotal, _packTotal);\r
+      return _extractCallback2->SetCompleted(&packCur);\r
+    }\r
+  }\r
+  return _extractCallback2->SetCompleted(completeValue);\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)\r
+{\r
+  COM_TRY_BEGIN\r
+  return _localProgress->SetRatioInfo(inSize, outSize);\r
+  COM_TRY_END\r
+}\r
+\r
+void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath)\r
+{\r
+  fullPath = _directoryPath;\r
+  for (int i = 0; i < dirPathParts.Size(); i++)\r
+  {\r
+    if (i > 0)\r
+      fullPath += wchar_t(NFile::NName::kDirDelimiter);\r
+    fullPath += dirPathParts[i];\r
+    NFile::NDirectory::MyCreateDirectory(fullPath);\r
+  }\r
+}\r
+\r
+HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)\r
+{\r
+  filetimeIsDefined = false;\r
+  NCOM::CPropVariant prop;\r
+  RINOK(_arc->Archive->GetProperty(index, propID, &prop));\r
+  if (prop.vt == VT_FILETIME)\r
+  {\r
+    filetime = prop.filetime;\r
+    filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0);\r
+  }\r
+  else if (prop.vt != VT_EMPTY)\r
+    return E_FAIL;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CArchiveExtractCallback::GetUnpackSize()\r
+{\r
+  NCOM::CPropVariant prop;\r
+  RINOK(_arc->Archive->GetProperty(_index, kpidSize, &prop));\r
+  _curSizeDefined = (prop.vt != VT_EMPTY);\r
+  if (_curSizeDefined)\r
+    _curSize = ConvertPropVariantToUInt64(prop);\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)\r
+{\r
+  COM_TRY_BEGIN\r
+  _crcStream.Release();\r
+  *outStream = 0;\r
+  _outFileStream.Release();\r
+\r
+  _encrypted = false;\r
+  _isSplit = false;\r
+  _curSize = 0;\r
+  _curSizeDefined = false;\r
+  _index = index;\r
+\r
+  UString fullPath;\r
+\r
+  IInArchive *archive = _arc->Archive;\r
+  RINOK(_arc->GetItemPath(index, fullPath));\r
+  RINOK(IsArchiveItemFolder(archive, index, _fi.IsDir));\r
+\r
+  _filePath = fullPath;\r
+\r
+  {\r
+    NCOM::CPropVariant prop;\r
+    RINOK(archive->GetProperty(index, kpidPosition, &prop));\r
+    if (prop.vt != VT_EMPTY)\r
+    {\r
+      if (prop.vt != VT_UI8)\r
+        return E_FAIL;\r
+      _position = prop.uhVal.QuadPart;\r
+      _isSplit = true;\r
+    }\r
+  }\r
+    \r
+  RINOK(GetArchiveItemBoolProp(archive, index, kpidEncrypted, _encrypted));\r
+\r
+  RINOK(GetUnpackSize());\r
+\r
+  if (_wildcardCensor)\r
+  {\r
+    if (!_wildcardCensor->CheckPath(fullPath, !_fi.IsDir))\r
+      return S_OK;\r
+  }\r
+\r
+  if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)\r
+  {\r
+    if (_stdOutMode)\r
+    {\r
+      CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream;\r
+      *outStream = outStreamLoc.Detach();\r
+      return S_OK;\r
+    }\r
+\r
+    {\r
+      NCOM::CPropVariant prop;\r
+      RINOK(archive->GetProperty(index, kpidAttrib, &prop));\r
+      if (prop.vt == VT_UI4)\r
+      {\r
+        _fi.Attrib = prop.ulVal;\r
+        _fi.AttribDefined = true;\r
+      }\r
+      else if (prop.vt == VT_EMPTY)\r
+        _fi.AttribDefined = false;\r
+      else\r
+        return E_FAIL;\r
+    }\r
+\r
+    RINOK(GetTime(index, kpidCTime, _fi.CTime, _fi.CTimeDefined));\r
+    RINOK(GetTime(index, kpidATime, _fi.ATime, _fi.ATimeDefined));\r
+    RINOK(GetTime(index, kpidMTime, _fi.MTime, _fi.MTimeDefined));\r
+\r
+    bool isAnti = false;\r
+    RINOK(_arc->IsItemAnti(index, isAnti));\r
+\r
+    UStringVector pathParts;\r
+    SplitPathToParts(fullPath, pathParts);\r
+    \r
+    if (pathParts.IsEmpty())\r
+      return E_FAIL;\r
+    int numRemovePathParts = 0;\r
+    switch(_pathMode)\r
+    {\r
+      case NExtract::NPathMode::kFullPathnames:\r
+        break;\r
+      case NExtract::NPathMode::kCurrentPathnames:\r
+      {\r
+        numRemovePathParts = _removePathParts.Size();\r
+        if (pathParts.Size() <= numRemovePathParts)\r
+          return E_FAIL;\r
+        for (int i = 0; i < numRemovePathParts; i++)\r
+          if (_removePathParts[i].CompareNoCase(pathParts[i]) != 0)\r
+            return E_FAIL;\r
+        break;\r
+      }\r
+      case NExtract::NPathMode::kNoPathnames:\r
+      {\r
+        numRemovePathParts = pathParts.Size() - 1;\r
+        break;\r
+      }\r
+    }\r
+    pathParts.Delete(0, numRemovePathParts);\r
+    MakeCorrectPath(pathParts);\r
+    UString processedPath = MakePathNameFromParts(pathParts);\r
+    if (!isAnti)\r
+    {\r
+      if (!_fi.IsDir)\r
+      {\r
+        if (!pathParts.IsEmpty())\r
+          pathParts.DeleteBack();\r
+      }\r
+    \r
+      if (!pathParts.IsEmpty())\r
+      {\r
+        UString fullPathNew;\r
+        CreateComplexDirectory(pathParts, fullPathNew);\r
+        if (_fi.IsDir)\r
+          NFile::NDirectory::SetDirTime(fullPathNew,\r
+            (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,\r
+            (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,\r
+            (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));\r
+      }\r
+    }\r
+\r
+\r
+    UString fullProcessedPath = _directoryPath + processedPath;\r
+\r
+    if (_fi.IsDir)\r
+    {\r
+      _diskFilePath = fullProcessedPath;\r
+      if (isAnti)\r
+        NFile::NDirectory::MyRemoveDirectory(_diskFilePath);\r
+      return S_OK;\r
+    }\r
+\r
+    if (!_isSplit)\r
+    {\r
+    NFile::NFind::CFileInfoW fileInfo;\r
+    if (fileInfo.Find(fullProcessedPath))\r
+    {\r
+      switch(_overwriteMode)\r
+      {\r
+        case NExtract::NOverwriteMode::kSkipExisting:\r
+          return S_OK;\r
+        case NExtract::NOverwriteMode::kAskBefore:\r
+        {\r
+          Int32 overwiteResult;\r
+          RINOK(_extractCallback2->AskOverwrite(\r
+              fullProcessedPath, &fileInfo.MTime, &fileInfo.Size, fullPath,\r
+              _fi.MTimeDefined ? &_fi.MTime : NULL,\r
+              _curSizeDefined ? &_curSize : NULL,\r
+              &overwiteResult))\r
+\r
+          switch(overwiteResult)\r
+          {\r
+            case NOverwriteAnswer::kCancel:\r
+              return E_ABORT;\r
+            case NOverwriteAnswer::kNo:\r
+              return S_OK;\r
+            case NOverwriteAnswer::kNoToAll:\r
+              _overwriteMode = NExtract::NOverwriteMode::kSkipExisting;\r
+              return S_OK;\r
+            case NOverwriteAnswer::kYesToAll:\r
+              _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;\r
+              break;\r
+            case NOverwriteAnswer::kYes:\r
+              break;\r
+            case NOverwriteAnswer::kAutoRename:\r
+              _overwriteMode = NExtract::NOverwriteMode::kAutoRename;\r
+              break;\r
+            default:\r
+              return E_FAIL;\r
+          }\r
+        }\r
+      }\r
+      if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename)\r
+      {\r
+        if (!AutoRenamePath(fullProcessedPath))\r
+        {\r
+          UString message = UString(kCantAutoRename) + fullProcessedPath;\r
+          RINOK(_extractCallback2->MessageError(message));\r
+          return E_FAIL;\r
+        }\r
+      }\r
+      else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)\r
+      {\r
+        UString existPath = fullProcessedPath;\r
+        if (!AutoRenamePath(existPath))\r
+        {\r
+          UString message = kCantAutoRename + fullProcessedPath;\r
+          RINOK(_extractCallback2->MessageError(message));\r
+          return E_FAIL;\r
+        }\r
+        if (!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))\r
+        {\r
+          UString message = UString(kCantRenameFile) + fullProcessedPath;\r
+          RINOK(_extractCallback2->MessageError(message));\r
+          return E_FAIL;\r
+        }\r
+      }\r
+      else\r
+        if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))\r
+        {\r
+          UString message = UString(kCantDeleteOutputFile) +  fullProcessedPath;\r
+          RINOK(_extractCallback2->MessageError(message));\r
+          return S_OK;\r
+          // return E_FAIL;\r
+        }\r
+    }\r
+    }\r
+    if (!isAnti)\r
+    {\r
+      _outFileStreamSpec = new COutFileStream;\r
+      CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);\r
+      if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))\r
+      {\r
+        // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)\r
+        {\r
+          UString message = L"can not open output file " + fullProcessedPath;\r
+          RINOK(_extractCallback2->MessageError(message));\r
+          return S_OK;\r
+        }\r
+      }\r
+      if (_isSplit)\r
+      {\r
+        RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));\r
+      }\r
+      _outFileStream = outStreamLoc;\r
+      *outStream = outStreamLoc.Detach();\r
+    }\r
+    _diskFilePath = fullProcessedPath;\r
+  }\r
+  else\r
+  {\r
+    *outStream = NULL;\r
+  }\r
+  if (_crcMode)\r
+  {\r
+    _crcStreamSpec = new COutStreamWithCRC;\r
+    _crcStream = _crcStreamSpec;\r
+    CMyComPtr<ISequentialOutStream> crcStream = _crcStreamSpec;\r
+    _crcStreamSpec->SetStream(*outStream);\r
+    if (*outStream)\r
+      (*outStream)->Release();\r
+    *outStream = crcStream.Detach();\r
+    _crcStreamSpec->Init(true);\r
+  }\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)\r
+{\r
+  COM_TRY_BEGIN\r
+  _extractMode = false;\r
+  switch (askExtractMode)\r
+  {\r
+    case NArchive::NExtract::NAskMode::kExtract:\r
+      if (_testMode)\r
+        askExtractMode = NArchive::NExtract::NAskMode::kTest;\r
+      else\r
+        _extractMode = true;\r
+      break;\r
+  };\r
+  return _extractCallback2->PrepareOperation(_filePath, _fi.IsDir,\r
+      askExtractMode, _isSplit ? &_position: 0);\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)\r
+{\r
+  COM_TRY_BEGIN\r
+  switch(operationResult)\r
+  {\r
+    case NArchive::NExtract::NOperationResult::kOK:\r
+    case NArchive::NExtract::NOperationResult::kUnSupportedMethod:\r
+    case NArchive::NExtract::NOperationResult::kCRCError:\r
+    case NArchive::NExtract::NOperationResult::kDataError:\r
+      break;\r
+    default:\r
+      _outFileStream.Release();\r
+      return E_FAIL;\r
+  }\r
+  if (_crcStream)\r
+  {\r
+    CrcSum += _crcStreamSpec->GetCRC();\r
+    _curSize = _crcStreamSpec->GetSize();\r
+    _curSizeDefined = true;\r
+    _crcStream.Release();\r
+  }\r
+  if (_outFileStream)\r
+  {\r
+    _outFileStreamSpec->SetTime(\r
+        (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,\r
+        (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,\r
+        (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));\r
+    _curSize = _outFileStreamSpec->ProcessedSize;\r
+    _curSizeDefined = true;\r
+    RINOK(_outFileStreamSpec->Close());\r
+    _outFileStream.Release();\r
+  }\r
+  if (!_curSizeDefined)\r
+    GetUnpackSize();\r
+  if (_curSizeDefined)\r
+    UnpackSize += _curSize;\r
+  if (_fi.IsDir)\r
+    NumFolders++;\r
+  else\r
+    NumFiles++;\r
+\r
+  if (_extractMode && _fi.AttribDefined)\r
+    NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib);\r
+  RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+/*\r
+STDMETHODIMP CArchiveExtractCallback::GetInStream(\r
+    const wchar_t *name, ISequentialInStream **inStream)\r
+{\r
+  COM_TRY_BEGIN\r
+  CInFileStream *inFile = new CInFileStream;\r
+  CMyComPtr<ISequentialInStream> inStreamTemp = inFile;\r
+  if (!inFile->Open(_srcDirectoryPrefix + name))\r
+    return ::GetLastError();\r
+  *inStream = inStreamTemp.Detach();\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+*/\r
+\r
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (!_cryptoGetTextPassword)\r
+  {\r
+    RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword,\r
+        &_cryptoGetTextPassword));\r
+  }\r
+  return _cryptoGetTextPassword->CryptoGetTextPassword(password);\r
+  COM_TRY_END\r
+}\r
+\r
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
new file mode 100755 (executable)
index 0000000..b7a6a47
--- /dev/null
@@ -0,0 +1,143 @@
+// ArchiveExtractCallback.h\r
+\r
+#ifndef __ARCHIVE_EXTRACT_CALLBACK_H\r
+#define __ARCHIVE_EXTRACT_CALLBACK_H\r
+\r
+#include "Common/MyCom.h"\r
+#include "Common/Wildcard.h"\r
+\r
+#include "../../IPassword.h"\r
+\r
+#include "../../Common/FileStreams.h"\r
+#include "../../Common/ProgressUtils.h"\r
+\r
+#include "../../Archive/IArchive.h"\r
+\r
+#include "../../Archive/Common/OutStreamWithCRC.h"\r
+\r
+#include "ExtractMode.h"\r
+#include "IFileExtractCallback.h"\r
+#include "OpenArchive.h"\r
+\r
+class CArchiveExtractCallback:\r
+  public IArchiveExtractCallback,\r
+  // public IArchiveVolumeExtractCallback,\r
+  public ICryptoGetTextPassword,\r
+  public ICompressProgressInfo,\r
+  public CMyUnknownImp\r
+{\r
+  const CArc *_arc;\r
+  const NWildcard::CCensorNode *_wildcardCensor;\r
+  CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;\r
+  CMyComPtr<ICompressProgressInfo> _compressProgress;\r
+  CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;\r
+  UString _directoryPath;\r
+  NExtract::NPathMode::EEnum _pathMode;\r
+  NExtract::NOverwriteMode::EEnum _overwriteMode;\r
+\r
+  UString _diskFilePath;\r
+  UString _filePath;\r
+  UInt64 _position;\r
+  bool _isSplit;\r
+\r
+  bool _extractMode;\r
+\r
+  bool WriteCTime;\r
+  bool WriteATime;\r
+  bool WriteMTime;\r
+\r
+  bool _encrypted;\r
+\r
+  struct CProcessedFileInfo\r
+  {\r
+    FILETIME CTime;\r
+    FILETIME ATime;\r
+    FILETIME MTime;\r
+    UInt32 Attrib;\r
+  \r
+    bool CTimeDefined;\r
+    bool ATimeDefined;\r
+    bool MTimeDefined;\r
+    bool AttribDefined;\r
+\r
+    bool IsDir;\r
+  } _fi;\r
+\r
+  UInt32 _index;\r
+  UInt64 _curSize;\r
+  bool _curSizeDefined;\r
+  COutFileStream *_outFileStreamSpec;\r
+  CMyComPtr<ISequentialOutStream> _outFileStream;\r
+\r
+  COutStreamWithCRC *_crcStreamSpec;\r
+  CMyComPtr<ISequentialOutStream> _crcStream;\r
+\r
+  UStringVector _removePathParts;\r
+\r
+  bool _stdOutMode;\r
+  bool _testMode;\r
+  bool _crcMode;\r
+  bool _multiArchives;\r
+\r
+  CMyComPtr<ICompressProgressInfo> _localProgress;\r
+  UInt64 _packTotal;\r
+  UInt64 _unpTotal;\r
+\r
+  void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath);\r
+  HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);\r
+  HRESULT GetUnpackSize();\r
+\r
+public:\r
+\r
+  CLocalProgress *LocalProgressSpec;\r
+\r
+  UInt64 NumFolders;\r
+  UInt64 NumFiles;\r
+  UInt64 UnpackSize;\r
+  UInt32 CrcSum;\r
+  \r
+  MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)\r
+  // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)\r
+\r
+  INTERFACE_IArchiveExtractCallback(;)\r
+\r
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);\r
+\r
+  // IArchiveVolumeExtractCallback\r
+  // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);\r
+\r
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);\r
+\r
+  CArchiveExtractCallback():\r
+      WriteCTime(true),\r
+      WriteATime(true),\r
+      WriteMTime(true),\r
+      _multiArchives(false)\r
+  {\r
+    LocalProgressSpec = new CLocalProgress();\r
+    _localProgress = LocalProgressSpec;\r
+  }\r
+\r
+  void InitForMulti(bool multiArchives,\r
+      NExtract::NPathMode::EEnum pathMode,\r
+      NExtract::NOverwriteMode::EEnum overwriteMode)\r
+  {\r
+    _multiArchives = multiArchives;\r
+    _pathMode = pathMode;\r
+    _overwriteMode = overwriteMode;\r
+    NumFolders = NumFiles = UnpackSize = 0;\r
+    CrcSum = 0;\r
+  }\r
+\r
+  void Init(\r
+      const NWildcard::CCensorNode *wildcardCensor,\r
+      const CArc *arc,\r
+      IFolderArchiveExtractCallback *extractCallback2,\r
+      bool stdOutMode, bool testMode, bool crcMode,\r
+      const UString &directoryPath,\r
+      const UStringVector &removePathParts,\r
+      UInt64 packSize);\r
+\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp
new file mode 100755 (executable)
index 0000000..c62c7f1
--- /dev/null
@@ -0,0 +1,54 @@
+// ArchiveName.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/FileFind.h"\r
+\r
+#include "ExtractingFilePath.h"\r
+\r
+using namespace NWindows;\r
+\r
+static UString CreateArchiveName2(const UString &srcName, bool fromPrev, bool keepName)\r
+{\r
+  UString resultName = L"Archive";\r
+  if (fromPrev)\r
+  {\r
+    UString dirPrefix;\r
+    if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix))\r
+    {\r
+      if (dirPrefix.Length() > 0)\r
+        if (dirPrefix[dirPrefix.Length() - 1] == WCHAR_PATH_SEPARATOR)\r
+        {\r
+          dirPrefix.Delete(dirPrefix.Length() - 1);\r
+          NFile::NFind::CFileInfoW fileInfo;\r
+          if (fileInfo.Find(dirPrefix))\r
+            resultName = fileInfo.Name;\r
+        }\r
+    }\r
+  }\r
+  else\r
+  {\r
+    NFile::NFind::CFileInfoW fileInfo;\r
+    if (!fileInfo.Find(srcName))\r
+      // return resultName;\r
+      return srcName;\r
+    resultName = fileInfo.Name;\r
+    if (!fileInfo.IsDir() && !keepName)\r
+    {\r
+      int dotPos = resultName.ReverseFind('.');\r
+      if (dotPos > 0)\r
+      {\r
+        UString archiveName2 = resultName.Left(dotPos);\r
+        if (archiveName2.ReverseFind('.') < 0)\r
+          resultName = archiveName2;\r
+      }\r
+    }\r
+  }\r
+  return resultName;\r
+}\r
+\r
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)\r
+{\r
+  return GetCorrectFsPath(CreateArchiveName2(srcName, fromPrev, keepName));\r
+}\r
diff --git a/CPP/7zip/UI/Common/ArchiveName.h b/CPP/7zip/UI/Common/ArchiveName.h
new file mode 100755 (executable)
index 0000000..ba18eea
--- /dev/null
@@ -0,0 +1,10 @@
+// ArchiveName.h\r
+\r
+#ifndef __ARCHIVENAME_H\r
+#define __ARCHIVENAME_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
new file mode 100755 (executable)
index 0000000..bb8b6cc
--- /dev/null
@@ -0,0 +1,133 @@
+// ArchiveOpenCallback.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/StringConvert.h"\r
+#include "Common/ComTry.h"\r
+\r
+#include "Windows/PropVariant.h"\r
+\r
+#include "../../Common/FileStreams.h"\r
+\r
+#include "ArchiveOpenCallback.h"\r
+\r
+using namespace NWindows;\r
+\r
+STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (ReOpenCallback)\r
+    return ReOpenCallback->SetTotal(files, bytes);\r
+  if (!Callback)\r
+    return S_OK;\r
+  return Callback->Open_SetTotal(files, bytes);\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (ReOpenCallback)\r
+    return ReOpenCallback->SetCompleted(files, bytes);\r
+  if (!Callback)\r
+    return S_OK;\r
+  return Callback->Open_SetCompleted(files, bytes);\r
+  COM_TRY_END\r
+}\r
+  \r
+STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)\r
+{\r
+  COM_TRY_BEGIN\r
+  NCOM::CPropVariant prop;\r
+  if (_subArchiveMode)\r
+    switch(propID)\r
+    {\r
+      case kpidName: prop = _subArchiveName; break;\r
+    }\r
+  else\r
+    switch(propID)\r
+    {\r
+      case kpidName:  prop = _fileInfo.Name; break;\r
+      case kpidIsDir:  prop = _fileInfo.IsDir(); break;\r
+      case kpidSize:  prop = _fileInfo.Size; break;\r
+      case kpidAttrib:  prop = (UInt32)_fileInfo.Attrib; break;\r
+      case kpidCTime:  prop = _fileInfo.CTime; break;\r
+      case kpidATime:  prop = _fileInfo.ATime; break;\r
+      case kpidMTime:  prop = _fileInfo.MTime; break;\r
+    }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+int COpenCallbackImp::FindName(const UString &name)\r
+{\r
+  for (int i = 0; i < FileNames.Size(); i++)\r
+    if (name.CompareNoCase(FileNames[i]) == 0)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+struct CInFileStreamVol: public CInFileStream\r
+{\r
+  UString Name;\r
+  COpenCallbackImp *OpenCallbackImp;\r
+  CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;\r
+  ~CInFileStreamVol()\r
+  {\r
+    if (OpenCallbackRef)\r
+    {\r
+      int index = OpenCallbackImp->FindName(Name);\r
+      if (index >= 0)\r
+        OpenCallbackImp->FileNames.Delete(index);\r
+    }\r
+  }\r
+};\r
+\r
+STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (_subArchiveMode)\r
+    return S_FALSE;\r
+  if (Callback)\r
+  {\r
+    RINOK(Callback->Open_CheckBreak());\r
+  }\r
+  *inStream = NULL;\r
+  UString fullPath = _folderPrefix + name;\r
+  if (!_fileInfo.Find(fullPath))\r
+    return S_FALSE;\r
+  if (_fileInfo.IsDir())\r
+    return S_FALSE;\r
+  CInFileStreamVol *inFile = new CInFileStreamVol;\r
+  CMyComPtr<IInStream> inStreamTemp = inFile;\r
+  if (!inFile->Open(fullPath))\r
+    return ::GetLastError();\r
+  *inStream = inStreamTemp.Detach();\r
+  inFile->Name = name;\r
+  inFile->OpenCallbackImp = this;\r
+  inFile->OpenCallbackRef = this;\r
+  FileNames.Add(name);\r
+  TotalSize += _fileInfo.Size;\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+#ifndef _NO_CRYPTO\r
+STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)\r
+{\r
+  COM_TRY_BEGIN\r
+  if (ReOpenCallback)\r
+  {\r
+    CMyComPtr<ICryptoGetTextPassword> getTextPassword;\r
+    ReOpenCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);\r
+    if (getTextPassword)\r
+      return getTextPassword->CryptoGetTextPassword(password);\r
+  }\r
+  if (!Callback)\r
+    return E_NOTIMPL;\r
+  return Callback->Open_CryptoGetTextPassword(password);\r
+  COM_TRY_END\r
+}\r
+#endif\r
+  \r
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
new file mode 100755 (executable)
index 0000000..a60fca3
--- /dev/null
@@ -0,0 +1,103 @@
+// ArchiveOpenCallback.h\r
+\r
+#ifndef __ARCHIVE_OPEN_CALLBACK_H\r
+#define __ARCHIVE_OPEN_CALLBACK_H\r
+\r
+#include "Common/MyCom.h"\r
+#include "Common/MyString.h"\r
+\r
+#include "Windows/FileFind.h"\r
+\r
+#ifndef _NO_CRYPTO\r
+#include "../../IPassword.h"\r
+#endif\r
+#include "../../Archive/IArchive.h"\r
+\r
+#ifdef _NO_CRYPTO\r
+\r
+#define INTERFACE_IOpenCallbackUI_Crypto(x)\r
+\r
+#else\r
+\r
+#define INTERFACE_IOpenCallbackUI_Crypto(x) \\r
+  virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x; \\r
+  virtual HRESULT Open_GetPasswordIfAny(UString &password) x; \\r
+  virtual bool Open_WasPasswordAsked() x; \\r
+  virtual void Open_ClearPasswordWasAskedFlag() x; \\r
+  \r
+#endif\r
+\r
+#define INTERFACE_IOpenCallbackUI(x) \\r
+  virtual HRESULT Open_CheckBreak() x; \\r
+  virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x; \\r
+  virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x; \\r
+  INTERFACE_IOpenCallbackUI_Crypto(x)\r
+\r
+struct IOpenCallbackUI\r
+{\r
+  INTERFACE_IOpenCallbackUI(=0)\r
+};\r
+\r
+class COpenCallbackImp:\r
+  public IArchiveOpenCallback,\r
+  public IArchiveOpenVolumeCallback,\r
+  public IArchiveOpenSetSubArchiveName,\r
+  #ifndef _NO_CRYPTO\r
+  public ICryptoGetTextPassword,\r
+  #endif\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  #ifndef _NO_CRYPTO\r
+  MY_UNKNOWN_IMP3(\r
+      IArchiveOpenVolumeCallback,\r
+      ICryptoGetTextPassword,\r
+      IArchiveOpenSetSubArchiveName\r
+      )\r
+  #else\r
+  MY_UNKNOWN_IMP2(\r
+      IArchiveOpenVolumeCallback,\r
+      IArchiveOpenSetSubArchiveName\r
+      )\r
+  #endif\r
+\r
+  INTERFACE_IArchiveOpenCallback(;)\r
+  INTERFACE_IArchiveOpenVolumeCallback(;)\r
+\r
+  #ifndef _NO_CRYPTO\r
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);\r
+  #endif\r
+\r
+  STDMETHOD(SetSubArchiveName(const wchar_t *name))\r
+  {\r
+    _subArchiveMode = true;\r
+    _subArchiveName = name;\r
+    TotalSize = 0;\r
+    return  S_OK;\r
+  }\r
+\r
+private:\r
+  UString _folderPrefix;\r
+  NWindows::NFile::NFind::CFileInfoW _fileInfo;\r
+  bool _subArchiveMode;\r
+  UString _subArchiveName;\r
+public:\r
+  UStringVector FileNames;\r
+  IOpenCallbackUI *Callback;\r
+  CMyComPtr<IArchiveOpenCallback> ReOpenCallback;\r
+  UInt64 TotalSize;\r
+\r
+  COpenCallbackImp(): Callback(NULL) {}\r
+  void Init(const UString &folderPrefix, const UString &fileName)\r
+  {\r
+    _folderPrefix = folderPrefix;\r
+    if (!_fileInfo.Find(_folderPrefix + fileName))\r
+      throw 1;\r
+    FileNames.Clear();\r
+    _subArchiveMode = false;\r
+    TotalSize = 0;\r
+  }\r
+  int FindName(const UString &name);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp
new file mode 100755 (executable)
index 0000000..0c85695
--- /dev/null
@@ -0,0 +1,1028 @@
+// Bench.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Bench.h"\r
+\r
+#ifndef _WIN32\r
+#define USE_POSIX_TIME\r
+#define USE_POSIX_TIME2\r
+#endif\r
+\r
+#ifdef USE_POSIX_TIME\r
+#include <time.h>\r
+#ifdef USE_POSIX_TIME2\r
+#include <sys/time.h>\r
+#endif\r
+#endif\r
+\r
+#ifdef _WIN32\r
+#define USE_ALLOCA\r
+#endif\r
+\r
+#ifdef USE_ALLOCA\r
+#ifdef _WIN32\r
+#include <malloc.h>\r
+#else\r
+#include <stdlib.h>\r
+#endif\r
+#endif\r
+\r
+#include "../../../../C/7zCrc.h"\r
+#include "../../../../C/Alloc.h"\r
+\r
+#ifndef _7ZIP_ST\r
+#include "../../../Windows/Synchronization.h"\r
+#include "../../../Windows/Thread.h"\r
+#endif\r
+\r
+#include "../../../Windows/PropVariant.h"\r
+\r
+static const UInt32 kUncompressMinBlockSize =\r
+#ifdef UNDER_CE\r
+1 << 24;\r
+#else\r
+1 << 26;\r
+#endif\r
+\r
+static const UInt32 kCrcBlockSize =\r
+#ifdef UNDER_CE\r
+1 << 25;\r
+#else\r
+1 << 30;\r
+#endif\r
+\r
+static const UInt32 kAdditionalSize = (1 << 16);\r
+static const UInt32 kCompressedAdditionalSize = (1 << 10);\r
+static const UInt32 kMaxLzmaPropSize = 5;\r
+\r
+class CBaseRandomGenerator\r
+{\r
+  UInt32 A1;\r
+  UInt32 A2;\r
+public:\r
+  CBaseRandomGenerator() { Init(); }\r
+  void Init() { A1 = 362436069; A2 = 521288629;}\r
+  UInt32 GetRnd()\r
+  {\r
+    return\r
+      ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +\r
+      ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );\r
+  }\r
+};\r
+\r
+class CBenchBuffer\r
+{\r
+public:\r
+  size_t BufferSize;\r
+  Byte *Buffer;\r
+  CBenchBuffer(): Buffer(0) {}\r
+  virtual ~CBenchBuffer() { Free(); }\r
+  void Free()\r
+  {\r
+    ::MidFree(Buffer);\r
+    Buffer = 0;\r
+  }\r
+  bool Alloc(size_t bufferSize)\r
+  {\r
+    if (Buffer != 0 && BufferSize == bufferSize)\r
+      return true;\r
+    Free();\r
+    Buffer = (Byte *)::MidAlloc(bufferSize);\r
+    BufferSize = bufferSize;\r
+    return (Buffer != 0);\r
+  }\r
+};\r
+\r
+class CBenchRandomGenerator: public CBenchBuffer\r
+{\r
+  CBaseRandomGenerator *RG;\r
+public:\r
+  void Set(CBaseRandomGenerator *rg) { RG = rg; }\r
+  UInt32 GetVal(UInt32 &res, int numBits)\r
+  {\r
+    UInt32 val = res & (((UInt32)1 << numBits) - 1);\r
+    res >>= numBits;\r
+    return val;\r
+  }\r
+  UInt32 GetLen(UInt32 &res)\r
+  {\r
+    UInt32 len = GetVal(res, 2);\r
+    return GetVal(res, 1 + len);\r
+  }\r
+  void Generate()\r
+  {\r
+    UInt32 pos = 0;\r
+    UInt32 rep0 = 1;\r
+    while (pos < BufferSize)\r
+    {\r
+      UInt32 res = RG->GetRnd();\r
+      res >>= 1;\r
+      if (GetVal(res, 1) == 0 || pos < 1024)\r
+        Buffer[pos++] = (Byte)(res & 0xFF);\r
+      else\r
+      {\r
+        UInt32 len;\r
+        len = 1 + GetLen(res);\r
+        if (GetVal(res, 3) != 0)\r
+        {\r
+          len += GetLen(res);\r
+          do\r
+          {\r
+            UInt32 ppp = GetVal(res, 5) + 6;\r
+            res = RG->GetRnd();\r
+            if (ppp > 30)\r
+              continue;\r
+            rep0 = /* (1 << ppp) +*/  GetVal(res, ppp);\r
+            res = RG->GetRnd();\r
+          }\r
+          while (rep0 >= pos);\r
+          rep0++;\r
+        }\r
+\r
+        for (UInt32 i = 0; i < len && pos < BufferSize; i++, pos++)\r
+          Buffer[pos] = Buffer[pos - rep0];\r
+      }\r
+    }\r
+  }\r
+};\r
+\r
+\r
+class CBenchmarkInStream:\r
+  public ISequentialInStream,\r
+  public CMyUnknownImp\r
+{\r
+  const Byte *Data;\r
+  size_t Pos;\r
+  size_t Size;\r
+public:\r
+  MY_UNKNOWN_IMP\r
+  void Init(const Byte *data, size_t size)\r
+  {\r
+    Data = data;\r
+    Size = size;\r
+    Pos = 0;\r
+  }\r
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  size_t remain = Size - Pos;\r
+  UInt32 kMaxBlockSize = (1 << 20);\r
+  if (size > kMaxBlockSize)\r
+    size = kMaxBlockSize;\r
+  if (size > remain)\r
+    size = (UInt32)remain;\r
+  for (UInt32 i = 0; i < size; i++)\r
+    ((Byte *)data)[i] = Data[Pos + i];\r
+  Pos += size;\r
+  if(processedSize != NULL)\r
+    *processedSize = size;\r
+  return S_OK;\r
+}\r
+  \r
+class CBenchmarkOutStream:\r
+  public ISequentialOutStream,\r
+  public CBenchBuffer,\r
+  public CMyUnknownImp\r
+{\r
+  // bool _overflow;\r
+public:\r
+  UInt32 Pos;\r
+  // CBenchmarkOutStream(): _overflow(false) {}\r
+  void Init()\r
+  {\r
+    // _overflow = false;\r
+    Pos = 0;\r
+  }\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  size_t curSize = BufferSize - Pos;\r
+  if (curSize > size)\r
+    curSize = size;\r
+  memcpy(Buffer + Pos, data, curSize);\r
+  Pos += (UInt32)curSize;\r
+  if(processedSize != NULL)\r
+    *processedSize = (UInt32)curSize;\r
+  if (curSize != size)\r
+  {\r
+    // _overflow = true;\r
+    return E_FAIL;\r
+  }\r
+  return S_OK;\r
+}\r
+  \r
+class CCrcOutStream:\r
+  public ISequentialOutStream,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  UInt32 Crc;\r
+  MY_UNKNOWN_IMP\r
+  void Init() { Crc = CRC_INIT_VAL; }\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+};\r
+\r
+STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  Crc = CrcUpdate(Crc, data, size);\r
+  if (processedSize != NULL)\r
+    *processedSize = size;\r
+  return S_OK;\r
+}\r
+  \r
+static UInt64 GetTimeCount()\r
+{\r
+  #ifdef USE_POSIX_TIME\r
+  #ifdef USE_POSIX_TIME2\r
+  timeval v;\r
+  if (gettimeofday(&v, 0) == 0)\r
+    return (UInt64)(v.tv_sec) * 1000000 + v.tv_usec;\r
+  return (UInt64)time(NULL) * 1000000;\r
+  #else\r
+  return time(NULL);\r
+  #endif\r
+  #else\r
+  /*\r
+  LARGE_INTEGER value;\r
+  if (::QueryPerformanceCounter(&value))\r
+    return value.QuadPart;\r
+  */\r
+  return GetTickCount();\r
+  #endif\r
+}\r
+\r
+static UInt64 GetFreq()\r
+{\r
+  #ifdef USE_POSIX_TIME\r
+  #ifdef USE_POSIX_TIME2\r
+  return 1000000;\r
+  #else\r
+  return 1;\r
+  #endif\r
+  #else\r
+  /*\r
+  LARGE_INTEGER value;\r
+  if (::QueryPerformanceFrequency(&value))\r
+    return value.QuadPart;\r
+  */\r
+  return 1000;\r
+  #endif\r
+}\r
+\r
+#ifndef USE_POSIX_TIME\r
+static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }\r
+#endif\r
+\r
+static UInt64 GetUserTime()\r
+{\r
+  #ifdef USE_POSIX_TIME\r
+  return clock();\r
+  #else\r
+  FILETIME creationTime, exitTime, kernelTime, userTime;\r
+  if (\r
+  #ifdef UNDER_CE\r
+    ::GetThreadTimes(::GetCurrentThread()\r
+  #else\r
+    ::GetProcessTimes(::GetCurrentProcess()\r
+  #endif\r
+    , &creationTime, &exitTime, &kernelTime, &userTime) != 0)\r
+    return GetTime64(userTime) + GetTime64(kernelTime);\r
+  return (UInt64)GetTickCount() * 10000;\r
+  #endif\r
+}\r
+\r
+static UInt64 GetUserFreq()\r
+{\r
+  #ifdef USE_POSIX_TIME\r
+  return CLOCKS_PER_SEC;\r
+  #else\r
+  return 10000000;\r
+  #endif\r
+}\r
+\r
+class CBenchProgressStatus\r
+{\r
+  #ifndef _7ZIP_ST\r
+  NWindows::NSynchronization::CCriticalSection CS;\r
+  #endif\r
+public:\r
+  HRESULT Res;\r
+  bool EncodeMode;\r
+  void SetResult(HRESULT res)\r
+  {\r
+    #ifndef _7ZIP_ST\r
+    NWindows::NSynchronization::CCriticalSectionLock lock(CS);\r
+    #endif\r
+    Res = res;\r
+  }\r
+  HRESULT GetResult()\r
+  {\r
+    #ifndef _7ZIP_ST\r
+    NWindows::NSynchronization::CCriticalSectionLock lock(CS);\r
+    #endif\r
+    return Res;\r
+  }\r
+};\r
+\r
+class CBenchProgressInfo:\r
+  public ICompressProgressInfo,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  CBenchProgressStatus *Status;\r
+  CBenchInfo BenchInfo;\r
+  HRESULT Res;\r
+  IBenchCallback *callback;\r
+  CBenchProgressInfo(): callback(0) {}\r
+  MY_UNKNOWN_IMP\r
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);\r
+};\r
+\r
+static void SetStartTime(CBenchInfo &bi)\r
+{\r
+  bi.GlobalFreq = GetFreq();\r
+  bi.UserFreq = GetUserFreq();\r
+  bi.GlobalTime = ::GetTimeCount();\r
+  bi.UserTime = ::GetUserTime();\r
+}\r
+\r
+static void SetFinishTime(const CBenchInfo &biStart, CBenchInfo &dest)\r
+{\r
+  dest.GlobalFreq = GetFreq();\r
+  dest.UserFreq = GetUserFreq();\r
+  dest.GlobalTime = ::GetTimeCount() - biStart.GlobalTime;\r
+  dest.UserTime = ::GetUserTime() - biStart.UserTime;\r
+}\r
+\r
+STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)\r
+{\r
+  HRESULT res = Status->GetResult();\r
+  if (res != S_OK)\r
+    return res;\r
+  if (!callback)\r
+    return res;\r
+  CBenchInfo info = BenchInfo;\r
+  SetFinishTime(BenchInfo, info);\r
+  if (Status->EncodeMode)\r
+  {\r
+    info.UnpackSize = *inSize;\r
+    info.PackSize = *outSize;\r
+    res = callback->SetEncodeResult(info, false);\r
+  }\r
+  else\r
+  {\r
+    info.PackSize = BenchInfo.PackSize + *inSize;\r
+    info.UnpackSize = BenchInfo.UnpackSize + *outSize;\r
+    res = callback->SetDecodeResult(info, false);\r
+  }\r
+  if (res != S_OK)\r
+    Status->SetResult(res);\r
+  return res;\r
+}\r
+\r
+static const int kSubBits = 8;\r
+\r
+static UInt32 GetLogSize(UInt32 size)\r
+{\r
+  for (int i = kSubBits; i < 32; i++)\r
+    for (UInt32 j = 0; j < (1 << kSubBits); j++)\r
+      if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))\r
+        return (i << kSubBits) + j;\r
+  return (32 << kSubBits);\r
+}\r
+\r
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)\r
+{\r
+  while (v1 > 1000000)\r
+  {\r
+    v1 >>= 1;\r
+    v2 >>= 1;\r
+  }\r
+}\r
+\r
+UInt64 GetUsage(const CBenchInfo &info)\r
+{\r
+  UInt64 userTime = info.UserTime;\r
+  UInt64 userFreq = info.UserFreq;\r
+  UInt64 globalTime = info.GlobalTime;\r
+  UInt64 globalFreq = info.GlobalFreq;\r
+  NormalizeVals(userTime, userFreq);\r
+  NormalizeVals(globalFreq, globalTime);\r
+  if (userFreq == 0)\r
+    userFreq = 1;\r
+  if (globalTime == 0)\r
+    globalTime = 1;\r
+  return userTime * globalFreq * 1000000 / userFreq / globalTime;\r
+}\r
+\r
+UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating)\r
+{\r
+  UInt64 userTime = info.UserTime;\r
+  UInt64 userFreq = info.UserFreq;\r
+  UInt64 globalTime = info.GlobalTime;\r
+  UInt64 globalFreq = info.GlobalFreq;\r
+  NormalizeVals(userFreq, userTime);\r
+  NormalizeVals(globalTime, globalFreq);\r
+  if (globalFreq == 0)\r
+    globalFreq = 1;\r
+  if (userTime == 0)\r
+    userTime = 1;\r
+  return userFreq * globalTime / globalFreq *  rating / userTime;\r
+}\r
+\r
+static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)\r
+{\r
+  UInt64 elTime = elapsedTime;\r
+  NormalizeVals(freq, elTime);\r
+  if (elTime == 0)\r
+    elTime = 1;\r
+  return value * freq / elTime;\r
+}\r
+\r
+UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size)\r
+{\r
+  UInt64 t = GetLogSize(dictionarySize) - (kBenchMinDicLogSize << kSubBits);\r
+  UInt64 numCommandsForOne = 870 + ((t * t * 5) >> (2 * kSubBits));\r
+  UInt64 numCommands = (UInt64)(size) * numCommandsForOne;\r
+  return MyMultDiv64(numCommands, elapsedTime, freq);\r
+}\r
+\r
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)\r
+{\r
+  UInt64 numCommands = (inSize * 200 + outSize * 4) * numIterations;\r
+  return MyMultDiv64(numCommands, elapsedTime, freq);\r
+}\r
+\r
+struct CEncoderInfo;\r
+\r
+struct CEncoderInfo\r
+{\r
+  #ifndef _7ZIP_ST\r
+  NWindows::CThread thread[2];\r
+  #endif\r
+  CMyComPtr<ICompressCoder> encoder;\r
+  CBenchProgressInfo *progressInfoSpec[2];\r
+  CMyComPtr<ICompressProgressInfo> progressInfo[2];\r
+  UInt32 NumIterations;\r
+  #ifdef USE_ALLOCA\r
+  size_t AllocaSize;\r
+  #endif\r
+\r
+  struct CDecoderInfo\r
+  {\r
+    CEncoderInfo *Encoder;\r
+    UInt32 DecoderIndex;\r
+    #ifdef USE_ALLOCA\r
+    size_t AllocaSize;\r
+    #endif\r
+    bool CallbackMode;\r
+  };\r
+  CDecoderInfo decodersInfo[2];\r
+\r
+  CMyComPtr<ICompressCoder> decoders[2];\r
+  HRESULT Results[2];\r
+  CBenchmarkOutStream *outStreamSpec;\r
+  CMyComPtr<ISequentialOutStream> outStream;\r
+  IBenchCallback *callback;\r
+  UInt32 crc;\r
+  UInt32 kBufferSize;\r
+  UInt32 compressedSize;\r
+  CBenchRandomGenerator rg;\r
+  CBenchmarkOutStream *propStreamSpec;\r
+  CMyComPtr<ISequentialOutStream> propStream;\r
+  HRESULT Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rg);\r
+  HRESULT Encode();\r
+  HRESULT Decode(UInt32 decoderIndex);\r
+\r
+  CEncoderInfo(): outStreamSpec(0), callback(0), propStreamSpec(0) {}\r
+\r
+  #ifndef _7ZIP_ST\r
+  static THREAD_FUNC_DECL EncodeThreadFunction(void *param)\r
+  {\r
+    CEncoderInfo *encoder = (CEncoderInfo *)param;\r
+    #ifdef USE_ALLOCA\r
+    alloca(encoder->AllocaSize);\r
+    #endif\r
+    HRESULT res = encoder->Encode();\r
+    encoder->Results[0] = res;\r
+    if (res != S_OK)\r
+      encoder->progressInfoSpec[0]->Status->SetResult(res);\r
+\r
+    return 0;\r
+  }\r
+  static THREAD_FUNC_DECL DecodeThreadFunction(void *param)\r
+  {\r
+    CDecoderInfo *decoder = (CDecoderInfo *)param;\r
+    #ifdef USE_ALLOCA\r
+    alloca(decoder->AllocaSize);\r
+    #endif\r
+    CEncoderInfo *encoder = decoder->Encoder;\r
+    encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);\r
+    return 0;\r
+  }\r
+\r
+  HRESULT CreateEncoderThread()\r
+  {\r
+    return thread[0].Create(EncodeThreadFunction, this);\r
+  }\r
+\r
+  HRESULT CreateDecoderThread(int index, bool callbackMode\r
+      #ifdef USE_ALLOCA\r
+      , size_t allocaSize\r
+      #endif\r
+      )\r
+  {\r
+    CDecoderInfo &decoder = decodersInfo[index];\r
+    decoder.DecoderIndex = index;\r
+    decoder.Encoder = this;\r
+    #ifdef USE_ALLOCA\r
+    decoder.AllocaSize = allocaSize;\r
+    #endif\r
+    decoder.CallbackMode = callbackMode;\r
+    return thread[index].Create(DecodeThreadFunction, &decoder);\r
+  }\r
+  #endif\r
+};\r
+\r
+HRESULT CEncoderInfo::Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rgLoc)\r
+{\r
+  rg.Set(rgLoc);\r
+  kBufferSize = dictionarySize + kAdditionalSize;\r
+  UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;\r
+  if (!rg.Alloc(kBufferSize))\r
+    return E_OUTOFMEMORY;\r
+  rg.Generate();\r
+  crc = CrcCalc(rg.Buffer, rg.BufferSize);\r
+\r
+  outStreamSpec = new CBenchmarkOutStream;\r
+  if (!outStreamSpec->Alloc(kCompressedBufferSize))\r
+    return E_OUTOFMEMORY;\r
+\r
+  outStream = outStreamSpec;\r
+\r
+  propStreamSpec = 0;\r
+  if (!propStream)\r
+  {\r
+    propStreamSpec = new CBenchmarkOutStream;\r
+    propStream = propStreamSpec;\r
+  }\r
+  if (!propStreamSpec->Alloc(kMaxLzmaPropSize))\r
+    return E_OUTOFMEMORY;\r
+  propStreamSpec->Init();\r
+  \r
+  PROPID propIDs[] =\r
+  {\r
+    NCoderPropID::kDictionarySize,\r
+    NCoderPropID::kNumThreads\r
+  };\r
+  const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);\r
+  PROPVARIANT props[kNumProps];\r
+  props[0].vt = VT_UI4;\r
+  props[0].ulVal = dictionarySize;\r
+\r
+  props[1].vt = VT_UI4;\r
+  props[1].ulVal = numThreads;\r
+\r
+  {\r
+    CMyComPtr<ICompressSetCoderProperties> setCoderProperties;\r
+    RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));\r
+    if (!setCoderProperties)\r
+      return E_FAIL;\r
+    RINOK(setCoderProperties->SetCoderProperties(propIDs, props, kNumProps));\r
+\r
+    CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;\r
+    encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);\r
+    if (writeCoderProperties)\r
+    {\r
+      RINOK(writeCoderProperties->WriteCoderProperties(propStream));\r
+    }\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CEncoderInfo::Encode()\r
+{\r
+  CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;\r
+  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;\r
+  inStreamSpec->Init(rg.Buffer, rg.BufferSize);\r
+  outStreamSpec->Init();\r
+\r
+  RINOK(encoder->Code(inStream, outStream, 0, 0, progressInfo[0]));\r
+  compressedSize = outStreamSpec->Pos;\r
+  encoder.Release();\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)\r
+{\r
+  CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;\r
+  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;\r
+  CMyComPtr<ICompressCoder> &decoder = decoders[decoderIndex];\r
+\r
+  CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;\r
+  decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);\r
+  if (!compressSetDecoderProperties)\r
+    return E_FAIL;\r
+\r
+  CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;\r
+  CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;\r
+    \r
+  CBenchProgressInfo *pi = progressInfoSpec[decoderIndex];\r
+  pi->BenchInfo.UnpackSize = 0;\r
+  pi->BenchInfo.PackSize = 0;\r
+\r
+  for (UInt32 j = 0; j < NumIterations; j++)\r
+  {\r
+    inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);\r
+    crcOutStreamSpec->Init();\r
+    \r
+    RINOK(compressSetDecoderProperties->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos));\r
+    UInt64 outSize = kBufferSize;\r
+    RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));\r
+    if (CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)\r
+      return S_FALSE;\r
+    pi->BenchInfo.UnpackSize += kBufferSize;\r
+    pi->BenchInfo.PackSize += compressedSize;\r
+  }\r
+  decoder.Release();\r
+  return S_OK;\r
+}\r
+\r
+static const UInt32 kNumThreadsMax = (1 << 16);\r
+\r
+struct CBenchEncoders\r
+{\r
+  CEncoderInfo *encoders;\r
+  CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }\r
+  ~CBenchEncoders() { delete []encoders; }\r
+};\r
+\r
+HRESULT LzmaBench(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback)\r
+{\r
+  UInt32 numEncoderThreads =\r
+    #ifndef _7ZIP_ST\r
+    (numThreads > 1 ? numThreads / 2 : 1);\r
+    #else\r
+    1;\r
+    #endif\r
+  UInt32 numSubDecoderThreads =\r
+    #ifndef _7ZIP_ST\r
+    (numThreads > 1 ? 2 : 1);\r
+    #else\r
+    1;\r
+    #endif\r
+  if (dictionarySize < (1 << kBenchMinDicLogSize) || numThreads < 1 || numEncoderThreads > kNumThreadsMax)\r
+  {\r
+    return E_INVALIDARG;\r
+  }\r
+\r
+  CBenchEncoders encodersSpec(numEncoderThreads);\r
+  CEncoderInfo *encoders = encodersSpec.encoders;\r
+\r
+\r
+  UInt32 i;\r
+  for (i = 0; i < numEncoderThreads; i++)\r
+  {\r
+    CEncoderInfo &encoder = encoders[i];\r
+    encoder.callback = (i == 0) ? callback : 0;\r
+\r
+    const UInt32 kLzmaId = 0x030101;\r
+    RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.encoder, true));\r
+    if (!encoder.encoder)\r
+      return E_NOTIMPL;\r
+    for (UInt32 j = 0; j < numSubDecoderThreads; j++)\r
+    {\r
+      RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.decoders[j], false));\r
+      if (!encoder.decoders[j])\r
+        return E_NOTIMPL;\r
+    }\r
+  }\r
+\r
+  CBaseRandomGenerator rg;\r
+  rg.Init();\r
+  for (i = 0; i < numEncoderThreads; i++)\r
+  {\r
+    RINOK(encoders[i].Init(dictionarySize, numThreads, &rg));\r
+  }\r
+\r
+  CBenchProgressStatus status;\r
+  status.Res = S_OK;\r
+  status.EncodeMode = true;\r
+\r
+  for (i = 0; i < numEncoderThreads; i++)\r
+  {\r
+    CEncoderInfo &encoder = encoders[i];\r
+    for (int j = 0; j < 2; j++)\r
+    {\r
+      encoder.progressInfo[j] = encoder.progressInfoSpec[j] = new CBenchProgressInfo;\r
+      encoder.progressInfoSpec[j]->Status = &status;\r
+    }\r
+    if (i == 0)\r
+    {\r
+      encoder.progressInfoSpec[0]->callback = callback;\r
+      encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numEncoderThreads;\r
+      SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);\r
+    }\r
+\r
+    #ifndef _7ZIP_ST\r
+    if (numEncoderThreads > 1)\r
+    {\r
+      #ifdef USE_ALLOCA\r
+      encoder.AllocaSize = (i * 16 * 21) & 0x7FF;\r
+      #endif\r
+      RINOK(encoder.CreateEncoderThread())\r
+    }\r
+    else\r
+    #endif\r
+    {\r
+      RINOK(encoder.Encode());\r
+    }\r
+  }\r
+  #ifndef _7ZIP_ST\r
+  if (numEncoderThreads > 1)\r
+    for (i = 0; i < numEncoderThreads; i++)\r
+      encoders[i].thread[0].Wait();\r
+  #endif\r
+\r
+  RINOK(status.Res);\r
+\r
+  CBenchInfo info;\r
+\r
+  SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);\r
+  info.UnpackSize = 0;\r
+  info.PackSize = 0;\r
+  info.NumIterations = 1; // progressInfoSpec->NumIterations;\r
+  for (i = 0; i < numEncoderThreads; i++)\r
+  {\r
+    CEncoderInfo &encoder = encoders[i];\r
+    info.UnpackSize += encoder.kBufferSize;\r
+    info.PackSize += encoder.compressedSize;\r
+  }\r
+  RINOK(callback->SetEncodeResult(info, true));\r
+\r
+\r
+  status.Res = S_OK;\r
+  status.EncodeMode = false;\r
+\r
+  UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;\r
+  for (i = 0; i < numEncoderThreads; i++)\r
+  {\r
+    CEncoderInfo &encoder = encoders[i];\r
+    encoder.NumIterations = 2 + kUncompressMinBlockSize / encoder.kBufferSize;\r
+\r
+    if (i == 0)\r
+    {\r
+      encoder.progressInfoSpec[0]->callback = callback;\r
+      encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numDecoderThreads;\r
+      SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);\r
+    }\r
+\r
+    #ifndef _7ZIP_ST\r
+    if (numDecoderThreads > 1)\r
+    {\r
+      for (UInt32 j = 0; j < numSubDecoderThreads; j++)\r
+      {\r
+        HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)\r
+            #ifdef USE_ALLOCA\r
+            , ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF\r
+            #endif\r
+            );\r
+        RINOK(res);\r
+      }\r
+    }\r
+    else\r
+    #endif\r
+    {\r
+      RINOK(encoder.Decode(0));\r
+    }\r
+  }\r
+  #ifndef _7ZIP_ST\r
+  HRESULT res = S_OK;\r
+  if (numDecoderThreads > 1)\r
+    for (i = 0; i < numEncoderThreads; i++)\r
+      for (UInt32 j = 0; j < numSubDecoderThreads; j++)\r
+      {\r
+        CEncoderInfo &encoder = encoders[i];\r
+        encoder.thread[j].Wait();\r
+        if (encoder.Results[j] != S_OK)\r
+          res = encoder.Results[j];\r
+      }\r
+  RINOK(res);\r
+  #endif\r
+  RINOK(status.Res);\r
+  SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);\r
+  #ifndef _7ZIP_ST\r
+  #ifdef UNDER_CE\r
+  if (numDecoderThreads > 1)\r
+    for (i = 0; i < numEncoderThreads; i++)\r
+      for (UInt32 j = 0; j < numSubDecoderThreads; j++)\r
+      {\r
+        FILETIME creationTime, exitTime, kernelTime, userTime;\r
+        if (::GetThreadTimes(encoders[i].thread[j], &creationTime, &exitTime, &kernelTime, &userTime) != 0)\r
+          info.UserTime += GetTime64(userTime) + GetTime64(kernelTime);\r
+      }\r
+  #endif\r
+  #endif\r
+  info.UnpackSize = 0;\r
+  info.PackSize = 0;\r
+  info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations;\r
+  for (i = 0; i < numEncoderThreads; i++)\r
+  {\r
+    CEncoderInfo &encoder = encoders[i];\r
+    info.UnpackSize += encoder.kBufferSize;\r
+    info.PackSize += encoder.compressedSize;\r
+  }\r
+  RINOK(callback->SetDecodeResult(info, false));\r
+  RINOK(callback->SetDecodeResult(info, true));\r
+  return S_OK;\r
+}\r
+\r
+\r
+inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)\r
+{\r
+  UInt32 hs = dictionary - 1;\r
+  hs |= (hs >> 1);\r
+  hs |= (hs >> 2);\r
+  hs |= (hs >> 4);\r
+  hs |= (hs >> 8);\r
+  hs >>= 1;\r
+  hs |= 0xFFFF;\r
+  if (hs > (1 << 24))\r
+    hs >>= 1;\r
+  hs++;\r
+  return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 +\r
+      (1 << 20) + (multiThread ? (6 << 20) : 0);\r
+}\r
+\r
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary)\r
+{\r
+  const UInt32 kBufferSize = dictionary;\r
+  const UInt32 kCompressedBufferSize = (kBufferSize / 2);\r
+  UInt32 numSubThreads = (numThreads > 1) ? 2 : 1;\r
+  UInt32 numBigThreads = numThreads / numSubThreads;\r
+  return (kBufferSize + kCompressedBufferSize +\r
+    GetLZMAUsage((numThreads > 1), dictionary) + (2 << 20)) * numBigThreads;\r
+}\r
+\r
+static bool CrcBig(const void *data, UInt32 size, UInt32 numCycles, UInt32 crcBase)\r
+{\r
+  for (UInt32 i = 0; i < numCycles; i++)\r
+    if (CrcCalc(data, size) != crcBase)\r
+      return false;\r
+  return true;\r
+}\r
+\r
+#ifndef _7ZIP_ST\r
+struct CCrcInfo\r
+{\r
+  NWindows::CThread Thread;\r
+  const Byte *Data;\r
+  UInt32 Size;\r
+  UInt32 NumCycles;\r
+  UInt32 Crc;\r
+  bool Res;\r
+  void Wait()\r
+  {\r
+    Thread.Wait();\r
+    Thread.Close();\r
+  }\r
+};\r
+\r
+static THREAD_FUNC_DECL CrcThreadFunction(void *param)\r
+{\r
+  CCrcInfo *p = (CCrcInfo *)param;\r
+  p->Res = CrcBig(p->Data, p->Size, p->NumCycles, p->Crc);\r
+  return 0;\r
+}\r
+\r
+struct CCrcThreads\r
+{\r
+  UInt32 NumThreads;\r
+  CCrcInfo *Items;\r
+  CCrcThreads(): Items(0), NumThreads(0) {}\r
+  void WaitAll()\r
+  {\r
+    for (UInt32 i = 0; i < NumThreads; i++)\r
+      Items[i].Wait();\r
+    NumThreads = 0;\r
+  }\r
+  ~CCrcThreads()\r
+  {\r
+    WaitAll();\r
+    delete []Items;\r
+  }\r
+};\r
+#endif\r
+\r
+static UInt32 CrcCalc1(const Byte *buf, UInt32 size)\r
+{\r
+  UInt32 crc = CRC_INIT_VAL;;\r
+  for (UInt32 i = 0; i < size; i++)\r
+    crc = CRC_UPDATE_BYTE(crc, buf[i]);\r
+  return CRC_GET_DIGEST(crc);\r
+}\r
+\r
+static void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)\r
+{\r
+  for (UInt32 i = 0; i < size; i++)\r
+    buf[i] = (Byte)RG.GetRnd();\r
+}\r
+\r
+static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)\r
+{\r
+  RandGen(buf, size, RG);\r
+  return CrcCalc1(buf, size);\r
+}\r
+\r
+bool CrcInternalTest()\r
+{\r
+  CBenchBuffer buffer;\r
+  const UInt32 kBufferSize0 = (1 << 8);\r
+  const UInt32 kBufferSize1 = (1 << 10);\r
+  const UInt32 kCheckSize = (1 << 5);\r
+  if (!buffer.Alloc(kBufferSize0 + kBufferSize1))\r
+    return false;\r
+  Byte *buf = buffer.Buffer;\r
+  UInt32 i;\r
+  for (i = 0; i < kBufferSize0; i++)\r
+    buf[i] = (Byte)i;\r
+  UInt32 crc1 = CrcCalc1(buf, kBufferSize0);\r
+  if (crc1 != 0x29058C73)\r
+    return false;\r
+  CBaseRandomGenerator RG;\r
+  RandGen(buf + kBufferSize0, kBufferSize1, RG);\r
+  for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++)\r
+    for (UInt32 j = 0; j < kCheckSize; j++)\r
+      if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j))\r
+        return false;\r
+  return true;\r
+}\r
+\r
+HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed)\r
+{\r
+  if (numThreads == 0)\r
+    numThreads = 1;\r
+\r
+  CBenchBuffer buffer;\r
+  size_t totalSize = (size_t)bufferSize * numThreads;\r
+  if (totalSize / numThreads != bufferSize)\r
+    return E_OUTOFMEMORY;\r
+  if (!buffer.Alloc(totalSize))\r
+    return E_OUTOFMEMORY;\r
+\r
+  Byte *buf = buffer.Buffer;\r
+  CBaseRandomGenerator RG;\r
+  UInt32 numCycles = (kCrcBlockSize) / ((bufferSize >> 2) + 1) + 1;\r
+\r
+  UInt64 timeVal;\r
+  #ifndef _7ZIP_ST\r
+  CCrcThreads threads;\r
+  if (numThreads > 1)\r
+  {\r
+    threads.Items = new CCrcInfo[numThreads];\r
+    UInt32 i;\r
+    for (i = 0; i < numThreads; i++)\r
+    {\r
+      CCrcInfo &info = threads.Items[i];\r
+      Byte *data = buf + (size_t)bufferSize * i;\r
+      info.Data = data;\r
+      info.NumCycles = numCycles;\r
+      info.Size = bufferSize;\r
+      info.Crc = RandGenCrc(data, bufferSize, RG);\r
+    }\r
+    timeVal = GetTimeCount();\r
+    for (i = 0; i < numThreads; i++)\r
+    {\r
+      CCrcInfo &info = threads.Items[i];\r
+      RINOK(info.Thread.Create(CrcThreadFunction, &info));\r
+      threads.NumThreads++;\r
+    }\r
+    threads.WaitAll();\r
+    for (i = 0; i < numThreads; i++)\r
+      if (!threads.Items[i].Res)\r
+        return S_FALSE;\r
+  }\r
+  else\r
+  #endif\r
+  {\r
+    UInt32 crc = RandGenCrc(buf, bufferSize, RG);\r
+    timeVal = GetTimeCount();\r
+    if (!CrcBig(buf, bufferSize, numCycles, crc))\r
+      return S_FALSE;\r
+  }\r
+  timeVal = GetTimeCount() - timeVal;\r
+  if (timeVal == 0)\r
+    timeVal = 1;\r
+\r
+  UInt64 size = (UInt64)numCycles * totalSize;\r
+  speed = MyMultDiv64(size, timeVal, GetFreq());\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/UI/Common/Bench.h b/CPP/7zip/UI/Common/Bench.h
new file mode 100755 (executable)
index 0000000..f6e8064
--- /dev/null
@@ -0,0 +1,42 @@
+// Bench.h\r
+\r
+#ifndef __7ZIP_BENCH_H\r
+#define __7ZIP_BENCH_H\r
+\r
+#include "../../Common/CreateCoder.h"\r
+\r
+struct CBenchInfo\r
+{\r
+  UInt64 GlobalTime;\r
+  UInt64 GlobalFreq;\r
+  UInt64 UserTime;\r
+  UInt64 UserFreq;\r
+  UInt64 UnpackSize;\r
+  UInt64 PackSize;\r
+  UInt32 NumIterations;\r
+  CBenchInfo(): NumIterations(0) {}\r
+};\r
+\r
+struct IBenchCallback\r
+{\r
+  virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0;\r
+  virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0;\r
+};\r
+\r
+UInt64 GetUsage(const CBenchInfo &benchOnfo);\r
+UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating);\r
+UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size);\r
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);\r
+\r
+HRESULT LzmaBench(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback);\r
+\r
+const int kBenchMinDicLogSize = 18;\r
+\r
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary);\r
+\r
+bool CrcInternalTest();\r
+HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/DefaultName.cpp b/CPP/7zip/UI/Common/DefaultName.cpp
new file mode 100755 (executable)
index 0000000..5c46500
--- /dev/null
@@ -0,0 +1,35 @@
+// DefaultName.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "DefaultName.h"\r
+\r
+static UString GetDefaultName3(const UString &fileName,\r
+    const UString &extension, const UString &addSubExtension)\r
+{\r
+  int extLength = extension.Length();\r
+  int fileNameLength = fileName.Length();\r
+  if (fileNameLength > extLength + 1)\r
+  {\r
+    int dotPos = fileNameLength - (extLength + 1);\r
+    if (fileName[dotPos] == '.')\r
+      if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0)\r
+        return fileName.Left(dotPos) + addSubExtension;\r
+  }\r
+  int dotPos = fileName.ReverseFind(L'.');\r
+  if (dotPos > 0)\r
+    return fileName.Left(dotPos) + addSubExtension;\r
+\r
+  if (addSubExtension.IsEmpty())\r
+    return fileName + L"~";\r
+  else\r
+    return fileName + addSubExtension;\r
+}\r
+\r
+UString GetDefaultName2(const UString &fileName,\r
+    const UString &extension, const UString &addSubExtension)\r
+{\r
+  UString name = GetDefaultName3(fileName, extension, addSubExtension);\r
+  name.TrimRight();\r
+  return name;\r
+}\r
diff --git a/CPP/7zip/UI/Common/DefaultName.h b/CPP/7zip/UI/Common/DefaultName.h
new file mode 100755 (executable)
index 0000000..3989a1f
--- /dev/null
@@ -0,0 +1,11 @@
+// DefaultName.h\r
+\r
+#ifndef __DEFAULTNAME_H\r
+#define __DEFAULTNAME_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+UString GetDefaultName2(const UString &fileName,\r
+    const UString &extension, const UString &addSubExtension);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h
new file mode 100755 (executable)
index 0000000..e10d6b9
--- /dev/null
@@ -0,0 +1,69 @@
+// DirItem.h\r
+\r
+#ifndef __DIR_ITEM_H\r
+#define __DIR_ITEM_H\r
+\r
+#include "Common/MyString.h"\r
+#include "Common/Types.h"\r
+#include "../../Archive/IArchive.h"\r
+\r
+struct CDirItem\r
+{\r
+  UInt64 Size;\r
+  FILETIME CTime;\r
+  FILETIME ATime;\r
+  FILETIME MTime;\r
+  UString Name;\r
+  UInt32 Attrib;\r
+  int PhyParent;\r
+  int LogParent;\r
+  \r
+  CDirItem(): PhyParent(-1), LogParent(-1) {}\r
+  bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }\r
+};\r
+\r
+class CDirItems\r
+{\r
+  UStringVector Prefixes;\r
+  CIntVector PhyParents;\r
+  CIntVector LogParents;\r
+\r
+  UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const;\r
+public:\r
+  CObjectVector<CDirItem> Items;\r
+\r
+  int GetNumFolders() const { return Prefixes.Size(); }\r
+  UString GetPhyPath(int index) const;\r
+  UString GetLogPath(int index) const;\r
+\r
+  int AddPrefix(int phyParent, int logParent, const UString &prefix);\r
+  void DeleteLastPrefix();\r
+\r
+  void EnumerateDirectory(int phyParent, int logParent, const UString &phyPrefix,\r
+    UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);\r
+\r
+  void EnumerateDirItems2(\r
+    const UString &phyPrefix,\r
+    const UString &logPrefix,\r
+    const UStringVector &filePaths,\r
+    UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);\r
+\r
+  void ReserveDown();\r
+};\r
+\r
+struct CArcItem\r
+{\r
+  UInt64 Size;\r
+  FILETIME MTime;\r
+  UString Name;\r
+  bool IsDir;\r
+  bool SizeDefined;\r
+  bool MTimeDefined;\r
+  bool Censored;\r
+  UInt32 IndexInServer;\r
+  int TimeType;\r
+  \r
+  CArcItem(): IsDir(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp
new file mode 100755 (executable)
index 0000000..61ecaba
--- /dev/null
@@ -0,0 +1,361 @@
+// EnumDirItems.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "EnumDirItems.h"\r
+\r
+using namespace NWindows;\r
+using namespace NFile;\r
+using namespace NName;\r
+\r
+void AddDirFileInfo(int phyParent, int logParent,\r
+    const NFind::CFileInfoW &fi, CObjectVector<CDirItem> &dirItems)\r
+{\r
+  CDirItem di;\r
+  di.Size = fi.Size;\r
+  di.CTime = fi.CTime;\r
+  di.ATime = fi.ATime;\r
+  di.MTime = fi.MTime;\r
+  di.Attrib = fi.Attrib;\r
+  di.PhyParent = phyParent;\r
+  di.LogParent = logParent;\r
+  di.Name = fi.Name;\r
+  dirItems.Add(di);\r
+}\r
+\r
+UString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const\r
+{\r
+  UString path;\r
+  int len = name.Length();\r
+  int i;\r
+  for (i = index; i >= 0; i = parents[i])\r
+    len += Prefixes[i].Length();\r
+  int totalLen = len;\r
+  wchar_t *p = path.GetBuffer(len);\r
+  p[len] = 0;\r
+  len -= name.Length();\r
+  memcpy(p + len, (const wchar_t *)name, name.Length() * sizeof(wchar_t));\r
+  for (i = index; i >= 0; i = parents[i])\r
+  {\r
+    const UString &s = Prefixes[i];\r
+    len -= s.Length();\r
+    memcpy(p + len, (const wchar_t *)s, s.Length() * sizeof(wchar_t));\r
+  }\r
+  path.ReleaseBuffer(totalLen);\r
+  return path;\r
+}\r
+\r
+UString CDirItems::GetPhyPath(int index) const\r
+{\r
+  const CDirItem &di = Items[index];\r
+  return GetPrefixesPath(PhyParents, di.PhyParent, di.Name);\r
+}\r
+\r
+UString CDirItems::GetLogPath(int index) const\r
+{\r
+  const CDirItem &di = Items[index];\r
+  return GetPrefixesPath(LogParents, di.LogParent, di.Name);\r
+}\r
+\r
+void CDirItems::ReserveDown()\r
+{\r
+  Prefixes.ReserveDown();\r
+  PhyParents.ReserveDown();\r
+  LogParents.ReserveDown();\r
+  Items.ReserveDown();\r
+}\r
+\r
+int CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix)\r
+{\r
+  PhyParents.Add(phyParent);\r
+  LogParents.Add(logParent);\r
+  return Prefixes.Add(prefix);\r
+}\r
+\r
+void CDirItems::DeleteLastPrefix()\r
+{\r
+  PhyParents.DeleteBack();\r
+  LogParents.DeleteBack();\r
+  Prefixes.DeleteBack();\r
+}\r
+\r
+void CDirItems::EnumerateDirectory(int phyParent, int logParent, const UString &phyPrefix,\r
+    UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)\r
+{\r
+  NFind::CEnumeratorW enumerator(phyPrefix + (wchar_t)kAnyStringWildcard);\r
+  for (;;)\r
+  {\r
+    NFind::CFileInfoW fi;\r
+    bool found;\r
+    if (!enumerator.Next(fi, found))\r
+    {\r
+      errorCodes.Add(::GetLastError());\r
+      errorPaths.Add(phyPrefix);\r
+      return;\r
+    }\r
+    if (!found)\r
+      break;\r
+    AddDirFileInfo(phyParent, logParent, fi, Items);\r
+    if (fi.IsDir())\r
+    {\r
+      const UString name2 = fi.Name + (wchar_t)kDirDelimiter;\r
+      int parent = AddPrefix(phyParent, logParent, name2);\r
+      EnumerateDirectory(parent, parent, phyPrefix + name2, errorPaths, errorCodes);\r
+    }\r
+  }\r
+}\r
+\r
+void CDirItems::EnumerateDirItems2(const UString &phyPrefix, const UString &logPrefix,\r
+    const UStringVector &filePaths, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)\r
+{\r
+  int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, phyPrefix);\r
+  int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix);\r
+\r
+  for (int i = 0; i < filePaths.Size(); i++)\r
+  {\r
+    const UString &filePath = filePaths[i];\r
+    NFind::CFileInfoW fi;\r
+    const UString phyPath = phyPrefix + filePath;\r
+    if (!fi.Find(phyPath))\r
+    {\r
+      errorCodes.Add(::GetLastError());\r
+      errorPaths.Add(phyPath);\r
+      continue;\r
+    }\r
+    int delimiter = filePath.ReverseFind((wchar_t)kDirDelimiter);\r
+    UString phyPrefixCur;\r
+    int phyParentCur = phyParent;\r
+    if (delimiter >= 0)\r
+    {\r
+      phyPrefixCur = filePath.Left(delimiter + 1);\r
+      phyParentCur = AddPrefix(phyParent, logParent, phyPrefixCur);\r
+    }\r
+    AddDirFileInfo(phyParentCur, logParent, fi, Items);\r
+    if (fi.IsDir())\r
+    {\r
+      const UString name2 = fi.Name + (wchar_t)kDirDelimiter;\r
+      int parent = AddPrefix(phyParentCur, logParent, name2);\r
+      EnumerateDirectory(parent, parent, phyPrefix + phyPrefixCur + name2, errorPaths, errorCodes);\r
+    }\r
+  }\r
+  ReserveDown();\r
+}\r
+\r
+static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,\r
+    int phyParent, int logParent, const UString &phyPrefix,\r
+    const UStringVector &addArchivePrefix,\r
+    CDirItems &dirItems,\r
+    bool enterToSubFolders,\r
+    IEnumDirItemCallback *callback,\r
+    UStringVector &errorPaths,\r
+    CRecordVector<DWORD> &errorCodes);\r
+\r
+static HRESULT EnumerateDirItems_Spec(const NWildcard::CCensorNode &curNode,\r
+    int phyParent, int logParent, const UString &curFolderName,\r
+    const UString &phyPrefix,\r
+    const UStringVector &addArchivePrefix,\r
+    CDirItems &dirItems,\r
+    bool enterToSubFolders,\r
+    IEnumDirItemCallback *callback,\r
+    UStringVector &errorPaths,\r
+    CRecordVector<DWORD> &errorCodes)\r
+  \r
+{\r
+  const UString name2 = curFolderName + (wchar_t)kDirDelimiter;\r
+  int parent = dirItems.AddPrefix(phyParent, logParent, name2);\r
+  int numItems = dirItems.Items.Size();\r
+  HRESULT res = EnumerateDirItems(curNode, parent, parent, phyPrefix + name2,\r
+    addArchivePrefix, dirItems, enterToSubFolders, callback, errorPaths, errorCodes);\r
+  if (numItems == dirItems.Items.Size())\r
+    dirItems.DeleteLastPrefix();\r
+  return res;\r
+}\r
+\r
+\r
+static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,\r
+    int phyParent, int logParent, const UString &phyPrefix,\r
+    const UStringVector &addArchivePrefix,  // prefix from curNode\r
+    CDirItems &dirItems,\r
+    bool enterToSubFolders,\r
+    IEnumDirItemCallback *callback,\r
+    UStringVector &errorPaths,\r
+    CRecordVector<DWORD> &errorCodes)\r
+{\r
+  if (!enterToSubFolders)\r
+    if (curNode.NeedCheckSubDirs())\r
+      enterToSubFolders = true;\r
+  if (callback)\r
+    RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), phyPrefix));\r
+\r
+  // try direct_names case at first\r
+  if (addArchivePrefix.IsEmpty() && !enterToSubFolders)\r
+  {\r
+    // check that all names are direct\r
+    int i;\r
+    for (i = 0; i < curNode.IncludeItems.Size(); i++)\r
+    {\r
+      const NWildcard::CItem &item = curNode.IncludeItems[i];\r
+      if (item.Recursive || item.PathParts.Size() != 1)\r
+        break;\r
+      const UString &name = item.PathParts.Front();\r
+      if (name.IsEmpty() || DoesNameContainWildCard(name))\r
+        break;\r
+    }\r
+    if (i == curNode.IncludeItems.Size())\r
+    {\r
+      // all names are direct (no wildcards)\r
+      // so we don't need file_system's dir enumerator\r
+      CRecordVector<bool> needEnterVector;\r
+      for (i = 0; i < curNode.IncludeItems.Size(); i++)\r
+      {\r
+        const NWildcard::CItem &item = curNode.IncludeItems[i];\r
+        const UString &name = item.PathParts.Front();\r
+        const UString fullPath = phyPrefix + name;\r
+        NFind::CFileInfoW fi;\r
+        if (!fi.Find(fullPath))\r
+        {\r
+          errorCodes.Add(::GetLastError());\r
+          errorPaths.Add(fullPath);\r
+          continue;\r
+        }\r
+        bool isDir = fi.IsDir();\r
+        if (isDir && !item.ForDir || !isDir && !item.ForFile)\r
+        {\r
+          errorCodes.Add((DWORD)E_FAIL);\r
+          errorPaths.Add(fullPath);\r
+          continue;\r
+        }\r
+        {\r
+          UStringVector pathParts;\r
+          pathParts.Add(fi.Name);\r
+          if (curNode.CheckPathToRoot(false, pathParts, !isDir))\r
+            continue;\r
+        }\r
+        AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);\r
+        if (!isDir)\r
+          continue;\r
+        \r
+        UStringVector addArchivePrefixNew;\r
+        const NWildcard::CCensorNode *nextNode = 0;\r
+        int index = curNode.FindSubNode(name);\r
+        if (index >= 0)\r
+        {\r
+          for (int t = needEnterVector.Size(); t <= index; t++)\r
+            needEnterVector.Add(true);\r
+          needEnterVector[index] = false;\r
+          nextNode = &curNode.SubNodes[index];\r
+        }\r
+        else\r
+        {\r
+          nextNode = &curNode;\r
+          addArchivePrefixNew.Add(name); // don't change it to fi.Name. It's for shortnames support\r
+        }\r
+\r
+        RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,\r
+            addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));\r
+      }\r
+      for (i = 0; i < curNode.SubNodes.Size(); i++)\r
+      {\r
+        if (i < needEnterVector.Size())\r
+          if (!needEnterVector[i])\r
+            continue;\r
+        const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];\r
+        const UString fullPath = phyPrefix + nextNode.Name;\r
+        NFind::CFileInfoW fi;\r
+        if (!fi.Find(fullPath))\r
+        {\r
+          if (!nextNode.AreThereIncludeItems())\r
+            continue;\r
+          errorCodes.Add(::GetLastError());\r
+          errorPaths.Add(fullPath);\r
+          continue;\r
+        }\r
+        if (!fi.IsDir())\r
+        {\r
+          errorCodes.Add((DWORD)E_FAIL);\r
+          errorPaths.Add(fullPath);\r
+          continue;\r
+        }\r
+\r
+        RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix,\r
+            UStringVector(), dirItems, false, callback, errorPaths, errorCodes));\r
+      }\r
+      return S_OK;\r
+    }\r
+  }\r
+\r
+\r
+  NFind::CEnumeratorW enumerator(phyPrefix + wchar_t(kAnyStringWildcard));\r
+  for (int ttt = 0; ; ttt++)\r
+  {\r
+    NFind::CFileInfoW fi;\r
+    bool found;\r
+    if (!enumerator.Next(fi, found))\r
+    {\r
+      errorCodes.Add(::GetLastError());\r
+      errorPaths.Add(phyPrefix);\r
+      break;\r
+    }\r
+    if (!found)\r
+      break;\r
+\r
+    if (callback && (ttt & 0xFF) == 0xFF)\r
+      RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), phyPrefix));\r
+    const UString &name = fi.Name;\r
+    bool enterToSubFolders2 = enterToSubFolders;\r
+    UStringVector addArchivePrefixNew = addArchivePrefix;\r
+    addArchivePrefixNew.Add(name);\r
+    {\r
+      UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);\r
+      if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir()))\r
+        continue;\r
+    }\r
+    if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))\r
+    {\r
+      AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);\r
+      if (fi.IsDir())\r
+        enterToSubFolders2 = true;\r
+    }\r
+    if (!fi.IsDir())\r
+      continue;\r
+\r
+    const NWildcard::CCensorNode *nextNode = 0;\r
+    if (addArchivePrefix.IsEmpty())\r
+    {\r
+      int index = curNode.FindSubNode(name);\r
+      if (index >= 0)\r
+        nextNode = &curNode.SubNodes[index];\r
+    }\r
+    if (!enterToSubFolders2 && nextNode == 0)\r
+      continue;\r
+\r
+    addArchivePrefixNew = addArchivePrefix;\r
+    if (nextNode == 0)\r
+    {\r
+      nextNode = &curNode;\r
+      addArchivePrefixNew.Add(name);\r
+    }\r
+\r
+    RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, name, phyPrefix,\r
+        addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT EnumerateItems(\r
+    const NWildcard::CCensor &censor,\r
+    CDirItems &dirItems,\r
+    IEnumDirItemCallback *callback,\r
+    UStringVector &errorPaths,\r
+    CRecordVector<DWORD> &errorCodes)\r
+{\r
+  for (int i = 0; i < censor.Pairs.Size(); i++)\r
+  {\r
+    const NWildcard::CPair &pair = censor.Pairs[i];\r
+    int phyParent = pair.Prefix.IsEmpty() ? -1 : dirItems.AddPrefix(-1, -1, pair.Prefix);\r
+    RINOK(EnumerateDirItems(pair.Head, phyParent, -1, pair.Prefix, UStringVector(), dirItems, false,\r
+        callback, errorPaths, errorCodes));\r
+  }\r
+  dirItems.ReserveDown();\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h
new file mode 100755 (executable)
index 0000000..835ae02
--- /dev/null
@@ -0,0 +1,25 @@
+// EnumDirItems.h\r
+\r
+#ifndef __ENUM_DIR_ITEMS_H\r
+#define __ENUM_DIR_ITEMS_H\r
+\r
+#include "Common/Wildcard.h"\r
+#include "Windows/FileFind.h"\r
+#include "DirItem.h"\r
+\r
+void AddDirFileInfo(int phyParent, int logParent,\r
+    const NWindows::NFile::NFind::CFileInfoW &fi, CObjectVector<CDirItem> &dirItems);\r
+\r
+struct IEnumDirItemCallback\r
+{\r
+  virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) = 0;\r
+};\r
+\r
+HRESULT EnumerateItems(\r
+    const NWildcard::CCensor &censor,\r
+    CDirItems &dirItems,\r
+    IEnumDirItemCallback *callback,\r
+    UStringVector &errorPaths,\r
+    CRecordVector<DWORD> &errorCodes);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/ExitCode.h b/CPP/7zip/UI/Common/ExitCode.h
new file mode 100755 (executable)
index 0000000..d03ec6d
--- /dev/null
@@ -0,0 +1,27 @@
+// ExitCode.h\r
+\r
+#ifndef __EXIT_CODE_H\r
+#define __EXIT_CODE_H\r
+\r
+namespace NExitCode {\r
+\r
+enum EEnum {\r
+\r
+  kSuccess       = 0,     // Successful operation\r
+  kWarning       = 1,     // Non fatal error(s) occurred\r
+  kFatalError    = 2,     // A fatal error occurred\r
+  // kCRCError      = 3,     // A CRC error occurred when unpacking\r
+  // kLockedArchive = 4,     // Attempt to modify an archive previously locked\r
+  // kWriteError    = 5,     // Write to disk error\r
+  // kOpenError     = 6,     // Open file error\r
+  kUserError     = 7,     // Command line option error\r
+  kMemoryError   = 8,     // Not enough memory for operation\r
+  // kCreateFileError = 9,     // Create file error\r
+  \r
+  kUserBreak     = 255   // User stopped the process\r
+\r
+};\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
new file mode 100755 (executable)
index 0000000..2f5a293
--- /dev/null
@@ -0,0 +1,263 @@
+// Extract.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include <stdio.h>\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/PropVariant.h"\r
+#include "Windows/PropVariantConversions.h"\r
+\r
+#include "../Common/ExtractingFilePath.h"\r
+\r
+#include "Extract.h"\r
+#include "SetProperties.h"\r
+\r
+using namespace NWindows;\r
+\r
+static HRESULT DecompressArchive(\r
+    const CArc &arc,\r
+    UInt64 packSize,\r
+    const NWildcard::CCensorNode &wildcardCensor,\r
+    const CExtractOptions &options,\r
+    IExtractCallbackUI *callback,\r
+    CArchiveExtractCallback *extractCallbackSpec,\r
+    UString &errorMessage,\r
+    UInt64 &stdInProcessed)\r
+{\r
+  stdInProcessed = 0;\r
+  IInArchive *archive = arc.Archive;\r
+  CRecordVector<UInt32> realIndices;\r
+  if (!options.StdInMode)\r
+  {\r
+    UInt32 numItems;\r
+    RINOK(archive->GetNumberOfItems(&numItems));\r
+    \r
+    for (UInt32 i = 0; i < numItems; i++)\r
+    {\r
+      UString filePath;\r
+      RINOK(arc.GetItemPath(i, filePath));\r
+      bool isFolder;\r
+      RINOK(IsArchiveItemFolder(archive, i, isFolder));\r
+      if (!wildcardCensor.CheckPath(filePath, !isFolder))\r
+        continue;\r
+      realIndices.Add(i);\r
+    }\r
+    if (realIndices.Size() == 0)\r
+    {\r
+      callback->ThereAreNoFiles();\r
+      return S_OK;\r
+    }\r
+  }\r
+\r
+  UStringVector removePathParts;\r
+\r
+  UString outDir = options.OutputDir;\r
+  outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName));\r
+  #ifdef _WIN32\r
+  // GetCorrectFullFsPath doesn't like "..".\r
+  // outDir.TrimRight();\r
+  // outDir = GetCorrectFullFsPath(outDir);\r
+  #endif\r
+\r
+  if (!outDir.IsEmpty())\r
+    if (!NFile::NDirectory::CreateComplexDirectory(outDir))\r
+    {\r
+      HRESULT res = ::GetLastError();\r
+      if (res == S_OK)\r
+        res = E_FAIL;\r
+      errorMessage = ((UString)L"Can not create output directory ") + outDir;\r
+      return res;\r
+    }\r
+\r
+  extractCallbackSpec->Init(\r
+      options.StdInMode ? &wildcardCensor : NULL,\r
+      &arc,\r
+      callback,\r
+      options.StdOutMode, options.TestMode, options.CalcCrc,\r
+      outDir,\r
+      removePathParts,\r
+      packSize);\r
+\r
+  #if !defined(_7ZIP_ST) && !defined(_SFX)\r
+  RINOK(SetProperties(archive, options.Properties));\r
+  #endif\r
+\r
+  HRESULT result;\r
+  Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0;\r
+  if (options.StdInMode)\r
+  {\r
+    result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec);\r
+    NCOM::CPropVariant prop;\r
+    if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK)\r
+      if (prop.vt == VT_UI8 || prop.vt == VT_UI4)\r
+        stdInProcessed = ConvertPropVariantToUInt64(prop);\r
+  }\r
+  else\r
+    result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec);\r
+\r
+  return callback->ExtractResult(result);\r
+}\r
+\r
+HRESULT DecompressArchives(\r
+    CCodecs *codecs, const CIntVector &formatIndices,\r
+    UStringVector &arcPaths, UStringVector &arcPathsFull,\r
+    const NWildcard::CCensorNode &wildcardCensor,\r
+    const CExtractOptions &options,\r
+    IOpenCallbackUI *openCallback,\r
+    IExtractCallbackUI *extractCallback,\r
+    UString &errorMessage,\r
+    CDecompressStat &stat)\r
+{\r
+  stat.Clear();\r
+  int i;\r
+  UInt64 totalPackSize = 0;\r
+  CRecordVector<UInt64> archiveSizes;\r
+\r
+  int numArcs = options.StdInMode ? 1 : arcPaths.Size();\r
+\r
+  for (i = 0; i < numArcs; i++)\r
+  {\r
+    NFile::NFind::CFileInfoW fi;\r
+    fi.Size = 0;\r
+    if (!options.StdInMode)\r
+    {\r
+      const UString &arcPath = arcPaths[i];\r
+      if (!fi.Find(arcPath))\r
+        throw "there is no such archive";\r
+      if (fi.IsDir())\r
+        throw "can't decompress folder";\r
+    }\r
+    archiveSizes.Add(fi.Size);\r
+    totalPackSize += fi.Size;\r
+  }\r
+  CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;\r
+  CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);\r
+  bool multi = (numArcs > 1);\r
+  extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);\r
+  if (multi)\r
+  {\r
+    RINOK(extractCallback->SetTotal(totalPackSize));\r
+  }\r
+  for (i = 0; i < numArcs; i++)\r
+  {\r
+    const UString &arcPath = arcPaths[i];\r
+    NFile::NFind::CFileInfoW fi;\r
+    if (options.StdInMode)\r
+    {\r
+      fi.Size = 0;\r
+      fi.Attrib = 0;\r
+    }\r
+    else\r
+    {\r
+      if (!fi.Find(arcPath) || fi.IsDir())\r
+        throw "there is no such archive";\r
+    }\r
+\r
+    #ifndef _NO_CRYPTO\r
+    openCallback->Open_ClearPasswordWasAskedFlag();\r
+    #endif\r
+\r
+    RINOK(extractCallback->BeforeOpen(arcPath));\r
+    CArchiveLink archiveLink;\r
+\r
+    CIntVector formatIndices2 = formatIndices;\r
+    #ifndef _SFX\r
+    if (formatIndices.IsEmpty())\r
+    {\r
+      int pos = arcPath.ReverseFind(L'.');\r
+      if (pos >= 0)\r
+      {\r
+        UString s = arcPath.Mid(pos + 1);\r
+        int index = codecs->FindFormatForExtension(s);\r
+        if (index >= 0 && s == L"001")\r
+        {\r
+          s = arcPath.Left(pos);\r
+          pos = s.ReverseFind(L'.');\r
+          if (pos >= 0)\r
+          {\r
+            int index2 = codecs->FindFormatForExtension(s.Mid(pos + 1));\r
+            if (index2 >= 0 && s.CompareNoCase(L"rar") != 0)\r
+            {\r
+              formatIndices2.Add(index2);\r
+              formatIndices2.Add(index);\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+    #endif\r
+    HRESULT result = archiveLink.Open2(codecs, formatIndices2, options.StdInMode, NULL, arcPath, openCallback);\r
+    if (result == E_ABORT)\r
+      return result;\r
+\r
+    bool crypted = false;\r
+    #ifndef _NO_CRYPTO\r
+    crypted = openCallback->Open_WasPasswordAsked();\r
+    #endif\r
+\r
+    RINOK(extractCallback->OpenResult(arcPath, result, crypted));\r
+    if (result != S_OK)\r
+      continue;\r
+\r
+    if (!options.StdInMode)\r
+    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)\r
+    {\r
+      int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);\r
+      if (index >= 0 && index > i)\r
+      {\r
+        arcPaths.Delete(index);\r
+        arcPathsFull.Delete(index);\r
+        totalPackSize -= archiveSizes[index];\r
+        archiveSizes.Delete(index);\r
+        numArcs = arcPaths.Size();\r
+      }\r
+    }\r
+    if (archiveLink.VolumePaths.Size() != 0)\r
+    {\r
+      totalPackSize += archiveLink.VolumesSize;\r
+      RINOK(extractCallback->SetTotal(totalPackSize));\r
+    }\r
+\r
+    #ifndef _NO_CRYPTO\r
+    UString password;\r
+    RINOK(openCallback->Open_GetPasswordIfAny(password));\r
+    if (!password.IsEmpty())\r
+    {\r
+      RINOK(extractCallback->SetPassword(password));\r
+    }\r
+    #endif\r
+\r
+    for (int v = 0; v < archiveLink.Arcs.Size(); v++)\r
+    {\r
+      const UString &s = archiveLink.Arcs[v].ErrorMessage;\r
+      if (!s.IsEmpty())\r
+      {\r
+        RINOK(extractCallback->MessageError(s));\r
+      }\r
+    }\r
+\r
+    CArc &arc = archiveLink.Arcs.Back();\r
+    arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);\r
+    arc.MTime = fi.MTime;\r
+\r
+    UInt64 packProcessed;\r
+    RINOK(DecompressArchive(arc,\r
+        fi.Size + archiveLink.VolumesSize,\r
+        wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage, packProcessed));\r
+    if (!options.StdInMode)\r
+      packProcessed = fi.Size + archiveLink.VolumesSize;\r
+    extractCallbackSpec->LocalProgressSpec->InSize += packProcessed;\r
+    extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;\r
+    if (!errorMessage.IsEmpty())\r
+      return E_FAIL;\r
+  }\r
+  stat.NumFolders = extractCallbackSpec->NumFolders;\r
+  stat.NumFiles = extractCallbackSpec->NumFiles;\r
+  stat.UnpackSize = extractCallbackSpec->UnpackSize;\r
+  stat.CrcSum = extractCallbackSpec->CrcSum;\r
+\r
+  stat.NumArchives = arcPaths.Size();\r
+  stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/UI/Common/Extract.h b/CPP/7zip/UI/Common/Extract.h
new file mode 100755 (executable)
index 0000000..70926d7
--- /dev/null
@@ -0,0 +1,76 @@
+// Extract.h\r
+\r
+#ifndef __EXTRACT_H\r
+#define __EXTRACT_H\r
+\r
+#include "Windows/FileFind.h"\r
+\r
+#include "../../Archive/IArchive.h"\r
+\r
+#include "ArchiveExtractCallback.h"\r
+#include "ArchiveOpenCallback.h"\r
+#include "ExtractMode.h"\r
+#include "Property.h"\r
+\r
+#include "../Common/LoadCodecs.h"\r
+\r
+struct CExtractOptions\r
+{\r
+  bool StdInMode;\r
+  bool StdOutMode;\r
+  bool YesToAll;\r
+  bool TestMode;\r
+  bool CalcCrc;\r
+  NExtract::NPathMode::EEnum PathMode;\r
+  NExtract::NOverwriteMode::EEnum OverwriteMode;\r
+  UString OutputDir;\r
+  \r
+  // bool ShowDialog;\r
+  // bool PasswordEnabled;\r
+  // UString Password;\r
+  #if !defined(_7ZIP_ST) && !defined(_SFX)\r
+  CObjectVector<CProperty> Properties;\r
+  #endif\r
+\r
+  #ifdef EXTERNAL_CODECS\r
+  CCodecs *Codecs;\r
+  #endif\r
+\r
+  CExtractOptions():\r
+      StdInMode(false),\r
+      StdOutMode(false),\r
+      YesToAll(false),\r
+      TestMode(false),\r
+      CalcCrc(false),\r
+      PathMode(NExtract::NPathMode::kFullPathnames),\r
+      OverwriteMode(NExtract::NOverwriteMode::kAskBefore)\r
+      {}\r
+};\r
+\r
+struct CDecompressStat\r
+{\r
+  UInt64 NumArchives;\r
+  UInt64 UnpackSize;\r
+  UInt64 PackSize;\r
+  UInt64 NumFolders;\r
+  UInt64 NumFiles;\r
+  UInt32 CrcSum;\r
+\r
+  void Clear()\r
+  {\r
+    NumArchives = UnpackSize = PackSize = NumFolders = NumFiles = 0;\r
+    CrcSum = 0;\r
+  }\r
+};\r
+\r
+HRESULT DecompressArchives(\r
+    CCodecs *codecs, const CIntVector &formatIndices,\r
+    UStringVector &archivePaths, UStringVector &archivePathsFull,\r
+    const NWildcard::CCensorNode &wildcardCensor,\r
+    const CExtractOptions &options,\r
+    IOpenCallbackUI *openCallback,\r
+    IExtractCallbackUI *extractCallback,\r
+    UString &errorMessage,\r
+    CDecompressStat &stat);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/ExtractMode.h b/CPP/7zip/UI/Common/ExtractMode.h
new file mode 100755 (executable)
index 0000000..44c4053
--- /dev/null
@@ -0,0 +1,31 @@
+// ExtractMode.h\r
+\r
+#ifndef __EXTRACT_MODE_H\r
+#define __EXTRACT_MODE_H\r
+\r
+namespace NExtract {\r
+  \r
+  namespace NPathMode\r
+  {\r
+    enum EEnum\r
+    {\r
+      kFullPathnames,\r
+      kCurrentPathnames,\r
+      kNoPathnames\r
+    };\r
+  }\r
+  \r
+  namespace NOverwriteMode\r
+  {\r
+    enum EEnum\r
+    {\r
+      kAskBefore,\r
+      kWithoutPrompt,\r
+      kSkipExisting,\r
+      kAutoRename,\r
+      kAutoRenameExisting\r
+    };\r
+  }\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
new file mode 100755 (executable)
index 0000000..604148a
--- /dev/null
@@ -0,0 +1,142 @@
+// ExtractingFilePath.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../../C/Types.h"\r
+\r
+#include "Common/Wildcard.h"\r
+\r
+#include "ExtractingFilePath.h"\r
+\r
+static UString ReplaceIncorrectChars(const UString &s)\r
+{\r
+  #ifdef _WIN32\r
+  UString res;\r
+  for (int i = 0; i < s.Length(); i++)\r
+  {\r
+    wchar_t c = s[i];\r
+    if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>'  || c == '|' || c == ':' || c == '"')\r
+      c = '_';\r
+    res += c;\r
+  }\r
+  res.TrimRight();\r
+  while (!res.IsEmpty() && res[res.Length() - 1] == '.')\r
+    res.Delete(res.Length() - 1);\r
+  return res;\r
+  #else\r
+  return s;\r
+  #endif\r
+}\r
+\r
+#ifdef _WIN32\r
+static const wchar_t *g_ReservedNames[] =\r
+{\r
+  L"CON", L"PRN", L"AUX", L"NUL"\r
+};\r
+\r
+static bool CheckTail(const UString &name, int len)\r
+{\r
+  int dotPos = name.Find(L'.');\r
+  if (dotPos < 0)\r
+    dotPos = name.Length();\r
+  UString s = name.Left(dotPos);\r
+  s.TrimRight();\r
+  return (s.Length() != len);\r
+}\r
+\r
+static bool CheckNameNum(const UString &name, const wchar_t *reservedName)\r
+{\r
+  int len = MyStringLen(reservedName);\r
+  if (name.Length() <= len)\r
+    return true;\r
+  if (name.Left(len).CompareNoCase(reservedName) != 0)\r
+    return true;\r
+  wchar_t c = name[len];\r
+  if (c < L'0' || c > L'9')\r
+    return true;\r
+  return CheckTail(name, len + 1);\r
+}\r
+\r
+static bool IsSupportedName(const UString &name)\r
+{\r
+  for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)\r
+  {\r
+    const wchar_t *reservedName = g_ReservedNames[i];\r
+    int len = MyStringLen(reservedName);\r
+    if (name.Length() < len)\r
+      continue;\r
+    if (name.Left(len).CompareNoCase(reservedName) != 0)\r
+      continue;\r
+    if (!CheckTail(name, len))\r
+      return false;\r
+  }\r
+  if (!CheckNameNum(name, L"COM"))\r
+    return false;\r
+  return CheckNameNum(name, L"LPT");\r
+}\r
+#endif\r
+\r
+static UString GetCorrectFileName(const UString &path)\r
+{\r
+  if (path == L".." || path == L".")\r
+    return UString();\r
+  return ReplaceIncorrectChars(path);\r
+}\r
+\r
+void MakeCorrectPath(UStringVector &pathParts)\r
+{\r
+  for (int i = 0; i < pathParts.Size();)\r
+  {\r
+    UString &s = pathParts[i];\r
+    s = GetCorrectFileName(s);\r
+    if (s.IsEmpty())\r
+      pathParts.Delete(i);\r
+    else\r
+    {\r
+      #ifdef _WIN32\r
+      if (!IsSupportedName(s))\r
+        s = (UString)L"_" + s;\r
+      #endif\r
+      i++;\r
+    }\r
+  }\r
+}\r
+\r
+UString MakePathNameFromParts(const UStringVector &parts)\r
+{\r
+  UString result;\r
+  for (int i = 0; i < parts.Size(); i++)\r
+  {\r
+    if (i != 0)\r
+      result += WCHAR_PATH_SEPARATOR;\r
+    result += parts[i];\r
+  }\r
+  return result;\r
+}\r
+\r
+UString GetCorrectFsPath(const UString &path)\r
+{\r
+  UString res = GetCorrectFileName(path);\r
+  #ifdef _WIN32\r
+  if (!IsSupportedName(res))\r
+    res = (UString)L"_" + res;\r
+  #endif\r
+  return res;\r
+}\r
+  \r
+UString GetCorrectFullFsPath(const UString &path)\r
+{\r
+  UStringVector parts;\r
+  SplitPathToParts(path, parts);\r
+  for (int i = 0; i < parts.Size(); i++)\r
+  {\r
+    UString &s = parts[i];\r
+    #ifdef _WIN32\r
+    while (!s.IsEmpty() && s[s.Length() - 1] == '.')\r
+      s.Delete(s.Length() - 1);\r
+    if (!IsSupportedName(s))\r
+      s = (UString)L"_" + s;\r
+    #endif\r
+  }\r
+  return MakePathNameFromParts(parts);\r
+}\r
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.h b/CPP/7zip/UI/Common/ExtractingFilePath.h
new file mode 100755 (executable)
index 0000000..54bdc72
--- /dev/null
@@ -0,0 +1,13 @@
+// ExtractingFilePath.h\r
+\r
+#ifndef __EXTRACTING_FILE_PATH_H\r
+#define __EXTRACTING_FILE_PATH_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+UString MakePathNameFromParts(const UStringVector &parts);\r
+void MakeCorrectPath(UStringVector &pathParts);\r
+UString GetCorrectFsPath(const UString &path);\r
+UString GetCorrectFullFsPath(const UString &path);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/IFileExtractCallback.h b/CPP/7zip/UI/Common/IFileExtractCallback.h
new file mode 100755 (executable)
index 0000000..5aff92f
--- /dev/null
@@ -0,0 +1,46 @@
+// IFileExtractCallback.h\r
+\r
+#ifndef __IFILEEXTRACTCALLBACK_H\r
+#define __IFILEEXTRACTCALLBACK_H\r
+\r
+#include "Common/MyString.h"\r
+#include "../../IDecl.h"\r
+\r
+namespace NOverwriteAnswer\r
+{\r
+  enum EEnum\r
+  {\r
+    kYes,\r
+    kYesToAll,\r
+    kNo,\r
+    kNoToAll,\r
+    kAutoRename,\r
+    kCancel\r
+  };\r
+}\r
+\r
+DECL_INTERFACE_SUB(IFolderArchiveExtractCallback, IProgress, 0x01, 0x07)\r
+{\r
+public:\r
+  STDMETHOD(AskOverwrite)(\r
+      const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,\r
+      const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,\r
+      Int32 *answer) PURE;\r
+  STDMETHOD(PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position) PURE;\r
+  STDMETHOD(MessageError)(const wchar_t *message) PURE;\r
+  STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted) PURE;\r
+};\r
+\r
+struct IExtractCallbackUI: IFolderArchiveExtractCallback\r
+{\r
+  virtual HRESULT BeforeOpen(const wchar_t *name) = 0;\r
+  virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0;\r
+  virtual HRESULT ThereAreNoFiles() = 0;\r
+  virtual HRESULT ExtractResult(HRESULT result) = 0;\r
+\r
+  #ifndef _NO_CRYPTO\r
+  virtual HRESULT SetPassword(const UString &password) = 0;\r
+  #endif\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp
new file mode 100755 (executable)
index 0000000..67a0cc7
--- /dev/null
@@ -0,0 +1,681 @@
+// LoadCodecs.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "LoadCodecs.h"\r
+\r
+#include "../../../Common/MyCom.h"\r
+#ifdef NEW_FOLDER_INTERFACE\r
+#include "../../../Common/StringToInt.h"\r
+#endif\r
+#include "../../../Windows/PropVariant.h"\r
+\r
+#include "../../ICoder.h"\r
+#include "../../Common/RegisterArc.h"\r
+\r
+#ifdef EXTERNAL_CODECS\r
+#include "../../../Windows/FileFind.h"\r
+#include "../../../Windows/DLL.h"\r
+#ifdef NEW_FOLDER_INTERFACE\r
+#include "../../../Windows/ResourceString.h"\r
+static const UINT kIconTypesResId = 100;\r
+#endif\r
+\r
+#ifdef _WIN32\r
+#include "Windows/Registry.h"\r
+#endif\r
+\r
+using namespace NWindows;\r
+using namespace NFile;\r
+\r
+#ifdef _WIN32\r
+extern HINSTANCE g_hInstance;\r
+#endif\r
+\r
+static CSysString GetLibraryFolderPrefix()\r
+{\r
+  #ifdef _WIN32\r
+  TCHAR fullPath[MAX_PATH + 1];\r
+  ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);\r
+  CSysString path = fullPath;\r
+  int pos = path.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));\r
+  return path.Left(pos + 1);\r
+  #else\r
+  return CSysString(); // FIX IT\r
+  #endif\r
+}\r
+\r
+#define kCodecsFolderName TEXT("Codecs")\r
+#define kFormatsFolderName TEXT("Formats")\r
+static const TCHAR *kMainDll = TEXT("7z.dll");\r
+\r
+#ifdef _WIN32\r
+static LPCTSTR kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip");\r
+static LPCTSTR kProgramPathValue = TEXT("Path");\r
+static bool ReadPathFromRegistry(HKEY baseKey, CSysString &path)\r
+{\r
+  NRegistry::CKey key;\r
+  if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)\r
+    if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS)\r
+    {\r
+      NName::NormalizeDirPathPrefix(path);\r
+      return true;\r
+    }\r
+  return false;\r
+}\r
+\r
+#endif\r
+\r
+CSysString GetBaseFolderPrefixFromRegistry()\r
+{\r
+  CSysString moduleFolderPrefix = GetLibraryFolderPrefix();\r
+  #ifdef _WIN32\r
+  if (!NFind::DoesFileExist(moduleFolderPrefix + kMainDll) &&\r
+      !NFind::DoesDirExist(moduleFolderPrefix + kCodecsFolderName) &&\r
+      !NFind::DoesDirExist(moduleFolderPrefix + kFormatsFolderName))\r
+  {\r
+    CSysString path;\r
+    if (ReadPathFromRegistry(HKEY_CURRENT_USER, path))\r
+      return path;\r
+    if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))\r
+      return path;\r
+  }\r
+  #endif\r
+  return moduleFolderPrefix;\r
+}\r
+\r
+typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);\r
+typedef UInt32 (WINAPI *GetNumberOfFormatsFunc)(UInt32 *numFormats);\r
+typedef UInt32 (WINAPI *GetHandlerPropertyFunc)(PROPID propID, PROPVARIANT *value);\r
+typedef UInt32 (WINAPI *GetHandlerPropertyFunc2)(UInt32 index, PROPID propID, PROPVARIANT *value);\r
+typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *iid, void **outObject);\r
+typedef UInt32 (WINAPI *SetLargePageModeFunc)();\r
+\r
+\r
+static HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 index,\r
+    PROPID propId, CLSID &clsId, bool &isAssigned)\r
+{\r
+  NWindows::NCOM::CPropVariant prop;\r
+  isAssigned = false;\r
+  RINOK(getMethodProperty(index, propId, &prop));\r
+  if (prop.vt == VT_BSTR)\r
+  {\r
+    isAssigned = true;\r
+    clsId = *(const GUID *)prop.bstrVal;\r
+  }\r
+  else if (prop.vt != VT_EMPTY)\r
+    return E_FAIL;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CCodecs::LoadCodecs()\r
+{\r
+  CCodecLib &lib = Libs.Back();\r
+  lib.GetMethodProperty = (GetMethodPropertyFunc)lib.Lib.GetProc("GetMethodProperty");\r
+  if (lib.GetMethodProperty == NULL)\r
+    return S_OK;\r
+\r
+  UInt32 numMethods = 1;\r
+  GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)lib.Lib.GetProc("GetNumberOfMethods");\r
+  if (getNumberOfMethodsFunc != NULL)\r
+  {\r
+    RINOK(getNumberOfMethodsFunc(&numMethods));\r
+  }\r
+\r
+  for(UInt32 i = 0; i < numMethods; i++)\r
+  {\r
+    CDllCodecInfo info;\r
+    info.LibIndex = Libs.Size() - 1;\r
+    info.CodecIndex = i;\r
+\r
+    RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));\r
+    RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));\r
+\r
+    Codecs.Add(info);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+static HRESULT ReadProp(\r
+    GetHandlerPropertyFunc getProp,\r
+    GetHandlerPropertyFunc2 getProp2,\r
+    UInt32 index, PROPID propID, NCOM::CPropVariant &prop)\r
+{\r
+  if (getProp2)\r
+    return getProp2(index, propID, &prop);;\r
+  return getProp(propID, &prop);\r
+}\r
+\r
+static HRESULT ReadBoolProp(\r
+    GetHandlerPropertyFunc getProp,\r
+    GetHandlerPropertyFunc2 getProp2,\r
+    UInt32 index, PROPID propID, bool &res)\r
+{\r
+  NCOM::CPropVariant prop;\r
+  RINOK(ReadProp(getProp, getProp2, index, propID, prop));\r
+  if (prop.vt == VT_BOOL)\r
+    res = VARIANT_BOOLToBool(prop.boolVal);\r
+  else if (prop.vt != VT_EMPTY)\r
+    return E_FAIL;\r
+  return S_OK;\r
+}\r
+\r
+static HRESULT ReadStringProp(\r
+    GetHandlerPropertyFunc getProp,\r
+    GetHandlerPropertyFunc2 getProp2,\r
+    UInt32 index, PROPID propID, UString &res)\r
+{\r
+  NCOM::CPropVariant prop;\r
+  RINOK(ReadProp(getProp, getProp2, index, propID, prop));\r
+  if (prop.vt == VT_BSTR)\r
+    res = prop.bstrVal;\r
+  else if (prop.vt != VT_EMPTY)\r
+    return E_FAIL;\r
+  return S_OK;\r
+}\r
+\r
+#endif\r
+\r
+static const unsigned int kNumArcsMax = 48;\r
+static unsigned int g_NumArcs = 0;\r
+static const CArcInfo *g_Arcs[kNumArcsMax];\r
+void RegisterArc(const CArcInfo *arcInfo)\r
+{\r
+  if (g_NumArcs < kNumArcsMax)\r
+    g_Arcs[g_NumArcs++] = arcInfo;\r
+}\r
+\r
+static void SplitString(const UString &srcString, UStringVector &destStrings)\r
+{\r
+  destStrings.Clear();\r
+  UString s;\r
+  int len = srcString.Length();\r
+  if (len == 0)\r
+    return;\r
+  for (int i = 0; i < len; i++)\r
+  {\r
+    wchar_t c = srcString[i];\r
+    if (c == L' ')\r
+    {\r
+      if (!s.IsEmpty())\r
+      {\r
+        destStrings.Add(s);\r
+        s.Empty();\r
+      }\r
+    }\r
+    else\r
+      s += c;\r
+  }\r
+  if (!s.IsEmpty())\r
+    destStrings.Add(s);\r
+}\r
+\r
+void CArcInfoEx::AddExts(const wchar_t *ext, const wchar_t *addExt)\r
+{\r
+  UStringVector exts, addExts;\r
+  if (ext != 0)\r
+    SplitString(ext, exts);\r
+  if (addExt != 0)\r
+    SplitString(addExt, addExts);\r
+  for (int i = 0; i < exts.Size(); i++)\r
+  {\r
+    CArcExtInfo extInfo;\r
+    extInfo.Ext = exts[i];\r
+    if (i < addExts.Size())\r
+    {\r
+      extInfo.AddExt = addExts[i];\r
+      if (extInfo.AddExt == L"*")\r
+        extInfo.AddExt.Empty();\r
+    }\r
+    Exts.Add(extInfo);\r
+  }\r
+}\r
+\r
+#ifdef EXTERNAL_CODECS\r
+\r
+HRESULT CCodecs::LoadFormats()\r
+{\r
+  const NDLL::CLibrary &lib = Libs.Back().Lib;\r
+  GetHandlerPropertyFunc getProp = 0;\r
+  GetHandlerPropertyFunc2 getProp2 = (GetHandlerPropertyFunc2)lib.GetProc("GetHandlerProperty2");\r
+  if (getProp2 == NULL)\r
+  {\r
+    getProp = (GetHandlerPropertyFunc)lib.GetProc("GetHandlerProperty");\r
+    if (getProp == NULL)\r
+      return S_OK;\r
+  }\r
+\r
+  UInt32 numFormats = 1;\r
+  GetNumberOfFormatsFunc getNumberOfFormats = (GetNumberOfFormatsFunc)lib.GetProc("GetNumberOfFormats");\r
+  if (getNumberOfFormats != NULL)\r
+  {\r
+    RINOK(getNumberOfFormats(&numFormats));\r
+  }\r
+  if (getProp2 == NULL)\r
+    numFormats = 1;\r
+\r
+  for(UInt32 i = 0; i < numFormats; i++)\r
+  {\r
+    CArcInfoEx item;\r
+    item.LibIndex = Libs.Size() - 1;\r
+    item.FormatIndex = i;\r
+\r
+    RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kName, item.Name));\r
+\r
+    NCOM::CPropVariant prop;\r
+    if (ReadProp(getProp, getProp2, i, NArchive::kClassID, prop) != S_OK)\r
+      continue;\r
+    if (prop.vt != VT_BSTR)\r
+      continue;\r
+    item.ClassID = *(const GUID *)prop.bstrVal;\r
+    prop.Clear();\r
+\r
+    UString ext, addExt;\r
+    RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kExtension, ext));\r
+    RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kAddExtension, addExt));\r
+    item.AddExts(ext, addExt);\r
+\r
+    ReadBoolProp(getProp, getProp2, i, NArchive::kUpdate, item.UpdateEnabled);\r
+    if (item.UpdateEnabled)\r
+      ReadBoolProp(getProp, getProp2, i, NArchive::kKeepName, item.KeepName);\r
+    \r
+    if (ReadProp(getProp, getProp2, i, NArchive::kStartSignature, prop) == S_OK)\r
+      if (prop.vt == VT_BSTR)\r
+      {\r
+        UINT len = ::SysStringByteLen(prop.bstrVal);\r
+        item.StartSignature.SetCapacity(len);\r
+        memmove(item.StartSignature, prop.bstrVal, len);\r
+      }\r
+    Formats.Add(item);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+#ifdef NEW_FOLDER_INTERFACE\r
+void CCodecIcons::LoadIcons(HMODULE m)\r
+{\r
+  UString iconTypes = MyLoadStringW(m, kIconTypesResId);\r
+  UStringVector pairs;\r
+  SplitString(iconTypes, pairs);\r
+  for (int i = 0; i < pairs.Size(); i++)\r
+  {\r
+    const UString &s = pairs[i];\r
+    int pos = s.Find(L':');\r
+    CIconPair iconPair;\r
+    iconPair.IconIndex = -1;\r
+    if (pos < 0)\r
+      pos = s.Length();\r
+    else\r
+    {\r
+      UString num = s.Mid(pos + 1);\r
+      if (!num.IsEmpty())\r
+      {\r
+        const wchar_t *end;\r
+        iconPair.IconIndex = (UInt32)ConvertStringToUInt64(num, &end);\r
+        if (*end != L'\0')\r
+          continue;\r
+      }\r
+    }\r
+    iconPair.Ext = s.Left(pos);\r
+    IconPairs.Add(iconPair);\r
+  }\r
+}\r
+\r
+bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const\r
+{\r
+  iconIndex = -1;\r
+  for (int i = 0; i < IconPairs.Size(); i++)\r
+  {\r
+    const CIconPair &pair = IconPairs[i];\r
+    if (ext.CompareNoCase(pair.Ext) == 0)\r
+    {\r
+      iconIndex = pair.IconIndex;\r
+      return true;\r
+    }\r
+  }\r
+  return false;\r
+}\r
+#endif\r
+\r
+#ifdef _7ZIP_LARGE_PAGES\r
+extern "C"\r
+{\r
+  extern SIZE_T g_LargePageSize;\r
+}\r
+#endif\r
+\r
+HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)\r
+{\r
+  if (needCheckDll)\r
+  {\r
+    NDLL::CLibrary library;\r
+    if (!library.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE))\r
+      return S_OK;\r
+  }\r
+  Libs.Add(CCodecLib());\r
+  CCodecLib &lib = Libs.Back();\r
+  #ifdef NEW_FOLDER_INTERFACE\r
+  lib.Path = dllPath;\r
+  #endif\r
+  bool used = false;\r
+  HRESULT res = S_OK;\r
+  if (lib.Lib.Load(dllPath))\r
+  {\r
+    #ifdef NEW_FOLDER_INTERFACE\r
+    lib.LoadIcons();\r
+    #endif\r
+\r
+    #ifdef _7ZIP_LARGE_PAGES\r
+    if (g_LargePageSize != 0)\r
+    {\r
+      SetLargePageModeFunc setLargePageMode = (SetLargePageModeFunc)lib.Lib.GetProc("SetLargePageMode");\r
+      if (setLargePageMode != 0)\r
+        setLargePageMode();\r
+    }\r
+    #endif\r
+\r
+    lib.CreateObject = (CreateObjectFunc)lib.Lib.GetProc("CreateObject");\r
+    if (lib.CreateObject != 0)\r
+    {\r
+      int startSize = Codecs.Size();\r
+      res = LoadCodecs();\r
+      used = (Codecs.Size() != startSize);\r
+      if (res == S_OK)\r
+      {\r
+        startSize = Formats.Size();\r
+        res = LoadFormats();\r
+        used = used || (Formats.Size() != startSize);\r
+      }\r
+    }\r
+  }\r
+  if (!used)\r
+    Libs.DeleteBack();\r
+  return res;\r
+}\r
+\r
+HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix)\r
+{\r
+  NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));\r
+  NFile::NFind::CFileInfo fi;\r
+  while (enumerator.Next(fi))\r
+  {\r
+    if (fi.IsDir())\r
+      continue;\r
+    RINOK(LoadDll(folderPrefix + fi.Name, true));\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+#endif\r
+\r
+#ifndef _SFX\r
+static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size)\r
+{\r
+  bb.SetCapacity(size);\r
+  memmove((Byte *)bb, data, size);\r
+}\r
+#endif\r
+\r
+HRESULT CCodecs::Load()\r
+{\r
+  #ifdef NEW_FOLDER_INTERFACE\r
+  InternalIcons.LoadIcons(g_hInstance);\r
+  #endif\r
+\r
+  Formats.Clear();\r
+  #ifdef EXTERNAL_CODECS\r
+  Codecs.Clear();\r
+  #endif\r
+  for (UInt32 i = 0; i < g_NumArcs; i++)\r
+  {\r
+    const CArcInfo &arc = *g_Arcs[i];\r
+    CArcInfoEx item;\r
+    item.Name = arc.Name;\r
+    item.CreateInArchive = arc.CreateInArchive;\r
+    item.CreateOutArchive = arc.CreateOutArchive;\r
+    item.AddExts(arc.Ext, arc.AddExt);\r
+    item.UpdateEnabled = (arc.CreateOutArchive != 0);\r
+    item.KeepName = arc.KeepName;\r
+\r
+    #ifndef _SFX\r
+    SetBuffer(item.StartSignature, arc.Signature, arc.SignatureSize);\r
+    #endif\r
+    Formats.Add(item);\r
+  }\r
+  #ifdef EXTERNAL_CODECS\r
+  const CSysString baseFolder = GetBaseFolderPrefixFromRegistry();\r
+  RINOK(LoadDll(baseFolder + kMainDll, false));\r
+  RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName TEXT(STRING_PATH_SEPARATOR)));\r
+  RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName TEXT(STRING_PATH_SEPARATOR)));\r
+  #endif\r
+  return S_OK;\r
+}\r
+\r
+#ifndef _SFX\r
+\r
+int CCodecs::FindFormatForArchiveName(const UString &arcPath) const\r
+{\r
+  int slashPos1 = arcPath.ReverseFind(WCHAR_PATH_SEPARATOR);\r
+  int slashPos2 = arcPath.ReverseFind(L'.');\r
+  int dotPos = arcPath.ReverseFind(L'.');\r
+  if (dotPos < 0 || dotPos < slashPos1 || dotPos < slashPos2)\r
+    return -1;\r
+  UString ext = arcPath.Mid(dotPos + 1);\r
+  for (int i = 0; i < Formats.Size(); i++)\r
+  {\r
+    const CArcInfoEx &arc = Formats[i];\r
+    if (!arc.UpdateEnabled)\r
+      continue;\r
+    if (arc.FindExtension(ext) >= 0)\r
+      return i;\r
+  }\r
+  return -1;\r
+}\r
+\r
+int CCodecs::FindFormatForExtension(const UString &ext) const\r
+{\r
+  if (ext.IsEmpty())\r
+    return -1;\r
+  for (int i = 0; i < Formats.Size(); i++)\r
+    if (Formats[i].FindExtension(ext) >= 0)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+int CCodecs::FindFormatForArchiveType(const UString &arcType) const\r
+{\r
+  for (int i = 0; i < Formats.Size(); i++)\r
+    if (Formats[i].Name.CompareNoCase(arcType) == 0)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const\r
+{\r
+  formatIndices.Clear();\r
+  for (int pos = 0; pos < arcType.Length();)\r
+  {\r
+    int pos2 = arcType.Find('.', pos);\r
+    if (pos2 < 0)\r
+      pos2 = arcType.Length();\r
+    const UString name = arcType.Mid(pos, pos2 - pos);\r
+    int index = FindFormatForArchiveType(name);\r
+    if (index < 0 && name != L"*")\r
+    {\r
+      formatIndices.Clear();\r
+      return false;\r
+    }\r
+    formatIndices.Add(index);\r
+    pos = pos2 + 1;\r
+  }\r
+  return true;\r
+}\r
+\r
+#endif\r
+\r
+#ifdef EXTERNAL_CODECS\r
+\r
+#ifdef EXPORT_CODECS\r
+extern unsigned int g_NumCodecs;\r
+STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject);\r
+STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);\r
+// STDAPI GetNumberOfMethods(UInt32 *numCodecs);\r
+#endif\r
+\r
+STDMETHODIMP CCodecs::GetNumberOfMethods(UInt32 *numMethods)\r
+{\r
+  *numMethods =\r
+      #ifdef EXPORT_CODECS\r
+      g_NumCodecs +\r
+      #endif\r
+      Codecs.Size();\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)\r
+{\r
+  #ifdef EXPORT_CODECS\r
+  if (index < g_NumCodecs)\r
+    return GetMethodProperty(index, propID, value);\r
+  #endif\r
+\r
+  const CDllCodecInfo &ci = Codecs[index\r
+      #ifdef EXPORT_CODECS\r
+      - g_NumCodecs\r
+      #endif\r
+      ];\r
+\r
+  if (propID == NMethodPropID::kDecoderIsAssigned)\r
+  {\r
+    NWindows::NCOM::CPropVariant propVariant;\r
+    propVariant = ci.DecoderIsAssigned;\r
+    propVariant.Detach(value);\r
+    return S_OK;\r
+  }\r
+  if (propID == NMethodPropID::kEncoderIsAssigned)\r
+  {\r
+    NWindows::NCOM::CPropVariant propVariant;\r
+    propVariant = ci.EncoderIsAssigned;\r
+    propVariant.Detach(value);\r
+    return S_OK;\r
+  }\r
+  return Libs[ci.LibIndex].GetMethodProperty(ci.CodecIndex, propID, value);\r
+}\r
+\r
+STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)\r
+{\r
+  #ifdef EXPORT_CODECS\r
+  if (index < g_NumCodecs)\r
+    return CreateCoder2(false, index, iid, coder);\r
+  #endif\r
+  const CDllCodecInfo &ci = Codecs[index\r
+      #ifdef EXPORT_CODECS\r
+      - g_NumCodecs\r
+      #endif\r
+      ];\r
+  if (ci.DecoderIsAssigned)\r
+    return Libs[ci.LibIndex].CreateObject(&ci.Decoder, iid, (void **)coder);\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)\r
+{\r
+  #ifdef EXPORT_CODECS\r
+  if (index < g_NumCodecs)\r
+    return CreateCoder2(true, index, iid, coder);\r
+  #endif\r
+  const CDllCodecInfo &ci = Codecs[index\r
+      #ifdef EXPORT_CODECS\r
+      - g_NumCodecs\r
+      #endif\r
+      ];\r
+  if (ci.EncoderIsAssigned)\r
+    return Libs[ci.LibIndex].CreateObject(&ci.Encoder, iid, (void **)coder);\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CCodecs::CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const\r
+{\r
+  for (int i = 0; i < Codecs.Size(); i++)\r
+  {\r
+    const CDllCodecInfo &codec = Codecs[i];\r
+    if (encode && !codec.EncoderIsAssigned || !encode && !codec.DecoderIsAssigned)\r
+      continue;\r
+    const CCodecLib &lib = Libs[codec.LibIndex];\r
+    UString res;\r
+    NWindows::NCOM::CPropVariant prop;\r
+    RINOK(lib.GetMethodProperty(codec.CodecIndex, NMethodPropID::kName, &prop));\r
+    if (prop.vt == VT_BSTR)\r
+      res = prop.bstrVal;\r
+    else if (prop.vt != VT_EMPTY)\r
+      continue;\r
+    if (name.CompareNoCase(res) == 0)\r
+      return lib.CreateObject(encode ? &codec.Encoder : &codec.Decoder, &IID_ICompressCoder, (void **)&coder);\r
+  }\r
+  return CLASS_E_CLASSNOTAVAILABLE;\r
+}\r
+\r
+int CCodecs::GetCodecLibIndex(UInt32 index)\r
+{\r
+  #ifdef EXPORT_CODECS\r
+  if (index < g_NumCodecs)\r
+    return -1;\r
+  #endif\r
+  #ifdef EXTERNAL_CODECS\r
+  const CDllCodecInfo &ci = Codecs[index\r
+      #ifdef EXPORT_CODECS\r
+      - g_NumCodecs\r
+      #endif\r
+      ];\r
+  return ci.LibIndex;\r
+  #else\r
+  return -1;\r
+  #endif\r
+}\r
+\r
+bool CCodecs::GetCodecEncoderIsAssigned(UInt32 index)\r
+{\r
+  #ifdef EXPORT_CODECS\r
+  if (index < g_NumCodecs)\r
+  {\r
+    NWindows::NCOM::CPropVariant prop;\r
+    if (GetProperty(index, NMethodPropID::kEncoder, &prop) == S_OK)\r
+      if (prop.vt != VT_EMPTY)\r
+        return true;\r
+    return false;\r
+  }\r
+  #endif\r
+  #ifdef EXTERNAL_CODECS\r
+  const CDllCodecInfo &ci = Codecs[index\r
+      #ifdef EXPORT_CODECS\r
+      - g_NumCodecs\r
+      #endif\r
+      ];\r
+  return ci.EncoderIsAssigned;\r
+  #else\r
+  return false;\r
+  #endif\r
+}\r
+\r
+HRESULT CCodecs::GetCodecId(UInt32 index, UInt64 &id)\r
+{\r
+  UString s;\r
+  NWindows::NCOM::CPropVariant prop;\r
+  RINOK(GetProperty(index, NMethodPropID::kID, &prop));\r
+  if (prop.vt != VT_UI8)\r
+    return E_INVALIDARG;\r
+  id = prop.uhVal.QuadPart;\r
+  return S_OK;\r
+}\r
+\r
+UString CCodecs::GetCodecName(UInt32 index)\r
+{\r
+  UString s;\r
+  NWindows::NCOM::CPropVariant prop;\r
+  if (GetProperty(index, NMethodPropID::kName, &prop) == S_OK)\r
+    if (prop.vt == VT_BSTR)\r
+      s = prop.bstrVal;\r
+  return s;\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/LoadCodecs.h b/CPP/7zip/UI/Common/LoadCodecs.h
new file mode 100755 (executable)
index 0000000..5630b59
--- /dev/null
@@ -0,0 +1,235 @@
+// LoadCodecs.h\r
+\r
+#ifndef __LOADCODECS_H\r
+#define __LOADCODECS_H\r
+\r
+#include "../../../Common/Types.h"\r
+#include "../../../Common/MyCom.h"\r
+#include "../../../Common/MyString.h"\r
+#include "../../../Common/Buffer.h"\r
+#include "../../ICoder.h"\r
+\r
+#ifdef EXTERNAL_CODECS\r
+#include "../../../Windows/DLL.h"\r
+#endif\r
+\r
+struct CDllCodecInfo\r
+{\r
+  CLSID Encoder;\r
+  CLSID Decoder;\r
+  bool EncoderIsAssigned;\r
+  bool DecoderIsAssigned;\r
+  int LibIndex;\r
+  UInt32 CodecIndex;\r
+};\r
+\r
+#include "../../Archive/IArchive.h"\r
+\r
+typedef IInArchive * (*CreateInArchiveP)();\r
+typedef IOutArchive * (*CreateOutArchiveP)();\r
+\r
+struct CArcExtInfo\r
+{\r
+  UString Ext;\r
+  UString AddExt;\r
+  CArcExtInfo() {}\r
+  CArcExtInfo(const UString &ext): Ext(ext) {}\r
+  CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}\r
+};\r
+\r
+\r
+struct CArcInfoEx\r
+{\r
+  #ifdef EXTERNAL_CODECS\r
+  int LibIndex;\r
+  UInt32 FormatIndex;\r
+  CLSID ClassID;\r
+  #endif\r
+  bool UpdateEnabled;\r
+  CreateInArchiveP CreateInArchive;\r
+  CreateOutArchiveP CreateOutArchive;\r
+  UString Name;\r
+  CObjectVector<CArcExtInfo> Exts;\r
+  #ifndef _SFX\r
+  CByteBuffer StartSignature;\r
+  // CByteBuffer FinishSignature;\r
+  #ifdef NEW_FOLDER_INTERFACE\r
+  UStringVector AssociateExts;\r
+  #endif\r
+  #endif\r
+  bool KeepName;\r
+  UString GetMainExt() const\r
+  {\r
+    if (Exts.IsEmpty())\r
+      return UString();\r
+    return Exts[0].Ext;\r
+  }\r
+  int FindExtension(const UString &ext) const\r
+  {\r
+    for (int i = 0; i < Exts.Size(); i++)\r
+      if (ext.CompareNoCase(Exts[i].Ext) == 0)\r
+        return i;\r
+    return -1;\r
+  }\r
+  UString GetAllExtensions() const\r
+  {\r
+    UString s;\r
+    for (int i = 0; i < Exts.Size(); i++)\r
+    {\r
+      if (i > 0)\r
+        s += ' ';\r
+      s += Exts[i].Ext;\r
+    }\r
+    return s;\r
+  }\r
+\r
+  void AddExts(const wchar_t* ext, const wchar_t* addExt);\r
+\r
+  CArcInfoEx():\r
+    #ifdef EXTERNAL_CODECS\r
+    LibIndex(-1),\r
+    #endif\r
+    UpdateEnabled(false),\r
+    CreateInArchive(0), CreateOutArchive(0),\r
+    KeepName(false)\r
+    #ifndef _SFX\r
+    #endif\r
+  {}\r
+};\r
+\r
+#ifdef EXTERNAL_CODECS\r
+typedef UInt32 (WINAPI *GetMethodPropertyFunc)(UInt32 index, PROPID propID, PROPVARIANT *value);\r
+typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject);\r
+\r
+\r
+#ifdef NEW_FOLDER_INTERFACE\r
+struct CCodecIcons\r
+{\r
+  struct CIconPair\r
+  {\r
+    UString Ext;\r
+    int IconIndex;\r
+  };\r
+  CObjectVector<CIconPair> IconPairs;\r
+  void LoadIcons(HMODULE m);\r
+  bool FindIconIndex(const UString &ext, int &iconIndex) const;\r
+};\r
+#endif\r
+\r
+struct CCodecLib\r
+#ifdef NEW_FOLDER_INTERFACE\r
+: public CCodecIcons\r
+#endif\r
+{\r
+  NWindows::NDLL::CLibrary Lib;\r
+  GetMethodPropertyFunc GetMethodProperty;\r
+  CreateObjectFunc CreateObject;\r
+  #ifdef NEW_FOLDER_INTERFACE\r
+  CSysString Path;\r
+  void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }\r
+  #endif\r
+  CCodecLib(): GetMethodProperty(0) {}\r
+};\r
+#endif\r
+\r
+class CCodecs:\r
+  #ifdef EXTERNAL_CODECS\r
+  public ICompressCodecsInfo,\r
+  #else\r
+  public IUnknown,\r
+  #endif\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  #ifdef EXTERNAL_CODECS\r
+  CObjectVector<CCodecLib> Libs;\r
+  CObjectVector<CDllCodecInfo> Codecs;\r
+\r
+  #ifdef NEW_FOLDER_INTERFACE\r
+  CCodecIcons InternalIcons;\r
+  #endif\r
+\r
+  HRESULT LoadCodecs();\r
+  HRESULT LoadFormats();\r
+  HRESULT LoadDll(const CSysString &path, bool needCheckDll);\r
+  HRESULT LoadDllsFromFolder(const CSysString &folderPrefix);\r
+\r
+  HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const\r
+  {\r
+    return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);\r
+  }\r
+  #endif\r
+\r
+public:\r
+  CObjectVector<CArcInfoEx> Formats;\r
+  HRESULT Load();\r
+  \r
+  #ifndef _SFX\r
+  int FindFormatForArchiveName(const UString &arcPath) const;\r
+  int FindFormatForExtension(const UString &ext) const;\r
+  int FindFormatForArchiveType(const UString &arcType) const;\r
+  bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const;\r
+  #endif\r
+\r
+  MY_UNKNOWN_IMP\r
+\r
+  #ifdef EXTERNAL_CODECS\r
+  STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods);\r
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);\r
+  STDMETHOD(CreateDecoder)(UInt32 index, const GUID *interfaceID, void **coder);\r
+  STDMETHOD(CreateEncoder)(UInt32 index, const GUID *interfaceID, void **coder);\r
+  #endif\r
+\r
+  int GetCodecLibIndex(UInt32 index);\r
+  bool GetCodecEncoderIsAssigned(UInt32 index);\r
+  HRESULT GetCodecId(UInt32 index, UInt64 &id);\r
+  UString GetCodecName(UInt32 index);\r
+\r
+  HRESULT CreateInArchive(int formatIndex, CMyComPtr<IInArchive> &archive) const\r
+  {\r
+    const CArcInfoEx &ai = Formats[formatIndex];\r
+    #ifdef EXTERNAL_CODECS\r
+    if (ai.LibIndex < 0)\r
+    #endif\r
+    {\r
+      archive = ai.CreateInArchive();\r
+      return S_OK;\r
+    }\r
+    #ifdef EXTERNAL_CODECS\r
+    return CreateArchiveHandler(ai, (void **)&archive, false);\r
+    #endif\r
+  }\r
+  HRESULT CreateOutArchive(int formatIndex, CMyComPtr<IOutArchive> &archive) const\r
+  {\r
+    const CArcInfoEx &ai = Formats[formatIndex];\r
+    #ifdef EXTERNAL_CODECS\r
+    if (ai.LibIndex < 0)\r
+    #endif\r
+    {\r
+      archive = ai.CreateOutArchive();\r
+      return S_OK;\r
+    }\r
+    #ifdef EXTERNAL_CODECS\r
+    return CreateArchiveHandler(ai, (void **)&archive, true);\r
+    #endif\r
+  }\r
+  int FindOutFormatFromName(const UString &name) const\r
+  {\r
+    for (int i = 0; i < Formats.Size(); i++)\r
+    {\r
+      const CArcInfoEx &arc = Formats[i];\r
+      if (!arc.UpdateEnabled)\r
+        continue;\r
+      if (arc.Name.CompareNoCase(name) == 0)\r
+        return i;\r
+    }\r
+    return -1;\r
+  }\r
+\r
+  #ifdef EXTERNAL_CODECS\r
+  HRESULT CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const;\r
+  #endif\r
+\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
new file mode 100755 (executable)
index 0000000..c489e0a
--- /dev/null
@@ -0,0 +1,536 @@
+// OpenArchive.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/Wildcard.h"\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/PropVariant.h"\r
+\r
+#include "../../Common/FileStreams.h"\r
+#include "../../Common/StreamUtils.h"\r
+\r
+#include "DefaultName.h"\r
+#include "OpenArchive.h"\r
+\r
+using namespace NWindows;\r
+\r
+// Static-SFX (for Linux) can be big.\r
+const UInt64 kMaxCheckStartPosition = 1 << 22;\r
+\r
+HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)\r
+{\r
+  NCOM::CPropVariant prop;\r
+  result = false;\r
+  RINOK(archive->GetProperty(index, propID, &prop));\r
+  if (prop.vt == VT_BOOL)\r
+    result = VARIANT_BOOLToBool(prop.boolVal);\r
+  else if (prop.vt != VT_EMPTY)\r
+    return E_FAIL;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)\r
+{\r
+  return GetArchiveItemBoolProp(archive, index, kpidIsDir, result);\r
+}\r
+\r
+HRESULT CArc::GetItemPath(UInt32 index, UString &result) const\r
+{\r
+  {\r
+    NCOM::CPropVariant prop;\r
+    RINOK(Archive->GetProperty(index, kpidPath, &prop));\r
+    if (prop.vt == VT_BSTR)\r
+      result = prop.bstrVal;\r
+    else if (prop.vt == VT_EMPTY)\r
+      result.Empty();\r
+    else\r
+      return E_FAIL;\r
+  }\r
+  if (result.IsEmpty())\r
+  {\r
+    result = DefaultName;\r
+    NCOM::CPropVariant prop;\r
+    RINOK(Archive->GetProperty(index, kpidExtension, &prop));\r
+    if (prop.vt == VT_BSTR)\r
+    {\r
+      result += L'.';\r
+      result += prop.bstrVal;\r
+    }\r
+    else if (prop.vt != VT_EMPTY)\r
+      return E_FAIL;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const\r
+{\r
+  NCOM::CPropVariant prop;\r
+  defined = false;\r
+  ft.dwHighDateTime = ft.dwLowDateTime = 0;\r
+  RINOK(Archive->GetProperty(index, kpidMTime, &prop));\r
+  if (prop.vt == VT_FILETIME)\r
+  {\r
+    ft = prop.filetime;\r
+    defined = true;\r
+  }\r
+  else if (prop.vt != VT_EMPTY)\r
+    return E_FAIL;\r
+  else if (MTimeDefined)\r
+  {\r
+    ft = MTime;\r
+    defined = true;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+#ifndef _SFX\r
+static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)\r
+{\r
+  for (size_t i = 0; i < size; i++)\r
+    if (p1[i] != p2[i])\r
+      return false;\r
+  return true;\r
+}\r
+#endif\r
+\r
+#ifdef UNDER_CE\r
+static const int kNumHashBytes = 1;\r
+#define HASH_VAL(buf, pos) ((buf)[pos])\r
+#else\r
+static const int kNumHashBytes = 2;\r
+#define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))\r
+#endif\r
+\r
+\r
+HRESULT CArc::OpenStream(\r
+    CCodecs *codecs,\r
+    int formatIndex,\r
+    IInStream *stream,\r
+    ISequentialInStream *seqStream,\r
+    IArchiveOpenCallback *callback)\r
+{\r
+  Archive.Release();\r
+  ErrorMessage.Empty();\r
+  const UString fileName = ExtractFileNameFromPath(Path);\r
+  UString extension;\r
+  {\r
+    int dotPos = fileName.ReverseFind(L'.');\r
+    if (dotPos >= 0)\r
+      extension = fileName.Mid(dotPos + 1);\r
+  }\r
+  CIntVector orderIndices;\r
+  if (formatIndex >= 0)\r
+    orderIndices.Add(formatIndex);\r
+  else\r
+  {\r
+\r
+  int i;\r
+  int numFinded = 0;\r
+  for (i = 0; i < codecs->Formats.Size(); i++)\r
+    if (codecs->Formats[i].FindExtension(extension) >= 0)\r
+      orderIndices.Insert(numFinded++, i);\r
+    else\r
+      orderIndices.Add(i);\r
+  \r
+  if (!stream)\r
+  {\r
+    if (numFinded != 1)\r
+      return E_NOTIMPL;\r
+    orderIndices.DeleteFrom(1);\r
+  }\r
+\r
+  #ifndef _SFX\r
+  if (orderIndices.Size() >= 2 && (numFinded == 0 || extension.CompareNoCase(L"exe") == 0))\r
+  {\r
+    CIntVector orderIndices2;\r
+    CByteBuffer byteBuffer;\r
+    const size_t kBufferSize = (1 << 21);\r
+    byteBuffer.SetCapacity(kBufferSize);\r
+    RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));\r
+    size_t processedSize = kBufferSize;\r
+    RINOK(ReadStream(stream, byteBuffer, &processedSize));\r
+    if (processedSize == 0)\r
+      return S_FALSE;\r
+\r
+    const Byte *buf = byteBuffer;\r
+    CByteBuffer hashBuffer;\r
+    const UInt32 kNumVals = 1 << (kNumHashBytes * 8);\r
+    hashBuffer.SetCapacity(kNumVals);\r
+    Byte *hash = hashBuffer;\r
+    memset(hash, 0xFF, kNumVals);\r
+    Byte prevs[256];\r
+    if (orderIndices.Size() >= 256)\r
+      return S_FALSE;\r
+    int i;\r
+    for (i = 0; i < orderIndices.Size(); i++)\r
+    {\r
+      const CArcInfoEx &ai = codecs->Formats[orderIndices[i]];\r
+      const CByteBuffer &sig = ai.StartSignature;\r
+      if (sig.GetCapacity() < kNumHashBytes)\r
+        continue;\r
+      UInt32 v = HASH_VAL(sig, 0);\r
+      prevs[i] = hash[v];\r
+      hash[v] = (Byte)i;\r
+    }\r
+\r
+    processedSize -= (kNumHashBytes - 1);\r
+    for (UInt32 pos = 0; pos < processedSize; pos++)\r
+    {\r
+      for (; pos < processedSize && hash[HASH_VAL(buf, pos)] == 0xFF; pos++);\r
+      if (pos == processedSize)\r
+        break;\r
+      UInt32 v = HASH_VAL(buf, pos);\r
+      Byte *ptr = &hash[v];\r
+      int i = *ptr;\r
+      do\r
+      {\r
+        int index = orderIndices[i];\r
+        const CArcInfoEx &ai = codecs->Formats[index];\r
+        const CByteBuffer &sig = ai.StartSignature;\r
+        if (sig.GetCapacity() != 0 && pos + sig.GetCapacity() <= processedSize + (kNumHashBytes - 1) &&\r
+            TestSignature(buf + pos, sig, sig.GetCapacity()))\r
+        {\r
+          orderIndices2.Add(index);\r
+          orderIndices[i] = 0xFF;\r
+          *ptr = prevs[i];\r
+        }\r
+        else\r
+          ptr = &prevs[i];\r
+        i = *ptr;\r
+      }\r
+      while (i != 0xFF);\r
+    }\r
+    \r
+    for (i = 0; i < orderIndices.Size(); i++)\r
+    {\r
+      int val = orderIndices[i];\r
+      if (val != 0xFF)\r
+        orderIndices2.Add(val);\r
+    }\r
+    orderIndices = orderIndices2;\r
+  }\r
+  else if (extension == L"000" || extension == L"001")\r
+  {\r
+    CByteBuffer byteBuffer;\r
+    const size_t kBufferSize = (1 << 10);\r
+    byteBuffer.SetCapacity(kBufferSize);\r
+    Byte *buffer = byteBuffer;\r
+    RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));\r
+    size_t processedSize = kBufferSize;\r
+    RINOK(ReadStream(stream, buffer, &processedSize));\r
+    if (processedSize >= 16)\r
+    {\r
+      Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};\r
+      if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[10] & 1) != 0)\r
+      {\r
+        for (int i = 0; i < orderIndices.Size(); i++)\r
+        {\r
+          int index = orderIndices[i];\r
+          const CArcInfoEx &ai = codecs->Formats[index];\r
+          if (ai.Name.CompareNoCase(L"rar") != 0)\r
+            continue;\r
+          orderIndices.Delete(i--);\r
+          orderIndices.Insert(0, index);\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  if (orderIndices.Size() >= 2)\r
+  {\r
+    int isoIndex = codecs->FindFormatForArchiveType(L"iso");\r
+    int udfIndex = codecs->FindFormatForArchiveType(L"udf");\r
+    int iIso = -1;\r
+    int iUdf = -1;\r
+    for (int i = 0; i < orderIndices.Size(); i++)\r
+    {\r
+      if (orderIndices[i] == isoIndex) iIso = i;\r
+      if (orderIndices[i] == udfIndex) iUdf = i;\r
+    }\r
+    if (iUdf > iIso && iIso >= 0)\r
+    {\r
+      orderIndices[iUdf] = isoIndex;\r
+      orderIndices[iIso] = udfIndex;\r
+    }\r
+  }\r
+\r
+  #endif\r
+  }\r
+\r
+  for (int i = 0; i < orderIndices.Size(); i++)\r
+  {\r
+    if (stream)\r
+    {\r
+      RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));\r
+    }\r
+    CMyComPtr<IInArchive> archive;\r
+\r
+    FormatIndex = orderIndices[i];\r
+    RINOK(codecs->CreateInArchive(FormatIndex, archive));\r
+    if (!archive)\r
+      continue;\r
+\r
+    #ifdef EXTERNAL_CODECS\r
+    {\r
+      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;\r
+      archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);\r
+      if (setCompressCodecsInfo)\r
+      {\r
+        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));\r
+      }\r
+    }\r
+    #endif\r
+\r
+    // OutputDebugStringW(codecs->Formats[FormatIndex].Name);\r
+\r
+    HRESULT result;\r
+    if (stream)\r
+      result = archive->Open(stream, &kMaxCheckStartPosition, callback);\r
+    else\r
+    {\r
+      CMyComPtr<IArchiveOpenSeq> openSeq;\r
+      archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq);\r
+      if (!openSeq)\r
+        return E_NOTIMPL;\r
+      result = openSeq->OpenSeq(seqStream);\r
+    }\r
+\r
+    if (result == S_FALSE)\r
+      continue;\r
+    RINOK(result);\r
+\r
+    {\r
+      NCOM::CPropVariant prop;\r
+      archive->GetArchiveProperty(kpidError, &prop);\r
+      if (prop.vt != VT_EMPTY)\r
+        ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error";\r
+    }\r
+    \r
+    Archive = archive;\r
+    const CArcInfoEx &format = codecs->Formats[FormatIndex];\r
+    if (format.Exts.Size() == 0)\r
+      DefaultName = GetDefaultName2(fileName, L"", L"");\r
+    else\r
+    {\r
+      int subExtIndex = format.FindExtension(extension);\r
+      if (subExtIndex < 0)\r
+        subExtIndex = 0;\r
+      const CArcExtInfo &extInfo = format.Exts[subExtIndex];\r
+      DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);\r
+    }\r
+    return S_OK;\r
+  }\r
+  return S_FALSE;\r
+}\r
+\r
+HRESULT CArc::OpenStreamOrFile(\r
+    CCodecs *codecs,\r
+    int formatIndex,\r
+    bool stdInMode,\r
+    IInStream *stream,\r
+    IArchiveOpenCallback *callback)\r
+{\r
+  CMyComPtr<IInStream> fileStream;\r
+  CMyComPtr<ISequentialInStream> seqStream;\r
+  if (stdInMode)\r
+    seqStream = new CStdInFileStream;\r
+  else if (!stream)\r
+  {\r
+    CInFileStream *fileStreamSpec = new CInFileStream;\r
+    fileStream = fileStreamSpec;\r
+    if (!fileStreamSpec->Open(Path))\r
+      return GetLastError();\r
+    stream = fileStream;\r
+  }\r
+\r
+  /*\r
+  if (callback)\r
+  {\r
+    UInt64 fileSize;\r
+    RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));\r
+    RINOK(callback->SetTotal(NULL, &fileSize))\r
+  }\r
+  */\r
+\r
+  return OpenStream(codecs, formatIndex, stream, seqStream, callback);\r
+}\r
+\r
+HRESULT CArchiveLink::Close()\r
+{\r
+  for (int i = Arcs.Size() - 1;  i >= 0; i--)\r
+  {\r
+    RINOK(Arcs[i].Archive->Close());\r
+  }\r
+  IsOpen = false;\r
+  return S_OK;\r
+}\r
+\r
+void CArchiveLink::Release()\r
+{\r
+  while (!Arcs.IsEmpty())\r
+    Arcs.DeleteBack();\r
+}\r
+\r
+HRESULT CArchiveLink::Open(\r
+    CCodecs *codecs,\r
+    const CIntVector &formatIndices,\r
+    bool stdInMode,\r
+    IInStream *stream,\r
+    const UString &filePath,\r
+    IArchiveOpenCallback *callback)\r
+{\r
+  Release();\r
+  if (formatIndices.Size() >= 32)\r
+    return E_NOTIMPL;\r
+  \r
+  HRESULT resSpec;\r
+\r
+  for (;;)\r
+  {\r
+    resSpec = S_OK;\r
+    int formatIndex = -1;\r
+    if (formatIndices.Size() >= 1)\r
+    {\r
+      if (Arcs.Size() >= formatIndices.Size())\r
+        break;\r
+      formatIndex = formatIndices[formatIndices.Size() - Arcs.Size() - 1];\r
+    }\r
+    else if (Arcs.Size() >= 32)\r
+      break;\r
+\r
+    if (Arcs.IsEmpty())\r
+    {\r
+      CArc arc;\r
+      arc.Path = filePath;\r
+      arc.SubfileIndex = (UInt32)(Int32)-1;\r
+      RINOK(arc.OpenStreamOrFile(codecs, formatIndex, stdInMode, stream, callback));\r
+      Arcs.Add(arc);\r
+      continue;\r
+    }\r
+    \r
+    const CArc &arc = Arcs.Back();\r
+    \r
+    resSpec = (formatIndices.Size() == 0 ? S_OK : E_NOTIMPL);\r
+    \r
+    UInt32 mainSubfile;\r
+    {\r
+      NCOM::CPropVariant prop;\r
+      RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop));\r
+      if (prop.vt == VT_UI4)\r
+        mainSubfile = prop.ulVal;\r
+      else\r
+        break;\r
+      UInt32 numItems;\r
+      RINOK(arc.Archive->GetNumberOfItems(&numItems));\r
+      if (mainSubfile >= numItems)\r
+        break;\r
+    }\r
+\r
+  \r
+    CMyComPtr<IInArchiveGetStream> getStream;\r
+    if (arc.Archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream)\r
+      break;\r
+    \r
+    CMyComPtr<ISequentialInStream> subSeqStream;\r
+    if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream)\r
+      break;\r
+    \r
+    CMyComPtr<IInStream> subStream;\r
+    if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK || !subStream)\r
+      break;\r
+    \r
+    CArc arc2;\r
+    RINOK(arc.GetItemPath(mainSubfile, arc2.Path));\r
+    \r
+    CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;\r
+    callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);\r
+    if (setSubArchiveName)\r
+      setSubArchiveName->SetSubArchiveName(arc2.Path);\r
+    \r
+    arc2.SubfileIndex = mainSubfile;\r
+    HRESULT result = arc2.OpenStream(codecs, formatIndex, subStream, NULL, callback);\r
+    resSpec = (formatIndices.Size() == 0 ? S_OK : S_FALSE);\r
+    if (result == S_FALSE)\r
+      break;\r
+    RINOK(result);\r
+    RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined));\r
+    Arcs.Add(arc2);\r
+  }\r
+  IsOpen = !Arcs.IsEmpty();\r
+  return S_OK;\r
+}\r
+\r
+static void SetCallback(const UString &filePath,\r
+    IOpenCallbackUI *callbackUI,\r
+    IArchiveOpenCallback *reOpenCallback,\r
+    CMyComPtr<IArchiveOpenCallback> &callback)\r
+{\r
+  COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;\r
+  callback = openCallbackSpec;\r
+  openCallbackSpec->Callback = callbackUI;\r
+  openCallbackSpec->ReOpenCallback = reOpenCallback;\r
+\r
+  UString fullName;\r
+  int fileNamePartStartIndex;\r
+  NFile::NDirectory::MyGetFullPathName(filePath, fullName, fileNamePartStartIndex);\r
+  openCallbackSpec->Init(\r
+      fullName.Left(fileNamePartStartIndex),\r
+      fullName.Mid(fileNamePartStartIndex));\r
+}\r
+\r
+HRESULT CArchiveLink::Open2(CCodecs *codecs,\r
+    const CIntVector &formatIndices,\r
+    bool stdInMode,\r
+    IInStream *stream,\r
+    const UString &filePath,\r
+    IOpenCallbackUI *callbackUI)\r
+{\r
+  VolumesSize = 0;\r
+  COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;\r
+  CMyComPtr<IArchiveOpenCallback> callback = openCallbackSpec;\r
+  openCallbackSpec->Callback = callbackUI;\r
+\r
+  UString fullName, prefix, name;\r
+  if (!stream && !stdInMode)\r
+  {\r
+    int fileNamePartStartIndex;\r
+    if (!NFile::NDirectory::MyGetFullPathName(filePath, fullName, fileNamePartStartIndex))\r
+      return GetLastError();\r
+    prefix = fullName.Left(fileNamePartStartIndex);\r
+    name = fullName.Mid(fileNamePartStartIndex);\r
+    openCallbackSpec->Init(prefix, name);\r
+  }\r
+  else\r
+  {\r
+    openCallbackSpec->SetSubArchiveName(filePath);\r
+  }\r
+\r
+  RINOK(Open(codecs, formatIndices, stdInMode, stream, filePath, callback));\r
+  VolumePaths.Add(prefix + name);\r
+  for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)\r
+    VolumePaths.Add(prefix + openCallbackSpec->FileNames[i]);\r
+  VolumesSize = openCallbackSpec->TotalSize;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CArchiveLink::ReOpen(CCodecs *codecs, const UString &filePath,\r
+    IArchiveOpenCallback *callback)\r
+{\r
+  if (Arcs.Size() > 1)\r
+    return E_NOTIMPL;\r
+\r
+  if (Arcs.Size() == 0)\r
+    return Open2(codecs, CIntVector(), false, NULL, filePath, 0);\r
+\r
+  CMyComPtr<IArchiveOpenCallback> openCallbackNew;\r
+  SetCallback(filePath, NULL, callback, openCallbackNew);\r
+\r
+  CInFileStream *fileStreamSpec = new CInFileStream;\r
+  CMyComPtr<IInStream> stream(fileStreamSpec);\r
+  if (!fileStreamSpec->Open(filePath))\r
+    return GetLastError();\r
+  HRESULT res = GetArchive()->Open(stream, &kMaxCheckStartPosition, callback);\r
+  IsOpen = (res == S_OK);\r
+  return res;\r
+}\r
diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h
new file mode 100755 (executable)
index 0000000..18ca0ea
--- /dev/null
@@ -0,0 +1,87 @@
+// OpenArchive.h\r
+\r
+#ifndef __OPEN_ARCHIVE_H\r
+#define __OPEN_ARCHIVE_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+#include "Windows/FileFind.h"\r
+\r
+#include "../../Archive/IArchive.h"\r
+\r
+#include "ArchiveOpenCallback.h"\r
+#include "LoadCodecs.h"\r
+\r
+HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);\r
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);\r
+\r
+struct CArc\r
+{\r
+  CMyComPtr<IInArchive> Archive;\r
+  UString Path;\r
+  UString DefaultName;\r
+  int FormatIndex;\r
+  int SubfileIndex;\r
+  FILETIME MTime;\r
+  bool MTimeDefined;\r
+  UString ErrorMessage;\r
+\r
+  CArc(): MTimeDefined(false) {}\r
+\r
+  HRESULT GetItemPath(UInt32 index, UString &result) const;\r
+  HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;\r
+  HRESULT IsItemAnti(UInt32 index, bool &result) const\r
+    { return GetArchiveItemBoolProp(Archive, index, kpidIsAnti, result); }\r
+\r
+  HRESULT OpenStream(\r
+    CCodecs *codecs,\r
+    int formatIndex,\r
+    IInStream *stream,\r
+    ISequentialInStream *seqStream,\r
+    IArchiveOpenCallback *callback);\r
+\r
+  HRESULT OpenStreamOrFile(\r
+    CCodecs *codecs,\r
+    int formatIndex,\r
+    bool stdInMode,\r
+    IInStream *stream,\r
+    IArchiveOpenCallback *callback);\r
+};\r
+\r
+struct CArchiveLink\r
+{\r
+  CObjectVector<CArc> Arcs;\r
+  UStringVector VolumePaths;\r
+  UInt64 VolumesSize;\r
+  bool IsOpen;\r
+\r
+  CArchiveLink(): VolumesSize(0), IsOpen(false) {}\r
+  HRESULT Close();\r
+  void Release();\r
+  ~CArchiveLink() { Release(); }\r
+\r
+  IInArchive *GetArchive() const { return Arcs.Back().Archive; }\r
+\r
+  HRESULT Open(\r
+    CCodecs *codecs,\r
+    const CIntVector &formatIndices,\r
+    bool stdInMode,\r
+    IInStream *stream,\r
+    const UString &filePath,\r
+    IArchiveOpenCallback *callback);\r
+\r
+  HRESULT Open2(\r
+    CCodecs *codecs,\r
+    const CIntVector &formatIndices,\r
+    bool stdInMode,\r
+    IInStream *stream,\r
+    const UString &filePath,\r
+    IOpenCallbackUI *callbackUI);\r
+\r
+  HRESULT ReOpen(\r
+    CCodecs *codecs,\r
+    const UString &filePath,\r
+    IArchiveOpenCallback *callback);\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp
new file mode 100755 (executable)
index 0000000..4a9e294
--- /dev/null
@@ -0,0 +1,120 @@
+// PropIDUtils.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/IntToString.h"\r
+\r
+#include "Windows/FileFind.h"\r
+#include "Windows/PropVariantConversions.h"\r
+\r
+#include "../../PropID.h"\r
+\r
+#include "PropIDUtils.h"\r
+\r
+using namespace NWindows;\r
+\r
+void ConvertUInt32ToHex(UInt32 value, wchar_t *s)\r
+{\r
+  for (int i = 0; i < 8; i++)\r
+  {\r
+    int t = value & 0xF;\r
+    value >>= 4;\r
+    s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));\r
+  }\r
+  s[8] = L'\0';\r
+}\r
+\r
+static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";\r
+/*\r
+0 READONLY\r
+1 HIDDEN\r
+3 SYSTEM\r
+\r
+4 DIRECTORY\r
+5 ARCHIVE\r
+6 DEVICE\r
+7 NORMAL\r
+8 TEMPORARY\r
+9 SPARSE_FILE\r
+10 REPARSE_POINT\r
+11 COMPRESSED\r
+12 OFFLINE\r
+13 NOT_CONTENT_INDEXED\r
+14 ENCRYPTED\r
+\r
+16 VIRTUAL\r
+*/\r
+\r
+static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };\r
+#define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';\r
+\r
+UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)\r
+{\r
+  switch(propID)\r
+  {\r
+    case kpidCTime:\r
+    case kpidATime:\r
+    case kpidMTime:\r
+    {\r
+      if (prop.vt != VT_FILETIME)\r
+        break;\r
+      FILETIME localFileTime;\r
+      if ((prop.filetime.dwHighDateTime == 0 &&\r
+          prop.filetime.dwLowDateTime == 0) ||\r
+          !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))\r
+        return UString();\r
+      return ConvertFileTimeToString(localFileTime, true, full);\r
+    }\r
+    case kpidCRC:\r
+    {\r
+      if (prop.vt != VT_UI4)\r
+        break;\r
+      wchar_t temp[12];\r
+      ConvertUInt32ToHex(prop.ulVal, temp);\r
+      return temp;\r
+    }\r
+    case kpidAttrib:\r
+    {\r
+      if (prop.vt != VT_UI4)\r
+        break;\r
+      UInt32 a = prop.ulVal;\r
+      wchar_t sz[32];\r
+      int pos = 0;\r
+      for (int i = 0; i < 16; i++)\r
+        if (a & (1 << i) && i != 7)\r
+          sz[pos++] = g_WinAttrib[i];\r
+      sz[pos] = '\0';\r
+      return sz;\r
+    }\r
+    case kpidPosixAttrib:\r
+    {\r
+      if (prop.vt != VT_UI4)\r
+        break;\r
+      UString res;\r
+      UInt32 a = prop.ulVal;\r
+      wchar_t temp[16];\r
+\r
+      temp[0] = kPosixTypes[(a >> 12) & 0xF];\r
+      for (int i = 6; i >= 0; i -= 3)\r
+      {\r
+        temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r');\r
+        temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w');\r
+        temp[9 - i] = MY_ATTR_CHAR(a, i + 0, L'x');\r
+      }\r
+      if ((a & 0x800) != 0) temp[3] = ((a & (1 << 6)) ? 's' : 'S');\r
+      if ((a & 0x400) != 0) temp[6] = ((a & (1 << 3)) ? 's' : 'S');\r
+      if ((a & 0x200) != 0) temp[9] = ((a & (1 << 0)) ? 't' : 'T');\r
+      temp[10] = 0;\r
+      res = temp;\r
+\r
+      a &= ~(UInt32)0xFFFF;\r
+      if (a != 0)\r
+      {\r
+        ConvertUInt32ToHex(a, temp);\r
+        res = UString(temp) + L' ' + res;\r
+      }\r
+      return res;\r
+    }\r
+  }\r
+  return ConvertPropVariantToString(prop);\r
+}\r
diff --git a/CPP/7zip/UI/Common/PropIDUtils.h b/CPP/7zip/UI/Common/PropIDUtils.h
new file mode 100755 (executable)
index 0000000..05c09e7
--- /dev/null
@@ -0,0 +1,12 @@
+// PropIDUtils.h\r
+\r
+#ifndef __PROPID_UTILS_H\r
+#define __PROPID_UTILS_H\r
+\r
+#include "Common/MyString.h"\r
+#include "Common/Types.h"\r
+\r
+void ConvertUInt32ToHex(UInt32 value, wchar_t *s);\r
+UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full = true);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/Property.h b/CPP/7zip/UI/Common/Property.h
new file mode 100755 (executable)
index 0000000..5253d52
--- /dev/null
@@ -0,0 +1,14 @@
+// Property.h\r
+\r
+#ifndef __PROPERTY_H\r
+#define __PROPERTY_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+struct CProperty\r
+{\r
+  UString Name;\r
+  UString Value;\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/SetProperties.cpp b/CPP/7zip/UI/Common/SetProperties.cpp
new file mode 100755 (executable)
index 0000000..b3347ce
--- /dev/null
@@ -0,0 +1,79 @@
+// SetProperties.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "SetProperties.h"\r
+\r
+#include "Windows/PropVariant.h"\r
+#include "Common/MyString.h"\r
+#include "Common/StringToInt.h"\r
+#include "Common/MyCom.h"\r
+\r
+#include "../../Archive/IArchive.h"\r
+\r
+using namespace NWindows;\r
+using namespace NCOM;\r
+\r
+static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)\r
+{\r
+  const wchar_t *endPtr;\r
+  UInt64 result = ConvertStringToUInt64(s, &endPtr);\r
+  if (endPtr - (const wchar_t *)s != s.Length())\r
+    prop = s;\r
+  else if (result <= 0xFFFFFFFF)\r
+    prop = (UInt32)result;\r
+  else\r
+    prop = result;\r
+}\r
+\r
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)\r
+{\r
+  if (properties.IsEmpty())\r
+    return S_OK;\r
+  CMyComPtr<ISetProperties> setProperties;\r
+  unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties);\r
+  if (!setProperties)\r
+    return S_OK;\r
+\r
+  UStringVector realNames;\r
+  CPropVariant *values = new CPropVariant[properties.Size()];\r
+  try\r
+  {\r
+    int i;\r
+    for(i = 0; i < properties.Size(); i++)\r
+    {\r
+      const CProperty &property = properties[i];\r
+      NCOM::CPropVariant propVariant;\r
+      UString name = property.Name;\r
+      if (property.Value.IsEmpty())\r
+      {\r
+        if (!name.IsEmpty())\r
+        {\r
+          wchar_t c = name[name.Length() - 1];\r
+          if (c == L'-')\r
+            propVariant = false;\r
+          else if (c == L'+')\r
+            propVariant = true;\r
+          if (propVariant.vt != VT_EMPTY)\r
+            name = name.Left(name.Length() - 1);\r
+        }\r
+      }\r
+      else\r
+        ParseNumberString(property.Value, propVariant);\r
+      realNames.Add(name);\r
+      values[i] = propVariant;\r
+    }\r
+    CRecordVector<const wchar_t *> names;\r
+    for(i = 0; i < realNames.Size(); i++)\r
+      names.Add((const wchar_t *)realNames[i]);\r
+    \r
+    RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));\r
+  }\r
+  catch(...)\r
+  {\r
+    delete []values;\r
+    throw;\r
+  }\r
+  delete []values;\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/UI/Common/SetProperties.h b/CPP/7zip/UI/Common/SetProperties.h
new file mode 100755 (executable)
index 0000000..64c947c
--- /dev/null
@@ -0,0 +1,10 @@
+// SetProperties.h\r
+\r
+#ifndef __SETPROPERTIES_H\r
+#define __SETPROPERTIES_H\r
+\r
+#include "Property.h"\r
+\r
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/SortUtils.cpp b/CPP/7zip/UI/Common/SortUtils.cpp
new file mode 100755 (executable)
index 0000000..039adfa
--- /dev/null
@@ -0,0 +1,22 @@
+// SortUtils.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "SortUtils.h"\r
+#include "Common/Wildcard.h"\r
+\r
+static int CompareStrings(const int *p1, const int *p2, void *param)\r
+{\r
+  const UStringVector &strings = *(const UStringVector *)param;\r
+  return CompareFileNames(strings[*p1], strings[*p2]);\r
+}\r
+\r
+void SortFileNames(const UStringVector &strings, CIntVector &indices)\r
+{\r
+  indices.Clear();\r
+  int numItems = strings.Size();\r
+  indices.Reserve(numItems);\r
+  for(int i = 0; i < numItems; i++)\r
+    indices.Add(i);\r
+  indices.Sort(CompareStrings, (void *)&strings);\r
+}\r
diff --git a/CPP/7zip/UI/Common/SortUtils.h b/CPP/7zip/UI/Common/SortUtils.h
new file mode 100755 (executable)
index 0000000..4835f11
--- /dev/null
@@ -0,0 +1,10 @@
+// SortUtils.h\r
+\r
+#ifndef __SORTUTLS_H\r
+#define __SORTUTLS_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+void SortFileNames(const UStringVector &strings, CIntVector &indices);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/StdAfx.h b/CPP/7zip/UI/Common/StdAfx.h
new file mode 100755 (executable)
index 0000000..ab2617e
--- /dev/null
@@ -0,0 +1,9 @@
+// stdafx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../../Common/MyWindows.h"\r
+#include "../../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/TempFiles.cpp b/CPP/7zip/UI/Common/TempFiles.cpp
new file mode 100755 (executable)
index 0000000..48fb4e7
--- /dev/null
@@ -0,0 +1,22 @@
+// TempFiles.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "TempFiles.h"\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/FileIO.h"\r
+\r
+using namespace NWindows;\r
+using namespace NFile;\r
+\r
+void CTempFiles::Clear()\r
+{\r
+  while(!Paths.IsEmpty())\r
+  {\r
+    NDirectory::DeleteFileAlways((LPCWSTR)Paths.Back());\r
+    Paths.DeleteBack();\r
+  }\r
+}\r
+\r
+\r
diff --git a/CPP/7zip/UI/Common/TempFiles.h b/CPP/7zip/UI/Common/TempFiles.h
new file mode 100755 (executable)
index 0000000..9e8e131
--- /dev/null
@@ -0,0 +1,16 @@
+// TempFiles.h\r
+\r
+#ifndef __TEMPFILES_H\r
+#define __TEMPFILES_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+class CTempFiles\r
+{\r
+  void Clear();\r
+public:\r
+  UStringVector Paths;\r
+  ~CTempFiles() { Clear(); }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp
new file mode 100755 (executable)
index 0000000..2e1cca0
--- /dev/null
@@ -0,0 +1,910 @@
+// Update.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Update.h"\r
+\r
+#include "Common/IntToString.h"\r
+#include "Common/StringConvert.h"\r
+\r
+#ifdef _WIN32\r
+#include "Windows/DLL.h"\r
+#endif\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/FileFind.h"\r
+#include "Windows/FileName.h"\r
+#include "Windows/PropVariant.h"\r
+#include "Windows/PropVariantConversions.h"\r
+#include "Windows/Time.h"\r
+\r
+#include "../../Common/FileStreams.h"\r
+\r
+#include "../../Compress/CopyCoder.h"\r
+\r
+#include "../Common/DirItem.h"\r
+#include "../Common/EnumDirItems.h"\r
+#include "../Common/OpenArchive.h"\r
+#include "../Common/UpdateProduce.h"\r
+\r
+#include "EnumDirItems.h"\r
+#include "SetProperties.h"\r
+#include "TempFiles.h"\r
+#include "UpdateCallback.h"\r
+\r
+static const char *kUpdateIsNotSupoorted =\r
+  "update operations are not supported for this archive";\r
+\r
+using namespace NWindows;\r
+using namespace NCOM;\r
+using namespace NFile;\r
+using namespace NName;\r
+\r
+static const wchar_t *kTempFolderPrefix = L"7zE";\r
+\r
+using namespace NUpdateArchive;\r
+\r
+class COutMultiVolStream:\r
+  public IOutStream,\r
+  public CMyUnknownImp\r
+{\r
+  int _streamIndex; // required stream\r
+  UInt64 _offsetPos; // offset from start of _streamIndex index\r
+  UInt64 _absPos;\r
+  UInt64 _length;\r
+\r
+  struct CSubStreamInfo\r
+  {\r
+    COutFileStream *StreamSpec;\r
+    CMyComPtr<IOutStream> Stream;\r
+    UString Name;\r
+    UInt64 Pos;\r
+    UInt64 RealSize;\r
+  };\r
+  CObjectVector<CSubStreamInfo> Streams;\r
+public:\r
+  // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;\r
+  CRecordVector<UInt64> Sizes;\r
+  UString Prefix;\r
+  CTempFiles *TempFiles;\r
+\r
+  void Init()\r
+  {\r
+    _streamIndex = 0;\r
+    _offsetPos = 0;\r
+    _absPos = 0;\r
+    _length = 0;\r
+  }\r
+\r
+  HRESULT Close();\r
+\r
+  MY_UNKNOWN_IMP1(IOutStream)\r
+\r
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);\r
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);\r
+  STDMETHOD(SetSize)(UInt64 newSize);\r
+};\r
+\r
+// static NSynchronization::CCriticalSection g_TempPathsCS;\r
+\r
+HRESULT COutMultiVolStream::Close()\r
+{\r
+  HRESULT res = S_OK;\r
+  for (int i = 0; i < Streams.Size(); i++)\r
+  {\r
+    CSubStreamInfo &s = Streams[i];\r
+    if (s.StreamSpec)\r
+    {\r
+      HRESULT res2 = s.StreamSpec->Close();\r
+      if (res2 != S_OK)\r
+        res = res2;\r
+    }\r
+  }\r
+  return res;\r
+}\r
+\r
+STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)\r
+{\r
+  if (processedSize != NULL)\r
+    *processedSize = 0;\r
+  while(size > 0)\r
+  {\r
+    if (_streamIndex >= Streams.Size())\r
+    {\r
+      CSubStreamInfo subStream;\r
+\r
+      wchar_t temp[16];\r
+      ConvertUInt32ToString(_streamIndex + 1, temp);\r
+      UString res = temp;\r
+      while (res.Length() < 3)\r
+        res = UString(L'0') + res;\r
+      UString name = Prefix + res;\r
+      subStream.StreamSpec = new COutFileStream;\r
+      subStream.Stream = subStream.StreamSpec;\r
+      if (!subStream.StreamSpec->Create(name, false))\r
+        return ::GetLastError();\r
+      {\r
+        // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);\r
+        TempFiles->Paths.Add(name);\r
+      }\r
+\r
+      subStream.Pos = 0;\r
+      subStream.RealSize = 0;\r
+      subStream.Name = name;\r
+      Streams.Add(subStream);\r
+      continue;\r
+    }\r
+    CSubStreamInfo &subStream = Streams[_streamIndex];\r
+\r
+    int index = _streamIndex;\r
+    if (index >= Sizes.Size())\r
+      index = Sizes.Size() - 1;\r
+    UInt64 volSize = Sizes[index];\r
+\r
+    if (_offsetPos >= volSize)\r
+    {\r
+      _offsetPos -= volSize;\r
+      _streamIndex++;\r
+      continue;\r
+    }\r
+    if (_offsetPos != subStream.Pos)\r
+    {\r
+      // CMyComPtr<IOutStream> outStream;\r
+      // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));\r
+      RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));\r
+      subStream.Pos = _offsetPos;\r
+    }\r
+\r
+    UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos);\r
+    UInt32 realProcessed;\r
+    RINOK(subStream.Stream->Write(data, curSize, &realProcessed));\r
+    data = (void *)((Byte *)data + realProcessed);\r
+    size -= realProcessed;\r
+    subStream.Pos += realProcessed;\r
+    _offsetPos += realProcessed;\r
+    _absPos += realProcessed;\r
+    if (_absPos > _length)\r
+      _length = _absPos;\r
+    if (_offsetPos > subStream.RealSize)\r
+      subStream.RealSize = _offsetPos;\r
+    if (processedSize != NULL)\r
+      *processedSize += realProcessed;\r
+    if (subStream.Pos == volSize)\r
+    {\r
+      _streamIndex++;\r
+      _offsetPos = 0;\r
+    }\r
+    if (realProcessed == 0 && curSize != 0)\r
+      return E_FAIL;\r
+    break;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)\r
+{\r
+  if (seekOrigin >= 3)\r
+    return STG_E_INVALIDFUNCTION;\r
+  switch(seekOrigin)\r
+  {\r
+    case STREAM_SEEK_SET:\r
+      _absPos = offset;\r
+      break;\r
+    case STREAM_SEEK_CUR:\r
+      _absPos += offset;\r
+      break;\r
+    case STREAM_SEEK_END:\r
+      _absPos = _length + offset;\r
+      break;\r
+  }\r
+  _offsetPos = _absPos;\r
+  if (newPosition != NULL)\r
+    *newPosition = _absPos;\r
+  _streamIndex = 0;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize)\r
+{\r
+  if (newSize < 0)\r
+    return E_INVALIDARG;\r
+  int i = 0;\r
+  while (i < Streams.Size())\r
+  {\r
+    CSubStreamInfo &subStream = Streams[i++];\r
+    if ((UInt64)newSize < subStream.RealSize)\r
+    {\r
+      RINOK(subStream.Stream->SetSize(newSize));\r
+      subStream.RealSize = newSize;\r
+      break;\r
+    }\r
+    newSize -= subStream.RealSize;\r
+  }\r
+  while (i < Streams.Size())\r
+  {\r
+    {\r
+      CSubStreamInfo &subStream = Streams.Back();\r
+      subStream.Stream.Release();\r
+      NDirectory::DeleteFileAlways(subStream.Name);\r
+    }\r
+    Streams.DeleteBack();\r
+  }\r
+  _offsetPos = _absPos;\r
+  _streamIndex = 0;\r
+  _length = newSize;\r
+  return S_OK;\r
+}\r
+\r
+static const wchar_t *kDefaultArchiveType = L"7z";\r
+static const wchar_t *kSFXExtension =\r
+  #ifdef _WIN32\r
+    L"exe";\r
+  #else\r
+    L"";\r
+  #endif\r
+\r
+bool CUpdateOptions::Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath)\r
+{\r
+  if (formatIndices.Size() > 1)\r
+    return false;\r
+  int arcTypeIndex = -1;\r
+  if (formatIndices.Size() != 0)\r
+    arcTypeIndex = formatIndices[0];\r
+  if (arcTypeIndex >= 0)\r
+    MethodMode.FormatIndex = arcTypeIndex;\r
+  else\r
+  {\r
+    MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath);\r
+    // It works incorrectly for update command if archive has some non-default extension!\r
+    if (MethodMode.FormatIndex < 0)\r
+      MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType);\r
+  }\r
+  if (MethodMode.FormatIndex < 0)\r
+    return false;\r
+  const CArcInfoEx &arcInfo = codecs->Formats[MethodMode.FormatIndex];\r
+  if (!arcInfo.UpdateEnabled)\r
+    return false;\r
+  UString typeExt = arcInfo.GetMainExt();\r
+  UString ext = typeExt;\r
+  if (SfxMode)\r
+    ext = kSFXExtension;\r
+  ArchivePath.BaseExtension = ext;\r
+  ArchivePath.VolExtension = typeExt;\r
+  ArchivePath.ParseFromPath(arcPath);\r
+  for (int i = 0; i < Commands.Size(); i++)\r
+  {\r
+    CUpdateArchiveCommand &uc = Commands[i];\r
+    uc.ArchivePath.BaseExtension = ext;\r
+    uc.ArchivePath.VolExtension = typeExt;\r
+    uc.ArchivePath.ParseFromPath(uc.UserArchivePath);\r
+  }\r
+  return true;\r
+}\r
+\r
+/*\r
+struct CUpdateProduceCallbackImp: public IUpdateProduceCallback\r
+{\r
+  const CObjectVector<CArcItem> *_arcItems;\r
+  IUpdateCallbackUI *_callback;\r
+  \r
+  CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,\r
+      IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {}\r
+  virtual HRESULT ShowDeleteFile(int arcIndex);\r
+};\r
+\r
+HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(int arcIndex)\r
+{\r
+  return _callback->ShowDeleteFile((*_arcItems)[arcIndex].Name);\r
+}\r
+*/\r
+\r
+static HRESULT Compress(\r
+    CCodecs *codecs,\r
+    const CActionSet &actionSet,\r
+    IInArchive *archive,\r
+    const CCompressionMethodMode &compressionMethod,\r
+    CArchivePath &archivePath,\r
+    const CObjectVector<CArcItem> &arcItems,\r
+    bool shareForWrite,\r
+    bool stdInMode,\r
+    /* const UString & stdInFileName, */\r
+    bool stdOutMode,\r
+    const CDirItems &dirItems,\r
+    bool sfxMode,\r
+    const UString &sfxModule,\r
+    const CRecordVector<UInt64> &volumesSizes,\r
+    CTempFiles &tempFiles,\r
+    CUpdateErrorInfo &errorInfo,\r
+    IUpdateCallbackUI *callback)\r
+{\r
+  CMyComPtr<IOutArchive> outArchive;\r
+  if (archive != NULL)\r
+  {\r
+    CMyComPtr<IInArchive> archive2 = archive;\r
+    HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);\r
+    if (result != S_OK)\r
+      throw kUpdateIsNotSupoorted;\r
+  }\r
+  else\r
+  {\r
+    RINOK(codecs->CreateOutArchive(compressionMethod.FormatIndex, outArchive));\r
+\r
+    #ifdef EXTERNAL_CODECS\r
+    {\r
+      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;\r
+      outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);\r
+      if (setCompressCodecsInfo)\r
+      {\r
+        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));\r
+      }\r
+    }\r
+    #endif\r
+  }\r
+  if (outArchive == 0)\r
+    throw kUpdateIsNotSupoorted;\r
+  \r
+  NFileTimeType::EEnum fileTimeType;\r
+  UInt32 value;\r
+  RINOK(outArchive->GetFileTimeType(&value));\r
+\r
+  switch(value)\r
+  {\r
+    case NFileTimeType::kWindows:\r
+    case NFileTimeType::kUnix:\r
+    case NFileTimeType::kDOS:\r
+      fileTimeType = (NFileTimeType::EEnum)value;\r
+      break;\r
+    default:\r
+      return E_FAIL;\r
+  }\r
+\r
+  CRecordVector<CUpdatePair2> updatePairs2;\r
+\r
+  {\r
+    CRecordVector<CUpdatePair> updatePairs;\r
+    GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!!\r
+    // CUpdateProduceCallbackImp upCallback(&arcItems, callback);\r
+    UpdateProduce(updatePairs, actionSet, updatePairs2, NULL /* &upCallback */);\r
+  }\r
+\r
+  UInt32 numFiles = 0;\r
+  for (int i = 0; i < updatePairs2.Size(); i++)\r
+    if (updatePairs2[i].NewData)\r
+      numFiles++;\r
+  \r
+  RINOK(callback->SetNumFiles(numFiles));\r
+\r
+  \r
+  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;\r
+  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);\r
+  \r
+  updateCallbackSpec->ShareForWrite = shareForWrite;\r
+  updateCallbackSpec->StdInMode = stdInMode;\r
+  updateCallbackSpec->Callback = callback;\r
+  updateCallbackSpec->DirItems = &dirItems;\r
+  updateCallbackSpec->ArcItems = &arcItems;\r
+  updateCallbackSpec->UpdatePairs = &updatePairs2;\r
+\r
+  CMyComPtr<ISequentialOutStream> outStream;\r
+\r
+  if (!stdOutMode)\r
+  {\r
+    UString resultPath;\r
+    int pos;\r
+    if (!NFile::NDirectory::MyGetFullPathName(archivePath.GetFinalPath(), resultPath, pos))\r
+      throw 1417161;\r
+    NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));\r
+  }\r
+\r
+  COutFileStream *outStreamSpec = NULL;\r
+  COutMultiVolStream *volStreamSpec = NULL;\r
+\r
+  if (volumesSizes.Size() == 0)\r
+  {\r
+    if (stdOutMode)\r
+      outStream = new CStdOutFileStream;\r
+    else\r
+    {\r
+      outStreamSpec = new COutFileStream;\r
+      outStream = outStreamSpec;\r
+      bool isOK = false;\r
+      UString realPath;\r
+      for (int i = 0; i < (1 << 16); i++)\r
+      {\r
+        if (archivePath.Temp)\r
+        {\r
+          if (i > 0)\r
+          {\r
+            wchar_t s[16];\r
+            ConvertUInt32ToString(i, s);\r
+            archivePath.TempPostfix = s;\r
+          }\r
+          realPath = archivePath.GetTempPath();\r
+        }\r
+        else\r
+          realPath = archivePath.GetFinalPath();\r
+        if (outStreamSpec->Create(realPath, false))\r
+        {\r
+          tempFiles.Paths.Add(realPath);\r
+          isOK = true;\r
+          break;\r
+        }\r
+        if (::GetLastError() != ERROR_FILE_EXISTS)\r
+          break;\r
+        if (!archivePath.Temp)\r
+          break;\r
+      }\r
+      if (!isOK)\r
+      {\r
+        errorInfo.SystemError = ::GetLastError();\r
+        errorInfo.FileName = realPath;\r
+        errorInfo.Message = L"7-Zip cannot open file";\r
+        return E_FAIL;\r
+      }\r
+    }\r
+  }\r
+  else\r
+  {\r
+    if (stdOutMode)\r
+      return E_FAIL;\r
+    volStreamSpec = new COutMultiVolStream;\r
+    outStream = volStreamSpec;\r
+    volStreamSpec->Sizes = volumesSizes;\r
+    volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L".");\r
+    volStreamSpec->TempFiles = &tempFiles;\r
+    volStreamSpec->Init();\r
+\r
+    /*\r
+    updateCallbackSpec->VolumesSizes = volumesSizes;\r
+    updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;\r
+    if (!archivePath.VolExtension.IsEmpty())\r
+      updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;\r
+    */\r
+  }\r
+\r
+  RINOK(SetProperties(outArchive, compressionMethod.Properties));\r
+\r
+  if (sfxMode)\r
+  {\r
+    CInFileStream *sfxStreamSpec = new CInFileStream;\r
+    CMyComPtr<IInStream> sfxStream(sfxStreamSpec);\r
+    if (!sfxStreamSpec->Open(sfxModule))\r
+    {\r
+      errorInfo.SystemError = ::GetLastError();\r
+      errorInfo.Message = L"7-Zip cannot open SFX module";\r
+      errorInfo.FileName = sfxModule;\r
+      return E_FAIL;\r
+    }\r
+\r
+    CMyComPtr<ISequentialOutStream> sfxOutStream;\r
+    COutFileStream *outStreamSpec = NULL;\r
+    if (volumesSizes.Size() == 0)\r
+      sfxOutStream = outStream;\r
+    else\r
+    {\r
+      outStreamSpec = new COutFileStream;\r
+      sfxOutStream = outStreamSpec;\r
+      UString realPath = archivePath.GetFinalPath();\r
+      if (!outStreamSpec->Create(realPath, false))\r
+      {\r
+        errorInfo.SystemError = ::GetLastError();\r
+        errorInfo.FileName = realPath;\r
+        errorInfo.Message = L"7-Zip cannot open file";\r
+        return E_FAIL;\r
+      }\r
+    }\r
+    RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL));\r
+    if (outStreamSpec)\r
+    {\r
+      RINOK(outStreamSpec->Close());\r
+    }\r
+  }\r
+\r
+  HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback);\r
+  callback->Finilize();\r
+  RINOK(result);\r
+  if (outStreamSpec)\r
+    result = outStreamSpec->Close();\r
+  else if (volStreamSpec)\r
+    result = volStreamSpec->Close();\r
+  return result;\r
+}\r
+\r
+HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,\r
+    const CArc &arc,\r
+    CObjectVector<CArcItem> &arcItems)\r
+{\r
+  arcItems.Clear();\r
+  UInt32 numItems;\r
+  IInArchive *archive = arc.Archive;\r
+  RINOK(archive->GetNumberOfItems(&numItems));\r
+  arcItems.Reserve(numItems);\r
+  for (UInt32 i = 0; i < numItems; i++)\r
+  {\r
+    CArcItem ai;\r
+\r
+    RINOK(arc.GetItemPath(i, ai.Name));\r
+    RINOK(IsArchiveItemFolder(archive, i, ai.IsDir));\r
+    ai.Censored = censor.CheckPath(ai.Name, !ai.IsDir);\r
+    RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));\r
+\r
+    {\r
+      CPropVariant prop;\r
+      RINOK(archive->GetProperty(i, kpidSize, &prop));\r
+      ai.SizeDefined = (prop.vt != VT_EMPTY);\r
+      if (ai.SizeDefined)\r
+        ai.Size = ConvertPropVariantToUInt64(prop);\r
+    }\r
+\r
+    {\r
+      CPropVariant prop;\r
+      RINOK(archive->GetProperty(i, kpidTimeType, &prop));\r
+      if (prop.vt == VT_UI4)\r
+      {\r
+        ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal;\r
+        switch(ai.TimeType)\r
+        {\r
+          case NFileTimeType::kWindows:\r
+          case NFileTimeType::kUnix:\r
+          case NFileTimeType::kDOS:\r
+            break;\r
+          default:\r
+            return E_FAIL;\r
+        }\r
+      }\r
+    }\r
+\r
+    ai.IndexInServer = i;\r
+    arcItems.Add(ai);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+\r
+static HRESULT UpdateWithItemLists(\r
+    CCodecs *codecs,\r
+    CUpdateOptions &options,\r
+    IInArchive *archive,\r
+    const CObjectVector<CArcItem> &arcItems,\r
+    CDirItems &dirItems,\r
+    CTempFiles &tempFiles,\r
+    CUpdateErrorInfo &errorInfo,\r
+    IUpdateCallbackUI2 *callback)\r
+{\r
+  for(int i = 0; i < options.Commands.Size(); i++)\r
+  {\r
+    CUpdateArchiveCommand &command = options.Commands[i];\r
+    if (options.StdOutMode)\r
+    {\r
+      RINOK(callback->StartArchive(L"stdout", archive != 0));\r
+    }\r
+    else\r
+    {\r
+      RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(),\r
+          i == 0 && options.UpdateArchiveItself && archive != 0));\r
+    }\r
+\r
+    RINOK(Compress(\r
+        codecs,\r
+        command.ActionSet, archive,\r
+        options.MethodMode,\r
+        command.ArchivePath,\r
+        arcItems,\r
+        options.OpenShareForWrite,\r
+        options.StdInMode,\r
+        /* options.StdInFileName, */\r
+        options.StdOutMode,\r
+        dirItems,\r
+        options.SfxMode, options.SfxModule,\r
+        options.VolumesSizes,\r
+        tempFiles,\r
+        errorInfo, callback));\r
+\r
+    RINOK(callback->FinishArchive());\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+#if defined(_WIN32) && !defined(UNDER_CE)\r
+class CCurrentDirRestorer\r
+{\r
+  UString _path;\r
+public:\r
+  CCurrentDirRestorer() { NFile::NDirectory::MyGetCurrentDirectory(_path); }\r
+  ~CCurrentDirRestorer() { RestoreDirectory();}\r
+  bool RestoreDirectory() { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(_path)); }\r
+};\r
+#endif\r
+\r
+struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback\r
+{\r
+  IUpdateCallbackUI2 *Callback;\r
+  HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path)\r
+  {\r
+    return Callback->ScanProgress(numFolders, numFiles, path);\r
+  }\r
+};\r
+\r
+#ifdef _WIN32\r
+typedef ULONG (FAR PASCAL MY_MAPISENDDOCUMENTS)(\r
+  ULONG_PTR ulUIParam,\r
+  LPSTR lpszDelimChar,\r
+  LPSTR lpszFilePaths,\r
+  LPSTR lpszFileNames,\r
+  ULONG ulReserved\r
+);\r
+typedef MY_MAPISENDDOCUMENTS FAR *MY_LPMAPISENDDOCUMENTS;\r
+#endif\r
+\r
+HRESULT UpdateArchive(\r
+    CCodecs *codecs,\r
+    const NWildcard::CCensor &censor,\r
+    CUpdateOptions &options,\r
+    CUpdateErrorInfo &errorInfo,\r
+    IOpenCallbackUI *openCallback,\r
+    IUpdateCallbackUI2 *callback)\r
+{\r
+  if (options.StdOutMode && options.EMailMode)\r
+    return E_FAIL;\r
+\r
+  if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode))\r
+    return E_NOTIMPL;\r
+\r
+  if (options.SfxMode)\r
+  {\r
+    CProperty property;\r
+    property.Name = L"rsfx";\r
+    property.Value = L"on";\r
+    options.MethodMode.Properties.Add(property);\r
+    if (options.SfxModule.IsEmpty())\r
+    {\r
+      errorInfo.Message = L"SFX file is not specified";\r
+      return E_FAIL;\r
+    }\r
+    UString name = options.SfxModule;\r
+    #ifdef UNDER_CE\r
+    if (!NFind::DoesFileExist(name))\r
+    #else\r
+    if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule))\r
+    #endif\r
+    {\r
+      errorInfo.SystemError = ::GetLastError();\r
+      errorInfo.Message = L"7-Zip cannot find specified SFX module";\r
+      errorInfo.FileName = name;\r
+      return E_FAIL;\r
+    }\r
+  }\r
+\r
+\r
+  CArchiveLink arcLink;\r
+  const UString arcPath = options.ArchivePath.GetFinalPath();\r
+\r
+  if (!options.ArchivePath.OriginalPath.IsEmpty())\r
+  {\r
+    NFind::CFileInfoW fi;\r
+    if (fi.Find(arcPath))\r
+    {\r
+      if (fi.IsDir())\r
+        throw "there is no such archive";\r
+      if (options.VolumesSizes.Size() > 0)\r
+        return E_NOTIMPL;\r
+      CIntVector formatIndices;\r
+      if (options.MethodMode.FormatIndex >= 0)\r
+        formatIndices.Add(options.MethodMode.FormatIndex);\r
+      HRESULT result = arcLink.Open2(codecs, formatIndices, false, NULL, arcPath, openCallback);\r
+      if (result == E_ABORT)\r
+        return result;\r
+      RINOK(callback->OpenResult(arcPath, result));\r
+      RINOK(result);\r
+      if (arcLink.VolumePaths.Size() > 1)\r
+      {\r
+        errorInfo.SystemError = (DWORD)E_NOTIMPL;\r
+        errorInfo.Message = L"Updating for multivolume archives is not implemented";\r
+        return E_NOTIMPL;\r
+      }\r
+      \r
+      CArc &arc = arcLink.Arcs.Back();\r
+      arc.MTimeDefined = !fi.IsDevice;\r
+      arc.MTime = fi.MTime;\r
+    }\r
+  }\r
+  else\r
+  {\r
+    /*\r
+    if (archiveType.IsEmpty())\r
+      throw "type of archive is not specified";\r
+    */\r
+  }\r
+\r
+  CDirItems dirItems;\r
+  if (options.StdInMode)\r
+  {\r
+    CDirItem di;\r
+    di.Name = options.StdInFileName;\r
+    di.Size = (UInt64)(Int64)-1;\r
+    di.Attrib = 0;\r
+    NTime::GetCurUtcFileTime(di.MTime);\r
+    di.CTime = di.ATime = di.MTime;\r
+    dirItems.Items.Add(di);\r
+  }\r
+  else\r
+  {\r
+    bool needScanning = false;\r
+    for(int i = 0; i < options.Commands.Size(); i++)\r
+      if (options.Commands[i].ActionSet.NeedScanning())\r
+        needScanning = true;\r
+    if (needScanning)\r
+    {\r
+      CEnumDirItemUpdateCallback enumCallback;\r
+      enumCallback.Callback = callback;\r
+      RINOK(callback->StartScanning());\r
+      UStringVector errorPaths;\r
+      CRecordVector<DWORD> errorCodes;\r
+      HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes);\r
+      for (int i = 0; i < errorPaths.Size(); i++)\r
+      {\r
+        RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i]));\r
+      }\r
+      if (res != S_OK)\r
+      {\r
+        if (res != E_ABORT)\r
+          errorInfo.Message = L"Scanning error";\r
+        return res;\r
+      }\r
+      RINOK(callback->FinishScanning());\r
+    }\r
+  }\r
+\r
+  UString tempDirPrefix;\r
+  bool usesTempDir = false;\r
+  \r
+  #ifdef _WIN32\r
+  NDirectory::CTempDirectoryW tempDirectory;\r
+  if (options.EMailMode && options.EMailRemoveAfter)\r
+  {\r
+    tempDirectory.Create(kTempFolderPrefix);\r
+    tempDirPrefix = tempDirectory.GetPath();\r
+    NormalizeDirPathPrefix(tempDirPrefix);\r
+    usesTempDir = true;\r
+  }\r
+  #endif\r
+\r
+  CTempFiles tempFiles;\r
+\r
+  bool createTempFile = false;\r
+\r
+  bool thereIsInArchive = arcLink.IsOpen;\r
+\r
+  if (!options.StdOutMode && options.UpdateArchiveItself)\r
+  {\r
+    CArchivePath &ap = options.Commands[0].ArchivePath;\r
+    ap = options.ArchivePath;\r
+    // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty())\r
+    if ((thereIsInArchive || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)\r
+    {\r
+      createTempFile = true;\r
+      ap.Temp = true;\r
+      if (!options.WorkingDir.IsEmpty())\r
+      {\r
+        ap.TempPrefix = options.WorkingDir;\r
+        NormalizeDirPathPrefix(ap.TempPrefix);\r
+      }\r
+    }\r
+  }\r
+\r
+  for(int i = 0; i < options.Commands.Size(); i++)\r
+  {\r
+    CArchivePath &ap = options.Commands[i].ArchivePath;\r
+    if (usesTempDir)\r
+    {\r
+      // Check it\r
+      ap.Prefix = tempDirPrefix;\r
+      // ap.Temp = true;\r
+      // ap.TempPrefix = tempDirPrefix;\r
+    }\r
+    if (!options.StdOutMode &&\r
+        (i > 0 || !createTempFile))\r
+    {\r
+      const UString &path = ap.GetFinalPath();\r
+      if (NFind::DoesFileOrDirExist(path))\r
+      {\r
+        errorInfo.SystemError = 0;\r
+        errorInfo.Message = L"The file already exists";\r
+        errorInfo.FileName = path;\r
+        return E_FAIL;\r
+      }\r
+    }\r
+  }\r
+\r
+  CObjectVector<CArcItem> arcItems;\r
+  if (thereIsInArchive)\r
+  {\r
+    RINOK(EnumerateInArchiveItems(censor, arcLink.Arcs.Back(), arcItems));\r
+  }\r
+\r
+  RINOK(UpdateWithItemLists(codecs, options,\r
+      thereIsInArchive ? arcLink.GetArchive() : 0,\r
+      arcItems, dirItems,\r
+      tempFiles, errorInfo, callback));\r
+\r
+  if (thereIsInArchive)\r
+  {\r
+    RINOK(arcLink.Close());\r
+    arcLink.Release();\r
+  }\r
+\r
+  tempFiles.Paths.Clear();\r
+  if (createTempFile)\r
+  {\r
+    try\r
+    {\r
+      CArchivePath &ap = options.Commands[0].ArchivePath;\r
+      const UString &tempPath = ap.GetTempPath();\r
+      if (thereIsInArchive)\r
+        if (!NDirectory::DeleteFileAlways(arcPath))\r
+        {\r
+          errorInfo.SystemError = ::GetLastError();\r
+          errorInfo.Message = L"7-Zip cannot delete the file";\r
+          errorInfo.FileName = arcPath;\r
+          return E_FAIL;\r
+        }\r
+      if (!NDirectory::MyMoveFile(tempPath, arcPath))\r
+      {\r
+        errorInfo.SystemError = ::GetLastError();\r
+        errorInfo.Message = L"7-Zip cannot move the file";\r
+        errorInfo.FileName = tempPath;\r
+        errorInfo.FileName2 = arcPath;\r
+        return E_FAIL;\r
+      }\r
+    }\r
+    catch(...)\r
+    {\r
+      throw;\r
+    }\r
+  }\r
+\r
+  #if defined(_WIN32) && !defined(UNDER_CE)\r
+  if (options.EMailMode)\r
+  {\r
+    NDLL::CLibrary mapiLib;\r
+    if (!mapiLib.Load(TEXT("Mapi32.dll")))\r
+    {\r
+      errorInfo.SystemError = ::GetLastError();\r
+      errorInfo.Message = L"7-Zip cannot load Mapi32.dll";\r
+      return E_FAIL;\r
+    }\r
+    MY_LPMAPISENDDOCUMENTS fnSend = (MY_LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments");\r
+    if (fnSend == 0)\r
+    {\r
+      errorInfo.SystemError = ::GetLastError();\r
+      errorInfo.Message = L"7-Zip cannot find MAPISendDocuments function";\r
+      return E_FAIL;\r
+    }\r
+    UStringVector fullPaths;\r
+    int i;\r
+    for(i = 0; i < options.Commands.Size(); i++)\r
+    {\r
+      CArchivePath &ap = options.Commands[i].ArchivePath;\r
+      UString arcPath;\r
+      if (!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))\r
+      {\r
+        errorInfo.SystemError = ::GetLastError();\r
+        errorInfo.Message = L"GetFullPathName error";\r
+        return E_FAIL;\r
+      }\r
+      fullPaths.Add(arcPath);\r
+    }\r
+    CCurrentDirRestorer curDirRestorer;\r
+    for(i = 0; i < fullPaths.Size(); i++)\r
+    {\r
+      UString arcPath = fullPaths[i];\r
+      UString fileName = ExtractFileNameFromPath(arcPath);\r
+      AString path = GetAnsiString(arcPath);\r
+      AString name = GetAnsiString(fileName);\r
+      // Warning!!! MAPISendDocuments function changes Current directory\r
+      fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);\r
+    }\r
+  }\r
+  #endif\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h
new file mode 100755 (executable)
index 0000000..6bc85b5
--- /dev/null
@@ -0,0 +1,175 @@
+// Update.h\r
+\r
+#ifndef __COMMON_UPDATE_H\r
+#define __COMMON_UPDATE_H\r
+\r
+#include "Common/Wildcard.h"\r
+\r
+#include "ArchiveOpenCallback.h"\r
+#include "LoadCodecs.h"\r
+#include "Property.h"\r
+#include "UpdateAction.h"\r
+#include "UpdateCallback.h"\r
+\r
+struct CArchivePath\r
+{\r
+  UString OriginalPath;\r
+\r
+  UString Prefix;   // path(folder) prefix including slash\r
+  UString Name; // base name\r
+  UString BaseExtension; // archive type extension or "exe" extension\r
+  UString VolExtension;  // archive type extension for volumes\r
+\r
+  bool Temp;\r
+  UString TempPrefix;  // path(folder) for temp location\r
+  UString TempPostfix;\r
+\r
+  CArchivePath(): Temp(false) {};\r
+  \r
+  void ParseFromPath(const UString &path)\r
+  {\r
+    OriginalPath = path;\r
+\r
+    SplitPathToParts(path, Prefix, Name);\r
+    int dotPos = Name.ReverseFind(L'.');\r
+    if (dotPos < 0)\r
+      return;\r
+    if (dotPos == Name.Length() - 1)\r
+    {\r
+      Name = Name.Left(dotPos);\r
+      BaseExtension.Empty();\r
+      return;\r
+    }\r
+    if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0)\r
+    {\r
+      BaseExtension = Name.Mid(dotPos + 1);\r
+      Name = Name.Left(dotPos);\r
+    }\r
+    else\r
+      BaseExtension.Empty();\r
+  }\r
+\r
+  UString GetPathWithoutExt() const\r
+  {\r
+    return Prefix + Name;\r
+  }\r
+\r
+  UString GetFinalPath() const\r
+  {\r
+    UString path = GetPathWithoutExt();\r
+    if (!BaseExtension.IsEmpty())\r
+      path += UString(L'.') + BaseExtension;\r
+    return path;\r
+  }\r
+\r
+  \r
+  UString GetTempPath() const\r
+  {\r
+    UString path = TempPrefix + Name;\r
+    if (!BaseExtension.IsEmpty())\r
+      path += UString(L'.') + BaseExtension;\r
+    path += L".tmp";\r
+    path += TempPostfix;\r
+    return path;\r
+  }\r
+};\r
+\r
+struct CUpdateArchiveCommand\r
+{\r
+  UString UserArchivePath;\r
+  CArchivePath ArchivePath;\r
+  NUpdateArchive::CActionSet ActionSet;\r
+};\r
+\r
+struct CCompressionMethodMode\r
+{\r
+  int FormatIndex;\r
+  CObjectVector<CProperty> Properties;\r
+  CCompressionMethodMode(): FormatIndex(-1) {}\r
+};\r
+\r
+struct CUpdateOptions\r
+{\r
+  CCompressionMethodMode MethodMode;\r
+\r
+  CObjectVector<CUpdateArchiveCommand> Commands;\r
+  bool UpdateArchiveItself;\r
+  CArchivePath ArchivePath;\r
+  \r
+  bool SfxMode;\r
+  UString SfxModule;\r
+  \r
+  bool OpenShareForWrite;\r
+\r
+  bool StdInMode;\r
+  UString StdInFileName;\r
+  bool StdOutMode;\r
+  \r
+  bool EMailMode;\r
+  bool EMailRemoveAfter;\r
+  UString EMailAddress;\r
+\r
+  UString WorkingDir;\r
+\r
+  bool Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath);\r
+\r
+  CUpdateOptions():\r
+    UpdateArchiveItself(true),\r
+    SfxMode(false),\r
+    StdInMode(false),\r
+    StdOutMode(false),\r
+    EMailMode(false),\r
+    EMailRemoveAfter(false),\r
+    OpenShareForWrite(false)\r
+      {};\r
+\r
+  void SetAddActionCommand()\r
+  {\r
+    Commands.Clear();\r
+    CUpdateArchiveCommand c;\r
+    c.ActionSet = NUpdateArchive::kAddActionSet;\r
+    Commands.Add(c);\r
+  }\r
+\r
+  CRecordVector<UInt64> VolumesSizes;\r
+};\r
+\r
+struct CErrorInfo\r
+{\r
+  DWORD SystemError;\r
+  UString FileName;\r
+  UString FileName2;\r
+  UString Message;\r
+  // UStringVector ErrorPaths;\r
+  // CRecordVector<DWORD> ErrorCodes;\r
+  CErrorInfo(): SystemError(0) {};\r
+};\r
+\r
+struct CUpdateErrorInfo: public CErrorInfo\r
+{\r
+};\r
+\r
+#define INTERFACE_IUpdateCallbackUI2(x) \\r
+  INTERFACE_IUpdateCallbackUI(x) \\r
+  virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) x; \\r
+  virtual HRESULT StartScanning() x; \\r
+  virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) x; \\r
+  virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) x; \\r
+  virtual HRESULT FinishScanning() x; \\r
+  virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \\r
+  virtual HRESULT FinishArchive() x; \\r
+\r
+struct IUpdateCallbackUI2: public IUpdateCallbackUI\r
+{\r
+  INTERFACE_IUpdateCallbackUI2(=0)\r
+};\r
+\r
+HRESULT UpdateArchive(\r
+    CCodecs *codecs,\r
+    const NWildcard::CCensor &censor,\r
+    CUpdateOptions &options,\r
+    CUpdateErrorInfo &errorInfo,\r
+    IOpenCallbackUI *openCallback,\r
+    IUpdateCallbackUI2 *callback);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/UpdateAction.cpp b/CPP/7zip/UI/Common/UpdateAction.cpp
new file mode 100755 (executable)
index 0000000..2e3dd62
--- /dev/null
@@ -0,0 +1,64 @@
+// UpdateAction.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "UpdateAction.h"\r
+\r
+namespace NUpdateArchive {\r
+\r
+const CActionSet kAddActionSet =\r
+{{\r
+  NPairAction::kCopy,\r
+  NPairAction::kCopy,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCompress\r
+}};\r
+\r
+const CActionSet kUpdateActionSet =\r
+{{\r
+  NPairAction::kCopy,\r
+  NPairAction::kCopy,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCopy,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCopy,\r
+  NPairAction::kCompress\r
+}};\r
+\r
+const CActionSet kFreshActionSet =\r
+{{\r
+  NPairAction::kCopy,\r
+  NPairAction::kCopy,\r
+  NPairAction::kIgnore,\r
+  NPairAction::kCopy,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCopy,\r
+  NPairAction::kCompress\r
+}};\r
+\r
+const CActionSet kSynchronizeActionSet =\r
+{{\r
+  NPairAction::kCopy,\r
+  NPairAction::kIgnore,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCopy,\r
+  NPairAction::kCompress,\r
+  NPairAction::kCopy,\r
+  NPairAction::kCompress,\r
+}};\r
+\r
+const CActionSet kDeleteActionSet =\r
+{{\r
+  NPairAction::kCopy,\r
+  NPairAction::kIgnore,\r
+  NPairAction::kIgnore,\r
+  NPairAction::kIgnore,\r
+  NPairAction::kIgnore,\r
+  NPairAction::kIgnore,\r
+  NPairAction::kIgnore\r
+}};\r
+\r
+}\r
diff --git a/CPP/7zip/UI/Common/UpdateAction.h b/CPP/7zip/UI/Common/UpdateAction.h
new file mode 100755 (executable)
index 0000000..7ad57ce
--- /dev/null
@@ -0,0 +1,57 @@
+// UpdateAction.h\r
+\r
+#ifndef __UPDATE_ACTION_H\r
+#define __UPDATE_ACTION_H\r
+\r
+namespace NUpdateArchive {\r
+\r
+  namespace NPairState\r
+  {\r
+    const int kNumValues = 7;\r
+    enum EEnum\r
+    {\r
+      kNotMasked = 0,\r
+      kOnlyInArchive,\r
+      kOnlyOnDisk,\r
+      kNewInArchive,\r
+      kOldInArchive,\r
+      kSameFiles,\r
+      kUnknowNewerFiles\r
+    };\r
+  }\r
\r
+  namespace NPairAction\r
+  {\r
+    enum EEnum\r
+    {\r
+      kIgnore = 0,\r
+      kCopy,\r
+      kCompress,\r
+      kCompressAsAnti\r
+    };\r
+  }\r
+  \r
+  struct CActionSet\r
+  {\r
+    NPairAction::EEnum StateActions[NPairState::kNumValues];\r
+    bool NeedScanning() const\r
+    {\r
+      int i;\r
+      for (i = 0; i < NPairState::kNumValues; i++)\r
+        if (StateActions[i] == NPairAction::kCompress)\r
+          return true;\r
+      for (i = 1; i < NPairState::kNumValues; i++)\r
+        if (StateActions[i] != NPairAction::kIgnore)\r
+          return true;\r
+      return false;\r
+    }\r
+  };\r
+  \r
+  extern const CActionSet kAddActionSet;\r
+  extern const CActionSet kUpdateActionSet;\r
+  extern const CActionSet kFreshActionSet;\r
+  extern const CActionSet kSynchronizeActionSet;\r
+  extern const CActionSet kDeleteActionSet;\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp
new file mode 100755 (executable)
index 0000000..55c9374
--- /dev/null
@@ -0,0 +1,249 @@
+// UpdateCallback.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/ComTry.h"\r
+#include "Common/Defs.h"\r
+#include "Common/IntToString.h"\r
+#include "Common/StringConvert.h"\r
+\r
+#include "Windows/PropVariant.h"\r
+\r
+#include "../../Common/FileStreams.h"\r
+\r
+#include "UpdateCallback.h"\r
+\r
+using namespace NWindows;\r
+\r
+CArchiveUpdateCallback::CArchiveUpdateCallback():\r
+  Callback(0),\r
+  ShareForWrite(false),\r
+  StdInMode(false),\r
+  DirItems(0),\r
+  ArcItems(0),\r
+  UpdatePairs(0),\r
+  NewNames(0)\r
+  {}\r
+\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)\r
+{\r
+  COM_TRY_BEGIN\r
+  return Callback->SetTotal(size);\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)\r
+{\r
+  COM_TRY_BEGIN\r
+  return Callback->SetCompleted(completeValue);\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)\r
+{\r
+  COM_TRY_BEGIN\r
+  return Callback->SetRatioInfo(inSize, outSize);\r
+  COM_TRY_END\r
+}\r
+\r
+\r
+/*\r
+STATPROPSTG kProperties[] =\r
+{\r
+  { NULL, kpidPath, VT_BSTR},\r
+  { NULL, kpidIsDir, VT_BOOL},\r
+  { NULL, kpidSize, VT_UI8},\r
+  { NULL, kpidCTime, VT_FILETIME},\r
+  { NULL, kpidATime, VT_FILETIME},\r
+  { NULL, kpidMTime, VT_FILETIME},\r
+  { NULL, kpidAttrib, VT_UI4},\r
+  { NULL, kpidIsAnti, VT_BOOL}\r
+};\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)\r
+{\r
+  return CStatPropEnumerator::CreateEnumerator(kProperties, sizeof(kProperties) / sizeof(kProperties[0]), enumerator);\r
+}\r
+*/\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,\r
+      Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)\r
+{\r
+  COM_TRY_BEGIN\r
+  RINOK(Callback->CheckBreak());\r
+  const CUpdatePair2 &up = (*UpdatePairs)[index];\r
+  if (newData != NULL) *newData = BoolToInt(up.NewData);\r
+  if (newProps != NULL) *newProps = BoolToInt(up.NewProps);\r
+  if (indexInArchive != NULL)\r
+  {\r
+    *indexInArchive = (UInt32)-1;\r
+    if (up.ExistInArchive())\r
+      *indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;\r
+  }\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)\r
+{\r
+  COM_TRY_BEGIN\r
+  const CUpdatePair2 &up = (*UpdatePairs)[index];\r
+  NWindows::NCOM::CPropVariant prop;\r
+  \r
+  if (propID == kpidIsAnti)\r
+  {\r
+    prop = up.IsAnti;\r
+    prop.Detach(value);\r
+    return S_OK;\r
+  }\r
+\r
+  if (up.IsAnti)\r
+  {\r
+    switch(propID)\r
+    {\r
+      case kpidIsDir:\r
+      case kpidPath:\r
+        break;\r
+      case kpidSize:\r
+        prop = (UInt64)0;\r
+        prop.Detach(value);\r
+        return S_OK;\r
+      default:\r
+        prop.Detach(value);\r
+        return S_OK;\r
+    }\r
+  }\r
+  \r
+  if (up.ExistOnDisk())\r
+  {\r
+    const CDirItem &di = DirItems->Items[up.DirIndex];\r
+    switch(propID)\r
+    {\r
+      case kpidPath:  prop = DirItems->GetLogPath(up.DirIndex); break;\r
+      case kpidIsDir:  prop = di.IsDir(); break;\r
+      case kpidSize:  prop = di.Size; break;\r
+      case kpidAttrib:  prop = di.Attrib; break;\r
+      case kpidCTime:  prop = di.CTime; break;\r
+      case kpidATime:  prop = di.ATime; break;\r
+      case kpidMTime:  prop = di.MTime; break;\r
+    }\r
+  }\r
+  else\r
+  {\r
+    if (propID == kpidPath)\r
+    {\r
+      if (up.NewNameIndex >= 0)\r
+      {\r
+        prop = (*NewNames)[up.NewNameIndex];\r
+        prop.Detach(value);\r
+        return S_OK;\r
+      }\r
+    }\r
+    if (up.ExistInArchive() && Archive)\r
+    {\r
+      UInt32 indexInArchive;\r
+      if (ArcItems == 0)\r
+        indexInArchive = up.ArcIndex;\r
+      else\r
+        indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;\r
+      return Archive->GetProperty(indexInArchive, propID, value);\r
+    }\r
+  }\r
+  prop.Detach(value);\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)\r
+{\r
+  COM_TRY_BEGIN\r
+  const CUpdatePair2 &up = (*UpdatePairs)[index];\r
+  if (!up.NewData)\r
+    return E_FAIL;\r
+  \r
+  RINOK(Callback->CheckBreak());\r
+  RINOK(Callback->Finilize());\r
+\r
+  if (up.IsAnti)\r
+  {\r
+    return Callback->GetStream((*ArcItems)[up.ArcIndex].Name, true);\r
+  }\r
+  const CDirItem &di = DirItems->Items[up.DirIndex];\r
+  RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), false));\r
\r
+  if (di.IsDir())\r
+    return S_OK;\r
+\r
+  if (StdInMode)\r
+  {\r
+    CStdInFileStream *inStreamSpec = new CStdInFileStream;\r
+    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);\r
+    *inStream = inStreamLoc.Detach();\r
+  }\r
+  else\r
+  {\r
+    CInFileStream *inStreamSpec = new CInFileStream;\r
+    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);\r
+    const UString path = DirItems->GetPhyPath(up.DirIndex);\r
+    if (!inStreamSpec->OpenShared(path, ShareForWrite))\r
+    {\r
+      return Callback->OpenFileError(path, ::GetLastError());\r
+    }\r
+    *inStream = inStreamLoc.Detach();\r
+  }\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)\r
+{\r
+  COM_TRY_BEGIN\r
+  return Callback->SetOperationResult(operationResult);\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)\r
+{\r
+  if (VolumesSizes.Size() == 0)\r
+    return S_FALSE;\r
+  if (index >= (UInt32)VolumesSizes.Size())\r
+    index = VolumesSizes.Size() - 1;\r
+  *size = VolumesSizes[index];\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)\r
+{\r
+  COM_TRY_BEGIN\r
+  wchar_t temp[16];\r
+  ConvertUInt32ToString(index + 1, temp);\r
+  UString res = temp;\r
+  while (res.Length() < 2)\r
+    res = UString(L'0') + res;\r
+  UString fileName = VolName;\r
+  fileName += L'.';\r
+  fileName += res;\r
+  fileName += VolExt;\r
+  COutFileStream *streamSpec = new COutFileStream;\r
+  CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);\r
+  if (!streamSpec->Create(fileName, false))\r
+    return ::GetLastError();\r
+  *volumeStream = streamLoc.Detach();\r
+  return S_OK;\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)\r
+{\r
+  COM_TRY_BEGIN\r
+  return Callback->CryptoGetTextPassword2(passwordIsDefined, password);\r
+  COM_TRY_END\r
+}\r
+\r
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)\r
+{\r
+  COM_TRY_BEGIN\r
+  return Callback->CryptoGetTextPassword(password);\r
+  COM_TRY_END\r
+}\r
diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h
new file mode 100755 (executable)
index 0000000..2785ee9
--- /dev/null
@@ -0,0 +1,74 @@
+// UpdateCallback.h\r
+\r
+#ifndef __UPDATECALLBACK_H\r
+#define __UPDATECALLBACK_H\r
+\r
+#include "Common/MyCom.h"\r
+#include "Common/MyString.h"\r
+\r
+#include "../../IPassword.h"\r
+#include "../../ICoder.h"\r
+\r
+#include "../Common/UpdatePair.h"\r
+#include "../Common/UpdateProduce.h"\r
+\r
+#define INTERFACE_IUpdateCallbackUI(x) \\r
+  virtual HRESULT SetTotal(UInt64 size) x; \\r
+  virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \\r
+  virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \\r
+  virtual HRESULT CheckBreak() x; \\r
+  virtual HRESULT Finilize() x; \\r
+  virtual HRESULT SetNumFiles(UInt64 numFiles) x; \\r
+  virtual HRESULT GetStream(const wchar_t *name, bool isAnti) x; \\r
+  virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) x; \\r
+  virtual HRESULT SetOperationResult(Int32 operationResult) x; \\r
+  virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \\r
+  virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \\r
+  /* virtual HRESULT ShowDeleteFile(const wchar_t *name) x; */ \\r
+  /* virtual HRESULT CloseProgress() { return S_OK; }; */\r
+\r
+struct IUpdateCallbackUI\r
+{\r
+  INTERFACE_IUpdateCallbackUI(=0)\r
+};\r
+\r
+class CArchiveUpdateCallback:\r
+  public IArchiveUpdateCallback2,\r
+  public ICryptoGetTextPassword2,\r
+  public ICryptoGetTextPassword,\r
+  public ICompressProgressInfo,\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_UNKNOWN_IMP4(\r
+      IArchiveUpdateCallback2,\r
+      ICryptoGetTextPassword2,\r
+      ICryptoGetTextPassword,\r
+      ICompressProgressInfo)\r
+\r
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);\r
+\r
+  INTERFACE_IArchiveUpdateCallback2(;)\r
+\r
+  STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);\r
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);\r
+\r
+public:\r
+  CRecordVector<UInt64> VolumesSizes;\r
+  UString VolName;\r
+  UString VolExt;\r
+\r
+  IUpdateCallbackUI *Callback;\r
+\r
+  bool ShareForWrite;\r
+  bool StdInMode;\r
+  const CDirItems *DirItems;\r
+  const CObjectVector<CArcItem> *ArcItems;\r
+  const CRecordVector<CUpdatePair2> *UpdatePairs;\r
+  const UStringVector *NewNames;\r
+  CMyComPtr<IInArchive> Archive;\r
+\r
+  CArchiveUpdateCallback();\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp
new file mode 100755 (executable)
index 0000000..812bff8
--- /dev/null
@@ -0,0 +1,158 @@
+// UpdatePair.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include <time.h>\r
+\r
+#include "Common/Defs.h"\r
+#include "Common/Wildcard.h"\r
+\r
+#include "Windows/Time.h"\r
+\r
+#include "SortUtils.h"\r
+#include "UpdatePair.h"\r
+\r
+using namespace NWindows;\r
+using namespace NTime;\r
+\r
+static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2)\r
+{\r
+  switch(fileTimeType)\r
+  {\r
+    case NFileTimeType::kWindows:\r
+      return ::CompareFileTime(&time1, &time2);\r
+    case NFileTimeType::kUnix:\r
+      {\r
+        UInt32 unixTime1, unixTime2;\r
+        FileTimeToUnixTime(time1, unixTime1);\r
+        FileTimeToUnixTime(time2, unixTime2);\r
+        return MyCompare(unixTime1, unixTime2);\r
+      }\r
+    case NFileTimeType::kDOS:\r
+      {\r
+        UInt32 dosTime1, dosTime2;\r
+        FileTimeToDosTime(time1, dosTime1);\r
+        FileTimeToDosTime(time2, dosTime2);\r
+        return MyCompare(dosTime1, dosTime2);\r
+      }\r
+  }\r
+  throw 4191618;\r
+}\r
+\r
+static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";\r
+static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):";\r
+\r
+static void ThrowError(const UString &message, const UString &s1, const UString &s2)\r
+{\r
+  UString m = message;\r
+  m += L'\n';\r
+  m += s1;\r
+  m += L'\n';\r
+  m += s2;\r
+  throw m;\r
+}\r
+\r
+static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)\r
+{\r
+  for(int i = 0; i + 1 < indices.Size(); i++)\r
+    if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)\r
+      ThrowError(kDuplicateFileNameMessage, strings[indices[i]], strings[indices[i + 1]]);\r
+}\r
+\r
+void GetUpdatePairInfoList(\r
+    const CDirItems &dirItems,\r
+    const CObjectVector<CArcItem> &arcItems,\r
+    NFileTimeType::EEnum fileTimeType,\r
+    CRecordVector<CUpdatePair> &updatePairs)\r
+{\r
+  CIntVector dirIndices, arcIndices;\r
+  \r
+  int numDirItems = dirItems.Items.Size();\r
+  int numArcItems = arcItems.Size();\r
+  \r
+  \r
+  {\r
+    UStringVector arcNames;\r
+    arcNames.Reserve(numArcItems);\r
+    for (int i = 0; i < numArcItems; i++)\r
+      arcNames.Add(arcItems[i].Name);\r
+    SortFileNames(arcNames, arcIndices);\r
+    TestDuplicateString(arcNames, arcIndices);\r
+  }\r
+\r
+  UStringVector dirNames;\r
+  {\r
+    dirNames.Reserve(numDirItems);\r
+    for (int i = 0; i < numDirItems; i++)\r
+      dirNames.Add(dirItems.GetLogPath(i));\r
+    SortFileNames(dirNames, dirIndices);\r
+    TestDuplicateString(dirNames, dirIndices);\r
+  }\r
+  \r
+  int dirIndex = 0, arcIndex = 0;\r
+  while (dirIndex < numDirItems && arcIndex < numArcItems)\r
+  {\r
+    CUpdatePair pair;\r
+    int dirIndex2 = dirIndices[dirIndex];\r
+    int arcIndex2 = arcIndices[arcIndex];\r
+    const CDirItem &di = dirItems.Items[dirIndex2];\r
+    const CArcItem &ai = arcItems[arcIndex2];\r
+    int compareResult = CompareFileNames(dirNames[dirIndex2], ai.Name);\r
+    if (compareResult < 0)\r
+    {\r
+      pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;\r
+      pair.DirIndex = dirIndex2;\r
+      dirIndex++;\r
+    }\r
+    else if (compareResult > 0)\r
+    {\r
+      pair.State = ai.Censored ?\r
+          NUpdateArchive::NPairState::kOnlyInArchive:\r
+          NUpdateArchive::NPairState::kNotMasked;\r
+      pair.ArcIndex = arcIndex2;\r
+      arcIndex++;\r
+    }\r
+    else\r
+    {\r
+      if (!ai.Censored)\r
+        ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name);\r
+      pair.DirIndex = dirIndex2;\r
+      pair.ArcIndex = arcIndex2;\r
+      switch (ai.MTimeDefined ? MyCompareTime(\r
+          ai.TimeType != - 1 ? (NFileTimeType::EEnum)ai.TimeType : fileTimeType,\r
+          di.MTime, ai.MTime): 0)\r
+      {\r
+        case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break;\r
+        case 1:  pair.State = NUpdateArchive::NPairState::kOldInArchive; break;\r
+        default:\r
+          pair.State = (ai.SizeDefined && di.Size == ai.Size) ?\r
+              NUpdateArchive::NPairState::kSameFiles :\r
+              NUpdateArchive::NPairState::kUnknowNewerFiles;\r
+      }\r
+      dirIndex++;\r
+      arcIndex++;\r
+    }\r
+    updatePairs.Add(pair);\r
+  }\r
+\r
+  for (; dirIndex < numDirItems; dirIndex++)\r
+  {\r
+    CUpdatePair pair;\r
+    pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;\r
+    pair.DirIndex = dirIndices[dirIndex];\r
+    updatePairs.Add(pair);\r
+  }\r
+  \r
+  for (; arcIndex < numArcItems; arcIndex++)\r
+  {\r
+    CUpdatePair pair;\r
+    int arcIndex2 = arcIndices[arcIndex];\r
+    pair.State = arcItems[arcIndex2].Censored ?\r
+        NUpdateArchive::NPairState::kOnlyInArchive:\r
+        NUpdateArchive::NPairState::kNotMasked;\r
+    pair.ArcIndex = arcIndex2;\r
+    updatePairs.Add(pair);\r
+  }\r
+\r
+  updatePairs.ReserveDown();\r
+}\r
diff --git a/CPP/7zip/UI/Common/UpdatePair.h b/CPP/7zip/UI/Common/UpdatePair.h
new file mode 100755 (executable)
index 0000000..5ee2665
--- /dev/null
@@ -0,0 +1,25 @@
+// UpdatePair.h\r
+\r
+#ifndef __UPDATE_PAIR_H\r
+#define __UPDATE_PAIR_H\r
+\r
+#include "DirItem.h"\r
+#include "UpdateAction.h"\r
+\r
+#include "../../Archive/IArchive.h"\r
+\r
+struct CUpdatePair\r
+{\r
+  NUpdateArchive::NPairState::EEnum State;\r
+  int ArcIndex;\r
+  int DirIndex;\r
+  CUpdatePair(): ArcIndex(-1), DirIndex(-1) {}\r
+};\r
+\r
+void GetUpdatePairInfoList(\r
+    const CDirItems &dirItems,\r
+    const CObjectVector<CArcItem> &arcItems,\r
+    NFileTimeType::EEnum fileTimeType,\r
+    CRecordVector<CUpdatePair> &updatePairs);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp
new file mode 100755 (executable)
index 0000000..3ba677d
--- /dev/null
@@ -0,0 +1,58 @@
+// UpdateProduce.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "UpdateProduce.h"\r
+\r
+using namespace NUpdateArchive;\r
+\r
+static const char *kUpdateActionSetCollision = "Internal collision in update action set";\r
+\r
+void UpdateProduce(\r
+    const CRecordVector<CUpdatePair> &updatePairs,\r
+    const CActionSet &actionSet,\r
+    CRecordVector<CUpdatePair2> &operationChain,\r
+    IUpdateProduceCallback *callback)\r
+{\r
+  for (int i = 0; i < updatePairs.Size(); i++)\r
+  {\r
+    const CUpdatePair &pair = updatePairs[i];\r
+\r
+    CUpdatePair2 up2;\r
+    up2.IsAnti = false;\r
+    up2.DirIndex = pair.DirIndex;\r
+    up2.ArcIndex = pair.ArcIndex;\r
+    up2.NewData = up2.NewProps = true;\r
+    \r
+    switch(actionSet.StateActions[pair.State])\r
+    {\r
+      case NPairAction::kIgnore:\r
+        /*\r
+        if (pair.State != NPairState::kOnlyOnDisk)\r
+          IgnoreArchiveItem(m_ArchiveItems[pair.ArcIndex]);\r
+        // cout << "deleting";\r
+        */\r
+        if (callback)\r
+          callback->ShowDeleteFile(pair.ArcIndex);\r
+        continue;\r
+\r
+      case NPairAction::kCopy:\r
+        if (pair.State == NPairState::kOnlyOnDisk)\r
+          throw kUpdateActionSetCollision;\r
+        up2.NewData = up2.NewProps = false;\r
+        break;\r
+      \r
+      case NPairAction::kCompress:\r
+        if (pair.State == NPairState::kOnlyInArchive ||\r
+            pair.State == NPairState::kNotMasked)\r
+          throw kUpdateActionSetCollision;\r
+        break;\r
+      \r
+      case NPairAction::kCompressAsAnti:\r
+        up2.IsAnti = true;\r
+        break;\r
+    }\r
+    operationChain.Add(up2);\r
+  }\r
+  operationChain.ReserveDown();\r
+}\r
diff --git a/CPP/7zip/UI/Common/UpdateProduce.h b/CPP/7zip/UI/Common/UpdateProduce.h
new file mode 100755 (executable)
index 0000000..c511caf
--- /dev/null
@@ -0,0 +1,35 @@
+// UpdateProduce.h\r
+\r
+#ifndef __UPDATE_PRODUCE_H\r
+#define __UPDATE_PRODUCE_H\r
+\r
+#include "UpdatePair.h"\r
+\r
+struct CUpdatePair2\r
+{\r
+  bool NewData;\r
+  bool NewProps;\r
+  bool IsAnti;\r
+  \r
+  int DirIndex;\r
+  int ArcIndex;\r
+  int NewNameIndex;\r
+\r
+  bool ExistOnDisk() const { return DirIndex != -1; }\r
+  bool ExistInArchive() const { return ArcIndex != -1; }\r
+\r
+  CUpdatePair2(): IsAnti(false), DirIndex(-1), ArcIndex(-1), NewNameIndex(-1) {}\r
+};\r
+\r
+struct IUpdateProduceCallback\r
+{\r
+  virtual HRESULT ShowDeleteFile(int arcIndex) = 0;\r
+};\r
+\r
+void UpdateProduce(\r
+    const CRecordVector<CUpdatePair> &updatePairs,\r
+    const NUpdateArchive::CActionSet &actionSet,\r
+    CRecordVector<CUpdatePair2> &operationChain,\r
+    IUpdateProduceCallback *callback);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/WorkDir.cpp b/CPP/7zip/UI/Common/WorkDir.cpp
new file mode 100755 (executable)
index 0000000..2989632
--- /dev/null
@@ -0,0 +1,59 @@
+// WorkDir.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/StringConvert.h"\r
+#include "Common/Wildcard.h"\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/FileName.h"\r
+\r
+#include "WorkDir.h"\r
+\r
+using namespace NWindows;\r
+using namespace NFile;\r
+\r
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path)\r
+{\r
+  NWorkDir::NMode::EEnum mode = workDirInfo.Mode;\r
+  #ifndef UNDER_CE\r
+  if (workDirInfo.ForRemovableOnly)\r
+  {\r
+    mode = NWorkDir::NMode::kCurrent;\r
+    UString prefix = path.Left(3);\r
+    if (prefix[1] == L':' && prefix[2] == L'\\')\r
+    {\r
+      UINT driveType = GetDriveType(GetSystemString(prefix, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP));\r
+      if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE)\r
+        mode = workDirInfo.Mode;\r
+    }\r
+    /*\r
+    CParsedPath parsedPath;\r
+    parsedPath.ParsePath(archiveName);\r
+    UINT driveType = GetDriveType(parsedPath.Prefix);\r
+    if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE))\r
+      mode = NZipSettings::NWorkDir::NMode::kCurrent;\r
+    */\r
+  }\r
+  #endif\r
+  switch(mode)\r
+  {\r
+    case NWorkDir::NMode::kCurrent:\r
+    {\r
+      return ExtractDirPrefixFromPath(path);\r
+    }\r
+    case NWorkDir::NMode::kSpecified:\r
+    {\r
+      UString tempDir = workDirInfo.Path;\r
+      NName::NormalizeDirPathPrefix(tempDir);\r
+      return tempDir;\r
+    }\r
+    default:\r
+    {\r
+      UString tempDir;\r
+      if (!NDirectory::MyGetTempPath(tempDir))\r
+        throw 141717;\r
+      return tempDir;\r
+    }\r
+  }\r
+}\r
diff --git a/CPP/7zip/UI/Common/WorkDir.h b/CPP/7zip/UI/Common/WorkDir.h
new file mode 100755 (executable)
index 0000000..8208f3a
--- /dev/null
@@ -0,0 +1,10 @@
+// WorkDir.h\r
+\r
+#ifndef __WORKDIR_H\r
+#define __WORKDIR_H\r
+\r
+#include "ZipRegistry.h"\r
+\r
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h
new file mode 100755 (executable)
index 0000000..1760d9b
--- /dev/null
@@ -0,0 +1,105 @@
+// ZipRegistry.h\r
+\r
+#ifndef __ZIP_REGISTRY_H\r
+#define __ZIP_REGISTRY_H\r
+\r
+#include "Common/MyString.h"\r
+#include "Common/Types.h"\r
+\r
+#include "ExtractMode.h"\r
+\r
+namespace NExtract\r
+{\r
+  struct CInfo\r
+  {\r
+    NPathMode::EEnum PathMode;\r
+    NOverwriteMode::EEnum OverwriteMode;\r
+    bool ShowPassword;\r
+    UStringVector Paths;\r
+\r
+    void Save() const;\r
+    void Load();\r
+  };\r
+}\r
+\r
+namespace NCompression\r
+{\r
+  struct CFormatOptions\r
+  {\r
+    UInt32 Level;\r
+    UInt32 Dictionary;\r
+    UInt32 Order;\r
+    UInt32 BlockLogSize;\r
+    UInt32 NumThreads;\r
+    \r
+    CSysString FormatID;\r
+    UString Method;\r
+    UString Options;\r
+    UString EncryptionMethod;\r
+\r
+    void ResetForLevelChange()\r
+    {\r
+      BlockLogSize = NumThreads = Level = Dictionary = Order = UInt32(-1);\r
+      Method.Empty();\r
+      // Options.Empty();\r
+      // EncryptionMethod.Empty();\r
+    }\r
+    CFormatOptions() { ResetForLevelChange(); }\r
+  };\r
+\r
+  struct CInfo\r
+  {\r
+    UInt32 Level;\r
+    bool ShowPassword;\r
+    bool EncryptHeaders;\r
+    UString ArcType;\r
+    UStringVector ArcPaths;\r
+\r
+    CObjectVector<CFormatOptions> Formats;\r
+\r
+    void Save() const;\r
+    void Load();\r
+  };\r
+}\r
+\r
+namespace NWorkDir\r
+{\r
+  namespace NMode\r
+  {\r
+    enum EEnum\r
+    {\r
+      kSystem,\r
+      kCurrent,\r
+      kSpecified\r
+    };\r
+  }\r
+  struct CInfo\r
+  {\r
+    NMode::EEnum Mode;\r
+    UString Path;\r
+    bool ForRemovableOnly;\r
+\r
+    void SetForRemovableOnlyDefault() { ForRemovableOnly = true; }\r
+    void SetDefault()\r
+    {\r
+      Mode = NMode::kSystem;\r
+      Path.Empty();\r
+      SetForRemovableOnlyDefault();\r
+    }\r
+\r
+    void Save() const;\r
+    void Load();\r
+  };\r
+}\r
+\r
+\r
+struct CContextMenuInfo\r
+{\r
+  bool Cascaded;\r
+  UInt32 Flags;\r
+\r
+  void Save() const;\r
+  void Load();\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/BenchCon.cpp b/CPP/7zip/UI/Console/BenchCon.cpp
new file mode 100755 (executable)
index 0000000..a31d8e0
--- /dev/null
@@ -0,0 +1,297 @@
+// BenchCon.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../../Common/IntToString.h"\r
+#include "../../../Common/MyCom.h"\r
+\r
+#if !defined(_7ZIP_ST) || defined(_WIN32)\r
+#include "../../../Windows/System.h"\r
+#endif\r
+\r
+#include "../Common/Bench.h"\r
+\r
+#include "BenchCon.h"\r
+#include "ConsoleClose.h"\r
+\r
+struct CTotalBenchRes\r
+{\r
+  UInt64 NumIterations;\r
+  UInt64 Rating;\r
+  UInt64 Usage;\r
+  UInt64 RPU;\r
+  void Init() { NumIterations = 0; Rating = 0; Usage = 0; RPU = 0; }\r
+  void Normalize()\r
+  {\r
+    if (NumIterations == 0)\r
+      return;\r
+    Rating /= NumIterations;\r
+    Usage /= NumIterations;\r
+    RPU /= NumIterations;\r
+    NumIterations = 1;\r
+  }\r
+  void SetMid(const CTotalBenchRes &r1, const CTotalBenchRes &r2)\r
+  {\r
+    Rating = (r1.Rating + r2.Rating) / 2;\r
+    Usage = (r1.Usage + r2.Usage) / 2;\r
+    RPU = (r1.RPU + r2.RPU) / 2;\r
+    NumIterations = (r1.NumIterations + r2.NumIterations) / 2;\r
+  }\r
+};\r
+\r
+struct CBenchCallback: public IBenchCallback\r
+{\r
+  CTotalBenchRes EncodeRes;\r
+  CTotalBenchRes DecodeRes;\r
+  FILE *f;\r
+  void Init() { EncodeRes.Init(); DecodeRes.Init(); }\r
+  void Normalize() { EncodeRes.Normalize(); DecodeRes.Normalize(); }\r
+  UInt32 dictionarySize;\r
+  HRESULT SetEncodeResult(const CBenchInfo &info, bool final);\r
+  HRESULT SetDecodeResult(const CBenchInfo &info, bool final);\r
+};\r
+\r
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)\r
+{\r
+  while (v1 > 1000000)\r
+  {\r
+    v1 >>= 1;\r
+    v2 >>= 1;\r
+  }\r
+}\r
+\r
+static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)\r
+{\r
+  UInt64 elTime = elapsedTime;\r
+  NormalizeVals(freq, elTime);\r
+  if (elTime == 0)\r
+    elTime = 1;\r
+  return value * freq / elTime;\r
+}\r
+\r
+static void PrintNumber(FILE *f, UInt64 value, int size)\r
+{\r
+  char s[32];\r
+  ConvertUInt64ToString(value, s);\r
+  fprintf(f, " ");\r
+  for (int len = (int)strlen(s); len < size; len++)\r
+    fprintf(f, " ");\r
+  fputs(s, f);\r
+}\r
+\r
+static void PrintRating(FILE *f, UInt64 rating)\r
+{\r
+  PrintNumber(f, rating / 1000000, 6);\r
+}\r
+\r
+static void PrintResults(FILE *f, UInt64 usage, UInt64 rpu, UInt64 rating)\r
+{\r
+  PrintNumber(f, (usage + 5000) / 10000, 5);\r
+  PrintRating(f, rpu);\r
+  PrintRating(f, rating);\r
+}\r
+\r
+\r
+static void PrintResults(FILE *f, const CBenchInfo &info, UInt64 rating, CTotalBenchRes &res)\r
+{\r
+  UInt64 speed = MyMultDiv64(info.UnpackSize, info.GlobalTime, info.GlobalFreq);\r
+  PrintNumber(f, speed / 1024, 7);\r
+  UInt64 usage = GetUsage(info);\r
+  UInt64 rpu = GetRatingPerUsage(info, rating);\r
+  PrintResults(f, usage, rpu, rating);\r
+  res.NumIterations++;\r
+  res.RPU += rpu;\r
+  res.Rating += rating;\r
+  res.Usage += usage;\r
+}\r
+\r
+static void PrintTotals(FILE *f, const CTotalBenchRes &res)\r
+{\r
+  fprintf(f, "       ");\r
+  PrintResults(f, res.Usage, res.RPU, res.Rating);\r
+}\r
+\r
+\r
+HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final)\r
+{\r
+  if (NConsoleClose::TestBreakSignal())\r
+    return E_ABORT;\r
+  if (final)\r
+  {\r
+    UInt64 rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, info.UnpackSize);\r
+    PrintResults(f, info, rating, EncodeRes);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+static const char *kSep = "  | ";\r
+\r
+\r
+HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)\r
+{\r
+  if (NConsoleClose::TestBreakSignal())\r
+    return E_ABORT;\r
+  if (final)\r
+  {\r
+    UInt64 rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);\r
+    fputs(kSep, f);\r
+    CBenchInfo info2 = info;\r
+    info2.UnpackSize *= info2.NumIterations;\r
+    info2.PackSize *= info2.NumIterations;\r
+    info2.NumIterations = 1;\r
+    PrintResults(f, info2, rating, DecodeRes);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+static void PrintRequirements(FILE *f, const char *sizeString, UInt64 size, const char *threadsString, UInt32 numThreads)\r
+{\r
+  fprintf(f, "\nRAM %s ", sizeString);\r
+  PrintNumber(f, (size >> 20), 5);\r
+  fprintf(f, " MB,  # %s %3d", threadsString, (unsigned int)numThreads);\r
+}\r
+\r
+HRESULT LzmaBenchCon(\r
+  DECL_EXTERNAL_CODECS_LOC_VARS\r
+  FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)\r
+{\r
+  if (!CrcInternalTest())\r
+    return S_FALSE;\r
+  #ifndef _7ZIP_ST\r
+  UInt64 ramSize = NWindows::NSystem::GetRamSize();  //\r
+  UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();\r
+  PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);\r
+  if (numThreads == (UInt32)-1)\r
+    numThreads = numCPUs;\r
+  if (numThreads > 1)\r
+    numThreads &= ~1;\r
+  if (dictionary == (UInt32)-1)\r
+  {\r
+    int dicSizeLog;\r
+    for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)\r
+      if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)\r
+        break;\r
+    dictionary = (1 << dicSizeLog);\r
+  }\r
+  #else\r
+  if (dictionary == (UInt32)-1)\r
+    dictionary = (1 << 22);\r
+  numThreads = 1;\r
+  #endif\r
+\r
+  PrintRequirements(f, "usage:", GetBenchMemoryUsage(numThreads, dictionary), "Benchmark threads:   ", numThreads);\r
+\r
+  CBenchCallback callback;\r
+  callback.Init();\r
+  callback.f = f;\r
+  \r
+  fprintf(f, "\n\nDict        Compressing          |        Decompressing\n   ");\r
+  int j;\r
+  for (j = 0; j < 2; j++)\r
+  {\r
+    fprintf(f, "   Speed Usage    R/U Rating");\r
+    if (j == 0)\r
+      fputs(kSep, f);\r
+  }\r
+  fprintf(f, "\n   ");\r
+  for (j = 0; j < 2; j++)\r
+  {\r
+    fprintf(f, "    KB/s     %%   MIPS   MIPS");\r
+    if (j == 0)\r
+      fputs(kSep, f);\r
+  }\r
+  fprintf(f, "\n\n");\r
+  for (UInt32 i = 0; i < numIterations; i++)\r
+  {\r
+    const int kStartDicLog = 22;\r
+    int pow = (dictionary < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;\r
+    while (((UInt32)1 << pow) > dictionary)\r
+      pow--;\r
+    for (; ((UInt32)1 << pow) <= dictionary; pow++)\r
+    {\r
+      fprintf(f, "%2d:", pow);\r
+      callback.dictionarySize = (UInt32)1 << pow;\r
+      HRESULT res = LzmaBench(\r
+        EXTERNAL_CODECS_LOC_VARS\r
+        numThreads, callback.dictionarySize, &callback);\r
+      fprintf(f, "\n");\r
+      RINOK(res);\r
+    }\r
+  }\r
+  callback.Normalize();\r
+  fprintf(f, "----------------------------------------------------------------\nAvr:");\r
+  PrintTotals(f, callback.EncodeRes);\r
+  fprintf(f, "     ");\r
+  PrintTotals(f, callback.DecodeRes);\r
+  fprintf(f, "\nTot:");\r
+  CTotalBenchRes midRes;\r
+  midRes.SetMid(callback.EncodeRes, callback.DecodeRes);\r
+  PrintTotals(f, midRes);\r
+  fprintf(f, "\n");\r
+  return S_OK;\r
+}\r
+\r
+struct CTempValues\r
+{\r
+  UInt64 *Values;\r
+  CTempValues(UInt32 num) { Values = new UInt64[num]; }\r
+  ~CTempValues() { delete []Values; }\r
+};\r
+\r
+HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)\r
+{\r
+  if (!CrcInternalTest())\r
+    return S_FALSE;\r
+\r
+  #ifndef _7ZIP_ST\r
+  UInt64 ramSize = NWindows::NSystem::GetRamSize();\r
+  UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();\r
+  PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);\r
+  if (numThreads == (UInt32)-1)\r
+    numThreads = numCPUs;\r
+  #else\r
+  numThreads = 1;\r
+  #endif\r
+  if (dictionary == (UInt32)-1)\r
+    dictionary = (1 << 24);\r
+\r
+  CTempValues speedTotals(numThreads);\r
+  fprintf(f, "\n\nSize");\r
+  for (UInt32 ti = 0; ti < numThreads; ti++)\r
+  {\r
+    fprintf(f, " %5d", ti + 1);\r
+    speedTotals.Values[ti] = 0;\r
+  }\r
+  fprintf(f, "\n\n");\r
+\r
+  UInt64 numSteps = 0;\r
+  for (UInt32 i = 0; i < numIterations; i++)\r
+  {\r
+    for (int pow = 10; pow < 32; pow++)\r
+    {\r
+      UInt32 bufSize = (UInt32)1 << pow;\r
+      if (bufSize > dictionary)\r
+        break;\r
+      fprintf(f, "%2d: ", pow);\r
+      UInt64 speed;\r
+      for (UInt32 ti = 0; ti < numThreads; ti++)\r
+      {\r
+        if (NConsoleClose::TestBreakSignal())\r
+          return E_ABORT;\r
+        RINOK(CrcBench(ti + 1, bufSize, speed));\r
+        PrintNumber(f, (speed >> 20), 5);\r
+        speedTotals.Values[ti] += speed;\r
+      }\r
+      fprintf(f, "\n");\r
+      numSteps++;\r
+    }\r
+  }\r
+  if (numSteps != 0)\r
+  {\r
+    fprintf(f, "\nAvg:");\r
+    for (UInt32 ti = 0; ti < numThreads; ti++)\r
+      PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), 5);\r
+    fprintf(f, "\n");\r
+  }\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/UI/Console/BenchCon.h b/CPP/7zip/UI/Console/BenchCon.h
new file mode 100755 (executable)
index 0000000..c5eafbf
--- /dev/null
@@ -0,0 +1,16 @@
+// BenchCon.h\r
+\r
+#ifndef __BENCH_CON_H\r
+#define __BENCH_CON_H\r
+\r
+#include <stdio.h>\r
+\r
+#include "../../Common/CreateCoder.h"\r
+\r
+HRESULT LzmaBenchCon(\r
+    DECL_EXTERNAL_CODECS_LOC_VARS\r
+    FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);\r
+\r
+HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/ConsoleClose.cpp b/CPP/7zip/UI/Console/ConsoleClose.cpp
new file mode 100755 (executable)
index 0000000..9fbad17
--- /dev/null
@@ -0,0 +1,73 @@
+// ConsoleClose.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "ConsoleClose.h"\r
+\r
+static int g_BreakCounter = 0;\r
+static const int kBreakAbortThreshold = 2;\r
+\r
+namespace NConsoleClose {\r
+\r
+#if !defined(UNDER_CE) && defined(_WIN32)\r
+static BOOL WINAPI HandlerRoutine(DWORD ctrlType)\r
+{\r
+  if (ctrlType == CTRL_LOGOFF_EVENT)\r
+  {\r
+    // printf("\nCTRL_LOGOFF_EVENT\n");\r
+    return TRUE;\r
+  }\r
+\r
+  g_BreakCounter++;\r
+  if (g_BreakCounter < kBreakAbortThreshold)\r
+    return TRUE;\r
+  return FALSE;\r
+  /*\r
+  switch(ctrlType)\r
+  {\r
+    case CTRL_C_EVENT:\r
+    case CTRL_BREAK_EVENT:\r
+      if (g_BreakCounter < kBreakAbortThreshold)\r
+      return TRUE;\r
+  }\r
+  return FALSE;\r
+  */\r
+}\r
+#endif\r
+\r
+bool TestBreakSignal()\r
+{\r
+  #ifdef UNDER_CE\r
+  return false;\r
+  #else\r
+  /*\r
+  if (g_BreakCounter > 0)\r
+    return true;\r
+  */\r
+  return (g_BreakCounter > 0);\r
+  #endif\r
+}\r
+\r
+void CheckCtrlBreak()\r
+{\r
+  if (TestBreakSignal())\r
+    throw CCtrlBreakException();\r
+}\r
+\r
+CCtrlHandlerSetter::CCtrlHandlerSetter()\r
+{\r
+  #if !defined(UNDER_CE) && defined(_WIN32)\r
+  if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE))\r
+    throw "SetConsoleCtrlHandler fails";\r
+  #endif\r
+}\r
+\r
+CCtrlHandlerSetter::~CCtrlHandlerSetter()\r
+{\r
+  #if !defined(UNDER_CE) && defined(_WIN32)\r
+  if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE))\r
+    throw "SetConsoleCtrlHandler fails";\r
+  #endif\r
+}\r
+\r
+}\r
diff --git a/CPP/7zip/UI/Console/ConsoleClose.h b/CPP/7zip/UI/Console/ConsoleClose.h
new file mode 100755 (executable)
index 0000000..7101018
--- /dev/null
@@ -0,0 +1,24 @@
+// ConsoleCloseUtils.h\r
+\r
+#ifndef __CONSOLECLOSEUTILS_H\r
+#define __CONSOLECLOSEUTILS_H\r
+\r
+namespace NConsoleClose {\r
+\r
+bool TestBreakSignal();\r
+\r
+class CCtrlHandlerSetter\r
+{\r
+public:\r
+  CCtrlHandlerSetter();\r
+  virtual ~CCtrlHandlerSetter();\r
+};\r
+\r
+class CCtrlBreakException\r
+{};\r
+\r
+void CheckCtrlBreak();\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
new file mode 100755 (executable)
index 0000000..278b069
--- /dev/null
@@ -0,0 +1,228 @@
+// ExtractCallbackConsole.h\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "ExtractCallbackConsole.h"\r
+#include "UserInputUtils.h"\r
+#include "ConsoleClose.h"\r
+\r
+#include "Common/Wildcard.h"\r
+\r
+#include "Windows/FileDir.h"\r
+#include "Windows/FileFind.h"\r
+#include "Windows/Time.h"\r
+#include "Windows/Defs.h"\r
+#include "Windows/PropVariant.h"\r
+#include "Windows/Error.h"\r
+#include "Windows/PropVariantConversions.h"\r
+\r
+#include "../../Common/FilePathAutoRename.h"\r
+\r
+#include "../Common/ExtractingFilePath.h"\r
+\r
+using namespace NWindows;\r
+using namespace NFile;\r
+using namespace NDirectory;\r
+\r
+static const char *kTestString    =  "Testing     ";\r
+static const char *kExtractString =  "Extracting  ";\r
+static const char *kSkipString   =  "Skipping    ";\r
+\r
+// static const char *kCantAutoRename = "can not create file with auto name\n";\r
+// static const char *kCantRenameFile = "can not rename existing file\n";\r
+// static const char *kCantDeleteOutputFile = "can not delete output file ";\r
+static const char *kError = "ERROR: ";\r
+static const char *kMemoryExceptionMessage = "Can't allocate required memory!";\r
+\r
+static const char *kProcessing = "Processing archive: ";\r
+static const char *kEverythingIsOk = "Everything is Ok";\r
+static const char *kNoFiles = "No files to process";\r
+\r
+static const char *kUnsupportedMethod = "Unsupported Method";\r
+static const char *kCrcFailed = "CRC Failed";\r
+static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";\r
+static const char *kDataError = "Data Error";\r
+static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";\r
+static const char *kUnknownError = "Unknown Error";\r
+\r
+STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)\r
+{\r
+  if (NConsoleClose::TestBreakSignal())\r
+    return E_ABORT;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)\r
+{\r
+  if (NConsoleClose::TestBreakSignal())\r
+    return E_ABORT;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CExtractCallbackConsole::AskOverwrite(\r
+    const wchar_t *existName, const FILETIME *, const UInt64 *,\r
+    const wchar_t *newName, const FILETIME *, const UInt64 *,\r
+    Int32 *answer)\r
+{\r
+  (*OutStream) << "file " << existName <<\r
+    "\nalready exists. Overwrite with " << endl;\r
+  (*OutStream) << newName;\r
+  \r
+  NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);\r
+  \r
+  switch(overwriteAnswer)\r
+  {\r
+    case NUserAnswerMode::kQuit:  return E_ABORT;\r
+    case NUserAnswerMode::kNo:     *answer = NOverwriteAnswer::kNo; break;\r
+    case NUserAnswerMode::kNoAll:  *answer = NOverwriteAnswer::kNoToAll; break;\r
+    case NUserAnswerMode::kYesAll: *answer = NOverwriteAnswer::kYesToAll; break;\r
+    case NUserAnswerMode::kYes:    *answer = NOverwriteAnswer::kYes; break;\r
+    case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break;\r
+    default: return E_FAIL;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position)\r
+{\r
+  switch (askExtractMode)\r
+  {\r
+    case NArchive::NExtract::NAskMode::kExtract: (*OutStream) << kExtractString; break;\r
+    case NArchive::NExtract::NAskMode::kTest:    (*OutStream) << kTestString; break;\r
+    case NArchive::NExtract::NAskMode::kSkip:    (*OutStream) << kSkipString; break;\r
+  };\r
+  (*OutStream) << name;\r
+  if (position != 0)\r
+    (*OutStream) << " <" << *position << ">";\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)\r
+{\r
+  (*OutStream) << message << endl;\r
+  NumFileErrorsInCurrentArchive++;\r
+  NumFileErrors++;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)\r
+{\r
+  switch(operationResult)\r
+  {\r
+    case NArchive::NExtract::NOperationResult::kOK:\r
+      break;\r
+    default:\r
+    {\r
+      NumFileErrorsInCurrentArchive++;\r
+      NumFileErrors++;\r
+      (*OutStream) << "     ";\r
+      switch(operationResult)\r
+      {\r
+        case NArchive::NExtract::NOperationResult::kUnSupportedMethod:\r
+          (*OutStream) << kUnsupportedMethod;\r
+          break;\r
+        case NArchive::NExtract::NOperationResult::kCRCError:\r
+          (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed);\r
+          break;\r
+        case NArchive::NExtract::NOperationResult::kDataError:\r
+          (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError);\r
+          break;\r
+        default:\r
+          (*OutStream) << kUnknownError;\r
+      }\r
+    }\r
+  }\r
+  (*OutStream) << endl;\r
+  return S_OK;\r
+}\r
+\r
+#ifndef _NO_CRYPTO\r
+\r
+HRESULT CExtractCallbackConsole::SetPassword(const UString &password)\r
+{\r
+  PasswordIsDefined = true;\r
+  Password = password;\r
+  return S_OK;\r
+}\r
+\r
+STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)\r
+{\r
+  if (!PasswordIsDefined)\r
+  {\r
+    Password = GetPassword(OutStream);\r
+    PasswordIsDefined = true;\r
+  }\r
+  return StringToBstr(Password, password);\r
+}\r
+\r
+#endif\r
+\r
+HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)\r
+{\r
+  NumArchives++;\r
+  NumFileErrorsInCurrentArchive = 0;\r
+  (*OutStream) << endl << kProcessing << name << endl;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)\r
+{\r
+  (*OutStream) << endl;\r
+  if (result != S_OK)\r
+  {\r
+    (*OutStream) << "Error: ";\r
+    if (result == S_FALSE)\r
+    {\r
+      (*OutStream) << (encrypted ?\r
+        "Can not open encrypted archive. Wrong password?" :\r
+        "Can not open file as archive");\r
+    }\r
+    else\r
+    {\r
+      if (result == E_OUTOFMEMORY)\r
+        (*OutStream) << "Can't allocate required memory";\r
+      else\r
+        (*OutStream) << NError::MyFormatMessage(result);\r
+    }\r
+    (*OutStream) << endl;\r
+    NumArchiveErrors++;\r
+  }\r
+  return S_OK;\r
+}\r
+  \r
+HRESULT CExtractCallbackConsole::ThereAreNoFiles()\r
+{\r
+  (*OutStream) << endl << kNoFiles << endl;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)\r
+{\r
+  if (result == S_OK)\r
+  {\r
+    (*OutStream) << endl;\r
+    if (NumFileErrorsInCurrentArchive == 0)\r
+      (*OutStream) << kEverythingIsOk << endl;\r
+    else\r
+    {\r
+      NumArchiveErrors++;\r
+      (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;\r
+    }\r
+  }\r
+  if (result == S_OK)\r
+    return result;\r
+  NumArchiveErrors++;\r
+  if (result == E_ABORT || result == ERROR_DISK_FULL)\r
+    return result;\r
+  (*OutStream) << endl << kError;\r
+  if (result == E_OUTOFMEMORY)\r
+    (*OutStream) << kMemoryExceptionMessage;\r
+  else\r
+  {\r
+    UString message;\r
+    NError::MyFormatMessage(result, message);\r
+    (*OutStream) << message;\r
+  }\r
+  (*OutStream) << endl;\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/CPP/7zip/UI/Console/ExtractCallbackConsole.h
new file mode 100755 (executable)
index 0000000..7086527
--- /dev/null
@@ -0,0 +1,73 @@
+// ExtractCallbackConsole.h\r
+\r
+#ifndef __EXTRACTCALLBACKCONSOLE_H\r
+#define __EXTRACTCALLBACKCONSOLE_H\r
+\r
+#include "Common/MyString.h"\r
+#include "Common/StdOutStream.h"\r
+#include "../../Common/FileStreams.h"\r
+#include "../../IPassword.h"\r
+#include "../../Archive/IArchive.h"\r
+#include "../Common/ArchiveExtractCallback.h"\r
+\r
+class CExtractCallbackConsole:\r
+  public IExtractCallbackUI,\r
+  #ifndef _NO_CRYPTO\r
+  public ICryptoGetTextPassword,\r
+  #endif\r
+  public CMyUnknownImp\r
+{\r
+public:\r
+  MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback)\r
+  #ifndef _NO_CRYPTO\r
+  MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)\r
+  #endif\r
+  MY_QUERYINTERFACE_END\r
+  MY_ADDREF_RELEASE\r
+\r
+  STDMETHOD(SetTotal)(UInt64 total);\r
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue);\r
+\r
+  // IFolderArchiveExtractCallback\r
+  STDMETHOD(AskOverwrite)(\r
+      const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,\r
+      const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,\r
+      Int32 *answer);\r
+  STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position);\r
+\r
+  STDMETHOD(MessageError)(const wchar_t *message);\r
+  STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);\r
+\r
+  HRESULT BeforeOpen(const wchar_t *name);\r
+  HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);\r
+  HRESULT ThereAreNoFiles();\r
+  HRESULT ExtractResult(HRESULT result);\r
+\r
\r
+  #ifndef _NO_CRYPTO\r
+  HRESULT SetPassword(const UString &password);\r
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);\r
+\r
+  bool PasswordIsDefined;\r
+  UString Password;\r
+\r
+  #endif\r
+  \r
+  UInt64 NumArchives;\r
+  UInt64 NumArchiveErrors;\r
+  UInt64 NumFileErrors;\r
+  UInt64 NumFileErrorsInCurrentArchive;\r
+\r
+  CStdOutStream *OutStream;\r
+\r
+  void Init()\r
+  {\r
+    NumArchives = 0;\r
+    NumArchiveErrors = 0;\r
+    NumFileErrors = 0;\r
+    NumFileErrorsInCurrentArchive = 0;\r
+  }\r
+\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp
new file mode 100755 (executable)
index 0000000..298adbd
--- /dev/null
@@ -0,0 +1,654 @@
+// List.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/IntToString.h"\r
+#include "Common/MyCom.h"\r
+#include "Common/StdOutStream.h"\r
+#include "Common/StringConvert.h"\r
+\r
+#include "Windows/Error.h"\r
+#include "Windows/FileDir.h"\r
+#include "Windows/PropVariant.h"\r
+#include "Windows/PropVariantConversions.h"\r
+\r
+#include "../../Archive/IArchive.h"\r
+\r
+#include "../Common/OpenArchive.h"\r
+#include "../Common/PropIDUtils.h"\r
+\r
+#include "ConsoleClose.h"\r
+#include "List.h"\r
+#include "OpenCallbackConsole.h"\r
+\r
+using namespace NWindows;\r
+\r
+struct CPropIdToName\r
+{\r
+  PROPID PropID;\r
+  const wchar_t *Name;\r
+};\r
+\r
+static const CPropIdToName kPropIdToName[] =\r
+{\r
+  { kpidPath, L"Path" },\r
+  { kpidName, L"Name" },\r
+  { kpidIsDir, L"Folder" },\r
+  { kpidSize, L"Size" },\r
+  { kpidPackSize, L"Packed Size" },\r
+  { kpidAttrib, L"Attributes" },\r
+  { kpidCTime, L"Created" },\r
+  { kpidATime, L"Accessed" },\r
+  { kpidMTime, L"Modified" },\r
+  { kpidSolid, L"Solid" },\r
+  { kpidCommented, L"Commented" },\r
+  { kpidEncrypted, L"Encrypted" },\r
+  { kpidSplitBefore, L"Split Before" },\r
+  { kpidSplitAfter, L"Split After" },\r
+  { kpidDictionarySize, L"Dictionary Size" },\r
+  { kpidCRC, L"CRC" },\r
+  { kpidType, L"Type" },\r
+  { kpidIsAnti, L"Anti" },\r
+  { kpidMethod, L"Method" },\r
+  { kpidHostOS, L"Host OS" },\r
+  { kpidFileSystem, L"File System" },\r
+  { kpidUser, L"User" },\r
+  { kpidGroup, L"Group" },\r
+  { kpidBlock, L"Block" },\r
+  { kpidComment, L"Comment" },\r
+  { kpidPosition, L"Position" },\r
+  { kpidPrefix, L"Prefix" },\r
+  { kpidNumSubDirs, L"Folders" },\r
+  { kpidNumSubFiles, L"Files" },\r
+  { kpidUnpackVer, L"Version" },\r
+  { kpidVolume, L"Volume" },\r
+  { kpidIsVolume, L"Multivolume" },\r
+  { kpidOffset, L"Offset" },\r
+  { kpidLinks, L"Links" },\r
+  { kpidNumBlocks, L"Blocks" },\r
+  { kpidNumVolumes, L"Volumes" },\r
+\r
+  { kpidBit64, L"64-bit" },\r
+  { kpidBigEndian, L"Big-endian" },\r
+  { kpidCpu, L"CPU" },\r
+  { kpidPhySize, L"Physical Size" },\r
+  { kpidHeadersSize, L"Headers Size" },\r
+  { kpidChecksum, L"Checksum" },\r
+  { kpidCharacts, L"Characteristics" },\r
+  { kpidVa, L"Virtual Address" },\r
+  { kpidId, L"ID" },\r
+  { kpidShortName, L"Short Name" },\r
+  { kpidCreatorApp, L"Creator Application"},\r
+  { kpidSectorSize, L"Sector Size" },\r
+  { kpidPosixAttrib, L"Mode" },\r
+  { kpidLink, L"Link" },\r
+  { kpidError, L"Error" },\r
+\r
+  { kpidTotalSize, L"Total Size" },\r
+  { kpidFreeSpace, L"Free Space" },\r
+  { kpidClusterSize, L"Cluster Size" },\r
+  { kpidVolumeName, L"Label" }\r
+};\r
+\r
+static const char kEmptyAttribChar = '.';\r
+\r
+static const char *kListing = "Listing archive: ";\r
+static const wchar_t *kFilesMessage = L"files";\r
+static const wchar_t *kDirsMessage = L"folders";\r
+\r
+static void GetAttribString(DWORD wa, bool isDir, char *s)\r
+{\r
+  s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar;\r
+  s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar;\r
+  s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar;\r
+  s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar;\r
+  s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar;\r
+  s[5] = '\0';\r
+}\r
+\r
+enum EAdjustment\r
+{\r
+  kLeft,\r
+  kCenter,\r
+  kRight\r
+};\r
+\r
+struct CFieldInfo\r
+{\r
+  PROPID PropID;\r
+  UString Name;\r
+  EAdjustment TitleAdjustment;\r
+  EAdjustment TextAdjustment;\r
+  int PrefixSpacesWidth;\r
+  int Width;\r
+};\r
+\r
+struct CFieldInfoInit\r
+{\r
+  PROPID PropID;\r
+  const wchar_t *Name;\r
+  EAdjustment TitleAdjustment;\r
+  EAdjustment TextAdjustment;\r
+  int PrefixSpacesWidth;\r
+  int Width;\r
+};\r
+\r
+static CFieldInfoInit kStandardFieldTable[] =\r
+{\r
+  { kpidMTime, L"   Date      Time", kLeft, kLeft, 0, 19 },\r
+  { kpidAttrib, L"Attr", kRight, kCenter, 1, 5 },\r
+  { kpidSize, L"Size", kRight, kRight, 1, 12 },\r
+  { kpidPackSize, L"Compressed", kRight, kRight, 1, 12 },\r
+  { kpidPath, L"Name", kLeft, kLeft, 2, 24 }\r
+};\r
+\r
+static void PrintSpaces(int numSpaces)\r
+{\r
+  for (int i = 0; i < numSpaces; i++)\r
+    g_StdOut << ' ';\r
+}\r
+\r
+static void PrintString(EAdjustment adjustment, int width, const UString &textString)\r
+{\r
+  const int numSpaces = width - textString.Length();\r
+  int numLeftSpaces = 0;\r
+  switch (adjustment)\r
+  {\r
+    case kLeft:\r
+      numLeftSpaces = 0;\r
+      break;\r
+    case kCenter:\r
+      numLeftSpaces = numSpaces / 2;\r
+      break;\r
+    case kRight:\r
+      numLeftSpaces = numSpaces;\r
+      break;\r
+  }\r
+  PrintSpaces(numLeftSpaces);\r
+  g_StdOut << textString;\r
+  PrintSpaces(numSpaces - numLeftSpaces);\r
+}\r
+\r
+class CFieldPrinter\r
+{\r
+  CObjectVector<CFieldInfo> _fields;\r
+public:\r
+  void Clear() { _fields.Clear(); }\r
+  void Init(const CFieldInfoInit *standardFieldTable, int numItems);\r
+  HRESULT Init(IInArchive *archive);\r
+  void PrintTitle();\r
+  void PrintTitleLines();\r
+  HRESULT PrintItemInfo(const CArc &arc, UInt32 index, bool techMode);\r
+  HRESULT PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,\r
+      const UInt64 *size, const UInt64 *compressedSize);\r
+};\r
+\r
+void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)\r
+{\r
+  Clear();\r
+  for (int i = 0; i < numItems; i++)\r
+  {\r
+    CFieldInfo fieldInfo;\r
+    const CFieldInfoInit &fieldInfoInit = standardFieldTable[i];\r
+    fieldInfo.PropID = fieldInfoInit.PropID;\r
+    fieldInfo.Name = fieldInfoInit.Name;\r
+    fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment;\r
+    fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment;\r
+    fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth;\r
+    fieldInfo.Width = fieldInfoInit.Width;\r
+    _fields.Add(fieldInfo);\r
+  }\r
+}\r
+\r
+static UString GetPropName(PROPID propID, BSTR name)\r
+{\r
+  for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)\r
+  {\r
+    const CPropIdToName &propIdToName = kPropIdToName[i];\r
+    if (propIdToName.PropID == propID)\r
+      return propIdToName.Name;\r
+  }\r
+  if (name)\r
+    return name;\r
+  wchar_t s[16];\r
+  ConvertUInt32ToString(propID, s);\r
+  return s;\r
+}\r
+\r
+HRESULT CFieldPrinter::Init(IInArchive *archive)\r
+{\r
+  Clear();\r
+  UInt32 numProps;\r
+  RINOK(archive->GetNumberOfProperties(&numProps));\r
+  for (UInt32 i = 0; i < numProps; i++)\r
+  {\r
+    CMyComBSTR name;\r
+    PROPID propID;\r
+    VARTYPE vt;\r
+    RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));\r
+    CFieldInfo fieldInfo;\r
+    fieldInfo.PropID = propID;\r
+    fieldInfo.Name = GetPropName(propID, name);\r
+    _fields.Add(fieldInfo);\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+void CFieldPrinter::PrintTitle()\r
+{\r
+  for (int i = 0; i < _fields.Size(); i++)\r
+  {\r
+    const CFieldInfo &fieldInfo = _fields[i];\r
+    PrintSpaces(fieldInfo.PrefixSpacesWidth);\r
+    PrintString(fieldInfo.TitleAdjustment,\r
+      ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);\r
+  }\r
+}\r
+\r
+void CFieldPrinter::PrintTitleLines()\r
+{\r
+  for (int i = 0; i < _fields.Size(); i++)\r
+  {\r
+    const CFieldInfo &fieldInfo = _fields[i];\r
+    PrintSpaces(fieldInfo.PrefixSpacesWidth);\r
+    for (int i = 0; i < fieldInfo.Width; i++)\r
+      g_StdOut << '-';\r
+  }\r
+}\r
+\r
+\r
+static BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)\r
+{\r
+  return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);\r
+}\r
+\r
+static const char *kEmptyTimeString = "                   ";\r
+static void PrintTime(const NCOM::CPropVariant &prop)\r
+{\r
+  if (prop.vt != VT_FILETIME)\r
+    throw "incorrect item";\r
+  if (IsFileTimeZero(&prop.filetime))\r
+    g_StdOut << kEmptyTimeString;\r
+  else\r
+  {\r
+    FILETIME localFileTime;\r
+    if (!FileTimeToLocalFileTime(&prop.filetime, &localFileTime))\r
+      throw "FileTimeToLocalFileTime error";\r
+    char s[32];\r
+    if (ConvertFileTimeToString(localFileTime, s, true, true))\r
+      g_StdOut << s;\r
+    else\r
+      g_StdOut << kEmptyTimeString;\r
+  }\r
+}\r
+\r
+HRESULT CFieldPrinter::PrintItemInfo(const CArc &arc, UInt32 index, bool techMode)\r
+{\r
+  /*\r
+  if (techMode)\r
+  {\r
+    g_StdOut << "Index = ";\r
+    g_StdOut << (UInt64)index;\r
+    g_StdOut << endl;\r
+  }\r
+  */\r
+  for (int i = 0; i < _fields.Size(); i++)\r
+  {\r
+    const CFieldInfo &fieldInfo = _fields[i];\r
+    if (!techMode)\r
+      PrintSpaces(fieldInfo.PrefixSpacesWidth);\r
+\r
+    NCOM::CPropVariant prop;\r
+    if (fieldInfo.PropID == kpidPath)\r
+    {\r
+      UString s;\r
+      RINOK(arc.GetItemPath(index, s));\r
+      prop = s;\r
+    }\r
+    else\r
+    {\r
+      RINOK(arc.Archive->GetProperty(index, fieldInfo.PropID, &prop));\r
+    }\r
+    if (techMode)\r
+    {\r
+      g_StdOut << fieldInfo.Name << " = ";\r
+    }\r
+    int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;\r
+    if (fieldInfo.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4))\r
+    {\r
+      UInt32 attrib = (prop.vt == VT_EMPTY) ? 0 : prop.ulVal;\r
+      bool isFolder;\r
+      RINOK(IsArchiveItemFolder(arc.Archive, index, isFolder));\r
+      char s[8];\r
+      GetAttribString(attrib, isFolder, s);\r
+      g_StdOut << s;\r
+    }\r
+    else if (prop.vt == VT_EMPTY)\r
+    {\r
+      if (!techMode)\r
+        PrintSpaces(width);\r
+    }\r
+    else if (fieldInfo.PropID == kpidMTime)\r
+    {\r
+      PrintTime(prop);\r
+    }\r
+    else if (prop.vt == VT_BSTR)\r
+    {\r
+      if (techMode)\r
+        g_StdOut << prop.bstrVal;\r
+      else\r
+        PrintString(fieldInfo.TextAdjustment, width, prop.bstrVal);\r
+    }\r
+    else\r
+    {\r
+      UString s = ConvertPropertyToString(prop, fieldInfo.PropID);\r
+      s.Replace(wchar_t(0xA), L' ');\r
+      s.Replace(wchar_t(0xD), L' ');\r
+\r
+      if (techMode)\r
+        g_StdOut << s;\r
+      else\r
+        PrintString(fieldInfo.TextAdjustment, width, s);\r
+    }\r
+    if (techMode)\r
+      g_StdOut << endl;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+static void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value)\r
+{\r
+  wchar_t textString[32] = { 0 };\r
+  if (value != NULL)\r
+    ConvertUInt64ToString(*value, textString);\r
+  PrintString(adjustment, width, textString);\r
+}\r
+\r
+\r
+HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,\r
+    const UInt64 *size, const UInt64 *compressedSize)\r
+{\r
+  for (int i = 0; i < _fields.Size(); i++)\r
+  {\r
+    const CFieldInfo &fieldInfo = _fields[i];\r
+    PrintSpaces(fieldInfo.PrefixSpacesWidth);\r
+    NCOM::CPropVariant prop;\r
+    if (fieldInfo.PropID == kpidSize)\r
+      PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size);\r
+    else if (fieldInfo.PropID == kpidPackSize)\r
+      PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize);\r
+    else if (fieldInfo.PropID == kpidPath)\r
+    {\r
+      wchar_t textString[32];\r
+      ConvertUInt64ToString(numFiles, textString);\r
+      UString temp = textString;\r
+      temp += L" ";\r
+      temp += kFilesMessage;\r
+      temp += L", ";\r
+      ConvertUInt64ToString(numDirs, textString);\r
+      temp += textString;\r
+      temp += L" ";\r
+      temp += kDirsMessage;\r
+      PrintString(fieldInfo.TextAdjustment, 0, temp);\r
+    }\r
+    else\r
+      PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value)\r
+{\r
+  NCOM::CPropVariant prop;\r
+  if (archive->GetProperty(index, propID, &prop) != S_OK)\r
+    throw "GetPropertyValue error";\r
+  if (prop.vt == VT_EMPTY)\r
+    return false;\r
+  value = ConvertPropVariantToUInt64(prop);\r
+  return true;\r
+}\r
+\r
+static void PrintPropPair(const wchar_t *name, const wchar_t *value)\r
+{\r
+  g_StdOut << name << " = " << value << endl;\r
+}\r
+\r
+HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,\r
+    bool stdInMode,\r
+    UStringVector &arcPaths, UStringVector &arcPathsFull,\r
+    const NWildcard::CCensorNode &wildcardCensor,\r
+    bool enableHeaders, bool techMode,\r
+    #ifndef _NO_CRYPTO\r
+    bool &passwordEnabled, UString &password,\r
+    #endif\r
+    UInt64 &numErrors)\r
+{\r
+  numErrors = 0;\r
+  CFieldPrinter fieldPrinter;\r
+  if (!techMode)\r
+    fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));\r
+\r
+  UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;\r
+  UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;\r
+  int numArcs = /* stdInMode ? 1 : */ arcPaths.Size();\r
+  for (int i = 0; i < numArcs; i++)\r
+  {\r
+    const UString &archiveName = arcPaths[i];\r
+    UInt64 arcPackSize = 0;\r
+    if (!stdInMode)\r
+    {\r
+      NFile::NFind::CFileInfoW fi;\r
+      if (!fi.Find(archiveName) || fi.IsDir())\r
+      {\r
+        g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;\r
+        numErrors++;\r
+        continue;\r
+      }\r
+      arcPackSize = fi.Size;\r
+    }\r
+\r
+    CArchiveLink archiveLink;\r
+\r
+    COpenCallbackConsole openCallback;\r
+    openCallback.OutStream = &g_StdOut;\r
+\r
+    #ifndef _NO_CRYPTO\r
+\r
+    openCallback.PasswordIsDefined = passwordEnabled;\r
+    openCallback.Password = password;\r
+\r
+    #endif\r
+\r
+    HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archiveName, &openCallback);\r
+    if (result != S_OK)\r
+    {\r
+      if (result == E_ABORT)\r
+        return result;\r
+      g_StdOut << endl << "Error: " << archiveName << ": ";\r
+      if (result == S_FALSE)\r
+      {\r
+        #ifndef _NO_CRYPTO\r
+        if (openCallback.Open_WasPasswordAsked())\r
+          g_StdOut << "Can not open encrypted archive. Wrong password?";\r
+        else\r
+        #endif\r
+          g_StdOut << "Can not open file as archive";\r
+      }\r
+      else if (result == E_OUTOFMEMORY)\r
+        g_StdOut << "Can't allocate required memory";\r
+      else\r
+        g_StdOut << NError::MyFormatMessage(result);\r
+      g_StdOut << endl;\r
+      numErrors++;\r
+      continue;\r
+    }\r
+\r
+    if (!stdInMode)\r
+    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)\r
+    {\r
+      int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);\r
+      if (index >= 0 && index > i)\r
+      {\r
+        arcPaths.Delete(index);\r
+        arcPathsFull.Delete(index);\r
+        numArcs = arcPaths.Size();\r
+      }\r
+    }\r
+\r
+    if (enableHeaders)\r
+    {\r
+      g_StdOut << endl << kListing << archiveName << endl << endl;\r
+\r
+      for (int i = 0; i < archiveLink.Arcs.Size(); i++)\r
+      {\r
+        const CArc &arc = archiveLink.Arcs[i];\r
+        \r
+        g_StdOut << "--\n";\r
+        PrintPropPair(L"Path", arc.Path);\r
+        PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);\r
+        if (!arc.ErrorMessage.IsEmpty())\r
+          PrintPropPair(L"Error", arc.ErrorMessage);\r
+        UInt32 numProps;\r
+        IInArchive *archive = arc.Archive;\r
+        if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)\r
+        {\r
+          for (UInt32 j = 0; j < numProps; j++)\r
+          {\r
+            CMyComBSTR name;\r
+            PROPID propID;\r
+            VARTYPE vt;\r
+            RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt));\r
+            NCOM::CPropVariant prop;\r
+            RINOK(archive->GetArchiveProperty(propID, &prop));\r
+            UString s = ConvertPropertyToString(prop, propID);\r
+            if (!s.IsEmpty())\r
+              PrintPropPair(GetPropName(propID, name), s);\r
+          }\r
+        }\r
+        if (i != archiveLink.Arcs.Size() - 1)\r
+        {\r
+          UInt32 numProps;\r
+          g_StdOut << "----\n";\r
+          if (archive->GetNumberOfProperties(&numProps) == S_OK)\r
+          {\r
+            UInt32 mainIndex = archiveLink.Arcs[i + 1].SubfileIndex;\r
+            for (UInt32 j = 0; j < numProps; j++)\r
+            {\r
+              CMyComBSTR name;\r
+              PROPID propID;\r
+              VARTYPE vt;\r
+              RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt));\r
+              NCOM::CPropVariant prop;\r
+              RINOK(archive->GetProperty(mainIndex, propID, &prop));\r
+              UString s = ConvertPropertyToString(prop, propID);\r
+              if (!s.IsEmpty())\r
+                PrintPropPair(GetPropName(propID, name), s);\r
+            }\r
+          }\r
+        }\r
+        \r
+      }\r
+      g_StdOut << endl;\r
+      if (techMode)\r
+        g_StdOut << "----------\n";\r
+    }\r
+\r
+    if (enableHeaders && !techMode)\r
+    {\r
+      fieldPrinter.PrintTitle();\r
+      g_StdOut << endl;\r
+      fieldPrinter.PrintTitleLines();\r
+      g_StdOut << endl;\r
+    }\r
+\r
+    const CArc &arc = archiveLink.Arcs.Back();\r
+    IInArchive *archive = arc.Archive;\r
+    if (techMode)\r
+    {\r
+      RINOK(fieldPrinter.Init(archive));\r
+    }\r
+    UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;\r
+    UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;\r
+    UInt32 numItems;\r
+    RINOK(archive->GetNumberOfItems(&numItems));\r
+    for (UInt32 i = 0; i < numItems; i++)\r
+    {\r
+      if (NConsoleClose::TestBreakSignal())\r
+        return E_ABORT;\r
+\r
+      UString filePath;\r
+      HRESULT res = arc.GetItemPath(i, filePath);\r
+      if (stdInMode && res == E_INVALIDARG)\r
+        break;\r
+      RINOK(res);\r
+\r
+      bool isFolder;\r
+      RINOK(IsArchiveItemFolder(archive, i, isFolder));\r
+      if (!wildcardCensor.CheckPath(filePath, !isFolder))\r
+        continue;\r
+      \r
+      fieldPrinter.PrintItemInfo(arc, i, techMode);\r
+      \r
+      UInt64 packSize, unpackSize;\r
+      if (!GetUInt64Value(archive, i, kpidSize, unpackSize))\r
+        unpackSize = 0;\r
+      else\r
+        totalUnPackSizePointer = &totalUnPackSize;\r
+      if (!GetUInt64Value(archive, i, kpidPackSize, packSize))\r
+        packSize = 0;\r
+      else\r
+        totalPackSizePointer = &totalPackSize;\r
+      \r
+      g_StdOut << endl;\r
+\r
+      if (isFolder)\r
+        numDirs++;\r
+      else\r
+        numFiles++;\r
+      totalPackSize += packSize;\r
+      totalUnPackSize += unpackSize;\r
+    }\r
+\r
+    if (!stdInMode && totalPackSizePointer == 0)\r
+    {\r
+      if (archiveLink.VolumePaths.Size() != 0)\r
+        arcPackSize += archiveLink.VolumesSize;\r
+      totalPackSize = (numFiles == 0) ? 0 : arcPackSize;\r
+      totalPackSizePointer = &totalPackSize;\r
+    }\r
+    if (totalUnPackSizePointer == 0 && numFiles == 0)\r
+    {\r
+      totalUnPackSize = 0;\r
+      totalUnPackSizePointer = &totalUnPackSize;\r
+    }\r
+    if (enableHeaders && !techMode)\r
+    {\r
+      fieldPrinter.PrintTitleLines();\r
+      g_StdOut << endl;\r
+      fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);\r
+      g_StdOut << endl;\r
+    }\r
+    if (totalPackSizePointer != 0)\r
+    {\r
+      totalPackSizePointer2 = &totalPackSize2;\r
+      totalPackSize2 += totalPackSize;\r
+    }\r
+    if (totalUnPackSizePointer != 0)\r
+    {\r
+      totalUnPackSizePointer2 = &totalUnPackSize2;\r
+      totalUnPackSize2 += totalUnPackSize;\r
+    }\r
+    numFiles2 += numFiles;\r
+    numDirs2 += numDirs;\r
+  }\r
+  if (enableHeaders && !techMode && numArcs > 1)\r
+  {\r
+    g_StdOut << endl;\r
+    fieldPrinter.PrintTitleLines();\r
+    g_StdOut << endl;\r
+    fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);\r
+    g_StdOut << endl;\r
+    g_StdOut << "Archives: " << numArcs << endl;\r
+  }\r
+  return S_OK;\r
+}\r
diff --git a/CPP/7zip/UI/Console/List.h b/CPP/7zip/UI/Console/List.h
new file mode 100755 (executable)
index 0000000..7ea02cc
--- /dev/null
@@ -0,0 +1,20 @@
+// List.h\r
+\r
+#ifndef __LIST_H\r
+#define __LIST_H\r
+\r
+#include "Common/Wildcard.h"\r
+#include "../Common/LoadCodecs.h"\r
+\r
+HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,\r
+    bool stdInMode,\r
+    UStringVector &archivePaths, UStringVector &archivePathsFull,\r
+    const NWildcard::CCensorNode &wildcardCensor,\r
+    bool enableHeaders, bool techMode,\r
+    #ifndef _NO_CRYPTO\r
+    bool &passwordEnabled, UString &password,\r
+    #endif\r
+    UInt64 &errors);\r
+\r
+#endif\r
+\r
diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp
new file mode 100755 (executable)
index 0000000..8946772
--- /dev/null
@@ -0,0 +1,598 @@
+// Main.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES)\r
+#include "../../../../C/Alloc.h"\r
+#endif\r
+\r
+#include "Common/MyInitGuid.h"\r
+\r
+#include "Common/CommandLineParser.h"\r
+#include "Common/IntToString.h"\r
+#include "Common/MyException.h"\r
+#include "Common/StdOutStream.h"\r
+#include "Common/StringConvert.h"\r
+#include "Common/StringToInt.h"\r
+\r
+#include "Windows/Error.h"\r
+#ifdef _WIN32\r
+#include "Windows/MemoryLock.h"\r
+#endif\r
+\r
+#include "../Common/ArchiveCommandLine.h"\r
+#include "../Common/ExitCode.h"\r
+#include "../Common/Extract.h"\r
+#ifdef EXTERNAL_CODECS\r
+#include "../Common/LoadCodecs.h"\r
+#endif\r
+\r
+#include "BenchCon.h"\r
+#include "ExtractCallbackConsole.h"\r
+#include "List.h"\r
+#include "OpenCallbackConsole.h"\r
+#include "UpdateCallbackConsole.h"\r
+\r
+#include "../../MyVersion.h"\r
+\r
+using namespace NWindows;\r
+using namespace NFile;\r
+using namespace NCommandLineParser;\r
+\r
+HINSTANCE g_hInstance = 0;\r
+extern CStdOutStream *g_StdStream;\r
+\r
+static const char *kCopyrightString = "\n7-Zip"\r
+#ifndef EXTERNAL_CODECS\r
+" (A)"\r
+#endif\r
+\r
+#ifdef _WIN64\r
+" [64]"\r
+#endif\r
+\r
+" " MY_VERSION_COPYRIGHT_DATE "\n";\r
+\r
+static const char *kHelpString =\r
+    "\nUsage: 7z"\r
+#ifdef _NO_CRYPTO\r
+    "r"\r
+#else\r
+#ifndef EXTERNAL_CODECS\r
+    "a"\r
+#endif\r
+#endif\r
+    " <command> [<switches>...] <archive_name> [<file_names>...]\n"\r
+    "       [<@listfiles...>]\n"\r
+    "\n"\r
+    "<Commands>\n"\r
+    "  a: Add files to archive\n"\r
+    "  b: Benchmark\n"\r
+    "  d: Delete files from archive\n"\r
+    "  e: Extract files from archive (without using directory names)\n"\r
+    "  l: List contents of archive\n"\r
+//    "  l[a|t][f]: List contents of archive\n"\r
+//    "    a - with Additional fields\n"\r
+//    "    t - with all fields\n"\r
+//    "    f - with Full pathnames\n"\r
+    "  t: Test integrity of archive\n"\r
+    "  u: Update files to archive\n"\r
+    "  x: eXtract files with full paths\n"\r
+    "<Switches>\n"\r
+    "  -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n"\r
+    "  -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n"\r
+    "  -bd: Disable percentage indicator\n"\r
+    "  -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n"\r
+    "  -m{Parameters}: set compression Method\n"\r
+    "  -o{Directory}: set Output directory\n"\r
+    #ifndef _NO_CRYPTO\r
+    "  -p{Password}: set Password\n"\r
+    #endif\r
+    "  -r[-|0]: Recurse subdirectories\n"\r
+    "  -scs{UTF-8 | WIN | DOS}: set charset for list files\n"\r
+    "  -sfx[{name}]: Create SFX archive\n"\r
+    "  -si[{name}]: read data from stdin\n"\r
+    "  -slt: show technical information for l (List) command\n"\r
+    "  -so: write data to stdout\n"\r
+    "  -ssc[-]: set sensitive case mode\n"\r
+    "  -ssw: compress shared files\n"\r
+    "  -t{Type}: Set type of archive\n"\r
+    "  -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n"\r
+    "  -v{Size}[b|k|m|g]: Create volumes\n"\r
+    "  -w[{path}]: assign Work directory. Empty path means a temporary directory\n"\r
+    "  -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n"\r
+    "  -y: assume Yes on all queries\n";\r
+\r
+// ---------------------------\r
+// exception messages\r
+\r
+static const char *kEverythingIsOk = "Everything is Ok";\r
+static const char *kUserErrorMessage = "Incorrect command line";\r
+static const char *kNoFormats = "7-Zip cannot find the code that works with archives.";\r
+static const char *kUnsupportedArcTypeMessage = "Unsupported archive type";\r
+\r
+static const wchar_t *kDefaultSfxModule = L"7zCon.sfx";\r
+\r
+static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)\r
+{\r
+  s << message << endl;\r
+  throw code;\r
+}\r
+\r
+static void PrintHelpAndExit(CStdOutStream &s)\r
+{\r
+  s << kHelpString;\r
+  ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError);\r
+}\r
+\r
+#ifndef _WIN32\r
+static void GetArguments(int numArgs, const char *args[], UStringVector &parts)\r
+{\r
+  parts.Clear();\r
+  for (int i = 0; i < numArgs; i++)\r
+  {\r
+    UString s = MultiByteToUnicodeString(args[i]);\r
+    parts.Add(s);\r
+  }\r
+}\r
+#endif\r
+\r
+static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)\r
+{\r
+  s << kCopyrightString;\r
+  // s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\n";\r
+  if (needHelp)\r
+    s << kHelpString;\r
+}\r
+\r
+#ifdef EXTERNAL_CODECS\r
+static void PrintString(CStdOutStream &stdStream, const AString &s, int size)\r
+{\r
+  int len = s.Length();\r
+  stdStream << s;\r
+  for (int i = len; i < size; i++)\r
+    stdStream << ' ';\r
+}\r
+#endif\r
+\r
+static void PrintString(CStdOutStream &stdStream, const UString &s, int size)\r
+{\r
+  int len = s.Length();\r
+  stdStream << s;\r
+  for (int i = len; i < size; i++)\r
+    stdStream << ' ';\r
+}\r
+\r
+static inline char GetHex(Byte value)\r
+{\r
+  return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));\r
+}\r
+\r
+int Main2(\r
+  #ifndef _WIN32\r
+  int numArgs, const char *args[]\r
+  #endif\r
+)\r
+{\r
+  #if defined(_WIN32) && !defined(UNDER_CE)\r
+  SetFileApisToOEM();\r
+  #endif\r
+  \r
+  UStringVector commandStrings;\r
+  #ifdef _WIN32\r
+  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);\r
+  #else\r
+  GetArguments(numArgs, args, commandStrings);\r
+  #endif\r
+\r
+  if (commandStrings.Size() == 1)\r
+  {\r
+    ShowCopyrightAndHelp(g_StdOut, true);\r
+    return 0;\r
+  }\r
+  commandStrings.Delete(0);\r
+\r
+  CArchiveCommandLineOptions options;\r
+\r
+  CArchiveCommandLineParser parser;\r
+\r
+  parser.Parse1(commandStrings, options);\r
+\r
+  if (options.HelpMode)\r
+  {\r
+    ShowCopyrightAndHelp(g_StdOut, true);\r
+    return 0;\r
+  }\r
+\r
+  #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)\r
+  if (options.LargePages)\r
+  {\r
+    SetLargePageSize();\r
+    NSecurity::EnableLockMemoryPrivilege();\r
+  }\r
+  #endif\r
+\r
+  CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;\r
+  g_StdStream = &stdStream;\r
+\r
+  if (options.EnableHeaders)\r
+    ShowCopyrightAndHelp(stdStream, false);\r
+\r
+  parser.Parse2(options);\r
+\r
+  CCodecs *codecs = new CCodecs;\r
+  CMyComPtr<\r
+    #ifdef EXTERNAL_CODECS\r
+    ICompressCodecsInfo\r
+    #else\r
+    IUnknown\r
+    #endif\r
+    > compressCodecsInfo = codecs;\r
+  HRESULT result = codecs->Load();\r
+  if (result != S_OK)\r
+    throw CSystemException(result);\r
+\r
+  bool isExtractGroupCommand = options.Command.IsFromExtractGroup();\r
+\r
+  if (codecs->Formats.Size() == 0 &&\r
+        (isExtractGroupCommand ||\r
+        options.Command.CommandType == NCommandType::kList ||\r
+        options.Command.IsFromUpdateGroup()))\r
+    throw kNoFormats;\r
+\r
+  CIntVector formatIndices;\r
+  if (!codecs->FindFormatForArchiveType(options.ArcType, formatIndices))\r
+    throw kUnsupportedArcTypeMessage;\r
+\r
+  if (options.Command.CommandType == NCommandType::kInfo)\r
+  {\r
+    stdStream << endl << "Formats:" << endl;\r
+    int i;\r
+    for (i = 0; i < codecs->Formats.Size(); i++)\r
+    {\r
+      const CArcInfoEx &arc = codecs->Formats[i];\r
+      #ifdef EXTERNAL_CODECS\r
+      if (arc.LibIndex >= 0)\r
+      {\r
+        char s[16];\r
+        ConvertUInt32ToString(arc.LibIndex, s);\r
+        PrintString(stdStream, s, 2);\r
+      }\r
+      else\r
+      #endif\r
+        stdStream << "  ";\r
+      stdStream << ' ';\r
+      stdStream << (char)(arc.UpdateEnabled ? 'C' : ' ');\r
+      stdStream << (char)(arc.KeepName ? 'K' : ' ');\r
+      stdStream << "  ";\r
+      PrintString(stdStream, arc.Name, 6);\r
+      stdStream << "  ";\r
+      UString s;\r
+      for (int t = 0; t < arc.Exts.Size(); t++)\r
+      {\r
+        const CArcExtInfo &ext = arc.Exts[t];\r
+        s += ext.Ext;\r
+        if (!ext.AddExt.IsEmpty())\r
+        {\r
+          s += L" (";\r
+          s += ext.AddExt;\r
+          s += L')';\r
+        }\r
+        s += L' ';\r
+      }\r
+      PrintString(stdStream, s, 14);\r
+      stdStream << "  ";\r
+      const CByteBuffer &sig = arc.StartSignature;\r
+      for (size_t j = 0; j < sig.GetCapacity(); j++)\r
+      {\r
+        Byte b = sig[j];\r
+        if (b > 0x20 && b < 0x80)\r
+        {\r
+          stdStream << (char)b;\r
+        }\r
+        else\r
+        {\r
+          stdStream << GetHex((Byte)((b >> 4) & 0xF));\r
+          stdStream << GetHex((Byte)(b & 0xF));\r
+        }\r
+        stdStream << ' ';\r
+      }\r
+      stdStream << endl;\r
+    }\r
+    stdStream << endl << "Codecs:" << endl;\r
+\r
+    #ifdef EXTERNAL_CODECS\r
+    UInt32 numMethods;\r
+    if (codecs->GetNumberOfMethods(&numMethods) == S_OK)\r
+    for (UInt32 j = 0; j < numMethods; j++)\r
+    {\r
+      int libIndex = codecs->GetCodecLibIndex(j);\r
+      if (libIndex >= 0)\r
+      {\r
+        char s[16];\r
+        ConvertUInt32ToString(libIndex, s);\r
+        PrintString(stdStream, s, 2);\r
+      }\r
+      else\r
+        stdStream << "  ";\r
+      stdStream << ' ';\r
+      stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' ');\r
+      UInt64 id;\r
+      stdStream << "  ";\r
+      HRESULT res = codecs->GetCodecId(j, id);\r
+      if (res != S_OK)\r
+        id = (UInt64)(Int64)-1;\r
+      char s[32];\r
+      ConvertUInt64ToString(id, s, 16);\r
+      PrintString(stdStream, s, 8);\r
+      stdStream << "  ";\r
+      PrintString(stdStream, codecs->GetCodecName(j), 11);\r
+      stdStream << endl;\r
+      /*\r
+      if (res != S_OK)\r
+        throw "incorrect Codec ID";\r
+      */\r
+    }\r
+    #endif\r
+    return S_OK;\r
+  }\r
+  else if (options.Command.CommandType == NCommandType::kBenchmark)\r
+  {\r
+    if (options.Method.CompareNoCase(L"CRC") == 0)\r
+    {\r
+      HRESULT res = CrcBenchCon((FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);\r
+      if (res != S_OK)\r
+      {\r
+        if (res == S_FALSE)\r
+        {\r
+          stdStream << "\nCRC Error\n";\r
+          return NExitCode::kFatalError;\r
+        }\r
+        throw CSystemException(res);\r
+      }\r
+    }\r
+    else\r
+    {\r
+      HRESULT res;\r
+      #ifdef EXTERNAL_CODECS\r
+      CObjectVector<CCodecInfoEx> externalCodecs;\r
+      res = LoadExternalCodecs(compressCodecsInfo, externalCodecs);\r
+      if (res != S_OK)\r
+        throw CSystemException(res);\r
+      #endif\r
+      res = LzmaBenchCon(\r
+          #ifdef EXTERNAL_CODECS\r
+          compressCodecsInfo, &externalCodecs,\r
+          #endif\r
+        (FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);\r
+      if (res != S_OK)\r
+      {\r
+        if (res == S_FALSE)\r
+        {\r
+          stdStream << "\nDecoding Error\n";\r
+          return NExitCode::kFatalError;\r
+        }\r
+        throw CSystemException(res);\r
+      }\r
+    }\r
+  }\r
+  else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)\r
+  {\r
+    if (isExtractGroupCommand)\r
+    {\r
+      CExtractCallbackConsole *ecs = new CExtractCallbackConsole;\r
+      CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;\r
+\r
+      ecs->OutStream = &stdStream;\r
+\r
+      #ifndef _NO_CRYPTO\r
+      ecs->PasswordIsDefined = options.PasswordEnabled;\r
+      ecs->Password = options.Password;\r
+      #endif\r
+\r
+      ecs->Init();\r
+\r
+      COpenCallbackConsole openCallback;\r
+      openCallback.OutStream = &stdStream;\r
+\r
+      #ifndef _NO_CRYPTO\r
+      openCallback.PasswordIsDefined = options.PasswordEnabled;\r
+      openCallback.Password = options.Password;\r
+      #endif\r
+\r
+      CExtractOptions eo;\r
+      eo.StdInMode = options.StdInMode;\r
+      eo.StdOutMode = options.StdOutMode;\r
+      eo.PathMode = options.Command.GetPathMode();\r
+      eo.TestMode = options.Command.IsTestMode();\r
+      eo.OverwriteMode = options.OverwriteMode;\r
+      eo.OutputDir = options.OutputDir;\r
+      eo.YesToAll = options.YesToAll;\r
+      eo.CalcCrc = options.CalcCrc;\r
+      #if !defined(_7ZIP_ST) && !defined(_SFX)\r
+      eo.Properties = options.ExtractProperties;\r
+      #endif\r
+      UString errorMessage;\r
+      CDecompressStat stat;\r
+      HRESULT result = DecompressArchives(\r
+          codecs,\r
+          formatIndices,\r
+          options.ArchivePathsSorted,\r
+          options.ArchivePathsFullSorted,\r
+          options.WildcardCensor.Pairs.Front().Head,\r
+          eo, &openCallback, ecs, errorMessage, stat);\r
+      if (!errorMessage.IsEmpty())\r
+      {\r
+        stdStream << endl << "Error: " << errorMessage;\r
+        if (result == S_OK)\r
+          result = E_FAIL;\r
+      }\r
+\r
+      stdStream << endl;\r
+      if (ecs->NumArchives > 1)\r
+        stdStream << "Archives: " << ecs->NumArchives << endl;\r
+      if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)\r
+      {\r
+        if (ecs->NumArchives > 1)\r
+        {\r
+          stdStream << endl;\r
+          if (ecs->NumArchiveErrors != 0)\r
+            stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl;\r
+          if (ecs->NumFileErrors != 0)\r
+            stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl;\r
+        }\r
+        if (result != S_OK)\r
+          throw CSystemException(result);\r
+        return NExitCode::kFatalError;\r
+      }\r
+      if (result != S_OK)\r
+        throw CSystemException(result);\r
+      if (stat.NumFolders != 0)\r
+        stdStream << "Folders: " << stat.NumFolders << endl;\r
+      if (stat.NumFiles != 1 || stat.NumFolders != 0)\r
+          stdStream << "Files: " << stat.NumFiles << endl;\r
+      stdStream\r
+           << "Size:       " << stat.UnpackSize << endl\r
+           << "Compressed: " << stat.PackSize << endl;\r
+      if (options.CalcCrc)\r
+      {\r
+        char s[16];\r
+        ConvertUInt32ToHexWithZeros(stat.CrcSum, s);\r
+        stdStream << "CRC: " << s << endl;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      UInt64 numErrors = 0;\r
+      HRESULT result = ListArchives(\r
+          codecs,\r
+          formatIndices,\r
+          options.StdInMode,\r
+          options.ArchivePathsSorted,\r
+          options.ArchivePathsFullSorted,\r
+          options.WildcardCensor.Pairs.Front().Head,\r
+          options.EnableHeaders,\r
+          options.TechMode,\r
+          #ifndef _NO_CRYPTO\r
+          options.PasswordEnabled,\r
+          options.Password,\r
+          #endif\r
+          numErrors);\r
+      if (numErrors > 0)\r
+      {\r
+        g_StdOut << endl << "Errors: " << numErrors;\r
+        return NExitCode::kFatalError;\r
+      }\r
+      if (result != S_OK)\r
+        throw CSystemException(result);\r
+    }\r
+  }\r
+  else if (options.Command.IsFromUpdateGroup())\r
+  {\r
+    CUpdateOptions &uo = options.UpdateOptions;\r
+    if (uo.SfxMode && uo.SfxModule.IsEmpty())\r
+      uo.SfxModule = kDefaultSfxModule;\r
+\r
+    COpenCallbackConsole openCallback;\r
+    openCallback.OutStream = &stdStream;\r
+\r
+    #ifndef _NO_CRYPTO\r
+    bool passwordIsDefined =\r
+        options.PasswordEnabled && !options.Password.IsEmpty();\r
+    openCallback.PasswordIsDefined = passwordIsDefined;\r
+    openCallback.Password = options.Password;\r
+    #endif\r
+\r
+    CUpdateCallbackConsole callback;\r
+    callback.EnablePercents = options.EnablePercents;\r
+\r
+    #ifndef _NO_CRYPTO\r
+    callback.PasswordIsDefined = passwordIsDefined;\r
+    callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();\r
+    callback.Password = options.Password;\r
+    #endif\r
+    callback.StdOutMode = uo.StdOutMode;\r
+    callback.Init(&stdStream);\r
+\r
+    CUpdateErrorInfo errorInfo;\r
+\r
+    if (!uo.Init(codecs, formatIndices, options.ArchiveName))\r
+      throw kUnsupportedArcTypeMessage;\r
+    HRESULT result = UpdateArchive(codecs,\r
+        options.WildcardCensor, uo,\r
+        errorInfo, &openCallback, &callback);\r
+\r
+    int exitCode = NExitCode::kSuccess;\r
+    if (callback.CantFindFiles.Size() > 0)\r
+    {\r
+      stdStream << endl;\r
+      stdStream << "WARNINGS for files:" << endl << endl;\r
+      int numErrors = callback.CantFindFiles.Size();\r
+      for (int i = 0; i < numErrors; i++)\r
+      {\r
+        stdStream << callback.CantFindFiles[i] << " : ";\r
+        stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl;\r
+      }\r
+      stdStream << "----------------" << endl;\r
+      stdStream << "WARNING: Cannot find " << numErrors << " file";\r
+      if (numErrors > 1)\r
+        stdStream << "s";\r
+      stdStream << endl;\r
+      exitCode = NExitCode::kWarning;\r
+    }\r
+\r
+    if (result != S_OK)\r
+    {\r
+      UString message;\r
+      if (!errorInfo.Message.IsEmpty())\r
+      {\r
+        message += errorInfo.Message;\r
+        message += L"\n";\r
+      }\r
+      if (!errorInfo.FileName.IsEmpty())\r
+      {\r
+        message += errorInfo.FileName;\r
+        message += L"\n";\r
+      }\r
+      if (!errorInfo.FileName2.IsEmpty())\r
+      {\r
+        message += errorInfo.FileName2;\r
+        message += L"\n";\r
+      }\r
+      if (errorInfo.SystemError != 0)\r
+      {\r
+        message += NError::MyFormatMessageW(errorInfo.SystemError);\r
+        message += L"\n";\r
+      }\r
+      if (!message.IsEmpty())\r
+        stdStream << L"\nError:\n" << message;\r
+      throw CSystemException(result);\r
+    }\r
+    int numErrors = callback.FailedFiles.Size();\r
+    if (numErrors == 0)\r
+    {\r
+      if (callback.CantFindFiles.Size() == 0)\r
+        stdStream << kEverythingIsOk << endl;\r
+    }\r
+    else\r
+    {\r
+      stdStream << endl;\r
+      stdStream << "WARNINGS for files:" << endl << endl;\r
+      for (int i = 0; i < numErrors; i++)\r
+      {\r
+        stdStream << callback.FailedFiles[i] << " : ";\r
+        stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl;\r
+      }\r
+      stdStream << "----------------" << endl;\r
+      stdStream << "WARNING: Cannot open " << numErrors << " file";\r
+      if (numErrors > 1)\r
+        stdStream << "s";\r
+      stdStream << endl;\r
+      exitCode = NExitCode::kWarning;\r
+    }\r
+    return exitCode;\r
+  }\r
+  else\r
+    PrintHelpAndExit(stdStream);\r
+  return 0;\r
+}\r
diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp
new file mode 100755 (executable)
index 0000000..b6681b4
--- /dev/null
@@ -0,0 +1,125 @@
+// MainAr.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/MyException.h"\r
+#include "Common/StdOutStream.h"\r
+\r
+#include "Windows/Error.h"\r
+#include "Windows/NtCheck.h"\r
+\r
+#include "../Common/ArchiveCommandLine.h"\r
+#include "../Common/ExitCode.h"\r
+\r
+#include "ConsoleClose.h"\r
+\r
+using namespace NWindows;\r
+\r
+CStdOutStream *g_StdStream = 0;\r
+\r
+extern int Main2(\r
+  #ifndef _WIN32\r
+  int numArgs, const char *args[]\r
+  #endif\r
+);\r
+\r
+static const char *kExceptionErrorMessage = "\n\nError:\n";\r
+static const char *kUserBreak  = "\nBreak signaled\n";\r
+static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n";\r
+static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n";\r
+static const char *kInternalExceptionMessage = "\n\nInternal Error #";\r
+\r
+#define NT_CHECK_FAIL_ACTION (*g_StdStream) << "Unsupported Windows version"; return NExitCode::kFatalError;\r
+\r
+int MY_CDECL main\r
+(\r
+  #ifndef _WIN32\r
+  int numArgs, const char *args[]\r
+  #endif\r
+)\r
+{\r
+  g_StdStream = &g_StdOut;\r
+\r
+  NT_CHECK\r
+\r
+  NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;\r
+  int res = 0;\r
+  try\r
+  {\r
+    res = Main2(\r
+    #ifndef _WIN32\r
+    numArgs, args\r
+    #endif\r
+    );\r
+  }\r
+  catch(const CNewException &)\r
+  {\r
+    (*g_StdStream) << kMemoryExceptionMessage;\r
+    return (NExitCode::kMemoryError);\r
+  }\r
+  catch(const NConsoleClose::CCtrlBreakException &)\r
+  {\r
+    (*g_StdStream) << endl << kUserBreak;\r
+    return (NExitCode::kUserBreak);\r
+  }\r
+  catch(const CArchiveCommandLineException &e)\r
+  {\r
+    (*g_StdStream) << kExceptionErrorMessage << e << endl;\r
+    return (NExitCode::kUserError);\r
+  }\r
+  catch(const CSystemException &systemError)\r
+  {\r
+    if (systemError.ErrorCode == E_OUTOFMEMORY)\r
+    {\r
+      (*g_StdStream) << kMemoryExceptionMessage;\r
+      return (NExitCode::kMemoryError);\r
+    }\r
+    if (systemError.ErrorCode == E_ABORT)\r
+    {\r
+      (*g_StdStream) << endl << kUserBreak;\r
+      return (NExitCode::kUserBreak);\r
+    }\r
+    UString message;\r
+    NError::MyFormatMessage(systemError.ErrorCode, message);\r
+    (*g_StdStream) << endl << endl << "System error:" << endl << message << endl;\r
+    return (NExitCode::kFatalError);\r
+  }\r
+  catch(NExitCode::EEnum &exitCode)\r
+  {\r
+    (*g_StdStream) << kInternalExceptionMessage << exitCode << endl;\r
+    return (exitCode);\r
+  }\r
+  /*\r
+  catch(const NExitCode::CMultipleErrors &multipleErrors)\r
+  {\r
+    (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl;\r
+    return (NExitCode::kFatalError);\r
+  }\r
+  */\r
+  catch(const UString &s)\r
+  {\r
+    (*g_StdStream) << kExceptionErrorMessage << s << endl;\r
+    return (NExitCode::kFatalError);\r
+  }\r
+  catch(const AString &s)\r
+  {\r
+    (*g_StdStream) << kExceptionErrorMessage << s << endl;\r
+    return (NExitCode::kFatalError);\r
+  }\r
+  catch(const char *s)\r
+  {\r
+    (*g_StdStream) << kExceptionErrorMessage << s << endl;\r
+    return (NExitCode::kFatalError);\r
+  }\r
+  catch(int t)\r
+  {\r
+    (*g_StdStream) << kInternalExceptionMessage << t << endl;\r
+    return (NExitCode::kFatalError);\r
+  }\r
+  catch(...)\r
+  {\r
+    (*g_StdStream) << kUnknownExceptionMessage;\r
+    return (NExitCode::kFatalError);\r
+  }\r
+  return  res;\r
+}\r
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
new file mode 100755 (executable)
index 0000000..986a592
--- /dev/null
@@ -0,0 +1,58 @@
+// OpenCallbackConsole.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "OpenCallbackConsole.h"\r
+\r
+#include "ConsoleClose.h"\r
+#include "UserInputUtils.h"\r
+\r
+HRESULT COpenCallbackConsole::Open_CheckBreak()\r
+{\r
+  if (NConsoleClose::TestBreakSignal())\r
+    return E_ABORT;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *, const UInt64 *)\r
+{\r
+  return Open_CheckBreak();\r
+}\r
+\r
+HRESULT COpenCallbackConsole::Open_SetCompleted(const UInt64 *, const UInt64 *)\r
+{\r
+  return Open_CheckBreak();\r
+}\r
\r
+#ifndef _NO_CRYPTO\r
+\r
+HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password)\r
+{\r
+  PasswordWasAsked = true;\r
+  RINOK(Open_CheckBreak());\r
+  if (!PasswordIsDefined)\r
+  {\r
+    Password = GetPassword(OutStream);\r
+    PasswordIsDefined = true;\r
+  }\r
+  return StringToBstr(Password, password);\r
+}\r
+\r
+HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(UString &password)\r
+{\r
+  if (PasswordIsDefined)\r
+    password = Password;\r
+  return S_OK;\r
+}\r
+\r
+bool COpenCallbackConsole::Open_WasPasswordAsked()\r
+{\r
+  return PasswordWasAsked;\r
+}\r
+\r
+void COpenCallbackConsole::Open_ClearPasswordWasAskedFlag()\r
+{\r
+  PasswordWasAsked = false;\r
+}\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h
new file mode 100755 (executable)
index 0000000..99e8c04
--- /dev/null
@@ -0,0 +1,24 @@
+// OpenCallbackConsole.h\r
+\r
+#ifndef __OPENCALLBACKCONSOLE_H\r
+#define __OPENCALLBACKCONSOLE_H\r
+\r
+#include "Common/StdOutStream.h"\r
+#include "../Common/ArchiveOpenCallback.h"\r
+\r
+class COpenCallbackConsole: public IOpenCallbackUI\r
+{\r
+public:\r
+  INTERFACE_IOpenCallbackUI(;)\r
+  \r
+  CStdOutStream *OutStream;\r
+\r
+  #ifndef _NO_CRYPTO\r
+  bool PasswordIsDefined;\r
+  bool PasswordWasAsked;\r
+  UString Password;\r
+  COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {}\r
+  #endif\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp
new file mode 100755 (executable)
index 0000000..111ae25
--- /dev/null
@@ -0,0 +1,90 @@
+// PercentPrinter.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/IntToString.h"\r
+#include "Common/MyString.h"\r
+\r
+#include "PercentPrinter.h"\r
+\r
+const int kPaddingSize = 2;\r
+const int kPercentsSize = 4;\r
+const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;\r
+\r
+static void ClearPrev(char *p, int num)\r
+{\r
+  int i;\r
+  for (i = 0; i < num; i++) *p++ = '\b';\r
+  for (i = 0; i < num; i++) *p++ = ' ';\r
+  for (i = 0; i < num; i++) *p++ = '\b';\r
+  *p = '\0';\r
+}\r
+\r
+void CPercentPrinter::ClosePrint()\r
+{\r
+  if (m_NumExtraChars == 0)\r
+    return;\r
+  char s[kMaxExtraSize * 3 + 1];\r
+  ClearPrev(s, m_NumExtraChars);\r
+  (*OutStream) << s;\r
+  m_NumExtraChars = 0;\r
+}\r
+\r
+void CPercentPrinter::PrintString(const char *s)\r
+{\r
+  ClosePrint();\r
+  (*OutStream) << s;\r
+}\r
+\r
+void CPercentPrinter::PrintString(const wchar_t *s)\r
+{\r
+  ClosePrint();\r
+  (*OutStream) << s;\r
+}\r
+\r
+void CPercentPrinter::PrintNewLine()\r
+{\r
+  ClosePrint();\r
+  (*OutStream) << "\n";\r
+}\r
+\r
+void CPercentPrinter::RePrintRatio()\r
+{\r
+  char s[32];\r
+  ConvertUInt64ToString(((m_Total == 0) ? 0 : (m_CurValue * 100 / m_Total)), s);\r
+  int size = (int)strlen(s);\r
+  s[size++] = '%';\r
+  s[size] = '\0';\r
+\r
+  int extraSize = kPaddingSize + MyMax(size, kPercentsSize);\r
+  if (extraSize < m_NumExtraChars)\r
+    extraSize = m_NumExtraChars;\r
+\r
+  char fullString[kMaxExtraSize * 3];\r
+  char *p = fullString;\r
+  int i;\r
+  if (m_NumExtraChars == 0)\r
+  {\r
+    for (i = 0; i < extraSize; i++)\r
+      *p++ = ' ';\r
+    m_NumExtraChars = extraSize;\r
+  }\r
+\r
+  for (i = 0; i < m_NumExtraChars; i++)\r
+    *p++ = '\b';\r
+  m_NumExtraChars = extraSize;\r
+  for (; size < m_NumExtraChars; size++)\r
+    *p++ = ' ';\r
+  MyStringCopy(p, s);\r
+  (*OutStream) << fullString;\r
+  OutStream->Flush();\r
+  m_PrevValue = m_CurValue;\r
+}\r
+\r
+void CPercentPrinter::PrintRatio()\r
+{\r
+  if (m_CurValue < m_PrevValue + m_MinStepSize &&\r
+      m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0)\r
+    return;\r
+  RePrintRatio();\r
+}\r
diff --git a/CPP/7zip/UI/Console/PercentPrinter.h b/CPP/7zip/UI/Console/PercentPrinter.h
new file mode 100755 (executable)
index 0000000..212e11e
--- /dev/null
@@ -0,0 +1,31 @@
+// PercentPrinter.h\r
+\r
+#ifndef __PERCENTPRINTER_H\r
+#define __PERCENTPRINTER_H\r
+\r
+#include "Common/Types.h"\r
+#include "Common/StdOutStream.h"\r
+\r
+class CPercentPrinter\r
+{\r
+  UInt64 m_MinStepSize;\r
+  UInt64 m_PrevValue;\r
+  UInt64 m_CurValue;\r
+  UInt64 m_Total;\r
+  int m_NumExtraChars;\r
+public:\r
+  CStdOutStream *OutStream;\r
+\r
+  CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize),\r
+      m_PrevValue(0), m_CurValue(0), m_Total(1), m_NumExtraChars(0) {}\r
+  void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; }\r
+  void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; }\r
+  void PrintString(const char *s);\r
+  void PrintString(const wchar_t *s);\r
+  void PrintNewLine();\r
+  void ClosePrint();\r
+  void RePrintRatio();\r
+  void PrintRatio();\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/StdAfx.cpp b/CPP/7zip/UI/Console/StdAfx.cpp
new file mode 100755 (executable)
index 0000000..c6d3b1f
--- /dev/null
@@ -0,0 +1,3 @@
+// StdAfx.cpp\r
+\r
+#include "StdAfx.h"\r
diff --git a/CPP/7zip/UI/Console/StdAfx.h b/CPP/7zip/UI/Console/StdAfx.h
new file mode 100755 (executable)
index 0000000..a4e6173
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../../../Common/MyWindows.h"\r
+#include "../../../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
new file mode 100755 (executable)
index 0000000..c482676
--- /dev/null
@@ -0,0 +1,261 @@
+// UpdateCallbackConsole.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "UpdateCallbackConsole.h"\r
+\r
+#include "Windows/Error.h"\r
+#ifndef _7ZIP_ST\r
+#include "Windows/Synchronization.h"\r
+#endif\r
+\r
+#include "ConsoleClose.h"\r
+#include "UserInputUtils.h"\r
+\r
+using namespace NWindows;\r
+\r
+#ifndef _7ZIP_ST\r
+static NSynchronization::CCriticalSection g_CriticalSection;\r
+#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);\r
+#else\r
+#define MT_LOCK\r
+#endif\r
+\r
+static const wchar_t *kEmptyFileAlias = L"[Content]";\r
+\r
+static const char *kCreatingArchiveMessage = "Creating archive ";\r
+static const char *kUpdatingArchiveMessage = "Updating archive ";\r
+static const char *kScanningMessage = "Scanning";\r
+\r
+\r
+HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)\r
+{\r
+  (*OutStream) << endl;\r
+  if (result != S_OK)\r
+    (*OutStream) << "Error: " << name << " is not supported archive" << endl;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::StartScanning()\r
+{\r
+  (*OutStream) << kScanningMessage;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::ScanProgress(UInt64 /* numFolders */, UInt64 /* numFiles */, const wchar_t * /* path */)\r
+{\r
+  return CheckBreak();\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)\r
+{\r
+  CantFindFiles.Add(name);\r
+  CantFindCodes.Add(systemError);\r
+  // m_PercentPrinter.ClosePrint();\r
+  if (!m_WarningsMode)\r
+  {\r
+    (*OutStream) << endl << endl;\r
+    m_PercentPrinter.PrintNewLine();\r
+    m_WarningsMode = true;\r
+  }\r
+  m_PercentPrinter.PrintString(name);\r
+  m_PercentPrinter.PrintString(":  WARNING: ");\r
+  m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));\r
+  m_PercentPrinter.PrintNewLine();\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::FinishScanning()\r
+{\r
+  (*OutStream) << endl << endl;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)\r
+{\r
+  if(updating)\r
+    (*OutStream) << kUpdatingArchiveMessage;\r
+  else\r
+    (*OutStream) << kCreatingArchiveMessage;\r
+  if (name != 0)\r
+    (*OutStream) << name;\r
+  else\r
+    (*OutStream) << "StdOut";\r
+  (*OutStream) << endl << endl;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::FinishArchive()\r
+{\r
+  (*OutStream) << endl;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::CheckBreak()\r
+{\r
+  if (NConsoleClose::TestBreakSignal())\r
+    return E_ABORT;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::Finilize()\r
+{\r
+  MT_LOCK\r
+  if (m_NeedBeClosed)\r
+  {\r
+    if (EnablePercents)\r
+    {\r
+      m_PercentPrinter.ClosePrint();\r
+    }\r
+    if (!StdOutMode && m_NeedNewLine)\r
+    {\r
+      m_PercentPrinter.PrintNewLine();\r
+      m_NeedNewLine = false;\r
+    }\r
+    m_NeedBeClosed = false;\r
+  }\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::SetNumFiles(UInt64 /* numFiles */)\r
+{\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)\r
+{\r
+  MT_LOCK\r
+  if (EnablePercents)\r
+    m_PercentPrinter.SetTotal(size);\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)\r
+{\r
+  MT_LOCK\r
+  if (completeValue != NULL)\r
+  {\r
+    if (EnablePercents)\r
+    {\r
+      m_PercentPrinter.SetRatio(*completeValue);\r
+      m_PercentPrinter.PrintRatio();\r
+      m_NeedBeClosed = true;\r
+    }\r
+  }\r
+  if (NConsoleClose::TestBreakSignal())\r
+    return E_ABORT;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)\r
+{\r
+  if (NConsoleClose::TestBreakSignal())\r
+    return E_ABORT;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)\r
+{\r
+  MT_LOCK\r
+  if (StdOutMode)\r
+    return S_OK;\r
+  if(isAnti)\r
+    m_PercentPrinter.PrintString("Anti item    ");\r
+  else\r
+    m_PercentPrinter.PrintString("Compressing  ");\r
+  if (name[0] == 0)\r
+    name = kEmptyFileAlias;\r
+  m_PercentPrinter.PrintString(name);\r
+  if (EnablePercents)\r
+    m_PercentPrinter.RePrintRatio();\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)\r
+{\r
+  MT_LOCK\r
+  FailedCodes.Add(systemError);\r
+  FailedFiles.Add(name);\r
+  // if (systemError == ERROR_SHARING_VIOLATION)\r
+  {\r
+    m_PercentPrinter.ClosePrint();\r
+    m_PercentPrinter.PrintNewLine();\r
+    m_PercentPrinter.PrintString("WARNING: ");\r
+    m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));\r
+    return S_FALSE;\r
+  }\r
+  // return systemError;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 )\r
+{\r
+  m_NeedBeClosed = true;\r
+  m_NeedNewLine = true;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)\r
+{\r
+  *password = NULL;\r
+\r
+  #ifdef _NO_CRYPTO\r
+\r
+  *passwordIsDefined = false;\r
+  return S_OK;\r
+  \r
+  #else\r
+  \r
+  if (!PasswordIsDefined)\r
+  {\r
+    if (AskPassword)\r
+    {\r
+      Password = GetPassword(OutStream);\r
+      PasswordIsDefined = true;\r
+    }\r
+  }\r
+  *passwordIsDefined = BoolToInt(PasswordIsDefined);\r
+  return StringToBstr(Password, password);\r
+  \r
+  #endif\r
+}\r
+\r
+HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)\r
+{\r
+  *password = NULL;\r
+\r
+  #ifdef _NO_CRYPTO\r
+\r
+  return E_NOTIMPL;\r
+  \r
+  #else\r
+  \r
+  if (!PasswordIsDefined)\r
+  {\r
+    {\r
+      Password = GetPassword(OutStream);\r
+      PasswordIsDefined = true;\r
+    }\r
+  }\r
+  return StringToBstr(Password, password);\r
+  \r
+  #endif\r
+}\r
+\r
+/*\r
+HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name)\r
+{\r
+  // MT_LOCK\r
+  if (StdOutMode)\r
+    return S_OK;\r
+  RINOK(Finilize());\r
+  m_PercentPrinter.PrintString("Deleting  ");\r
+  if (name[0] == 0)\r
+    name = kEmptyFileAlias;\r
+  m_PercentPrinter.PrintString(name);\r
+  if (EnablePercents)\r
+    m_PercentPrinter.RePrintRatio();\r
+  m_NeedBeClosed = true;\r
+  m_NeedNewLine = true;\r
+  return S_OK;\r
+}\r
+*/\r
diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/CPP/7zip/UI/Console/UpdateCallbackConsole.h
new file mode 100755 (executable)
index 0000000..59581f3
--- /dev/null
@@ -0,0 +1,62 @@
+// UpdateCallbackConsole.h\r
+\r
+#ifndef __UPDATE_CALLBACK_CONSOLE_H\r
+#define __UPDATE_CALLBACK_CONSOLE_H\r
+\r
+#include "Common/StdOutStream.h"\r
+\r
+#include "../Common/Update.h"\r
+\r
+#include "PercentPrinter.h"\r
+\r
+class CUpdateCallbackConsole: public IUpdateCallbackUI2\r
+{\r
+  CPercentPrinter m_PercentPrinter;\r
+  bool m_NeedBeClosed;\r
+  bool m_NeedNewLine;\r
+\r
+  bool m_WarningsMode;\r
+\r
+  CStdOutStream *OutStream;\r
+public:\r
+  bool EnablePercents;\r
+  bool StdOutMode;\r
+\r
+  #ifndef _NO_CRYPTO\r
+  bool PasswordIsDefined;\r
+  UString Password;\r
+  bool AskPassword;\r
+  #endif\r
+\r
+  CUpdateCallbackConsole():\r
+      m_PercentPrinter(1 << 16),\r
+      #ifndef _NO_CRYPTO\r
+      PasswordIsDefined(false),\r
+      AskPassword(false),\r
+      #endif\r
+      StdOutMode(false),\r
+      EnablePercents(true),\r
+      m_WarningsMode(false)\r
+      {}\r
+  \r
+  ~CUpdateCallbackConsole() { Finilize(); }\r
+  void Init(CStdOutStream *outStream)\r
+  {\r
+    m_NeedBeClosed = false;\r
+    m_NeedNewLine = false;\r
+    FailedFiles.Clear();\r
+    FailedCodes.Clear();\r
+    OutStream = outStream;\r
+    m_PercentPrinter.OutStream = outStream;\r
+  }\r
+\r
+  INTERFACE_IUpdateCallbackUI2(;)\r
+\r
+  UStringVector FailedFiles;\r
+  CRecordVector<HRESULT> FailedCodes;\r
+\r
+  UStringVector CantFindFiles;\r
+  CRecordVector<HRESULT> CantFindCodes;\r
+};\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp
new file mode 100755 (executable)
index 0000000..68481c2
--- /dev/null
@@ -0,0 +1,87 @@
+// UserInputUtils.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/StdInStream.h"\r
+#include "Common/StringConvert.h"\r
+\r
+#include "UserInputUtils.h"\r
+\r
+static const char kYes = 'Y';\r
+static const char kNo = 'N';\r
+static const char kYesAll = 'A';\r
+static const char kNoAll = 'S';\r
+static const char kAutoRenameAll = 'U';\r
+static const char kQuit = 'Q';\r
+\r
+static const char *kFirstQuestionMessage = "?\n";\r
+static const char *kHelpQuestionMessage =\r
+  "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? ";\r
+\r
+// return true if pressed Quite;\r
+\r
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)\r
+{\r
+  (*outStream) << kFirstQuestionMessage;\r
+  for (;;)\r
+  {\r
+    (*outStream) << kHelpQuestionMessage;\r
+    outStream->Flush();\r
+    AString scannedString = g_StdIn.ScanStringUntilNewLine();\r
+    scannedString.Trim();\r
+    if (!scannedString.IsEmpty())\r
+      switch(\r
+        ::MyCharUpper(\r
+        #ifdef UNDER_CE\r
+        (wchar_t)\r
+        #endif\r
+        scannedString[0]))\r
+      {\r
+        case kYes:\r
+          return NUserAnswerMode::kYes;\r
+        case kNo:\r
+          return NUserAnswerMode::kNo;\r
+        case kYesAll:\r
+          return NUserAnswerMode::kYesAll;\r
+        case kNoAll:\r
+          return NUserAnswerMode::kNoAll;\r
+        case kAutoRenameAll:\r
+          return NUserAnswerMode::kAutoRenameAll;\r
+        case kQuit:\r
+          return NUserAnswerMode::kQuit;\r
+      }\r
+  }\r
+}\r
+\r
+#ifdef _WIN32\r
+#ifndef UNDER_CE\r
+#define MY_DISABLE_ECHO\r
+#endif\r
+#endif\r
+\r
+UString GetPassword(CStdOutStream *outStream)\r
+{\r
+  (*outStream) << "\nEnter password"\r
+      #ifdef MY_DISABLE_ECHO\r
+      " (will not be echoed)"\r
+      #endif\r
+      ":";\r
+  outStream->Flush();\r
+\r
+  #ifdef MY_DISABLE_ECHO\r
+  HANDLE console = GetStdHandle(STD_INPUT_HANDLE);\r
+  bool wasChanged = false;\r
+  DWORD mode = 0;\r
+  if (console != INVALID_HANDLE_VALUE && console != 0)\r
+    if (GetConsoleMode(console, &mode))\r
+      wasChanged = (SetConsoleMode(console, mode & ~ENABLE_ECHO_INPUT) != 0);\r
+  UString res = g_StdIn.ScanUStringUntilNewLine();\r
+  if (wasChanged)\r
+    SetConsoleMode(console, mode);\r
+  (*outStream) << "\n";\r
+  outStream->Flush();\r
+  return res;\r
+  #else\r
+  return g_StdIn.ScanUStringUntilNewLine();\r
+  #endif\r
+}\r
diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h
new file mode 100755 (executable)
index 0000000..3740ad7
--- /dev/null
@@ -0,0 +1,24 @@
+// UserInputUtils.h\r
+\r
+#ifndef __USERINPUTUTILS_H\r
+#define __USERINPUTUTILS_H\r
+\r
+#include "Common/StdOutStream.h"\r
+\r
+namespace NUserAnswerMode {\r
+\r
+enum EEnum\r
+{\r
+  kYes,\r
+  kNo,\r
+  kYesAll,\r
+  kNoAll,\r
+  kAutoRenameAll,\r
+  kQuit\r
+};\r
+}\r
+\r
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);\r
+UString GetPassword(CStdOutStream *outStream);\r
+\r
+#endif\r
diff --git a/CPP/7zip/UI/Console/makefile b/CPP/7zip/UI/Console/makefile
new file mode 100755 (executable)
index 0000000..0d40eb5
--- /dev/null
@@ -0,0 +1,124 @@
+PROG = 7z.exe\r
+MY_CONSOLE = 1\r
+CFLAGS = $(CFLAGS) -I ../../../  \\r
+  -DEXTERNAL_CODECS \\r
+\r
+!IFNDEF UNDER_CE\r
+CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE\r
+!ENDIF\r
+\r
+\r
+CONSOLE_OBJS = \\r
+  $O\ConsoleClose.obj \\r
+  $O\ExtractCallbackConsole.obj \\r
+  $O\List.obj \\r
+  $O\BenchCon.obj \\r
+  $O\Main.obj \\r
+  $O\MainAr.obj \\r
+  $O\OpenCallbackConsole.obj \\r
+  $O\PercentPrinter.obj \\r
+  $O\UpdateCallbackConsole.obj \\r
+  $O\UserInputUtils.obj \\r
+\r
+COMMON_OBJS = \\r
+  $O\CommandLineParser.obj \\r
+  $O\CRC.obj \\r
+  $O\IntToString.obj \\r
+  $O\ListFileUtils.obj \\r
+  $O\NewHandler.obj \\r
+  $O\StdInStream.obj \\r
+  $O\StdOutStream.obj \\r
+  $O\MyString.obj \\r
+  $O\StringConvert.obj \\r
+  $O\StringToInt.obj \\r
+  $O\UTFConvert.obj \\r
+  $O\MyVector.obj \\r
+  $O\Wildcard.obj \\r
+\r
+WIN_OBJS = \\r
+  $O\DLL.obj \\r
+  $O\Error.obj \\r
+  $O\FileDir.obj \\r
+  $O\FileFind.obj \\r
+  $O\FileIO.obj \\r
+  $O\FileName.obj \\r
+  $O\MemoryLock.obj \\r
+  $O\PropVariant.obj \\r
+  $O\PropVariantConversions.obj \\r
+  $O\Registry.obj \\r
+  $O\System.obj \\r
+  $O\Time.obj \\r
+\r
+7ZIP_COMMON_OBJS = \\r
+  $O\CreateCoder.obj \\r
+  $O\FilePathAutoRename.obj \\r
+  $O\FileStreams.obj \\r
+  $O\FilterCoder.obj \\r
+  $O\ProgressUtils.obj \\r
+  $O\StreamUtils.obj \\r
+\r
+UI_COMMON_OBJS = \\r
+  $O\ArchiveCommandLine.obj \\r
+  $O\ArchiveExtractCallback.obj \\r
+  $O\ArchiveOpenCallback.obj \\r
+  $O\DefaultName.obj \\r
+  $O\EnumDirItems.obj \\r
+  $O\Extract.obj \\r
+  $O\ExtractingFilePath.obj \\r
+  $O\Bench.obj \\r
+  $O\LoadCodecs.obj \\r
+  $O\OpenArchive.obj \\r
+  $O\PropIDUtils.obj \\r
+  $O\SetProperties.obj \\r
+  $O\SortUtils.obj \\r
+  $O\TempFiles.obj \\r
+  $O\Update.obj \\r
+  $O\UpdateAction.obj \\r
+  $O\UpdateCallback.obj \\r
+  $O\UpdatePair.obj \\r
+  $O\UpdateProduce.obj \\r
+  $O\WorkDir.obj \\r
+\r
+AR_COMMON_OBJS = \\r
+  $O\OutStreamWithCRC.obj \\r
+\r
+C_OBJS = \\r
+  $O\Alloc.obj \\r
+  $O\CpuArch.obj \\r
+  $O\Threads.obj \\r
+\r
+!include "../../Crc.mak"\r
+\r
+OBJS = \\r
+  $O\StdAfx.obj \\r
+  $(CONSOLE_OBJS) \\r
+  $(COMMON_OBJS) \\r
+  $(WIN_OBJS) \\r
+  $(7ZIP_COMMON_OBJS) \\r
+  $(UI_COMMON_OBJS) \\r
+  $(AR_COMMON_OBJS) \\r
+  $O\CopyCoder.obj \\r
+  $(C_OBJS) \\r
+  $(ASM_OBJS) \\r
+  $O\resource.res\r
+\r
+!include "../../../Build.mak"\r
+\r
+$(CONSOLE_OBJS): $(*B).cpp\r
+       $(COMPL)\r
+$(COMMON_OBJS): ../../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(WIN_OBJS): ../../../Windows/$(*B).cpp\r
+       $(COMPL)\r
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(UI_COMMON_OBJS): ../Common/$(*B).cpp\r
+       $(COMPL)\r
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp\r
+       $(COMPL)\r
+$O\CopyCoder.obj: ../../Compress/$(*B).cpp\r
+       $(COMPL)\r
+$(C_OBJS): ../../../../C/$(*B).c\r
+       $(COMPL_O2)\r
+\r
+!include "../../Asm.mak"\r
diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc
new file mode 100755 (executable)
index 0000000..20dfee1
--- /dev/null
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"\r
+\r
+MY_VERSION_INFO_APP("7-Zip Console", "7z")\r
diff --git a/CPP/Build.mak b/CPP/Build.mak
new file mode 100755 (executable)
index 0000000..81ac79d
--- /dev/null
@@ -0,0 +1,94 @@
+LIBS = $(LIBS) oleaut32.lib ole32.lib\r
+\r
+!IFDEF CPU\r
+!IFNDEF NO_BUFFEROVERFLOWU\r
+LIBS = $(LIBS) bufferoverflowU.lib\r
+!ENDIF\r
+!ENDIF\r
+\r
+\r
+!IFNDEF O\r
+!IFDEF CPU\r
+O=$(CPU)\r
+!ELSE\r
+O=O\r
+!ENDIF\r
+!ENDIF\r
+\r
+!IF "$(CPU)" == "AMD64"\r
+MY_ML = ml64 -Dx64\r
+!ELSEIF "$(CPU)" == "ARM"\r
+MY_ML = armasm\r
+!ELSE\r
+MY_ML = ml\r
+!ENDIF\r
+\r
+\r
+!IFDEF UNDER_CE\r
+RFLAGS = $(RFLAGS) -dUNDER_CE\r
+!IFDEF MY_CONSOLE\r
+LFLAGS = $(LFLAGS) /ENTRY:mainACRTStartup\r
+!ENDIF\r
+!ELSE\r
+!IFNDEF NEW_COMPILER\r
+LFLAGS = $(LFLAGS) -OPT:NOWIN98\r
+!ENDIF\r
+CFLAGS = $(CFLAGS) -Gr\r
+LIBS = $(LIBS) user32.lib advapi32.lib shell32.lib\r
+!ENDIF\r
+\r
+!IF "$(CPU)" == "ARM"\r
+COMPL_ASM = $(MY_ML) $** $O/$(*B).obj\r
+!ELSE\r
+COMPL_ASM = $(MY_ML) -c -Fo$O/ $**\r
+!ENDIF\r
+\r
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -WX -EHsc -Gy -GR-\r
+\r
+!IFDEF MY_STATIC_LINK\r
+!IFNDEF MY_SINGLE_THREAD\r
+CFLAGS = $(CFLAGS) -MT\r
+!ENDIF\r
+!ELSE\r
+CFLAGS = $(CFLAGS) -MD\r
+!ENDIF\r
+\r
+!IFDEF NEW_COMPILER\r
+CFLAGS = $(CFLAGS) -W4 -GS- -Zc:forScope\r
+!ELSE\r
+CFLAGS = $(CFLAGS) -W3\r
+!ENDIF\r
+\r
+CFLAGS_O1 = $(CFLAGS) -O1\r
+CFLAGS_O2 = $(CFLAGS) -O2\r
+\r
+LFLAGS = $(LFLAGS) -nologo -OPT:REF -OPT:ICF\r
+\r
+!IFDEF DEF_FILE\r
+LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE)\r
+!ENDIF\r
+\r
+PROGPATH = $O\$(PROG)\r
+\r
+COMPL_O1   = $(CC) $(CFLAGS_O1) $**\r
+COMPL_O2   = $(CC) $(CFLAGS_O2) $**\r
+COMPL_PCH  = $(CC) $(CFLAGS_O1) -Yc"StdAfx.h" -Fp$O/a.pch $**\r
+COMPL      = $(CC) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $**\r
+\r
+all: $(PROGPATH)\r
+\r
+clean:\r
+       -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch\r
+\r
+$O:\r
+       if not exist "$O" mkdir "$O"\r
+\r
+$(PROGPATH): $O $(OBJS) $(DEF_FILE)\r
+       link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)\r
+\r
+!IFNDEF NO_DEFAULT_RES\r
+$O\resource.res: $(*B).rc\r
+       rc $(RFLAGS) -fo$@ $**\r
+!ENDIF\r
+$O\StdAfx.obj: $(*B).cpp\r
+       $(COMPL_PCH)\r
diff --git a/CPP/Common/AutoPtr.h b/CPP/Common/AutoPtr.h
new file mode 100755 (executable)
index 0000000..e53fb7f
--- /dev/null
@@ -0,0 +1,35 @@
+// Common/AutoPtr.h\r
+\r
+#ifndef __COMMON_AUTOPTR_H\r
+#define __COMMON_AUTOPTR_H\r
+\r
+template<class T> class CMyAutoPtr\r
+{\r
+  T *_p;\r
+public:\r
+  CMyAutoPtr(T *p = 0) : _p(p) {}\r
+  CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {}\r
+  CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p)\r
+  {\r
+    reset(p.release());\r
+    return (*this);\r
+  }\r
+  ~CMyAutoPtr() { delete _p; }\r
+  T& operator*() const { return *_p; }\r
+  // T* operator->() const { return (&**this); }\r
+  T* get() const { return _p; }\r
+  T* release()\r
+  {\r
+    T *tmp = _p;\r
+    _p = 0;\r
+    return tmp;\r
+  }\r
+  void reset(T* p = 0)\r
+  {\r
+    if (p != _p)\r
+      delete _p;\r
+    _p = p;\r
+  }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/Common/Buffer.h b/CPP/Common/Buffer.h
new file mode 100755 (executable)
index 0000000..defe943
--- /dev/null
@@ -0,0 +1,77 @@
+// Common/Buffer.h\r
+\r
+#ifndef __COMMON_BUFFER_H\r
+#define __COMMON_BUFFER_H\r
+\r
+#include "Defs.h"\r
+\r
+template <class T> class CBuffer\r
+{\r
+protected:\r
+  size_t _capacity;\r
+  T *_items;\r
+public:\r
+  void Free()\r
+  {\r
+    delete []_items;\r
+    _items = 0;\r
+    _capacity = 0;\r
+  }\r
+  CBuffer(): _capacity(0), _items(0) {};\r
+  CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; }\r
+  CBuffer(size_t size): _items(0), _capacity(0) {  SetCapacity(size); }\r
+  virtual ~CBuffer() { delete []_items; }\r
+  operator T *() { return _items; };\r
+  operator const T *() const { return _items; };\r
+  size_t GetCapacity() const { return  _capacity; }\r
+  void SetCapacity(size_t newCapacity)\r
+  {\r
+    if (newCapacity == _capacity)\r
+      return;\r
+    T *newBuffer;\r
+    if (newCapacity > 0)\r
+    {\r
+      newBuffer = new T[newCapacity];\r
+      if (_capacity > 0)\r
+        memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T));\r
+    }\r
+    else\r
+      newBuffer = 0;\r
+    delete []_items;\r
+    _items = newBuffer;\r
+    _capacity = newCapacity;\r
+  }\r
+  CBuffer& operator=(const CBuffer &buffer)\r
+  {\r
+    Free();\r
+    if (buffer._capacity > 0)\r
+    {\r
+      SetCapacity(buffer._capacity);\r
+      memmove(_items, buffer._items, buffer._capacity * sizeof(T));\r
+    }\r
+    return *this;\r
+  }\r
+};\r
+\r
+template <class T>\r
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)\r
+{\r
+  if (b1.GetCapacity() != b2.GetCapacity())\r
+    return false;\r
+  for (size_t i = 0; i < b1.GetCapacity(); i++)\r
+    if (b1[i] != b2[i])\r
+      return false;\r
+  return true;\r
+}\r
+\r
+template <class T>\r
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)\r
+{\r
+  return !(b1 == b2);\r
+}\r
+\r
+typedef CBuffer<char> CCharBuffer;\r
+typedef CBuffer<wchar_t> CWCharBuffer;\r
+typedef CBuffer<unsigned char> CByteBuffer;\r
+\r
+#endif\r
diff --git a/CPP/Common/CRC.cpp b/CPP/Common/CRC.cpp
new file mode 100755 (executable)
index 0000000..6ac52c4
--- /dev/null
@@ -0,0 +1,7 @@
+// Common/CRC.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../C/7zCrc.h"\r
+\r
+struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit;\r
diff --git a/CPP/Common/C_FileIO.cpp b/CPP/Common/C_FileIO.cpp
new file mode 100755 (executable)
index 0000000..0e5647f
--- /dev/null
@@ -0,0 +1,88 @@
+// Common/C_FileIO.h\r
+\r
+#include "C_FileIO.h"\r
+\r
+#include <fcntl.h>\r
+#include <unistd.h>\r
+\r
+namespace NC {\r
+namespace NFile {\r
+namespace NIO {\r
+\r
+bool CFileBase::OpenBinary(const char *name, int flags)\r
+{\r
+  #ifdef O_BINARY\r
+  flags |= O_BINARY;\r
+  #endif\r
+  Close();\r
+  _handle = ::open(name, flags, 0666);\r
+  return _handle != -1;\r
+}\r
+\r
+bool CFileBase::Close()\r
+{\r
+  if (_handle == -1)\r
+    return true;\r
+  if (close(_handle) != 0)\r
+    return false;\r
+  _handle = -1;\r
+  return true;\r
+}\r
+\r
+bool CFileBase::GetLength(UInt64 &length) const\r
+{\r
+  off_t curPos = Seek(0, SEEK_CUR);\r
+  off_t lengthTemp = Seek(0, SEEK_END);\r
+  Seek(curPos, SEEK_SET);\r
+  length = (UInt64)lengthTemp;\r
+  return true;\r
+}\r
+\r
+off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const\r
+{\r
+  return ::lseek(_handle, distanceToMove, moveMethod);\r
+}\r
+\r
+/////////////////////////\r
+// CInFile\r
+\r
+bool CInFile::Open(const char *name)\r
+{\r
+  return CFileBase::OpenBinary(name, O_RDONLY);\r
+}\r
+\r
+bool CInFile::OpenShared(const char *name, bool)\r
+{\r
+  return Open(name);\r
+}\r
+\r
+ssize_t CInFile::Read(void *data, size_t size)\r
+{\r
+  return read(_handle, data, size);\r
+}\r
+\r
+/////////////////////////\r
+// COutFile\r
+\r
+bool COutFile::Create(const char *name, bool createAlways)\r
+{\r
+  if (createAlways)\r
+  {\r
+    Close();\r
+    _handle = ::creat(name, 0666);\r
+    return _handle != -1;\r
+  }\r
+  return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY);\r
+}\r
+\r
+bool COutFile::Open(const char *name, DWORD creationDisposition)\r
+{\r
+  return Create(name, false);\r
+}\r
+\r
+ssize_t COutFile::Write(const void *data, size_t size)\r
+{\r
+  return write(_handle, data, size);\r
+}\r
+\r
+}}}\r
diff --git a/CPP/Common/C_FileIO.h b/CPP/Common/C_FileIO.h
new file mode 100755 (executable)
index 0000000..3f8cbca
--- /dev/null
@@ -0,0 +1,47 @@
+// Common/C_FileIO.h\r
+\r
+#ifndef __COMMON_C_FILEIO_H\r
+#define __COMMON_C_FILEIO_H\r
+\r
+#include <stdio.h>\r
+#include <sys/types.h>\r
+\r
+#include "Types.h"\r
+#include "MyWindows.h"\r
+\r
+namespace NC {\r
+namespace NFile {\r
+namespace NIO {\r
+\r
+class CFileBase\r
+{\r
+protected:\r
+  int _handle;\r
+  bool OpenBinary(const char *name, int flags);\r
+public:\r
+  CFileBase(): _handle(-1) {};\r
+  ~CFileBase() { Close(); }\r
+  bool Close();\r
+  bool GetLength(UInt64 &length) const;\r
+  off_t Seek(off_t distanceToMove, int moveMethod) const;\r
+};\r
+\r
+class CInFile: public CFileBase\r
+{\r
+public:\r
+  bool Open(const char *name);\r
+  bool OpenShared(const char *name, bool shareForWrite);\r
+  ssize_t Read(void *data, size_t size);\r
+};\r
+\r
+class COutFile: public CFileBase\r
+{\r
+public:\r
+  bool Create(const char *name, bool createAlways);\r
+  bool Open(const char *name, DWORD creationDisposition);\r
+  ssize_t Write(const void *data, size_t size);\r
+};\r
+\r
+}}}\r
+\r
+#endif\r
diff --git a/CPP/Common/ComTry.h b/CPP/Common/ComTry.h
new file mode 100755 (executable)
index 0000000..b2b3029
--- /dev/null
@@ -0,0 +1,17 @@
+// ComTry.h\r
+\r
+#ifndef __COM_TRY_H\r
+#define __COM_TRY_H\r
+\r
+#include "MyWindows.h"\r
+// #include "Exception.h"\r
+// #include "NewHandler.h"\r
+\r
+#define COM_TRY_BEGIN try {\r
+#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; }\r
+  \r
+  // catch(const CNewException &) { return E_OUTOFMEMORY; }\r
+  // catch(const CSystemException &e) { return e.ErrorCode; }\r
+  // catch(...) { return E_FAIL; }\r
+\r
+#endif\r
diff --git a/CPP/Common/CommandLineParser.cpp b/CPP/Common/CommandLineParser.cpp
new file mode 100755 (executable)
index 0000000..028f4f8
--- /dev/null
@@ -0,0 +1,229 @@
+// CommandLineParser.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "CommandLineParser.h"\r
+\r
+namespace NCommandLineParser {\r
+\r
+bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)\r
+{\r
+  dest1.Empty();\r
+  dest2.Empty();\r
+  bool quoteMode = false;\r
+  int i;\r
+  for (i = 0; i < src.Length(); i++)\r
+  {\r
+    wchar_t c = src[i];\r
+    if (c == L' ' && !quoteMode)\r
+    {\r
+      dest2 = src.Mid(i + 1);\r
+      return i != 0;\r
+    }\r
+    if (c == L'\"')\r
+      quoteMode = !quoteMode;\r
+    else\r
+      dest1 += c;\r
+  }\r
+  return i != 0;\r
+}\r
+\r
+void SplitCommandLine(const UString &s, UStringVector &parts)\r
+{\r
+  UString sTemp = s;\r
+  sTemp.Trim();\r
+  parts.Clear();\r
+  for (;;)\r
+  {\r
+    UString s1, s2;\r
+    if (SplitCommandLine(sTemp, s1, s2))\r
+      parts.Add(s1);\r
+    if (s2.IsEmpty())\r
+      break;\r
+    sTemp = s2;\r
+  }\r
+}\r
+\r
+\r
+static const wchar_t kSwitchID1 = '-';\r
+// static const wchar_t kSwitchID2 = '/';\r
+\r
+static const wchar_t kSwitchMinus = '-';\r
+static const wchar_t *kStopSwitchParsing = L"--";\r
+\r
+static bool IsItSwitchChar(wchar_t c)\r
+{\r
+  return (c == kSwitchID1 /*|| c == kSwitchID2 */);\r
+}\r
+\r
+CParser::CParser(int numSwitches):\r
+  _numSwitches(numSwitches)\r
+{\r
+  _switches = new CSwitchResult[_numSwitches];\r
+}\r
+\r
+CParser::~CParser()\r
+{\r
+  delete []_switches;\r
+}\r
+\r
+void CParser::ParseStrings(const CSwitchForm *switchForms,\r
+  const UStringVector &commandStrings)\r
+{\r
+  int numCommandStrings = commandStrings.Size();\r
+  bool stopSwitch = false;\r
+  for (int i = 0; i < numCommandStrings; i++)\r
+  {\r
+    const UString &s = commandStrings[i];\r
+    if (stopSwitch)\r
+      NonSwitchStrings.Add(s);\r
+    else\r
+      if (s == kStopSwitchParsing)\r
+        stopSwitch = true;\r
+      else\r
+        if (!ParseString(s, switchForms))\r
+          NonSwitchStrings.Add(s);\r
+  }\r
+}\r
+\r
+// if string contains switch then function updates switch structures\r
+// out: (string is a switch)\r
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)\r
+{\r
+  int len = s.Length();\r
+  if (len == 0)\r
+    return false;\r
+  int pos = 0;\r
+  if (!IsItSwitchChar(s[pos]))\r
+    return false;\r
+  while (pos < len)\r
+  {\r
+    if (IsItSwitchChar(s[pos]))\r
+      pos++;\r
+    const int kNoLen = -1;\r
+    int matchedSwitchIndex = 0; // GCC Warning\r
+    int maxLen = kNoLen;\r
+    for (int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)\r
+    {\r
+      int switchLen = MyStringLen(switchForms[switchIndex].IDString);\r
+      if (switchLen <= maxLen || pos + switchLen > len)\r
+        continue;\r
+\r
+      UString temp = s + pos;\r
+      temp = temp.Left(switchLen);\r
+      if (temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)\r
+      // if (_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)\r
+      {\r
+        matchedSwitchIndex = switchIndex;\r
+        maxLen = switchLen;\r
+      }\r
+    }\r
+    if (maxLen == kNoLen)\r
+      throw "maxLen == kNoLen";\r
+    CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];\r
+    const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];\r
+    if ((!switchForm.Multi) && matchedSwitch.ThereIs)\r
+      throw "switch must be single";\r
+    matchedSwitch.ThereIs = true;\r
+    pos += maxLen;\r
+    int tailSize = len - pos;\r
+    NSwitchType::EEnum type = switchForm.Type;\r
+    switch(type)\r
+    {\r
+      case NSwitchType::kPostMinus:\r
+        {\r
+          if (tailSize == 0)\r
+            matchedSwitch.WithMinus = false;\r
+          else\r
+          {\r
+            matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);\r
+            if (matchedSwitch.WithMinus)\r
+              pos++;\r
+          }\r
+          break;\r
+        }\r
+      case NSwitchType::kPostChar:\r
+        {\r
+          if (tailSize < switchForm.MinLen)\r
+            throw "switch is not full";\r
+          UString set = switchForm.PostCharSet;\r
+          const int kEmptyCharValue = -1;\r
+          if (tailSize == 0)\r
+            matchedSwitch.PostCharIndex = kEmptyCharValue;\r
+          else\r
+          {\r
+            int index = set.Find(s[pos]);\r
+            if (index < 0)\r
+              matchedSwitch.PostCharIndex =  kEmptyCharValue;\r
+            else\r
+            {\r
+              matchedSwitch.PostCharIndex = index;\r
+              pos++;\r
+            }\r
+          }\r
+          break;\r
+        }\r
+      case NSwitchType::kLimitedPostString:\r
+      case NSwitchType::kUnLimitedPostString:\r
+        {\r
+          int minLen = switchForm.MinLen;\r
+          if (tailSize < minLen)\r
+            throw "switch is not full";\r
+          if (type == NSwitchType::kUnLimitedPostString)\r
+          {\r
+            matchedSwitch.PostStrings.Add(s.Mid(pos));\r
+            return true;\r
+          }\r
+          int maxLen = switchForm.MaxLen;\r
+          UString stringSwitch = s.Mid(pos, minLen);\r
+          pos += minLen;\r
+          for (int i = minLen; i < maxLen && pos < len; i++, pos++)\r
+          {\r
+            wchar_t c = s[pos];\r
+            if (IsItSwitchChar(c))\r
+              break;\r
+            stringSwitch += c;\r
+          }\r
+          matchedSwitch.PostStrings.Add(stringSwitch);\r
+          break;\r
+        }\r
+      case NSwitchType::kSimple:\r
+          break;\r
+    }\r
+  }\r
+  return true;\r
+}\r
+\r
+const CSwitchResult& CParser::operator[](size_t index) const\r
+{\r
+  return _switches[index];\r
+}\r
+\r
+/////////////////////////////////\r
+// Command parsing procedures\r
+\r
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,\r
+    const UString &commandString, UString &postString)\r
+{\r
+  for (int i = 0; i < numCommandForms; i++)\r
+  {\r
+    const UString id = commandForms[i].IDString;\r
+    if (commandForms[i].PostStringMode)\r
+    {\r
+      if (commandString.Find(id) == 0)\r
+      {\r
+        postString = commandString.Mid(id.Length());\r
+        return i;\r
+      }\r
+    }\r
+    else\r
+      if (commandString == id)\r
+      {\r
+        postString.Empty();\r
+        return i;\r
+      }\r
+  }\r
+  return -1;\r
+}\r
+   \r
+}\r
diff --git a/CPP/Common/CommandLineParser.h b/CPP/Common/CommandLineParser.h
new file mode 100755 (executable)
index 0000000..ec079e3
--- /dev/null
@@ -0,0 +1,72 @@
+// Common/CommandLineParser.h\r
+\r
+#ifndef __COMMON_COMMAND_LINE_PARSER_H\r
+#define __COMMON_COMMAND_LINE_PARSER_H\r
+\r
+#include "MyString.h"\r
+\r
+namespace NCommandLineParser {\r
+\r
+bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2);\r
+void SplitCommandLine(const UString &s, UStringVector &parts);\r
+\r
+namespace NSwitchType {\r
+  enum EEnum\r
+  {\r
+    kSimple,\r
+    kPostMinus,\r
+    kLimitedPostString,\r
+    kUnLimitedPostString,\r
+    kPostChar\r
+  };\r
+}\r
+\r
+struct CSwitchForm\r
+{\r
+  const wchar_t *IDString;\r
+  NSwitchType::EEnum Type;\r
+  bool Multi;\r
+  int MinLen;\r
+  int MaxLen;\r
+  const wchar_t *PostCharSet;\r
+};\r
+\r
+struct CSwitchResult\r
+{\r
+  bool ThereIs;\r
+  bool WithMinus;\r
+  UStringVector PostStrings;\r
+  int PostCharIndex;\r
+  CSwitchResult(): ThereIs(false) {};\r
+};\r
+  \r
+class CParser\r
+{\r
+  int _numSwitches;\r
+  CSwitchResult *_switches;\r
+  bool ParseString(const UString &s, const CSwitchForm *switchForms);\r
+public:\r
+  UStringVector NonSwitchStrings;\r
+  CParser(int numSwitches);\r
+  ~CParser();\r
+  void ParseStrings(const CSwitchForm *switchForms,\r
+    const UStringVector &commandStrings);\r
+  const CSwitchResult& operator[](size_t index) const;\r
+};\r
+\r
+/////////////////////////////////\r
+// Command parsing procedures\r
+\r
+struct CCommandForm\r
+{\r
+  const wchar_t *IDString;\r
+  bool PostStringMode;\r
+};\r
+\r
+// Returns: Index of form and postString; -1, if there is no match\r
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,\r
+    const UString &commandString, UString &postString);\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/Common/Defs.h b/CPP/Common/Defs.h
new file mode 100755 (executable)
index 0000000..69b8ece
--- /dev/null
@@ -0,0 +1,20 @@
+// Common/Defs.h\r
+\r
+#ifndef __COMMON_DEFS_H\r
+#define __COMMON_DEFS_H\r
+\r
+template <class T> inline T MyMin(T a, T b)\r
+  {  return a < b ? a : b; }\r
+template <class T> inline T MyMax(T a, T b)\r
+  {  return a > b ? a : b; }\r
+\r
+template <class T> inline int MyCompare(T a, T b)\r
+  {  return a < b ? -1 : (a == b ? 0 : 1); }\r
+\r
+inline int BoolToInt(bool value)\r
+  { return (value ? 1: 0); }\r
+\r
+inline bool IntToBool(int value)\r
+  { return (value != 0); }\r
+\r
+#endif\r
diff --git a/CPP/Common/DynamicBuffer.h b/CPP/Common/DynamicBuffer.h
new file mode 100755 (executable)
index 0000000..2bd80ac
--- /dev/null
@@ -0,0 +1,50 @@
+// Common/DynamicBuffer.h\r
+\r
+#ifndef __COMMON_DYNAMIC_BUFFER_H\r
+#define __COMMON_DYNAMIC_BUFFER_H\r
+\r
+#include "Buffer.h"\r
+\r
+template <class T> class CDynamicBuffer: public CBuffer<T>\r
+{\r
+  void GrowLength(size_t size)\r
+  {\r
+    size_t delta;\r
+    if (this->_capacity > 64)\r
+      delta = this->_capacity / 4;\r
+    else if (this->_capacity > 8)\r
+      delta = 16;\r
+    else\r
+      delta = 4;\r
+    delta = MyMax(delta, size);\r
+    size_t newCap = this->_capacity + delta;\r
+    if (newCap < delta)\r
+      newCap = this->_capacity + size;\r
+    SetCapacity(newCap);\r
+  }\r
+public:\r
+  CDynamicBuffer(): CBuffer<T>() {};\r
+  CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer<T>(buffer) {};\r
+  CDynamicBuffer(size_t size): CBuffer<T>(size) {};\r
+  CDynamicBuffer& operator=(const CDynamicBuffer &buffer)\r
+  {\r
+    this->Free();\r
+    if (buffer._capacity > 0)\r
+    {\r
+      SetCapacity(buffer._capacity);\r
+      memmove(this->_items, buffer._items, buffer._capacity * sizeof(T));\r
+    }\r
+    return *this;\r
+  }\r
+  void EnsureCapacity(size_t capacity)\r
+  {\r
+    if (this->_capacity < capacity)\r
+      GrowLength(capacity - this->_capacity);\r
+  }\r
+};\r
+\r
+typedef CDynamicBuffer<char> CCharDynamicBuffer;\r
+typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer;\r
+typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;\r
+\r
+#endif\r
diff --git a/CPP/Common/IntToString.cpp b/CPP/Common/IntToString.cpp
new file mode 100755 (executable)
index 0000000..312e9f0
--- /dev/null
@@ -0,0 +1,77 @@
+// Common/IntToString.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "IntToString.h"\r
+\r
+void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base)\r
+{\r
+  if (base < 2 || base > 36)\r
+  {\r
+    *s = '\0';\r
+    return;\r
+  }\r
+  char temp[72];\r
+  int pos = 0;\r
+  do\r
+  {\r
+    int delta = (int)(value % base);\r
+    temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10)));\r
+    value /= base;\r
+  }\r
+  while (value != 0);\r
+  do\r
+    *s++ = temp[--pos];\r
+  while (pos > 0);\r
+  *s = '\0';\r
+}\r
+\r
+void ConvertUInt64ToString(UInt64 value, wchar_t *s)\r
+{\r
+  wchar_t temp[32];\r
+  int pos = 0;\r
+  do\r
+  {\r
+    temp[pos++] = (wchar_t)(L'0' + (int)(value % 10));\r
+    value /= 10;\r
+  }\r
+  while (value != 0);\r
+  do\r
+    *s++ = temp[--pos];\r
+  while (pos > 0);\r
+  *s = L'\0';\r
+}\r
+\r
+void ConvertUInt32ToString(UInt32 value, char *s) { ConvertUInt64ToString(value, s); }\r
+void ConvertUInt32ToString(UInt32 value, wchar_t *s) { ConvertUInt64ToString(value, s); }\r
+\r
+void ConvertInt64ToString(Int64 value, char *s)\r
+{\r
+  if (value < 0)\r
+  {\r
+    *s++ = '-';\r
+    value = -value;\r
+  }\r
+  ConvertUInt64ToString(value, s);\r
+}\r
+\r
+void ConvertInt64ToString(Int64 value, wchar_t *s)\r
+{\r
+  if (value < 0)\r
+  {\r
+    *s++ = L'-';\r
+    value = -value;\r
+  }\r
+  ConvertUInt64ToString(value, s);\r
+}\r
+\r
+void ConvertUInt32ToHexWithZeros(UInt32 value, char *s)\r
+{\r
+  for (int i = 0; i < 8; i++)\r
+  {\r
+    int t = value & 0xF;\r
+    value >>= 4;\r
+    s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));\r
+  }\r
+  s[8] = '\0';\r
+}\r
diff --git a/CPP/Common/IntToString.h b/CPP/Common/IntToString.h
new file mode 100755 (executable)
index 0000000..c57fd6a
--- /dev/null
@@ -0,0 +1,19 @@
+// Common/IntToString.h\r
+\r
+#ifndef __COMMON_INT_TO_STRING_H\r
+#define __COMMON_INT_TO_STRING_H\r
+\r
+#include <stddef.h>\r
+#include "Types.h"\r
+\r
+void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10);\r
+void ConvertUInt64ToString(UInt64 value, wchar_t *s);\r
+void ConvertInt64ToString(Int64 value, char *s);\r
+void ConvertInt64ToString(Int64 value, wchar_t *s);\r
+\r
+void ConvertUInt32ToString(UInt32 value, char *s);\r
+void ConvertUInt32ToString(UInt32 value, wchar_t *s);\r
+\r
+void ConvertUInt32ToHexWithZeros(UInt32 value, char *s);\r
+\r
+#endif\r
diff --git a/CPP/Common/ListFileUtils.cpp b/CPP/Common/ListFileUtils.cpp
new file mode 100755 (executable)
index 0000000..ff61b02
--- /dev/null
@@ -0,0 +1,75 @@
+// Common/ListFileUtils.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "MyWindows.h"\r
+#include "../Windows/FileIO.h"\r
+\r
+#include "ListFileUtils.h"\r
+#include "StringConvert.h"\r
+#include "UTFConvert.h"\r
+\r
+static const char kQuoteChar     = '\"';\r
+static void RemoveQuote(UString &s)\r
+{\r
+  if (s.Length() >= 2)\r
+    if (s[0] == kQuoteChar && s[s.Length() - 1] == kQuoteChar)\r
+      s = s.Mid(1, s.Length() - 2);\r
+}\r
+\r
+bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &resultStrings, UINT codePage)\r
+{\r
+  NWindows::NFile::NIO::CInFile file;\r
+  if (!file.Open(fileName))\r
+    return false;\r
+  UInt64 length;\r
+  if (!file.GetLength(length))\r
+    return false;\r
+  if (length > ((UInt32)1 << 31))\r
+    return false;\r
+  AString s;\r
+  char *p = s.GetBuffer((int)length + 1);\r
+  UInt32 processed;\r
+  if (!file.Read(p, (UInt32)length, processed))\r
+    return false;\r
+  p[(UInt32)length] = 0;\r
+  s.ReleaseBuffer();\r
+  file.Close();\r
+\r
+  UString u;\r
+  #ifdef CP_UTF8\r
+  if (codePage == CP_UTF8)\r
+  {\r
+    if (!ConvertUTF8ToUnicode(s, u))\r
+      return false;\r
+  }\r
+  else\r
+  #endif\r
+    u = MultiByteToUnicodeString(s, codePage);\r
+  if (!u.IsEmpty())\r
+  {\r
+    if (u[0] == 0xFEFF)\r
+      u.Delete(0);\r
+  }\r
+\r
+  UString t;\r
+  for (int i = 0; i < u.Length(); i++)\r
+  {\r
+    wchar_t c = u[i];\r
+    if (c == L'\n' || c == 0xD)\r
+    {\r
+      t.Trim();\r
+      RemoveQuote(t);\r
+      if (!t.IsEmpty())\r
+        resultStrings.Add(t);\r
+      t.Empty();\r
+    }\r
+    else\r
+      t += c;\r
+  }\r
+  t.Trim();\r
+  RemoveQuote(t);\r
+  if (!t.IsEmpty())\r
+    resultStrings.Add(t);\r
+  return true;\r
+}\r
diff --git a/CPP/Common/ListFileUtils.h b/CPP/Common/ListFileUtils.h
new file mode 100755 (executable)
index 0000000..64f2199
--- /dev/null
@@ -0,0 +1,11 @@
+// Common/ListFileUtils.h\r
+\r
+#ifndef __COMMON_LISTFILEUTILS_H\r
+#define __COMMON_LISTFILEUTILS_H\r
+\r
+#include "MyString.h"\r
+#include "Types.h"\r
+\r
+bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);\r
+\r
+#endif\r
diff --git a/CPP/Common/MyCom.h b/CPP/Common/MyCom.h
new file mode 100755 (executable)
index 0000000..d04fa4c
--- /dev/null
@@ -0,0 +1,225 @@
+// MyCom.h\r
+\r
+#ifndef __MYCOM_H\r
+#define __MYCOM_H\r
+\r
+#include "MyWindows.h"\r
+\r
+#ifndef RINOK\r
+#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }\r
+#endif\r
+\r
+template <class T>\r
+class CMyComPtr\r
+{\r
+  T* _p;\r
+public:\r
+  // typedef T _PtrClass;\r
+  CMyComPtr() { _p = NULL;}\r
+  CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }\r
+  CMyComPtr(const CMyComPtr<T>& lp)\r
+  {\r
+    if ((_p = lp._p) != NULL)\r
+      _p->AddRef();\r
+  }\r
+  ~CMyComPtr() { if (_p) _p->Release(); }\r
+  void Release() { if (_p) { _p->Release(); _p = NULL; } }\r
+  operator T*() const {  return (T*)_p;  }\r
+  // T& operator*() const {  return *_p; }\r
+  T** operator&() { return &_p; }\r
+  T* operator->() const { return _p; }\r
+  T* operator=(T* p)\r
+  {\r
+    if (p != 0)\r
+      p->AddRef();\r
+    if (_p)\r
+      _p->Release();\r
+    _p = p;\r
+    return p;\r
+  }\r
+  T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }\r
+  bool operator!() const { return (_p == NULL); }\r
+  // bool operator==(T* pT) const {  return _p == pT; }\r
+  // Compare two objects for equivalence\r
+  void Attach(T* p2)\r
+  {\r
+    Release();\r
+    _p = p2;\r
+  }\r
+  T* Detach()\r
+  {\r
+    T* pt = _p;\r
+    _p = NULL;\r
+    return pt;\r
+  }\r
+  #ifdef _WIN32\r
+  HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)\r
+  {\r
+    return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);\r
+  }\r
+  #endif\r
+  /*\r
+  HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)\r
+  {\r
+    CLSID clsid;\r
+    HRESULT hr = CLSIDFromProgID(szProgID, &clsid);\r
+    ATLASSERT(_p == NULL);\r
+    if (SUCCEEDED(hr))\r
+      hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);\r
+    return hr;\r
+  }\r
+  */\r
+  template <class Q>\r
+  HRESULT QueryInterface(REFGUID iid, Q** pp) const\r
+  {\r
+    return _p->QueryInterface(iid, (void**)pp);\r
+  }\r
+};\r
+\r
+//////////////////////////////////////////////////////////\r
+\r
+inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)\r
+{\r
+  *bstr = ::SysAllocString(src);\r
+  return (*bstr != 0) ? S_OK : E_OUTOFMEMORY;\r
+}\r
+\r
+class CMyComBSTR\r
+{\r
+public:\r
+  BSTR m_str;\r
+  CMyComBSTR(): m_str(NULL) {}\r
+  CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }\r
+  // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }\r
+  // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize);  }\r
+  CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }\r
+  /*\r
+  CMyComBSTR(REFGUID src)\r
+  {\r
+    LPOLESTR szGuid;\r
+    StringFromCLSID(src, &szGuid);\r
+    m_str = ::SysAllocString(szGuid);\r
+    CoTaskMemFree(szGuid);\r
+  }\r
+  */\r
+  ~CMyComBSTR() { ::SysFreeString(m_str); }\r
+  CMyComBSTR& operator=(const CMyComBSTR& src)\r
+  {\r
+    if (m_str != src.m_str)\r
+    {\r
+      if (m_str)\r
+        ::SysFreeString(m_str);\r
+      m_str = src.MyCopy();\r
+    }\r
+    return *this;\r
+  }\r
+  CMyComBSTR& operator=(LPCOLESTR src)\r
+  {\r
+    ::SysFreeString(m_str);\r
+    m_str = ::SysAllocString(src);\r
+    return *this;\r
+  }\r
+  unsigned int Length() const { return ::SysStringLen(m_str); }\r
+  operator BSTR() const { return m_str; }\r
+  BSTR* operator&() { return &m_str; }\r
+  BSTR MyCopy() const\r
+  {\r
+    int byteLen = ::SysStringByteLen(m_str);\r
+    BSTR res = ::SysAllocStringByteLen(NULL, byteLen);\r
+    memcpy(res, m_str, byteLen);\r
+    return res;\r
+  }\r
+  /*\r
+  void Attach(BSTR src) { m_str = src; }\r
+  BSTR Detach()\r
+  {\r
+    BSTR s = m_str;\r
+    m_str = NULL;\r
+    return s;\r
+  }\r
+  */\r
+  void Empty()\r
+  {\r
+    ::SysFreeString(m_str);\r
+    m_str = NULL;\r
+  }\r
+  bool operator!() const {  return (m_str == NULL); }\r
+};\r
+\r
+//////////////////////////////////////////////////////////\r
+\r
+class CMyUnknownImp\r
+{\r
+public:\r
+  ULONG __m_RefCount;\r
+  CMyUnknownImp(): __m_RefCount(0) {}\r
+};\r
+\r
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \\r
+    (REFGUID iid, void **outObject) {\r
+\r
+#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \\r
+    { *outObject = (void *)(i *)this; AddRef(); return S_OK; }\r
+\r
+#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \\r
+    { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; }\r
+\r
+#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \\r
+    MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \\r
+    MY_QUERYINTERFACE_ENTRY(i)\r
+\r
+#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }\r
+\r
+#define MY_ADDREF_RELEASE \\r
+STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \\r
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0)  \\r
+  return __m_RefCount; delete this; return 0; }\r
+\r
+#define MY_UNKNOWN_IMP_SPEC(i) \\r
+  MY_QUERYINTERFACE_BEGIN \\r
+  i \\r
+  MY_QUERYINTERFACE_END \\r
+  MY_ADDREF_RELEASE\r
+\r
+\r
+#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \\r
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \\r
+  MY_QUERYINTERFACE_END \\r
+  MY_ADDREF_RELEASE\r
+\r
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \\r
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \\r
+  MY_QUERYINTERFACE_ENTRY(i) \\r
+  )\r
+\r
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \\r
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \\r
+  MY_QUERYINTERFACE_ENTRY(i1) \\r
+  MY_QUERYINTERFACE_ENTRY(i2) \\r
+  )\r
+\r
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \\r
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \\r
+  MY_QUERYINTERFACE_ENTRY(i1) \\r
+  MY_QUERYINTERFACE_ENTRY(i2) \\r
+  MY_QUERYINTERFACE_ENTRY(i3) \\r
+  )\r
+\r
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \\r
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \\r
+  MY_QUERYINTERFACE_ENTRY(i1) \\r
+  MY_QUERYINTERFACE_ENTRY(i2) \\r
+  MY_QUERYINTERFACE_ENTRY(i3) \\r
+  MY_QUERYINTERFACE_ENTRY(i4) \\r
+  )\r
+\r
+#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \\r
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \\r
+  MY_QUERYINTERFACE_ENTRY(i1) \\r
+  MY_QUERYINTERFACE_ENTRY(i2) \\r
+  MY_QUERYINTERFACE_ENTRY(i3) \\r
+  MY_QUERYINTERFACE_ENTRY(i4) \\r
+  MY_QUERYINTERFACE_ENTRY(i5) \\r
+  )\r
+\r
+#endif\r
diff --git a/CPP/Common/MyException.h b/CPP/Common/MyException.h
new file mode 100755 (executable)
index 0000000..cd9fe69
--- /dev/null
@@ -0,0 +1,14 @@
+// Common/Exception.h\r
+\r
+#ifndef __COMMON_EXCEPTION_H\r
+#define __COMMON_EXCEPTION_H\r
+\r
+#include "MyWindows.h"\r
+\r
+struct CSystemException\r
+{\r
+  HRESULT ErrorCode;\r
+  CSystemException(HRESULT errorCode): ErrorCode(errorCode) {}\r
+};\r
+\r
+#endif\r
diff --git a/CPP/Common/MyGuidDef.h b/CPP/Common/MyGuidDef.h
new file mode 100755 (executable)
index 0000000..da73d0a
--- /dev/null
@@ -0,0 +1,54 @@
+// Common/MyGuidDef.h\r
+\r
+#ifndef GUID_DEFINED\r
+#define GUID_DEFINED\r
+\r
+#include "Types.h"\r
+\r
+typedef struct {\r
+  UInt32 Data1;\r
+  UInt16 Data2;\r
+  UInt16 Data3;\r
+  unsigned char Data4[8];\r
+} GUID;\r
+\r
+#ifdef __cplusplus\r
+#define REFGUID const GUID &\r
+#else\r
+#define REFGUID const GUID *\r
+#endif\r
+\r
+#define REFCLSID REFGUID\r
+#define REFIID REFGUID\r
+\r
+#ifdef __cplusplus\r
+inline int operator==(REFGUID g1, REFGUID g2)\r
+{\r
+  for (int i = 0; i < (int)sizeof(g1); i++)\r
+    if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])\r
+      return 0;\r
+  return 1;\r
+}\r
+inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+  #define MY_EXTERN_C extern "C"\r
+#else\r
+  #define MY_EXTERN_C extern\r
+#endif\r
+\r
+#endif\r
+\r
+\r
+#ifdef DEFINE_GUID\r
+#undef DEFINE_GUID\r
+#endif\r
+\r
+#ifdef INITGUID\r
+  #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \\r
+    MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }\r
+#else\r
+  #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \\r
+    MY_EXTERN_C const GUID name\r
+#endif\r
diff --git a/CPP/Common/MyInitGuid.h b/CPP/Common/MyInitGuid.h
new file mode 100755 (executable)
index 0000000..98d1705
--- /dev/null
@@ -0,0 +1,22 @@
+// Common/MyInitGuid.h\r
+\r
+#ifndef __COMMON_MY_INITGUID_H\r
+#define __COMMON_MY_INITGUID_H\r
+\r
+#ifdef _WIN32\r
+#ifdef UNDER_CE\r
+#include <basetyps.h>\r
+#endif\r
+#include <initguid.h>\r
+#ifdef UNDER_CE\r
+DEFINE_GUID(IID_IUnknown,\r
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);\r
+#endif\r
+#else\r
+#define INITGUID\r
+#include "MyGuidDef.h"\r
+DEFINE_GUID(IID_IUnknown,\r
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);\r
+#endif\r
+\r
+#endif\r
diff --git a/CPP/Common/MyString.cpp b/CPP/Common/MyString.cpp
new file mode 100755 (executable)
index 0000000..1a25c9e
--- /dev/null
@@ -0,0 +1,200 @@
+// Common/MyString.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#ifndef _WIN32\r
+#include <ctype.h>\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+#include "StringConvert.h"\r
+#endif\r
+\r
+#include "MyString.h"\r
+\r
+\r
+#ifdef _WIN32\r
+\r
+#ifndef _UNICODE\r
+\r
+wchar_t MyCharUpper(wchar_t c)\r
+{\r
+  if (c == 0)\r
+    return 0;\r
+  wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);\r
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)\r
+    return (wchar_t)(unsigned int)(UINT_PTR)res;\r
+  const int kBufferSize = 4;\r
+  char s[kBufferSize + 1];\r
+  int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);\r
+  if (numChars == 0 || numChars > kBufferSize)\r
+    return c;\r
+  s[numChars] = 0;\r
+  ::CharUpperA(s);\r
+  ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);\r
+  return c;\r
+}\r
+\r
+wchar_t MyCharLower(wchar_t c)\r
+{\r
+  if (c == 0)\r
+    return 0;\r
+  wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);\r
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)\r
+    return (wchar_t)(unsigned int)(UINT_PTR)res;\r
+  const int kBufferSize = 4;\r
+  char s[kBufferSize + 1];\r
+  int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);\r
+  if (numChars == 0 || numChars > kBufferSize)\r
+    return c;\r
+  s[numChars] = 0;\r
+  ::CharLowerA(s);\r
+  ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);\r
+  return c;\r
+}\r
+\r
+wchar_t * MyStringUpper(wchar_t *s)\r
+{\r
+  if (s == 0)\r
+    return 0;\r
+  wchar_t *res = CharUpperW(s);\r
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)\r
+    return res;\r
+  AString a = UnicodeStringToMultiByte(s);\r
+  a.MakeUpper();\r
+  return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));\r
+}\r
+\r
+wchar_t * MyStringLower(wchar_t *s)\r
+{\r
+  if (s == 0)\r
+    return 0;\r
+  wchar_t *res = CharLowerW(s);\r
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)\r
+    return res;\r
+  AString a = UnicodeStringToMultiByte(s);\r
+  a.MakeLower();\r
+  return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));\r
+}\r
+\r
+#endif\r
+\r
+/*\r
+inline int ConvertCompareResult(int r) { return r - 2; }\r
+\r
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2)\r
+{\r
+  int res = CompareStringW(\r
+        LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1);\r
+  #ifdef _UNICODE\r
+  return ConvertCompareResult(res);\r
+  #else\r
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)\r
+    return ConvertCompareResult(res);\r
+  return MyStringCollate(UnicodeStringToMultiByte(s1),\r
+        UnicodeStringToMultiByte(s2));\r
+  #endif\r
+}\r
+\r
+#ifndef UNDER_CE\r
+int MyStringCollate(const char *s1, const char *s2)\r
+{\r
+  return ConvertCompareResult(CompareStringA(\r
+    LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1));\r
+}\r
+\r
+int MyStringCollateNoCase(const char *s1, const char *s2)\r
+{\r
+  return ConvertCompareResult(CompareStringA(\r
+    LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1));\r
+}\r
+#endif\r
+\r
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)\r
+{\r
+  int res = CompareStringW(\r
+        LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1);\r
+  #ifdef _UNICODE\r
+  return ConvertCompareResult(res);\r
+  #else\r
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)\r
+    return ConvertCompareResult(res);\r
+  return MyStringCollateNoCase(UnicodeStringToMultiByte(s1),\r
+      UnicodeStringToMultiByte(s2));\r
+  #endif\r
+}\r
+*/\r
+\r
+#else\r
+\r
+wchar_t MyCharUpper(wchar_t c)\r
+{\r
+  return toupper(c);\r
+}\r
+\r
+/*\r
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)\r
+{\r
+  for (;;)\r
+  {\r
+    wchar_t c1 = *s1++;\r
+    wchar_t c2 = *s2++;\r
+    wchar_t u1 = MyCharUpper(c1);\r
+    wchar_t u2 = MyCharUpper(c2);\r
+\r
+    if (u1 < u2) return -1;\r
+    if (u1 > u2) return 1;\r
+    if (u1 == 0) return 0;\r
+  }\r
+}\r
+*/\r
+\r
+#endif\r
+\r
+int MyStringCompare(const char *s1, const char *s2)\r
+{\r
+  for (;;)\r
+  {\r
+    unsigned char c1 = (unsigned char)*s1++;\r
+    unsigned char c2 = (unsigned char)*s2++;\r
+    if (c1 < c2) return -1;\r
+    if (c1 > c2) return 1;\r
+    if (c1 == 0) return 0;\r
+  }\r
+}\r
+\r
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2)\r
+{\r
+  for (;;)\r
+  {\r
+    wchar_t c1 = *s1++;\r
+    wchar_t c2 = *s2++;\r
+    if (c1 < c2) return -1;\r
+    if (c1 > c2) return 1;\r
+    if (c1 == 0) return 0;\r
+  }\r
+}\r
+\r
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)\r
+{\r
+  for (;;)\r
+  {\r
+    wchar_t c1 = *s1++;\r
+    wchar_t c2 = *s2++;\r
+    if (c1 != c2)\r
+    {\r
+      wchar_t u1 = MyCharUpper(c1);\r
+      wchar_t u2 = MyCharUpper(c2);\r
+      if (u1 < u2) return -1;\r
+      if (u1 > u2) return 1;\r
+    }\r
+    if (c1 == 0) return 0;\r
+  }\r
+}\r
+\r
+/*\r
+int MyStringCompareNoCase(const char *s1, const char *s2)\r
+{\r
+  return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));\r
+}\r
+*/\r
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
new file mode 100755 (executable)
index 0000000..ede2573
--- /dev/null
@@ -0,0 +1,625 @@
+// Common/String.h\r
+\r
+#ifndef __COMMON_STRING_H\r
+#define __COMMON_STRING_H\r
+\r
+#include <string.h>\r
+\r
+#include "MyVector.h"\r
+\r
+template <class T>\r
+inline int MyStringLen(const T *s)\r
+{\r
+  int i;\r
+  for (i = 0; s[i] != '\0'; i++);\r
+  return i;\r
+}\r
+\r
+template <class T>\r
+inline T * MyStringCopy(T *dest, const T *src)\r
+{\r
+  T *destStart = dest;\r
+  while ((*dest++ = *src++) != 0);\r
+  return destStart;\r
+}\r
+\r
+inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)\r
+  { return (p + 1); }\r
+inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)\r
+  { return (p + 1); }\r
+inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)\r
+  { return (p - 1); }\r
+inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)\r
+  { return (p - 1); }\r
+\r
+#ifdef _WIN32\r
+\r
+inline const char* MyStringGetNextCharPointer(const char *p)\r
+{\r
+  #ifdef UNDER_CE\r
+  return p + 1;\r
+  #else\r
+  return CharNextA(p);\r
+  #endif\r
+}\r
+\r
+inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)\r
+  { return CharPrevA(base, p); }\r
+\r
+inline char MyCharUpper(char c)\r
+  { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }\r
+#ifdef _UNICODE\r
+inline wchar_t MyCharUpper(wchar_t c)\r
+  { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }\r
+#else\r
+wchar_t MyCharUpper(wchar_t c);\r
+#endif\r
+\r
+#ifdef _UNICODE\r
+inline wchar_t MyCharLower(wchar_t c)\r
+  { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }\r
+#else\r
+wchar_t MyCharLower(wchar_t c);\r
+#endif\r
+\r
+inline char MyCharLower(char c)\r
+#ifdef UNDER_CE\r
+  { return (char)MyCharLower((wchar_t)c); }\r
+#else\r
+  { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }\r
+#endif\r
+\r
+inline char * MyStringUpper(char *s) { return CharUpperA(s); }\r
+#ifdef _UNICODE\r
+inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }\r
+#else\r
+wchar_t * MyStringUpper(wchar_t *s);\r
+#endif\r
+\r
+inline char * MyStringLower(char *s) { return CharLowerA(s); }\r
+#ifdef _UNICODE\r
+inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }\r
+#else\r
+wchar_t * MyStringLower(wchar_t *s);\r
+#endif\r
+\r
+#else // Standard-C\r
+wchar_t MyCharUpper(wchar_t c);\r
+#endif\r
+\r
+//////////////////////////////////////\r
+// Compare\r
+\r
+/*\r
+#ifndef UNDER_CE\r
+int MyStringCollate(const char *s1, const char *s2);\r
+int MyStringCollateNoCase(const char *s1, const char *s2);\r
+#endif\r
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2);\r
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);\r
+*/\r
+\r
+int MyStringCompare(const char *s1, const char  *s2);\r
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2);\r
+\r
+// int MyStringCompareNoCase(const char *s1, const char  *s2);\r
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);\r
+\r
+template <class T>\r
+class CStringBase\r
+{\r
+  void TrimLeftWithCharSet(const CStringBase &charSet)\r
+  {\r
+    const T *p = _chars;\r
+    while (charSet.Find(*p) >= 0 && (*p != 0))\r
+      p = GetNextCharPointer(p);\r
+    Delete(0, (int)(p - _chars));\r
+  }\r
+  void TrimRightWithCharSet(const CStringBase &charSet)\r
+  {\r
+    const T *p = _chars;\r
+    const T *pLast = NULL;\r
+    while (*p != 0)\r
+    {\r
+      if (charSet.Find(*p) >= 0)\r
+      {\r
+        if (pLast == NULL)\r
+          pLast = p;\r
+      }\r
+      else\r
+        pLast = NULL;\r
+      p = GetNextCharPointer(p);\r
+    }\r
+    if (pLast != NULL)\r
+    {\r
+      int i = (int)(pLast - _chars);\r
+      Delete(i, _length - i);\r
+    }\r
+\r
+  }\r
+  void MoveItems(int destIndex, int srcIndex)\r
+  {\r
+    memmove(_chars + destIndex, _chars + srcIndex,\r
+        sizeof(T) * (_length - srcIndex + 1));\r
+  }\r
+  \r
+  void InsertSpace(int &index, int size)\r
+  {\r
+    CorrectIndex(index);\r
+    GrowLength(size);\r
+    MoveItems(index + size, index);\r
+  }\r
+\r
+  static const T *GetNextCharPointer(const T *p)\r
+    { return MyStringGetNextCharPointer(p); }\r
+  static const T *GetPrevCharPointer(const T *base, const T *p)\r
+    { return MyStringGetPrevCharPointer(base, p); }\r
+protected:\r
+  T *_chars;\r
+  int _length;\r
+  int _capacity;\r
+  \r
+  void SetCapacity(int newCapacity)\r
+  {\r
+    int realCapacity = newCapacity + 1;\r
+    if (realCapacity == _capacity)\r
+      return;\r
+    /*\r
+    const int kMaxStringSize = 0x20000000;\r
+    if (newCapacity > kMaxStringSize || newCapacity < _length)\r
+      throw 1052337;\r
+    */\r
+    T *newBuffer = new T[realCapacity];\r
+    if (_capacity > 0)\r
+    {\r
+      for (int i = 0; i < _length; i++)\r
+        newBuffer[i] = _chars[i];\r
+      delete []_chars;\r
+    }\r
+    _chars = newBuffer;\r
+    _chars[_length] = 0;\r
+    _capacity = realCapacity;\r
+  }\r
+\r
+  void GrowLength(int n)\r
+  {\r
+    int freeSize = _capacity - _length - 1;\r
+    if (n <= freeSize)\r
+      return;\r
+    int delta;\r
+    if (_capacity > 64)\r
+      delta = _capacity / 2;\r
+    else if (_capacity > 8)\r
+      delta = 16;\r
+    else\r
+      delta = 4;\r
+    if (freeSize + delta < n)\r
+      delta = n - freeSize;\r
+    SetCapacity(_capacity + delta);\r
+  }\r
+\r
+  void CorrectIndex(int &index) const\r
+  {\r
+    if (index > _length)\r
+      index = _length;\r
+  }\r
+\r
+public:\r
+  CStringBase(): _chars(0), _length(0), _capacity(0) { SetCapacity(3); }\r
+  CStringBase(T c):  _chars(0), _length(0), _capacity(0)\r
+  {\r
+    SetCapacity(1);\r
+    _chars[0] = c;\r
+    _chars[1] = 0;\r
+    _length = 1;\r
+  }\r
+  CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)\r
+  {\r
+    int length = MyStringLen(chars);\r
+    SetCapacity(length);\r
+    MyStringCopy(_chars, chars); // can be optimized by memove()\r
+    _length = length;\r
+  }\r
+  CStringBase(const CStringBase &s):  _chars(0), _length(0), _capacity(0)\r
+  {\r
+    SetCapacity(s._length);\r
+    MyStringCopy(_chars, s._chars);\r
+    _length = s._length;\r
+  }\r
+  ~CStringBase() {  delete []_chars; }\r
+\r
+  operator const T*() const { return _chars;}\r
+\r
+  T Back() const { return _chars[_length - 1]; }\r
+\r
+  // The minimum size of the character buffer in characters.\r
+  // This value does not include space for a null terminator.\r
+  T* GetBuffer(int minBufLength)\r
+  {\r
+    if (minBufLength >= _capacity)\r
+      SetCapacity(minBufLength);\r
+    return _chars;\r
+  }\r
+  void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }\r
+  void ReleaseBuffer(int newLength)\r
+  {\r
+    /*\r
+    if (newLength >= _capacity)\r
+      throw 282217;\r
+    */\r
+    _chars[newLength] = 0;\r
+    _length = newLength;\r
+  }\r
+\r
+  CStringBase& operator=(T c)\r
+  {\r
+    Empty();\r
+    SetCapacity(1);\r
+    _chars[0] = c;\r
+    _chars[1] = 0;\r
+    _length = 1;\r
+    return *this;\r
+  }\r
+  CStringBase& operator=(const T *chars)\r
+  {\r
+    Empty();\r
+    int length = MyStringLen(chars);\r
+    SetCapacity(length);\r
+    MyStringCopy(_chars, chars);\r
+    _length = length;\r
+    return *this;\r
+  }\r
+  CStringBase& operator=(const CStringBase& s)\r
+  {\r
+    if (&s == this)\r
+      return *this;\r
+    Empty();\r
+    SetCapacity(s._length);\r
+    MyStringCopy(_chars, s._chars);\r
+    _length = s._length;\r
+    return *this;\r
+  }\r
+  \r
+  CStringBase& operator+=(T c)\r
+  {\r
+    GrowLength(1);\r
+    _chars[_length] = c;\r
+    _chars[++_length] = 0;\r
+    return *this;\r
+  }\r
+  CStringBase& operator+=(const T *s)\r
+  {\r
+    int len = MyStringLen(s);\r
+    GrowLength(len);\r
+    MyStringCopy(_chars + _length, s);\r
+    _length += len;\r
+    return *this;\r
+  }\r
+  CStringBase& operator+=(const CStringBase &s)\r
+  {\r
+    GrowLength(s._length);\r
+    MyStringCopy(_chars + _length, s._chars);\r
+    _length += s._length;\r
+    return *this;\r
+  }\r
+  void Empty()\r
+  {\r
+    _length = 0;\r
+    _chars[0] = 0;\r
+  }\r
+  int Length() const { return _length; }\r
+  bool IsEmpty() const { return (_length == 0); }\r
+\r
+  CStringBase Mid(int startIndex) const\r
+    { return Mid(startIndex, _length - startIndex); }\r
+  CStringBase Mid(int startIndex, int count) const\r
+  {\r
+    if (startIndex + count > _length)\r
+      count = _length - startIndex;\r
+    \r
+    if (startIndex == 0 && startIndex + count == _length)\r
+      return *this;\r
+    \r
+    CStringBase<T> result;\r
+    result.SetCapacity(count);\r
+    // MyStringNCopy(result._chars, _chars + startIndex, count);\r
+    for (int i = 0; i < count; i++)\r
+      result._chars[i] = _chars[startIndex + i];\r
+    result._chars[count] = 0;\r
+    result._length = count;\r
+    return result;\r
+  }\r
+  CStringBase Left(int count) const\r
+    { return Mid(0, count); }\r
+  CStringBase Right(int count) const\r
+  {\r
+    if (count > _length)\r
+      count = _length;\r
+    return Mid(_length - count, count);\r
+  }\r
+\r
+  void MakeUpper()\r
+    { MyStringUpper(_chars); }\r
+  void MakeLower()\r
+    { MyStringLower(_chars); }\r
+\r
+  int Compare(const CStringBase& s) const\r
+    { return MyStringCompare(_chars, s._chars); }\r
+\r
+  int Compare(const T *s) const\r
+    { return MyStringCompare(_chars, s); }\r
+\r
+  int CompareNoCase(const CStringBase& s) const\r
+    { return MyStringCompareNoCase(_chars, s._chars); }\r
+\r
+  int CompareNoCase(const T *s) const\r
+    { return MyStringCompareNoCase(_chars, s); }\r
+\r
+  /*\r
+  int Collate(const CStringBase& s) const\r
+    { return MyStringCollate(_chars, s._chars); }\r
+  int CollateNoCase(const CStringBase& s) const\r
+    { return MyStringCollateNoCase(_chars, s._chars); }\r
+  */\r
+\r
+  int Find(T c) const { return Find(c, 0); }\r
+  int Find(T c, int startIndex) const\r
+  {\r
+    const T *p = _chars + startIndex;\r
+    for (;;)\r
+    {\r
+      if (*p == c)\r
+        return (int)(p - _chars);\r
+      if (*p == 0)\r
+        return -1;\r
+      p = GetNextCharPointer(p);\r
+    }\r
+  }\r
+  int Find(const CStringBase &s) const { return Find(s, 0); }\r
+  int Find(const CStringBase &s, int startIndex) const\r
+  {\r
+    if (s.IsEmpty())\r
+      return startIndex;\r
+    for (; startIndex < _length; startIndex++)\r
+    {\r
+      int j;\r
+      for (j = 0; j < s._length && startIndex + j < _length; j++)\r
+        if (_chars[startIndex+j] != s._chars[j])\r
+          break;\r
+      if (j == s._length)\r
+        return startIndex;\r
+    }\r
+    return -1;\r
+  }\r
+  int ReverseFind(T c) const\r
+  {\r
+    if (_length == 0)\r
+      return -1;\r
+    const T *p = _chars + _length - 1;\r
+    for (;;)\r
+    {\r
+      if (*p == c)\r
+        return (int)(p - _chars);\r
+      if (p == _chars)\r
+        return -1;\r
+      p = GetPrevCharPointer(_chars, p);\r
+    }\r
+  }\r
+  int FindOneOf(const CStringBase &s) const\r
+  {\r
+    for (int i = 0; i < _length; i++)\r
+      if (s.Find(_chars[i]) >= 0)\r
+        return i;\r
+      return -1;\r
+  }\r
+\r
+  void TrimLeft(T c)\r
+  {\r
+    const T *p = _chars;\r
+    while (c == *p)\r
+      p = GetNextCharPointer(p);\r
+    Delete(0, p - _chars);\r
+  }\r
+  private:\r
+  CStringBase GetTrimDefaultCharSet()\r
+  {\r
+    CStringBase<T> charSet;\r
+    charSet += (T)' ';\r
+    charSet += (T)'\n';\r
+    charSet += (T)'\t';\r
+    return charSet;\r
+  }\r
+  public:\r
+\r
+  void TrimLeft()\r
+  {\r
+    TrimLeftWithCharSet(GetTrimDefaultCharSet());\r
+  }\r
+  void TrimRight()\r
+  {\r
+    TrimRightWithCharSet(GetTrimDefaultCharSet());\r
+  }\r
+  void TrimRight(T c)\r
+  {\r
+    const T *p = _chars;\r
+    const T *pLast = NULL;\r
+    while (*p != 0)\r
+    {\r
+      if (*p == c)\r
+      {\r
+        if (pLast == NULL)\r
+          pLast = p;\r
+      }\r
+      else\r
+        pLast = NULL;\r
+      p = GetNextCharPointer(p);\r
+    }\r
+    if (pLast != NULL)\r
+    {\r
+      int i = pLast - _chars;\r
+      Delete(i, _length - i);\r
+    }\r
+  }\r
+  void Trim()\r
+  {\r
+    TrimRight();\r
+    TrimLeft();\r
+  }\r
+\r
+  int Insert(int index, T c)\r
+  {\r
+    InsertSpace(index, 1);\r
+    _chars[index] = c;\r
+    _length++;\r
+    return _length;\r
+  }\r
+  int Insert(int index, const CStringBase &s)\r
+  {\r
+    CorrectIndex(index);\r
+    if (s.IsEmpty())\r
+      return _length;\r
+    int numInsertChars = s.Length();\r
+    InsertSpace(index, numInsertChars);\r
+    for (int i = 0; i < numInsertChars; i++)\r
+      _chars[index + i] = s[i];\r
+    _length += numInsertChars;\r
+    return _length;\r
+  }\r
+\r
+  // !!!!!!!!!!!!!!! test it if newChar = '\0'\r
+  int Replace(T oldChar, T newChar)\r
+  {\r
+    if (oldChar == newChar)\r
+      return 0;\r
+    int number  = 0;\r
+    int pos  = 0;\r
+    while (pos < Length())\r
+    {\r
+      pos = Find(oldChar, pos);\r
+      if (pos < 0)\r
+        break;\r
+      _chars[pos] = newChar;\r
+      pos++;\r
+      number++;\r
+    }\r
+    return number;\r
+  }\r
+  int Replace(const CStringBase &oldString, const CStringBase &newString)\r
+  {\r
+    if (oldString.IsEmpty())\r
+      return 0;\r
+    if (oldString == newString)\r
+      return 0;\r
+    int oldStringLength = oldString.Length();\r
+    int newStringLength = newString.Length();\r
+    int number  = 0;\r
+    int pos  = 0;\r
+    while (pos < _length)\r
+    {\r
+      pos = Find(oldString, pos);\r
+      if (pos < 0)\r
+        break;\r
+      Delete(pos, oldStringLength);\r
+      Insert(pos, newString);\r
+      pos += newStringLength;\r
+      number++;\r
+    }\r
+    return number;\r
+  }\r
+  int Delete(int index, int count = 1)\r
+  {\r
+    if (index + count > _length)\r
+      count = _length - index;\r
+    if (count > 0)\r
+    {\r
+      MoveItems(index, index + count);\r
+      _length -= count;\r
+    }\r
+    return _length;\r
+  }\r
+  void DeleteBack() { Delete(_length - 1); }\r
+};\r
+\r
+template <class T>\r
+CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)\r
+{\r
+  CStringBase<T> result(s1);\r
+  result += s2;\r
+  return result;\r
+}\r
+\r
+template <class T>\r
+CStringBase<T> operator+(const CStringBase<T>& s, T c)\r
+{\r
+  CStringBase<T> result(s);\r
+  result += c;\r
+  return result;\r
+}\r
+\r
+template <class T>\r
+CStringBase<T> operator+(T c, const CStringBase<T>& s)\r
+{\r
+  CStringBase<T> result(c);\r
+  result += s;\r
+  return result;\r
+}\r
+\r
+template <class T>\r
+CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)\r
+{\r
+  CStringBase<T> result(s);\r
+  result += chars;\r
+  return result;\r
+}\r
+\r
+template <class T>\r
+CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)\r
+{\r
+  CStringBase<T> result(chars);\r
+  result += s;\r
+  return result;\r
+}\r
+\r
+template <class T>\r
+bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)\r
+  { return (s1.Compare(s2) == 0); }\r
+\r
+template <class T>\r
+bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)\r
+  { return (s1.Compare(s2) < 0); }\r
+\r
+template <class T>\r
+bool operator==(const T *s1, const CStringBase<T>& s2)\r
+  { return (s2.Compare(s1) == 0); }\r
+\r
+template <class T>\r
+bool operator==(const CStringBase<T>& s1, const T *s2)\r
+  { return (s1.Compare(s2) == 0); }\r
+\r
+template <class T>\r
+bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)\r
+  { return (s1.Compare(s2) != 0); }\r
+\r
+template <class T>\r
+bool operator!=(const T *s1, const CStringBase<T>& s2)\r
+  { return (s2.Compare(s1) != 0); }\r
+\r
+template <class T>\r
+bool operator!=(const CStringBase<T>& s1, const T *s2)\r
+  { return (s1.Compare(s2) != 0); }\r
+\r
+typedef CStringBase<char> AString;\r
+typedef CStringBase<wchar_t> UString;\r
+\r
+typedef CObjectVector<AString> AStringVector;\r
+typedef CObjectVector<UString> UStringVector;\r
+\r
+#ifdef _UNICODE\r
+  typedef UString CSysString;\r
+#else\r
+  typedef AString CSysString;\r
+#endif\r
+\r
+typedef CObjectVector<CSysString> CSysStringVector;\r
+\r
+#endif\r
diff --git a/CPP/Common/MyUnknown.h b/CPP/Common/MyUnknown.h
new file mode 100755 (executable)
index 0000000..7935124
--- /dev/null
@@ -0,0 +1,13 @@
+// MyUnknown.h\r
+\r
+#ifndef __MY_UNKNOWN_H\r
+#define __MY_UNKNOWN_H\r
+\r
+#ifdef _WIN32\r
+#include <basetyps.h>\r
+#include <unknwn.h>\r
+#else\r
+#include "MyWindows.h"\r
+#endif\r
+  \r
+#endif\r
diff --git a/CPP/Common/MyVector.cpp b/CPP/Common/MyVector.cpp
new file mode 100755 (executable)
index 0000000..054d0aa
--- /dev/null
@@ -0,0 +1,87 @@
+// Common/MyVector.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include <string.h>\r
+\r
+#include "MyVector.h"\r
+\r
+CBaseRecordVector::~CBaseRecordVector() { ClearAndFree(); }\r
+\r
+void CBaseRecordVector::ClearAndFree()\r
+{\r
+  Clear();\r
+  delete []((unsigned char *)_items);\r
+  _capacity = 0;\r
+  _size = 0;\r
+  _items = 0;\r
+}\r
+\r
+void CBaseRecordVector::Clear() { DeleteFrom(0); }\r
+void CBaseRecordVector::DeleteBack() { Delete(_size - 1); }\r
+void CBaseRecordVector::DeleteFrom(int index) { Delete(index, _size - index); }\r
+\r
+void CBaseRecordVector::ReserveOnePosition()\r
+{\r
+  if (_size != _capacity)\r
+    return;\r
+  unsigned delta = 1;\r
+  if (_capacity >= 64)\r
+    delta = (unsigned)_capacity / 4;\r
+  else if (_capacity >= 8)\r
+    delta = 8;\r
+  Reserve(_capacity + (int)delta);\r
+}\r
+\r
+void CBaseRecordVector::Reserve(int newCapacity)\r
+{\r
+  // if (newCapacity <= _capacity)\r
+  if (newCapacity == _capacity)\r
+    return;\r
+  if ((unsigned)newCapacity >= ((unsigned)1 << (sizeof(unsigned) * 8 - 1)))\r
+    throw 1052353;\r
+  size_t newSize = (size_t)(unsigned)newCapacity * _itemSize;\r
+  if (newSize / _itemSize != (size_t)(unsigned)newCapacity)\r
+    throw 1052354;\r
+  unsigned char *p = NULL;\r
+  if (newSize > 0)\r
+  {\r
+    p = new unsigned char[newSize];\r
+    if (p == 0)\r
+      throw 1052355;\r
+    int numRecordsToMove = (_size < newCapacity ? _size : newCapacity);\r
+    memcpy(p, _items, _itemSize * numRecordsToMove);\r
+  }\r
+  delete [](unsigned char *)_items;\r
+  _items = p;\r
+  _capacity = newCapacity;\r
+}\r
+\r
+void CBaseRecordVector::ReserveDown()\r
+{\r
+  Reserve(_size);\r
+}\r
+\r
+void CBaseRecordVector::MoveItems(int destIndex, int srcIndex)\r
+{\r
+  memmove(((unsigned char *)_items) + destIndex * _itemSize,\r
+    ((unsigned char  *)_items) + srcIndex * _itemSize,\r
+    _itemSize * (_size - srcIndex));\r
+}\r
+\r
+void CBaseRecordVector::InsertOneItem(int index)\r
+{\r
+  ReserveOnePosition();\r
+  MoveItems(index + 1, index);\r
+  _size++;\r
+}\r
+\r
+void CBaseRecordVector::Delete(int index, int num)\r
+{\r
+  TestIndexAndCorrectNum(index, num);\r
+  if (num > 0)\r
+  {\r
+    MoveItems(index, index + num);\r
+    _size -= num;\r
+  }\r
+}\r
diff --git a/CPP/Common/MyVector.h b/CPP/Common/MyVector.h
new file mode 100755 (executable)
index 0000000..24740dc
--- /dev/null
@@ -0,0 +1,266 @@
+// Common/Vector.h\r
+\r
+#ifndef __COMMON_VECTOR_H\r
+#define __COMMON_VECTOR_H\r
+\r
+#include "Defs.h"\r
+\r
+class CBaseRecordVector\r
+{\r
+  void MoveItems(int destIndex, int srcIndex);\r
+protected:\r
+  int _capacity;\r
+  int _size;\r
+  void *_items;\r
+  size_t _itemSize;\r
+  \r
+  void ReserveOnePosition();\r
+  void InsertOneItem(int index);\r
+  void TestIndexAndCorrectNum(int index, int &num) const\r
+    { if (index + num > _size) num = _size - index; }\r
+public:\r
+  CBaseRecordVector(size_t itemSize): _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}\r
+  virtual ~CBaseRecordVector();\r
+  void ClearAndFree();\r
+  int Size() const { return _size; }\r
+  bool IsEmpty() const { return (_size == 0); }\r
+  void Reserve(int newCapacity);\r
+  void ReserveDown();\r
+  virtual void Delete(int index, int num = 1);\r
+  void Clear();\r
+  void DeleteFrom(int index);\r
+  void DeleteBack();\r
+};\r
+\r
+template <class T>\r
+class CRecordVector: public CBaseRecordVector\r
+{\r
+public:\r
+  CRecordVector(): CBaseRecordVector(sizeof(T)){};\r
+  CRecordVector(const CRecordVector &v): CBaseRecordVector(sizeof(T)) { *this = v; }\r
+  CRecordVector& operator=(const CRecordVector &v)\r
+  {\r
+    Clear();\r
+    return (*this += v);\r
+  }\r
+  CRecordVector& operator+=(const CRecordVector &v)\r
+  {\r
+    int size = v.Size();\r
+    Reserve(Size() + size);\r
+    for (int i = 0; i < size; i++)\r
+      Add(v[i]);\r
+    return *this;\r
+  }\r
+  int Add(T item)\r
+  {\r
+    ReserveOnePosition();\r
+    ((T *)_items)[_size] = item;\r
+    return _size++;\r
+  }\r
+  void Insert(int index, T item)\r
+  {\r
+    InsertOneItem(index);\r
+    ((T *)_items)[index] = item;\r
+  }\r
+  // T* GetPointer() const { return (T*)_items; }\r
+  // operator const T *() const { return _items; };\r
+  const T& operator[](int index) const { return ((T *)_items)[index]; }\r
+  T& operator[](int index) { return ((T *)_items)[index]; }\r
+  const T& Front() const { return operator[](0); }\r
+  T& Front() { return operator[](0); }\r
+  const T& Back() const { return operator[](_size - 1); }\r
+  T& Back() { return operator[](_size - 1); }\r
+\r
+  void Swap(int i, int j)\r
+  {\r
+    T temp = operator[](i);\r
+    operator[](i) = operator[](j);\r
+    operator[](j) = temp;\r
+  }\r
+\r
+  int FindInSorted(const T& item, int left, int right) const\r
+  {\r
+    while (left != right)\r
+    {\r
+      int mid = (left + right) / 2;\r
+      const T& midValue = (*this)[mid];\r
+      if (item == midValue)\r
+        return mid;\r
+      if (item < midValue)\r
+        right = mid;\r
+      else\r
+        left = mid + 1;\r
+    }\r
+    return -1;\r
+  }\r
+\r
+  int FindInSorted(const T& item) const\r
+  {\r
+    int left = 0, right = Size();\r
+    while (left != right)\r
+    {\r
+      int mid = (left + right) / 2;\r
+      const T& midValue = (*this)[mid];\r
+      if (item == midValue)\r
+        return mid;\r
+      if (item < midValue)\r
+        right = mid;\r
+      else\r
+        left = mid + 1;\r
+    }\r
+    return -1;\r
+  }\r
+\r
+  int AddToUniqueSorted(const T& item)\r
+  {\r
+    int left = 0, right = Size();\r
+    while (left != right)\r
+    {\r
+      int mid = (left + right) / 2;\r
+      const T& midValue = (*this)[mid];\r
+      if (item == midValue)\r
+        return mid;\r
+      if (item < midValue)\r
+        right = mid;\r
+      else\r
+        left = mid + 1;\r
+    }\r
+    Insert(right, item);\r
+    return right;\r
+  }\r
+\r
+  static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param)\r
+  {\r
+    T temp = p[k];\r
+    for (;;)\r
+    {\r
+      int s = (k << 1);\r
+      if (s > size)\r
+        break;\r
+      if (s < size && compare(p + s + 1, p + s, param) > 0)\r
+        s++;\r
+      if (compare(&temp, p + s, param) >= 0)\r
+        break;\r
+      p[k] = p[s];\r
+      k = s;\r
+    }\r
+    p[k] = temp;\r
+  }\r
+\r
+  void Sort(int (*compare)(const T*, const T*, void *), void *param)\r
+  {\r
+    int size = _size;\r
+    if (size <= 1)\r
+      return;\r
+    T* p = (&Front()) - 1;\r
+    {\r
+      int i = size / 2;\r
+      do\r
+        SortRefDown(p, i, size, compare, param);\r
+      while (--i != 0);\r
+    }\r
+    do\r
+    {\r
+      T temp = p[size];\r
+      p[size--] = p[1];\r
+      p[1] = temp;\r
+      SortRefDown(p, 1, size, compare, param);\r
+    }\r
+    while (size > 1);\r
+  }\r
+};\r
+\r
+typedef CRecordVector<int> CIntVector;\r
+typedef CRecordVector<unsigned int> CUIntVector;\r
+typedef CRecordVector<bool> CBoolVector;\r
+typedef CRecordVector<unsigned char> CByteVector;\r
+typedef CRecordVector<void *> CPointerVector;\r
+\r
+template <class T>\r
+class CObjectVector: public CPointerVector\r
+{\r
+public:\r
+  CObjectVector() {};\r
+  ~CObjectVector() { Clear(); };\r
+  CObjectVector(const CObjectVector &v): CPointerVector() { *this = v; }\r
+  CObjectVector& operator=(const CObjectVector &v)\r
+  {\r
+    Clear();\r
+    return (*this += v);\r
+  }\r
+  CObjectVector& operator+=(const CObjectVector &v)\r
+  {\r
+    int size = v.Size();\r
+    Reserve(Size() + size);\r
+    for (int i = 0; i < size; i++)\r
+      Add(v[i]);\r
+    return *this;\r
+  }\r
+  const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }\r
+  T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }\r
+  T& Front() { return operator[](0); }\r
+  const T& Front() const { return operator[](0); }\r
+  T& Back() { return operator[](_size - 1); }\r
+  const T& Back() const { return operator[](_size - 1); }\r
+  int Add(const T& item) { return CPointerVector::Add(new T(item)); }\r
+  void Insert(int index, const T& item) { CPointerVector::Insert(index, new T(item)); }\r
+  virtual void Delete(int index, int num = 1)\r
+  {\r
+    TestIndexAndCorrectNum(index, num);\r
+    for (int i = 0; i < num; i++)\r
+      delete (T *)(((void **)_items)[index + i]);\r
+    CPointerVector::Delete(index, num);\r
+  }\r
+  int Find(const T& item) const\r
+  {\r
+    for (int i = 0; i < Size(); i++)\r
+      if (item == (*this)[i])\r
+        return i;\r
+    return -1;\r
+  }\r
+  int FindInSorted(const T& item) const\r
+  {\r
+    int left = 0, right = Size();\r
+    while (left != right)\r
+    {\r
+      int mid = (left + right) / 2;\r
+      const T& midValue = (*this)[mid];\r
+      if (item == midValue)\r
+        return mid;\r
+      if (item < midValue)\r
+        right = mid;\r
+      else\r
+        left = mid + 1;\r
+    }\r
+    return -1;\r
+  }\r
+  int AddToSorted(const T& item)\r
+  {\r
+    int left = 0, right = Size();\r
+    while (left != right)\r
+    {\r
+      int mid = (left + right) / 2;\r
+      const T& midValue = (*this)[mid];\r
+      if (item == midValue)\r
+      {\r
+        right = mid + 1;\r
+        break;\r
+      }\r
+      if (item < midValue)\r
+        right = mid;\r
+      else\r
+        left = mid + 1;\r
+    }\r
+    Insert(right, item);\r
+    return right;\r
+  }\r
+\r
+  void Sort(int (*compare)(void *const *, void *const *, void *), void *param)\r
+    { CPointerVector::Sort(compare, param); }\r
+\r
+  static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)\r
+    { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }\r
+  void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }\r
+};\r
+\r
+#endif\r
diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h
new file mode 100755 (executable)
index 0000000..5cfded1
--- /dev/null
@@ -0,0 +1,204 @@
+// MyWindows.h\r
+\r
+#ifndef __MYWINDOWS_H\r
+#define __MYWINDOWS_H\r
+\r
+#ifdef _WIN32\r
+\r
+#include <windows.h>\r
+\r
+#else\r
+\r
+#include <stddef.h> // for wchar_t\r
+#include <string.h>\r
+\r
+#include "MyGuidDef.h"\r
+\r
+typedef char CHAR;\r
+typedef unsigned char UCHAR;\r
+\r
+#undef BYTE\r
+typedef unsigned char BYTE;\r
+\r
+typedef short SHORT;\r
+typedef unsigned short USHORT;\r
+\r
+#undef WORD\r
+typedef unsigned short WORD;\r
+typedef short VARIANT_BOOL;\r
+\r
+typedef int INT;\r
+typedef Int32 INT32;\r
+typedef unsigned int UINT;\r
+typedef UInt32 UINT32;\r
+typedef INT32 LONG;   // LONG, ULONG and DWORD must be 32-bit\r
+typedef UINT32 ULONG;\r
+\r
+#undef DWORD\r
+typedef UINT32 DWORD;\r
+\r
+typedef Int64 LONGLONG;\r
+typedef UInt64 ULONGLONG;\r
+\r
+typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;\r
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;\r
+\r
+typedef const CHAR *LPCSTR;\r
+typedef CHAR TCHAR;\r
+typedef const TCHAR *LPCTSTR;\r
+typedef wchar_t WCHAR;\r
+typedef WCHAR OLECHAR;\r
+typedef const WCHAR *LPCWSTR;\r
+typedef OLECHAR *BSTR;\r
+typedef const OLECHAR *LPCOLESTR;\r
+typedef OLECHAR *LPOLESTR;\r
+\r
+typedef struct _FILETIME\r
+{\r
+  DWORD dwLowDateTime;\r
+  DWORD dwHighDateTime;\r
+}FILETIME;\r
+\r
+#define HRESULT LONG\r
+#define FAILED(Status) ((HRESULT)(Status)<0)\r
+typedef ULONG PROPID;\r
+typedef LONG SCODE;\r
+\r
+#define S_OK    ((HRESULT)0x00000000L)\r
+#define S_FALSE ((HRESULT)0x00000001L)\r
+#define E_NOTIMPL ((HRESULT)0x80004001L)\r
+#define E_NOINTERFACE ((HRESULT)0x80004002L)\r
+#define E_ABORT ((HRESULT)0x80004004L)\r
+#define E_FAIL ((HRESULT)0x80004005L)\r
+#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)\r
+#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)\r
+#define E_INVALIDARG ((HRESULT)0x80070057L)\r
+\r
+#ifdef _MSC_VER\r
+#define STDMETHODCALLTYPE __stdcall\r
+#else\r
+#define STDMETHODCALLTYPE\r
+#endif\r
+\r
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f\r
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)\r
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE\r
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)\r
+\r
+#define PURE = 0\r
+\r
+#define MIDL_INTERFACE(x) struct\r
+\r
+#ifdef __cplusplus\r
+\r
+DEFINE_GUID(IID_IUnknown,\r
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);\r
+struct IUnknown\r
+{\r
+  STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;\r
+  STDMETHOD_(ULONG, AddRef)() PURE;\r
+  STDMETHOD_(ULONG, Release)() PURE;\r
+  #ifndef _WIN32\r
+  virtual ~IUnknown() {}\r
+  #endif\r
+};\r
+\r
+typedef IUnknown *LPUNKNOWN;\r
+\r
+#endif\r
+\r
+#define VARIANT_TRUE ((VARIANT_BOOL)-1)\r
+#define VARIANT_FALSE ((VARIANT_BOOL)0)\r
+\r
+enum VARENUM\r
+{\r
+  VT_EMPTY = 0,\r
+  VT_NULL = 1,\r
+  VT_I2 = 2,\r
+  VT_I4 = 3,\r
+  VT_R4 = 4,\r
+  VT_R8 = 5,\r
+  VT_CY = 6,\r
+  VT_DATE = 7,\r
+  VT_BSTR = 8,\r
+  VT_DISPATCH = 9,\r
+  VT_ERROR = 10,\r
+  VT_BOOL = 11,\r
+  VT_VARIANT = 12,\r
+  VT_UNKNOWN = 13,\r
+  VT_DECIMAL = 14,\r
+  VT_I1 = 16,\r
+  VT_UI1 = 17,\r
+  VT_UI2 = 18,\r
+  VT_UI4 = 19,\r
+  VT_I8 = 20,\r
+  VT_UI8 = 21,\r
+  VT_INT = 22,\r
+  VT_UINT = 23,\r
+  VT_VOID = 24,\r
+  VT_HRESULT = 25,\r
+  VT_FILETIME = 64\r
+};\r
+\r
+typedef unsigned short VARTYPE;\r
+typedef WORD PROPVAR_PAD1;\r
+typedef WORD PROPVAR_PAD2;\r
+typedef WORD PROPVAR_PAD3;\r
+\r
+#ifdef __cplusplus\r
+\r
+typedef struct tagPROPVARIANT\r
+{\r
+  VARTYPE vt;\r
+  PROPVAR_PAD1 wReserved1;\r
+  PROPVAR_PAD2 wReserved2;\r
+  PROPVAR_PAD3 wReserved3;\r
+  union\r
+  {\r
+    CHAR cVal;\r
+    UCHAR bVal;\r
+    SHORT iVal;\r
+    USHORT uiVal;\r
+    LONG lVal;\r
+    ULONG ulVal;\r
+    INT intVal;\r
+    UINT uintVal;\r
+    LARGE_INTEGER hVal;\r
+    ULARGE_INTEGER uhVal;\r
+    VARIANT_BOOL boolVal;\r
+    SCODE scode;\r
+    FILETIME filetime;\r
+    BSTR bstrVal;\r
+  };\r
+} PROPVARIANT;\r
+\r
+typedef PROPVARIANT tagVARIANT;\r
+typedef tagVARIANT VARIANT;\r
+typedef VARIANT VARIANTARG;\r
+\r
+MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);\r
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);\r
+\r
+#endif\r
+\r
+MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);\r
+MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);\r
+MY_EXTERN_C void SysFreeString(BSTR bstr);\r
+MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);\r
+MY_EXTERN_C UINT SysStringLen(BSTR bstr);\r
+\r
+MY_EXTERN_C DWORD GetLastError();\r
+MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);\r
+\r
+#define CP_ACP    0\r
+#define CP_OEMCP  1\r
+\r
+typedef enum tagSTREAM_SEEK\r
+{\r
+  STREAM_SEEK_SET = 0,\r
+  STREAM_SEEK_CUR = 1,\r
+  STREAM_SEEK_END = 2\r
+} STREAM_SEEK;\r
+\r
+#endif\r
+#endif\r
diff --git a/CPP/Common/NewHandler.cpp b/CPP/Common/NewHandler.cpp
new file mode 100755 (executable)
index 0000000..611bbd8
--- /dev/null
@@ -0,0 +1,116 @@
+// NewHandler.cpp\r
\r
+#include "StdAfx.h"\r
+\r
+#include <stdlib.h>\r
+\r
+#include "NewHandler.h"\r
+\r
+// #define DEBUG_MEMORY_LEAK\r
+\r
+#ifndef DEBUG_MEMORY_LEAK\r
+\r
+#ifdef _WIN32\r
+void *\r
+#ifdef _MSC_VER\r
+__cdecl\r
+#endif\r
+operator new(size_t size)\r
+{\r
+  // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);\r
+  void *p = ::malloc(size);\r
+  if (p == 0)\r
+    throw CNewException();\r
+  return p;\r
+}\r
+\r
+void\r
+#ifdef _MSC_VER\r
+__cdecl\r
+#endif\r
+operator delete(void *p) throw()\r
+{\r
+  /*\r
+  if (p == 0)\r
+    return;\r
+  ::HeapFree(::GetProcessHeap(), 0, p);\r
+  */\r
+  ::free(p);\r
+}\r
+#endif\r
+\r
+#else\r
+\r
+#pragma init_seg(lib)\r
+const int kDebugSize = 1000000;\r
+static void *a[kDebugSize];\r
+static int index = 0;\r
+\r
+static int numAllocs = 0;\r
+void * __cdecl operator new(size_t size)\r
+{\r
+  numAllocs++;\r
+  void *p = HeapAlloc(GetProcessHeap(), 0, size);\r
+  if (index == 40)\r
+  {\r
+    int t = 1;\r
+  }\r
+  if (index < kDebugSize)\r
+  {\r
+    a[index] = p;\r
+    index++;\r
+  }\r
+  if (p == 0)\r
+    throw CNewException();\r
+  printf("Alloc %6d, size = %8d\n", numAllocs, size);\r
+  return p;\r
+}\r
+\r
+class CC\r
+{\r
+public:\r
+  CC()\r
+  {\r
+    for (int i = 0; i < kDebugSize; i++)\r
+      a[i] = 0;\r
+  }\r
+  ~CC()\r
+  {\r
+    for (int i = 0; i < kDebugSize; i++)\r
+      if (a[i] != 0)\r
+        return;\r
+  }\r
+} g_CC;\r
+\r
+\r
+void __cdecl operator delete(void *p)\r
+{\r
+  if (p == 0)\r
+    return;\r
+  /*\r
+  for (int i = 0; i < index; i++)\r
+    if (a[i] == p)\r
+      a[i] = 0;\r
+  */\r
+  HeapFree(GetProcessHeap(), 0, p);\r
+  numAllocs--;\r
+  printf("Free %d\n", numAllocs);\r
+}\r
+\r
+#endif\r
+\r
+/*\r
+int MemErrorVC(size_t)\r
+{\r
+  throw CNewException();\r
+  // return 1;\r
+}\r
+CNewHandlerSetter::CNewHandlerSetter()\r
+{\r
+  // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);\r
+}\r
+CNewHandlerSetter::~CNewHandlerSetter()\r
+{\r
+  // _set_new_handler(MemErrorOldVCFunction);\r
+}\r
+*/\r
diff --git a/CPP/Common/NewHandler.h b/CPP/Common/NewHandler.h
new file mode 100755 (executable)
index 0000000..6f710cd
--- /dev/null
@@ -0,0 +1,16 @@
+// Common/NewHandler.h\r
+\r
+#ifndef __COMMON_NEWHANDLER_H\r
+#define __COMMON_NEWHANDLER_H\r
+\r
+class CNewException {};\r
+\r
+#ifdef _WIN32\r
+void\r
+#ifdef _MSC_VER\r
+__cdecl\r
+#endif\r
+operator delete(void *p) throw();\r
+#endif\r
+\r
+#endif\r
diff --git a/CPP/Common/StdAfx.h b/CPP/Common/StdAfx.h
new file mode 100755 (executable)
index 0000000..9b43572
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+// #include "MyWindows.h"\r
+#include "NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/Common/StdInStream.cpp b/CPP/Common/StdInStream.cpp
new file mode 100755 (executable)
index 0000000..442191e
--- /dev/null
@@ -0,0 +1,107 @@
+// Common/StdInStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include <tchar.h>\r
+\r
+#include "StdInStream.h"\r
+#include "StringConvert.h"\r
+#include "UTFConvert.h"\r
+\r
+#ifdef _MSC_VER\r
+// "was declared deprecated" disabling\r
+#pragma warning(disable : 4996 )\r
+#endif\r
+\r
+static const char kIllegalChar = '\0';\r
+static const char kNewLineChar = '\n';\r
+\r
+static const char *kEOFMessage = "Unexpected end of input stream";\r
+static const char *kReadErrorMessage  ="Error reading input stream";\r
+static const char *kIllegalCharMessage = "Illegal character in input stream";\r
+\r
+static LPCTSTR kFileOpenMode = TEXT("r");\r
+\r
+extern int g_CodePage;\r
+\r
+CStdInStream g_StdIn(stdin);\r
+\r
+bool CStdInStream::Open(LPCTSTR fileName)\r
+{\r
+  Close();\r
+  _stream = _tfopen(fileName, kFileOpenMode);\r
+  _streamIsOpen = (_stream != 0);\r
+  return _streamIsOpen;\r
+}\r
+\r
+bool CStdInStream::Close()\r
+{\r
+  if (!_streamIsOpen)\r
+    return true;\r
+  _streamIsOpen = (fclose(_stream) != 0);\r
+  return !_streamIsOpen;\r
+}\r
+\r
+CStdInStream::~CStdInStream()\r
+{\r
+  Close();\r
+}\r
+\r
+AString CStdInStream::ScanStringUntilNewLine(bool allowEOF)\r
+{\r
+  AString s;\r
+  for (;;)\r
+  {\r
+    int intChar = GetChar();\r
+    if (intChar == EOF)\r
+    {\r
+      if (allowEOF)\r
+        break;\r
+      throw kEOFMessage;\r
+    }\r
+    char c = char(intChar);\r
+    if (c == kIllegalChar)\r
+      throw kIllegalCharMessage;\r
+    if (c == kNewLineChar)\r
+      break;\r
+    s += c;\r
+  }\r
+  return s;\r
+}\r
+\r
+UString CStdInStream::ScanUStringUntilNewLine()\r
+{\r
+  AString s = ScanStringUntilNewLine(true);\r
+  int codePage = g_CodePage;\r
+  if (codePage == -1)\r
+    codePage = CP_OEMCP;\r
+  UString dest;\r
+  if (codePage == CP_UTF8)\r
+    ConvertUTF8ToUnicode(s, dest);\r
+  else\r
+    dest = MultiByteToUnicodeString(s, (UINT)codePage);\r
+  return dest;\r
+}\r
+\r
+void CStdInStream::ReadToString(AString &resultString)\r
+{\r
+  resultString.Empty();\r
+  int c;\r
+  while ((c = GetChar()) != EOF)\r
+    resultString += char(c);\r
+}\r
+\r
+bool CStdInStream::Eof()\r
+{\r
+  return (feof(_stream) != 0);\r
+}\r
+\r
+int CStdInStream::GetChar()\r
+{\r
+  int c = fgetc(_stream); // getc() doesn't work in BeOS?\r
+  if (c == EOF && !Eof())\r
+    throw kReadErrorMessage;\r
+  return c;\r
+}\r
+\r
+\r
diff --git a/CPP/Common/StdInStream.h b/CPP/Common/StdInStream.h
new file mode 100755 (executable)
index 0000000..67ef82b
--- /dev/null
@@ -0,0 +1,32 @@
+// Common/StdInStream.h\r
+\r
+#ifndef __COMMON_STDINSTREAM_H\r
+#define __COMMON_STDINSTREAM_H\r
+\r
+#include <stdio.h>\r
+\r
+#include "MyString.h"\r
+#include "Types.h"\r
+\r
+class CStdInStream\r
+{\r
+  bool _streamIsOpen;\r
+  FILE *_stream;\r
+public:\r
+  CStdInStream(): _streamIsOpen(false) {};\r
+  CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {};\r
+  ~CStdInStream();\r
+  bool Open(LPCTSTR fileName);\r
+  bool Close();\r
+\r
+  AString ScanStringUntilNewLine(bool allowEOF = false);\r
+  void ReadToString(AString &resultString);\r
+  UString ScanUStringUntilNewLine();\r
+\r
+  bool Eof();\r
+  int GetChar();\r
+};\r
+\r
+extern CStdInStream g_StdIn;\r
+\r
+#endif\r
diff --git a/CPP/Common/StdOutStream.cpp b/CPP/Common/StdOutStream.cpp
new file mode 100755 (executable)
index 0000000..f7ec2a6
--- /dev/null
@@ -0,0 +1,104 @@
+// Common/StdOutStream.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include <tchar.h>\r
+\r
+#include "IntToString.h"\r
+#include "StdOutStream.h"\r
+#include "StringConvert.h"\r
+#include "UTFConvert.h"\r
+\r
+#ifdef _MSC_VER\r
+// "was declared deprecated" disabling\r
+#pragma warning(disable : 4996 )\r
+#endif\r
+\r
+static const char kNewLineChar =  '\n';\r
+\r
+static const char *kFileOpenMode = "wt";\r
+\r
+extern int g_CodePage;\r
+\r
+CStdOutStream  g_StdOut(stdout);\r
+CStdOutStream  g_StdErr(stderr);\r
+\r
+bool CStdOutStream::Open(const char *fileName)\r
+{\r
+  Close();\r
+  _stream = fopen(fileName, kFileOpenMode);\r
+  _streamIsOpen = (_stream != 0);\r
+  return _streamIsOpen;\r
+}\r
+\r
+bool CStdOutStream::Close()\r
+{\r
+  if (!_streamIsOpen)\r
+    return true;\r
+  if (fclose(_stream) != 0)\r
+    return false;\r
+  _stream = 0;\r
+  _streamIsOpen = false;\r
+  return true;\r
+}\r
+\r
+bool CStdOutStream::Flush()\r
+{\r
+  return (fflush(_stream) == 0);\r
+}\r
+\r
+CStdOutStream::~CStdOutStream ()\r
+{\r
+  Close();\r
+}\r
+\r
+CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream  &))\r
+{\r
+  (*aFunction)(*this);\r
+  return *this;\r
+}\r
+\r
+CStdOutStream & endl(CStdOutStream & outStream)\r
+{\r
+  return outStream << kNewLineChar;\r
+}\r
+\r
+CStdOutStream & CStdOutStream::operator<<(const char *s)\r
+{\r
+  fputs(s, _stream);\r
+  return *this;\r
+}\r
+\r
+CStdOutStream & CStdOutStream::operator<<(const wchar_t *s)\r
+{\r
+  int codePage = g_CodePage;\r
+  if (codePage == -1)\r
+    codePage = CP_OEMCP;\r
+  AString dest;\r
+  if (codePage == CP_UTF8)\r
+    ConvertUnicodeToUTF8(s, dest);\r
+  else\r
+    dest = UnicodeStringToMultiByte(s, (UINT)codePage);\r
+  *this << (const char *)dest;\r
+  return *this;\r
+}\r
+\r
+CStdOutStream & CStdOutStream::operator<<(char c)\r
+{\r
+  fputc(c, _stream);\r
+  return *this;\r
+}\r
+\r
+CStdOutStream & CStdOutStream::operator<<(int number)\r
+{\r
+  char textString[32];\r
+  ConvertInt64ToString(number, textString);\r
+  return operator<<(textString);\r
+}\r
+\r
+CStdOutStream & CStdOutStream::operator<<(UInt64 number)\r
+{\r
+  char textString[32];\r
+  ConvertUInt64ToString(number, textString);\r
+  return operator<<(textString);\r
+}\r
diff --git a/CPP/Common/StdOutStream.h b/CPP/Common/StdOutStream.h
new file mode 100755 (executable)
index 0000000..c2fcd9d
--- /dev/null
@@ -0,0 +1,35 @@
+// Common/StdOutStream.h\r
+\r
+#ifndef __COMMON_STDOUTSTREAM_H\r
+#define __COMMON_STDOUTSTREAM_H\r
+\r
+#include <stdio.h>\r
+\r
+#include "Types.h"\r
+\r
+class CStdOutStream\r
+{\r
+  bool _streamIsOpen;\r
+  FILE *_stream;\r
+public:\r
+  CStdOutStream (): _streamIsOpen(false), _stream(0) {};\r
+  CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {};\r
+  ~CStdOutStream ();\r
+  operator FILE *() { return _stream; }\r
+  bool Open(const char *fileName);\r
+  bool Close();\r
+  bool Flush();\r
+  CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream  &));\r
+  CStdOutStream & operator<<(const char *string);\r
+  CStdOutStream & operator<<(const wchar_t *string);\r
+  CStdOutStream & operator<<(char c);\r
+  CStdOutStream & operator<<(int number);\r
+  CStdOutStream & operator<<(UInt64 number);\r
+};\r
+\r
+CStdOutStream & endl(CStdOutStream & outStream);\r
+\r
+extern CStdOutStream g_StdOut;\r
+extern CStdOutStream g_StdErr;\r
+\r
+#endif\r
diff --git a/CPP/Common/StringConvert.cpp b/CPP/Common/StringConvert.cpp
new file mode 100755 (executable)
index 0000000..7f9999c
--- /dev/null
@@ -0,0 +1,97 @@
+// Common/StringConvert.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "StringConvert.h"\r
+\r
+#ifndef _WIN32\r
+#include <stdlib.h>\r
+#endif\r
+\r
+#ifdef _WIN32\r
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)\r
+{\r
+  UString resultString;\r
+  if (!srcString.IsEmpty())\r
+  {\r
+    int numChars = MultiByteToWideChar(codePage, 0, srcString,\r
+      srcString.Length(), resultString.GetBuffer(srcString.Length()),\r
+      srcString.Length() + 1);\r
+    if (numChars == 0)\r
+      throw 282228;\r
+    resultString.ReleaseBuffer(numChars);\r
+  }\r
+  return resultString;\r
+}\r
+\r
+AString UnicodeStringToMultiByte(const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed)\r
+{\r
+  AString dest;\r
+  defaultCharWasUsed = false;\r
+  if (!s.IsEmpty())\r
+  {\r
+    int numRequiredBytes = s.Length() * 2;\r
+    BOOL defUsed;\r
+    int numChars = WideCharToMultiByte(codePage, 0, s, s.Length(),\r
+        dest.GetBuffer(numRequiredBytes), numRequiredBytes + 1,\r
+        &defaultChar, &defUsed);\r
+    defaultCharWasUsed = (defUsed != FALSE);\r
+    if (numChars == 0)\r
+      throw 282229;\r
+    dest.ReleaseBuffer(numChars);\r
+  }\r
+  return dest;\r
+}\r
+\r
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)\r
+{\r
+  bool defaultCharWasUsed;\r
+  return UnicodeStringToMultiByte(srcString, codePage, '_', defaultCharWasUsed);\r
+}\r
+\r
+#ifndef UNDER_CE\r
+AString SystemStringToOemString(const CSysString &srcString)\r
+{\r
+  AString result;\r
+  CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));\r
+  result.ReleaseBuffer();\r
+  return result;\r
+}\r
+#endif\r
+\r
+#else\r
+\r
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)\r
+{\r
+  UString resultString;\r
+  for (int i = 0; i < srcString.Length(); i++)\r
+    resultString += wchar_t(srcString[i]);\r
+  /*\r
+  if (!srcString.IsEmpty())\r
+  {\r
+    int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1);\r
+    if (numChars < 0) throw "Your environment does not support UNICODE";\r
+    resultString.ReleaseBuffer(numChars);\r
+  }\r
+  */\r
+  return resultString;\r
+}\r
+\r
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)\r
+{\r
+  AString resultString;\r
+  for (int i = 0; i < srcString.Length(); i++)\r
+    resultString += char(srcString[i]);\r
+  /*\r
+  if (!srcString.IsEmpty())\r
+  {\r
+    int numRequiredBytes = srcString.Length() * 6 + 1;\r
+    int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);\r
+    if (numChars < 0) throw "Your environment does not support UNICODE";\r
+    resultString.ReleaseBuffer(numChars);\r
+  }\r
+  */\r
+  return resultString;\r
+}\r
+\r
+#endif\r
diff --git a/CPP/Common/StringConvert.h b/CPP/Common/StringConvert.h
new file mode 100755 (executable)
index 0000000..1c7a951
--- /dev/null
@@ -0,0 +1,73 @@
+// Common/StringConvert.h\r
+\r
+#ifndef __COMMON_STRING_CONVERT_H\r
+#define __COMMON_STRING_CONVERT_H\r
+\r
+#include "MyWindows.h"\r
+#include "MyString.h"\r
+#include "Types.h"\r
+\r
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);\r
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed);\r
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);\r
+\r
+\r
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)\r
+  { return unicodeString; }\r
+inline const UString& GetUnicodeString(const UString &unicodeString)\r
+  { return unicodeString; }\r
+inline UString GetUnicodeString(const AString &ansiString)\r
+  { return MultiByteToUnicodeString(ansiString); }\r
+inline UString GetUnicodeString(const AString &multiByteString, UINT codePage)\r
+  { return MultiByteToUnicodeString(multiByteString, codePage); }\r
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT)\r
+  { return unicodeString; }\r
+inline const UString& GetUnicodeString(const UString &unicodeString, UINT)\r
+  { return unicodeString; }\r
+\r
+inline const char* GetAnsiString(const char* ansiString)\r
+  { return ansiString; }\r
+inline const AString& GetAnsiString(const AString &ansiString)\r
+  { return ansiString; }\r
+inline AString GetAnsiString(const UString &unicodeString)\r
+  { return UnicodeStringToMultiByte(unicodeString); }\r
+\r
+inline const char* GetOemString(const char* oemString)\r
+  { return oemString; }\r
+inline const AString& GetOemString(const AString &oemString)\r
+  { return oemString; }\r
+inline AString GetOemString(const UString &unicodeString)\r
+  { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); }\r
+\r
+\r
+#ifdef _UNICODE\r
+  inline const wchar_t* GetSystemString(const wchar_t* unicodeString)\r
+    { return unicodeString;}\r
+  inline const UString& GetSystemString(const UString &unicodeString)\r
+    { return unicodeString;}\r
+  inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */)\r
+    { return unicodeString;}\r
+  inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */)\r
+    { return unicodeString;}\r
+  inline UString GetSystemString(const AString &multiByteString, UINT codePage)\r
+    { return MultiByteToUnicodeString(multiByteString, codePage);}\r
+  inline UString GetSystemString(const AString &multiByteString)\r
+    { return MultiByteToUnicodeString(multiByteString);}\r
+#else\r
+  inline const char* GetSystemString(const char *ansiString)\r
+    { return ansiString; }\r
+  inline const AString& GetSystemString(const AString &multiByteString, UINT)\r
+    { return multiByteString; }\r
+  inline const char * GetSystemString(const char *multiByteString, UINT)\r
+    { return multiByteString; }\r
+  inline AString GetSystemString(const UString &unicodeString)\r
+    { return UnicodeStringToMultiByte(unicodeString); }\r
+  inline AString GetSystemString(const UString &unicodeString, UINT codePage)\r
+    { return UnicodeStringToMultiByte(unicodeString, codePage); }\r
+#endif\r
+\r
+#ifndef UNDER_CE\r
+AString SystemStringToOemString(const CSysString &srcString);\r
+#endif\r
+\r
+#endif\r
diff --git a/CPP/Common/StringToInt.cpp b/CPP/Common/StringToInt.cpp
new file mode 100755 (executable)
index 0000000..77ce7c5
--- /dev/null
@@ -0,0 +1,90 @@
+// Common/StringToInt.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "StringToInt.h"\r
+\r
+UInt64 ConvertStringToUInt64(const char *s, const char **end)\r
+{\r
+  UInt64 result = 0;\r
+  for (;;)\r
+  {\r
+    char c = *s;\r
+    if (c < '0' || c > '9')\r
+    {\r
+      if (end != NULL)\r
+        *end = s;\r
+      return result;\r
+    }\r
+    result *= 10;\r
+    result += (c - '0');\r
+    s++;\r
+  }\r
+}\r
+\r
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end)\r
+{\r
+  UInt64 result = 0;\r
+  for (;;)\r
+  {\r
+    char c = *s;\r
+    if (c < '0' || c > '7')\r
+    {\r
+      if (end != NULL)\r
+        *end = s;\r
+      return result;\r
+    }\r
+    result <<= 3;\r
+    result += (c - '0');\r
+    s++;\r
+  }\r
+}\r
+\r
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end)\r
+{\r
+  UInt64 result = 0;\r
+  for (;;)\r
+  {\r
+    char c = *s;\r
+    UInt32 v;\r
+    if (c >= '0' && c <= '9') v = (c - '0');\r
+    else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');\r
+    else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');\r
+    else\r
+    {\r
+      if (end != NULL)\r
+        *end = s;\r
+      return result;\r
+    }\r
+    result <<= 4;\r
+    result |= v;\r
+    s++;\r
+  }\r
+}\r
+\r
+\r
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end)\r
+{\r
+  UInt64 result = 0;\r
+  for (;;)\r
+  {\r
+    wchar_t c = *s;\r
+    if (c < '0' || c > '9')\r
+    {\r
+      if (end != NULL)\r
+        *end = s;\r
+      return result;\r
+    }\r
+    result *= 10;\r
+    result += (c - '0');\r
+    s++;\r
+  }\r
+}\r
+\r
+\r
+Int64 ConvertStringToInt64(const char *s, const char **end)\r
+{\r
+  if (*s == '-')\r
+    return -(Int64)ConvertStringToUInt64(s + 1, end);\r
+  return ConvertStringToUInt64(s, end);\r
+}\r
diff --git a/CPP/Common/StringToInt.h b/CPP/Common/StringToInt.h
new file mode 100755 (executable)
index 0000000..16a1a4f
--- /dev/null
@@ -0,0 +1,18 @@
+// Common/StringToInt.h\r
+\r
+#ifndef __COMMON_STRINGTOINT_H\r
+#define __COMMON_STRINGTOINT_H\r
+\r
+#include <string.h>\r
+#include "Types.h"\r
+\r
+UInt64 ConvertStringToUInt64(const char *s, const char **end);\r
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end);\r
+UInt64 ConvertHexStringToUInt64(const char *s, const char **end);\r
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end);\r
+\r
+Int64 ConvertStringToInt64(const char *s, const char **end);\r
+\r
+#endif\r
+\r
+\r
diff --git a/CPP/Common/Types.h b/CPP/Common/Types.h
new file mode 100755 (executable)
index 0000000..fd00237
--- /dev/null
@@ -0,0 +1,11 @@
+// Common/Types.h\r
+\r
+#ifndef __COMMON_TYPES_H\r
+#define __COMMON_TYPES_H\r
+\r
+#include "../../C/Types.h"\r
+\r
+typedef int HRes;\r
+\r
+#endif\r
+\r
diff --git a/CPP/Common/UTFConvert.cpp b/CPP/Common/UTFConvert.cpp
new file mode 100755 (executable)
index 0000000..d3935b1
--- /dev/null
@@ -0,0 +1,145 @@
+// UTFConvert.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "UTFConvert.h"\r
+#include "Types.h"\r
+\r
+static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };\r
+\r
+static Bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, size_t srcLen)\r
+{\r
+  size_t destPos = 0, srcPos = 0;\r
+  for (;;)\r
+  {\r
+    Byte c;\r
+    int numAdds;\r
+    if (srcPos == srcLen)\r
+    {\r
+      *destLen = destPos;\r
+      return True;\r
+    }\r
+    c = (Byte)src[srcPos++];\r
+\r
+    if (c < 0x80)\r
+    {\r
+      if (dest)\r
+        dest[destPos] = (wchar_t)c;\r
+      destPos++;\r
+      continue;\r
+    }\r
+    if (c < 0xC0)\r
+      break;\r
+    for (numAdds = 1; numAdds < 5; numAdds++)\r
+      if (c < kUtf8Limits[numAdds])\r
+        break;\r
+    UInt32 value = (c - kUtf8Limits[numAdds - 1]);\r
+\r
+    do\r
+    {\r
+      Byte c2;\r
+      if (srcPos == srcLen)\r
+        break;\r
+      c2 = (Byte)src[srcPos++];\r
+      if (c2 < 0x80 || c2 >= 0xC0)\r
+        break;\r
+      value <<= 6;\r
+      value |= (c2 - 0x80);\r
+    }\r
+    while (--numAdds != 0);\r
+    \r
+    if (value < 0x10000)\r
+    {\r
+      if (dest)\r
+        dest[destPos] = (wchar_t)value;\r
+      destPos++;\r
+    }\r
+    else\r
+    {\r
+      value -= 0x10000;\r
+      if (value >= 0x100000)\r
+        break;\r
+      if (dest)\r
+      {\r
+        dest[destPos + 0] = (wchar_t)(0xD800 + (value >> 10));\r
+        dest[destPos + 1] = (wchar_t)(0xDC00 + (value & 0x3FF));\r
+      }\r
+      destPos += 2;\r
+    }\r
+  }\r
+  *destLen = destPos;\r
+  return False;\r
+}\r
+\r
+static Bool Utf16_To_Utf8(char *dest, size_t *destLen, const wchar_t *src, size_t srcLen)\r
+{\r
+  size_t destPos = 0, srcPos = 0;\r
+  for (;;)\r
+  {\r
+    unsigned numAdds;\r
+    UInt32 value;\r
+    if (srcPos == srcLen)\r
+    {\r
+      *destLen = destPos;\r
+      return True;\r
+    }\r
+    value = src[srcPos++];\r
+    if (value < 0x80)\r
+    {\r
+      if (dest)\r
+        dest[destPos] = (char)value;\r
+      destPos++;\r
+      continue;\r
+    }\r
+    if (value >= 0xD800 && value < 0xE000)\r
+    {\r
+      UInt32 c2;\r
+      if (value >= 0xDC00 || srcPos == srcLen)\r
+        break;\r
+      c2 = src[srcPos++];\r
+      if (c2 < 0xDC00 || c2 >= 0xE000)\r
+        break;\r
+      value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;\r
+    }\r
+    for (numAdds = 1; numAdds < 5; numAdds++)\r
+      if (value < (((UInt32)1) << (numAdds * 5 + 6)))\r
+        break;\r
+    if (dest)\r
+      dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));\r
+    destPos++;\r
+    do\r
+    {\r
+      numAdds--;\r
+      if (dest)\r
+        dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));\r
+      destPos++;\r
+    }\r
+    while (numAdds != 0);\r
+  }\r
+  *destLen = destPos;\r
+  return False;\r
+}\r
+\r
+bool ConvertUTF8ToUnicode(const AString &src, UString &dest)\r
+{\r
+  dest.Empty();\r
+  size_t destLen = 0;\r
+  Utf8_To_Utf16(NULL, &destLen, src, src.Length());\r
+  wchar_t *p = dest.GetBuffer((int)destLen);\r
+  Bool res = Utf8_To_Utf16(p, &destLen, src, src.Length());\r
+  p[destLen] = 0;\r
+  dest.ReleaseBuffer();\r
+  return res ? true : false;\r
+}\r
+\r
+bool ConvertUnicodeToUTF8(const UString &src, AString &dest)\r
+{\r
+  dest.Empty();\r
+  size_t destLen = 0;\r
+  Utf16_To_Utf8(NULL, &destLen, src, src.Length());\r
+  char *p = dest.GetBuffer((int)destLen);\r
+  Bool res = Utf16_To_Utf8(p, &destLen, src, src.Length());\r
+  p[destLen] = 0;\r
+  dest.ReleaseBuffer();\r
+  return res ? true : false;\r
+}\r
diff --git a/CPP/Common/UTFConvert.h b/CPP/Common/UTFConvert.h
new file mode 100755 (executable)
index 0000000..d553101
--- /dev/null
@@ -0,0 +1,11 @@
+// Common/UTFConvert.h\r
+\r
+#ifndef __COMMON_UTFCONVERT_H\r
+#define __COMMON_UTFCONVERT_H\r
+\r
+#include "MyString.h"\r
+\r
+bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);\r
+bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);\r
+\r
+#endif\r
diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp
new file mode 100755 (executable)
index 0000000..024d7a5
--- /dev/null
@@ -0,0 +1,462 @@
+// Common/Wildcard.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../../C/Types.h"\r
+\r
+#include "Wildcard.h"\r
+\r
+bool g_CaseSensitive =\r
+  #ifdef _WIN32\r
+    false;\r
+  #else\r
+    true;\r
+  #endif\r
+\r
+static const wchar_t kAnyCharsChar = L'*';\r
+static const wchar_t kAnyCharChar = L'?';\r
+\r
+#ifdef _WIN32\r
+static const wchar_t kDirDelimiter1 = L'\\';\r
+#endif\r
+static const wchar_t kDirDelimiter2 = L'/';\r
+\r
+static const UString kWildCardCharSet = L"?*";\r
+\r
+static const UString kIllegalWildCardFileNameChars=\r
+  L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"\r
+  L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"\r
+  L"\"/:<>\\|";\r
+\r
+\r
+static inline bool IsCharDirLimiter(wchar_t c)\r
+{\r
+  return (\r
+    #ifdef _WIN32\r
+    c == kDirDelimiter1 ||\r
+    #endif\r
+    c == kDirDelimiter2);\r
+}\r
+\r
+int CompareFileNames(const UString &s1, const UString &s2)\r
+{\r
+  if (g_CaseSensitive)\r
+    return s1.Compare(s2);\r
+  return s1.CompareNoCase(s2);\r
+}\r
+\r
+// -----------------------------------------\r
+// this function compares name with mask\r
+// ? - any char\r
+// * - any char or empty\r
+\r
+static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)\r
+{\r
+  for (;;)\r
+  {\r
+    wchar_t m = *mask;\r
+    wchar_t c = *name;\r
+    if (m == 0)\r
+      return (c == 0);\r
+    if (m == kAnyCharsChar)\r
+    {\r
+      if (EnhancedMaskTest(mask + 1, name))\r
+        return true;\r
+      if (c == 0)\r
+        return false;\r
+    }\r
+    else\r
+    {\r
+      if (m == kAnyCharChar)\r
+      {\r
+        if (c == 0)\r
+          return false;\r
+      }\r
+      else if (m != c)\r
+        if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c))\r
+          return false;\r
+      mask++;\r
+    }\r
+    name++;\r
+  }\r
+}\r
+\r
+// --------------------------------------------------\r
+// Splits path to strings\r
+\r
+void SplitPathToParts(const UString &path, UStringVector &pathParts)\r
+{\r
+  pathParts.Clear();\r
+  UString name;\r
+  int len = path.Length();\r
+  if (len == 0)\r
+    return;\r
+  for (int i = 0; i < len; i++)\r
+  {\r
+    wchar_t c = path[i];\r
+    if (IsCharDirLimiter(c))\r
+    {\r
+      pathParts.Add(name);\r
+      name.Empty();\r
+    }\r
+    else\r
+      name += c;\r
+  }\r
+  pathParts.Add(name);\r
+}\r
+\r
+void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name)\r
+{\r
+  int i;\r
+  for (i = path.Length() - 1; i >= 0; i--)\r
+    if (IsCharDirLimiter(path[i]))\r
+      break;\r
+  dirPrefix = path.Left(i + 1);\r
+  name = path.Mid(i + 1);\r
+}\r
+\r
+UString ExtractDirPrefixFromPath(const UString &path)\r
+{\r
+  int i;\r
+  for (i = path.Length() - 1; i >= 0; i--)\r
+    if (IsCharDirLimiter(path[i]))\r
+      break;\r
+  return path.Left(i + 1);\r
+}\r
+\r
+UString ExtractFileNameFromPath(const UString &path)\r
+{\r
+  int i;\r
+  for (i = path.Length() - 1; i >= 0; i--)\r
+    if (IsCharDirLimiter(path[i]))\r
+      break;\r
+  return path.Mid(i + 1);\r
+}\r
+\r
+\r
+bool CompareWildCardWithName(const UString &mask, const UString &name)\r
+{\r
+  return EnhancedMaskTest(mask, name);\r
+}\r
+\r
+bool DoesNameContainWildCard(const UString &path)\r
+{\r
+  return (path.FindOneOf(kWildCardCharSet) >= 0);\r
+}\r
+\r
+\r
+// ----------------------------------------------------------'\r
+// NWildcard\r
+\r
+namespace NWildcard {\r
+\r
+\r
+/*\r
+M = MaskParts.Size();\r
+N = TestNameParts.Size();\r
+\r
+                           File                          Dir\r
+ForFile     req   M<=N  [N-M, N)                          -\r
+         nonreq   M=N   [0, M)                            -\r
\r
+ForDir      req   M<N   [0, M) ... [N-M-1, N-1)  same as ForBoth-File\r
+         nonreq         [0, M)                   same as ForBoth-File\r
+\r
+ForBoth     req   m<=N  [0, M) ... [N-M, N)      same as ForBoth-File\r
+         nonreq         [0, M)                   same as ForBoth-File\r
+\r
+*/\r
+\r
+bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const\r
+{\r
+  if (!isFile && !ForDir)\r
+    return false;\r
+  int delta = (int)pathParts.Size() - (int)PathParts.Size();\r
+  if (delta < 0)\r
+    return false;\r
+  int start = 0;\r
+  int finish = 0;\r
+  if (isFile)\r
+  {\r
+    if (!ForDir && !Recursive && delta !=0)\r
+      return false;\r
+    if (!ForFile && delta == 0)\r
+      return false;\r
+    if (!ForDir && Recursive)\r
+      start = delta;\r
+  }\r
+  if (Recursive)\r
+  {\r
+    finish = delta;\r
+    if (isFile && !ForFile)\r
+      finish = delta - 1;\r
+  }\r
+  for (int d = start; d <= finish; d++)\r
+  {\r
+    int i;\r
+    for (i = 0; i < PathParts.Size(); i++)\r
+      if (!CompareWildCardWithName(PathParts[i], pathParts[i + d]))\r
+        break;\r
+    if (i == PathParts.Size())\r
+      return true;\r
+  }\r
+  return false;\r
+}\r
+\r
+int CCensorNode::FindSubNode(const UString &name) const\r
+{\r
+  for (int i = 0; i < SubNodes.Size(); i++)\r
+    if (CompareFileNames(SubNodes[i].Name, name) == 0)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+void CCensorNode::AddItemSimple(bool include, CItem &item)\r
+{\r
+  if (include)\r
+    IncludeItems.Add(item);\r
+  else\r
+    ExcludeItems.Add(item);\r
+}\r
+\r
+void CCensorNode::AddItem(bool include, CItem &item)\r
+{\r
+  if (item.PathParts.Size() <= 1)\r
+  {\r
+    AddItemSimple(include, item);\r
+    return;\r
+  }\r
+  const UString &front = item.PathParts.Front();\r
+  if (DoesNameContainWildCard(front))\r
+  {\r
+    AddItemSimple(include, item);\r
+    return;\r
+  }\r
+  int index = FindSubNode(front);\r
+  if (index < 0)\r
+    index = SubNodes.Add(CCensorNode(front, this));\r
+  item.PathParts.Delete(0);\r
+  SubNodes[index].AddItem(include, item);\r
+}\r
+\r
+void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir)\r
+{\r
+  CItem item;\r
+  SplitPathToParts(path, item.PathParts);\r
+  item.Recursive = recursive;\r
+  item.ForFile = forFile;\r
+  item.ForDir = forDir;\r
+  AddItem(include, item);\r
+}\r
+\r
+bool CCensorNode::NeedCheckSubDirs() const\r
+{\r
+  for (int i = 0; i < IncludeItems.Size(); i++)\r
+  {\r
+    const CItem &item = IncludeItems[i];\r
+    if (item.Recursive || item.PathParts.Size() > 1)\r
+      return true;\r
+  }\r
+  return false;\r
+}\r
+\r
+bool CCensorNode::AreThereIncludeItems() const\r
+{\r
+  if (IncludeItems.Size() > 0)\r
+    return true;\r
+  for (int i = 0; i < SubNodes.Size(); i++)\r
+    if (SubNodes[i].AreThereIncludeItems())\r
+      return true;\r
+  return false;\r
+}\r
+\r
+bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const\r
+{\r
+  const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;\r
+  for (int i = 0; i < items.Size(); i++)\r
+    if (items[i].CheckPath(pathParts, isFile))\r
+      return true;\r
+  return false;\r
+}\r
+\r
+bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const\r
+{\r
+  if (CheckPathCurrent(false, pathParts, isFile))\r
+  {\r
+    include = false;\r
+    return true;\r
+  }\r
+  include = true;\r
+  bool finded = CheckPathCurrent(true, pathParts, isFile);\r
+  if (pathParts.Size() == 1)\r
+    return finded;\r
+  int index = FindSubNode(pathParts.Front());\r
+  if (index >= 0)\r
+  {\r
+    UStringVector pathParts2 = pathParts;\r
+    pathParts2.Delete(0);\r
+    if (SubNodes[index].CheckPath(pathParts2, isFile, include))\r
+      return true;\r
+  }\r
+  return finded;\r
+}\r
+\r
+bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const\r
+{\r
+  UStringVector pathParts;\r
+  SplitPathToParts(path, pathParts);\r
+  return CheckPath(pathParts, isFile, include);\r
+}\r
+\r
+bool CCensorNode::CheckPath(const UString &path, bool isFile) const\r
+{\r
+  bool include;\r
+  if (CheckPath(path, isFile, include))\r
+    return include;\r
+  return false;\r
+}\r
+\r
+bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const\r
+{\r
+  if (CheckPathCurrent(include, pathParts, isFile))\r
+    return true;\r
+  if (Parent == 0)\r
+    return false;\r
+  pathParts.Insert(0, Name);\r
+  return Parent->CheckPathToRoot(include, pathParts, isFile);\r
+}\r
+\r
+/*\r
+bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const\r
+{\r
+  UStringVector pathParts;\r
+  SplitPathToParts(path, pathParts);\r
+  return CheckPathToRoot(include, pathParts, isFile);\r
+}\r
+*/\r
+\r
+void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)\r
+{\r
+  if (path.IsEmpty())\r
+    return;\r
+  bool forFile = true;\r
+  bool forFolder = true;\r
+  UString path2 = path;\r
+  if (IsCharDirLimiter(path[path.Length() - 1]))\r
+  {\r
+    path2.Delete(path.Length() - 1);\r
+    forFile = false;\r
+  }\r
+  AddItem(include, path2, recursive, forFile, forFolder);\r
+}\r
+\r
+void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)\r
+{\r
+  ExcludeItems += fromNodes.ExcludeItems;\r
+  for (int i = 0; i < fromNodes.SubNodes.Size(); i++)\r
+  {\r
+    const CCensorNode &node = fromNodes.SubNodes[i];\r
+    int subNodeIndex = FindSubNode(node.Name);\r
+    if (subNodeIndex < 0)\r
+      subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this));\r
+    SubNodes[subNodeIndex].ExtendExclude(node);\r
+  }\r
+}\r
+\r
+int CCensor::FindPrefix(const UString &prefix) const\r
+{\r
+  for (int i = 0; i < Pairs.Size(); i++)\r
+    if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)\r
+      return i;\r
+  return -1;\r
+}\r
+\r
+void CCensor::AddItem(bool include, const UString &path, bool recursive)\r
+{\r
+  UStringVector pathParts;\r
+  if (path.IsEmpty())\r
+    throw "Empty file path";\r
+  SplitPathToParts(path, pathParts);\r
+  bool forFile = true;\r
+  if (pathParts.Back().IsEmpty())\r
+  {\r
+    forFile = false;\r
+    pathParts.DeleteBack();\r
+  }\r
+  const UString &front = pathParts.Front();\r
+  bool isAbs = false;\r
+  if (front.IsEmpty())\r
+    isAbs = true;\r
+  else if (front.Length() == 2 && front[1] == L':')\r
+    isAbs = true;\r
+  else\r
+  {\r
+    for (int i = 0; i < pathParts.Size(); i++)\r
+    {\r
+      const UString &part = pathParts[i];\r
+      if (part == L".." || part == L".")\r
+      {\r
+        isAbs = true;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  int numAbsParts = 0;\r
+  if (isAbs)\r
+    if (pathParts.Size() > 1)\r
+      numAbsParts = pathParts.Size() - 1;\r
+    else\r
+      numAbsParts = 1;\r
+  UString prefix;\r
+  for (int i = 0; i < numAbsParts; i++)\r
+  {\r
+    const UString &front = pathParts.Front();\r
+    if (DoesNameContainWildCard(front))\r
+      break;\r
+    prefix += front;\r
+    prefix += WCHAR_PATH_SEPARATOR;\r
+    pathParts.Delete(0);\r
+  }\r
+  int index = FindPrefix(prefix);\r
+  if (index < 0)\r
+    index = Pairs.Add(CPair(prefix));\r
+\r
+  CItem item;\r
+  item.PathParts = pathParts;\r
+  item.ForDir = true;\r
+  item.ForFile = forFile;\r
+  item.Recursive = recursive;\r
+  Pairs[index].Head.AddItem(include, item);\r
+}\r
+\r
+bool CCensor::CheckPath(const UString &path, bool isFile) const\r
+{\r
+  bool finded = false;\r
+  for (int i = 0; i < Pairs.Size(); i++)\r
+  {\r
+    bool include;\r
+    if (Pairs[i].Head.CheckPath(path, isFile, include))\r
+    {\r
+      if (!include)\r
+        return false;\r
+      finded = true;\r
+    }\r
+  }\r
+  return finded;\r
+}\r
+\r
+void CCensor::ExtendExclude()\r
+{\r
+  int i;\r
+  for (i = 0; i < Pairs.Size(); i++)\r
+    if (Pairs[i].Prefix.IsEmpty())\r
+      break;\r
+  if (i == Pairs.Size())\r
+    return;\r
+  int index = i;\r
+  for (i = 0; i < Pairs.Size(); i++)\r
+    if (index != i)\r
+      Pairs[i].Head.ExtendExclude(Pairs[index].Head);\r
+}\r
+\r
+}\r
diff --git a/CPP/Common/Wildcard.h b/CPP/Common/Wildcard.h
new file mode 100755 (executable)
index 0000000..e2a42c8
--- /dev/null
@@ -0,0 +1,80 @@
+// Common/Wildcard.h\r
+\r
+#ifndef __COMMON_WILDCARD_H\r
+#define __COMMON_WILDCARD_H\r
+\r
+#include "MyString.h"\r
+\r
+int CompareFileNames(const UString &s1, const UString &s2);\r
+\r
+void SplitPathToParts(const UString &path, UStringVector &pathParts);\r
+void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name);\r
+UString ExtractDirPrefixFromPath(const UString &path);\r
+UString ExtractFileNameFromPath(const UString &path);\r
+bool DoesNameContainWildCard(const UString &path);\r
+bool CompareWildCardWithName(const UString &mask, const UString &name);\r
+\r
+namespace NWildcard {\r
+\r
+struct CItem\r
+{\r
+  UStringVector PathParts;\r
+  bool Recursive;\r
+  bool ForFile;\r
+  bool ForDir;\r
+  bool CheckPath(const UStringVector &pathParts, bool isFile) const;\r
+};\r
+\r
+class CCensorNode\r
+{\r
+  CCensorNode *Parent;\r
+  bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;\r
+  void AddItemSimple(bool include, CItem &item);\r
+  bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const;\r
+public:\r
+  CCensorNode(): Parent(0) { };\r
+  CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { };\r
+  UString Name;\r
+  CObjectVector<CCensorNode> SubNodes;\r
+  CObjectVector<CItem> IncludeItems;\r
+  CObjectVector<CItem> ExcludeItems;\r
+\r
+  int FindSubNode(const UString &path) const;\r
+\r
+  void AddItem(bool include, CItem &item);\r
+  void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir);\r
+  void AddItem2(bool include, const UString &path, bool recursive);\r
+\r
+  bool NeedCheckSubDirs() const;\r
+  bool AreThereIncludeItems() const;\r
+\r
+  bool CheckPath(const UString &path, bool isFile, bool &include) const;\r
+  bool CheckPath(const UString &path, bool isFile) const;\r
+\r
+  bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const;\r
+  // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const;\r
+  void ExtendExclude(const CCensorNode &fromNodes);\r
+};\r
+\r
+struct CPair\r
+{\r
+  UString Prefix;\r
+  CCensorNode Head;\r
+  CPair(const UString &prefix): Prefix(prefix) { };\r
+};\r
+\r
+class CCensor\r
+{\r
+  int FindPrefix(const UString &prefix) const;\r
+public:\r
+  CObjectVector<CPair> Pairs;\r
+  bool AllAreRelative() const\r
+    { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }\r
+  void AddItem(bool include, const UString &path, bool recursive);\r
+  bool CheckPath(const UString &path, bool isFile) const;\r
+  void ExtendExclude();\r
+};\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp
new file mode 100755 (executable)
index 0000000..6aaedb0
--- /dev/null
@@ -0,0 +1,110 @@
+// Windows/DLL.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#ifndef _UNICODE\r
+#include "../Common/StringConvert.h"\r
+#endif\r
+\r
+#include "DLL.h"\r
+\r
+#ifndef _UNICODE\r
+extern bool g_IsNT;\r
+#endif\r
+\r
+namespace NWindows {\r
+namespace NDLL {\r
+\r
+bool CLibrary::Free()\r
+{\r
+  if (_module == 0)\r
+    return true;\r
+  // MessageBox(0, TEXT(""), TEXT("Free"), 0);\r
+  // Sleep(5000);\r
+  if (!::FreeLibrary(_module))\r
+    return false;\r
+  _module = 0;\r
+  return true;\r
+}\r
+\r
+bool CLibrary::LoadOperations(HMODULE newModule)\r
+{\r
+  if (newModule == NULL)\r
+    return false;\r
+  if (!Free())\r
+    return false;\r
+  _module = newModule;\r
+  return true;\r
+}\r
+\r
+bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)\r
+{\r
+  // MessageBox(0, fileName, TEXT("LoadEx"), 0);\r
+  return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));\r
+}\r
+\r
+bool CLibrary::Load(LPCTSTR fileName)\r
+{\r
+  // MessageBox(0, fileName, TEXT("Load"), 0);\r
+  // Sleep(5000);\r
+  // OutputDebugString(fileName);\r
+  // OutputDebugString(TEXT("\n"));\r
+  return LoadOperations(::LoadLibrary(fileName));\r
+}\r
+\r
+#ifndef _UNICODE\r
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }\r
+CSysString GetSysPath(LPCWSTR sysPath)\r
+  { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }\r
+\r
+bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)\r
+{\r
+  if (g_IsNT)\r
+    return LoadOperations(::LoadLibraryExW(fileName, NULL, flags));\r
+  return LoadEx(GetSysPath(fileName), flags);\r
+}\r
+bool CLibrary::Load(LPCWSTR fileName)\r
+{\r
+  if (g_IsNT)\r
+    return LoadOperations(::LoadLibraryW(fileName));\r
+  return Load(GetSysPath(fileName));\r
+}\r
+#endif\r
+\r
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result)\r
+{\r
+  result.Empty();\r
+  TCHAR fullPath[MAX_PATH + 2];\r
+  DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);\r
+  if (size <= MAX_PATH && size != 0)\r
+  {\r
+    result = fullPath;\r
+    return true;\r
+  }\r
+  return false;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MyGetModuleFileName(HMODULE hModule, UString &result)\r
+{\r
+  result.Empty();\r
+  if (g_IsNT)\r
+  {\r
+    wchar_t fullPath[MAX_PATH + 2];\r
+    DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);\r
+    if (size <= MAX_PATH && size != 0)\r
+    {\r
+      result = fullPath;\r
+      return true;\r
+    }\r
+    return false;\r
+  }\r
+  CSysString resultSys;\r
+  if (!MyGetModuleFileName(hModule, resultSys))\r
+    return false;\r
+  result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());\r
+  return true;\r
+}\r
+#endif\r
+\r
+}}\r
diff --git a/CPP/Windows/DLL.h b/CPP/Windows/DLL.h
new file mode 100755 (executable)
index 0000000..7d02887
--- /dev/null
@@ -0,0 +1,59 @@
+// Windows/DLL.h\r
+\r
+#ifndef __WINDOWS_DLL_H\r
+#define __WINDOWS_DLL_H\r
+\r
+#include "../Common/MyString.h"\r
+\r
+namespace NWindows {\r
+namespace NDLL {\r
+\r
+#ifdef UNDER_CE\r
+#define My_GetProcAddress(module, proceName) GetProcAddressA(module, proceName)\r
+#else\r
+#define My_GetProcAddress(module, proceName) ::GetProcAddress(module, proceName)\r
+#endif\r
\r
+class CLibrary\r
+{\r
+  bool LoadOperations(HMODULE newModule);\r
+protected:\r
+  HMODULE _module;\r
+public:\r
+  CLibrary(): _module(NULL) {};\r
+  ~CLibrary() { Free(); }\r
+\r
+  operator HMODULE() const { return _module; }\r
+  HMODULE* operator&() { return &_module; }\r
+  bool IsLoaded() const { return (_module != NULL); };\r
+\r
+  void Attach(HMODULE m)\r
+  {\r
+    Free();\r
+    _module = m;\r
+  }\r
+  HMODULE Detach()\r
+  {\r
+    HMODULE m = _module;\r
+    _module = NULL;\r
+    return m;\r
+  }\r
+\r
+  bool Free();\r
+  bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);\r
+  bool Load(LPCTSTR fileName);\r
+  #ifndef _UNICODE\r
+  bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);\r
+  bool Load(LPCWSTR fileName);\r
+  #endif\r
+  FARPROC GetProc(LPCSTR procName) const { return My_GetProcAddress(_module, procName); }\r
+};\r
+\r
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result);\r
+#ifndef _UNICODE\r
+bool MyGetModuleFileName(HMODULE hModule, UString &result);\r
+#endif\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/Defs.h b/CPP/Windows/Defs.h
new file mode 100755 (executable)
index 0000000..f3d692f
--- /dev/null
@@ -0,0 +1,17 @@
+// Windows/Defs.h\r
+\r
+#ifndef __WINDOWS_DEFS_H\r
+#define __WINDOWS_DEFS_H\r
+\r
+#include "../Common/MyWindows.h"\r
+\r
+#ifdef _WIN32\r
+inline bool LRESULTToBool(LRESULT v) { return (v != FALSE); }\r
+inline bool BOOLToBool(BOOL v) { return (v != FALSE); }\r
+inline BOOL BoolToBOOL(bool v) { return (v ? TRUE: FALSE); }\r
+#endif\r
+\r
+inline VARIANT_BOOL BoolToVARIANT_BOOL(bool v) { return (v ? VARIANT_TRUE: VARIANT_FALSE); }\r
+inline bool VARIANT_BOOLToBool(VARIANT_BOOL v) { return (v != VARIANT_FALSE); }\r
+\r
+#endif\r
diff --git a/CPP/Windows/Error.cpp b/CPP/Windows/Error.cpp
new file mode 100755 (executable)
index 0000000..fcba1e6
--- /dev/null
@@ -0,0 +1,50 @@
+// Windows/Error.h\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Windows/Error.h"\r
+#ifndef _UNICODE\r
+#include "Common/StringConvert.h"\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+extern bool g_IsNT;\r
+#endif\r
+\r
+namespace NWindows {\r
+namespace NError {\r
+\r
+bool MyFormatMessage(DWORD messageID, CSysString &message)\r
+{\r
+  LPVOID msgBuf;\r
+  if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |\r
+      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\r
+      NULL,messageID, 0, (LPTSTR) &msgBuf,0, NULL) == 0)\r
+    return false;\r
+  message = (LPCTSTR)msgBuf;\r
+  ::LocalFree(msgBuf);\r
+  return true;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MyFormatMessage(DWORD messageID, UString &message)\r
+{\r
+  if (g_IsNT)\r
+  {\r
+    LPVOID msgBuf;\r
+    if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |\r
+        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\r
+        NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)\r
+      return false;\r
+    message = (LPCWSTR)msgBuf;\r
+    ::LocalFree(msgBuf);\r
+    return true;\r
+  }\r
+  CSysString messageSys;\r
+  bool result = MyFormatMessage(messageID, messageSys);\r
+  message = GetUnicodeString(messageSys);\r
+  return result;\r
+}\r
+#endif\r
+\r
+}}\r
diff --git a/CPP/Windows/Error.h b/CPP/Windows/Error.h
new file mode 100755 (executable)
index 0000000..d916e8e
--- /dev/null
@@ -0,0 +1,33 @@
+// Windows/Error.h\r
+\r
+#ifndef __WINDOWS_ERROR_H\r
+#define __WINDOWS_ERROR_H\r
+\r
+#include "Common/MyString.h"\r
+\r
+namespace NWindows {\r
+namespace NError {\r
+\r
+bool MyFormatMessage(DWORD messageID, CSysString &message);\r
+inline CSysString MyFormatMessage(DWORD messageID)\r
+{\r
+  CSysString message;\r
+  MyFormatMessage(messageID, message);\r
+  return message;\r
+}\r
+#ifdef _UNICODE\r
+inline UString MyFormatMessageW(DWORD messageID)\r
+  { return MyFormatMessage(messageID); }\r
+#else\r
+bool MyFormatMessage(DWORD messageID, UString &message);\r
+inline UString MyFormatMessageW(DWORD messageID)\r
+{\r
+  UString message;\r
+  MyFormatMessage(messageID, message);\r
+  return message;\r
+}\r
+#endif\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
new file mode 100755 (executable)
index 0000000..daec1d3
--- /dev/null
@@ -0,0 +1,909 @@
+// Windows/FileDir.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#ifndef _UNICODE\r
+#include "../Common/StringConvert.h"\r
+#endif\r
+\r
+#include "FileDir.h"\r
+#include "FileFind.h"\r
+#include "FileName.h"\r
+\r
+#ifndef _UNICODE\r
+extern bool g_IsNT;\r
+#endif\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+\r
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)\r
+#define WIN_LONG_PATH2\r
+#endif\r
+\r
+// SetCurrentDirectory doesn't support \\?\ prefix\r
+\r
+#ifdef WIN_LONG_PATH\r
+bool GetLongPathBase(LPCWSTR fileName, UString &res);\r
+bool GetLongPath(LPCWSTR fileName, UString &res);\r
+#endif\r
+\r
+namespace NDirectory {\r
+\r
+#ifndef _UNICODE\r
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }\r
+static UString GetUnicodePath(const CSysString &sysPath)\r
+  { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }\r
+static CSysString GetSysPath(LPCWSTR sysPath)\r
+  { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }\r
+#endif\r
+\r
+#ifndef UNDER_CE\r
+\r
+bool MyGetWindowsDirectory(CSysString &path)\r
+{\r
+  UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);\r
+  path.ReleaseBuffer();\r
+  return (needLength > 0 && needLength <= MAX_PATH);\r
+}\r
+\r
+bool MyGetSystemDirectory(CSysString &path)\r
+{\r
+  UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);\r
+  path.ReleaseBuffer();\r
+  return (needLength > 0 && needLength <= MAX_PATH);\r
+}\r
+\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+bool MyGetWindowsDirectory(UString &path)\r
+{\r
+  if (g_IsNT)\r
+  {\r
+    UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);\r
+    path.ReleaseBuffer();\r
+    return (needLength > 0 && needLength <= MAX_PATH);\r
+  }\r
+  CSysString sysPath;\r
+  if (!MyGetWindowsDirectory(sysPath))\r
+    return false;\r
+  path = GetUnicodePath(sysPath);\r
+  return true;\r
+}\r
+\r
+bool MyGetSystemDirectory(UString &path)\r
+{\r
+  if (g_IsNT)\r
+  {\r
+    UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);\r
+    path.ReleaseBuffer();\r
+    return (needLength > 0 && needLength <= MAX_PATH);\r
+  }\r
+  CSysString sysPath;\r
+  if (!MyGetSystemDirectory(sysPath))\r
+    return false;\r
+  path = GetUnicodePath(sysPath);\r
+  return true;\r
+}\r
+#endif\r
+\r
+bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)\r
+{\r
+  #ifndef _UNICODE\r
+  if (!g_IsNT)\r
+  {\r
+    ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);\r
+    return false;\r
+  }\r
+  #endif\r
+  HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,\r
+      FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+      NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);\r
+  #ifdef WIN_LONG_PATH\r
+  if (hDir == INVALID_HANDLE_VALUE)\r
+  {\r
+    UString longPath;\r
+    if (GetLongPath(fileName, longPath))\r
+      hDir = ::CreateFileW(longPath, GENERIC_WRITE,\r
+        FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);\r
+  }\r
+  #endif\r
+\r
+  bool res = false;\r
+  if (hDir != INVALID_HANDLE_VALUE)\r
+  {\r
+    res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime));\r
+    ::CloseHandle(hDir);\r
+  }\r
+  return res;\r
+}\r
+\r
+bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)\r
+{\r
+  if (::SetFileAttributes(fileName, fileAttributes))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH2\r
+  UString longPath;\r
+  if (GetLongPath(fileName, longPath))\r
+    return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));\r
+  #endif\r
+  return false;\r
+}\r
+\r
+bool MyRemoveDirectory(LPCTSTR pathName)\r
+{\r
+  if (::RemoveDirectory(pathName))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH2\r
+  UString longPath;\r
+  if (GetLongPath(pathName, longPath))\r
+    return BOOLToBool(::RemoveDirectoryW(longPath));\r
+  #endif\r
+  return false;\r
+}\r
+\r
+#ifdef WIN_LONG_PATH\r
+bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2)\r
+{\r
+  if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2))\r
+    return false;\r
+  if (d1.IsEmpty() && d2.IsEmpty()) return false;\r
+  if (d1.IsEmpty()) d1 = s1;\r
+  if (d2.IsEmpty()) d2 = s2;\r
+  return true;\r
+}\r
+#endif\r
+\r
+bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)\r
+{\r
+  if (::MoveFile(existFileName, newFileName))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH2\r
+  UString d1, d2;\r
+  if (GetLongPaths(existFileName, newFileName, d1, d2))\r
+    return BOOLToBool(::MoveFileW(d1, d2));\r
+  #endif\r
+  return false;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)\r
+{\r
+  if (!g_IsNT)\r
+    return MySetFileAttributes(GetSysPath(fileName), fileAttributes);\r
+  if (::SetFileAttributesW(fileName, fileAttributes))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH\r
+  UString longPath;\r
+  if (GetLongPath(fileName, longPath))\r
+    return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));\r
+  #endif\r
+  return false;\r
+}\r
+\r
+\r
+bool MyRemoveDirectory(LPCWSTR pathName)\r
+{\r
+  if (!g_IsNT)\r
+    return MyRemoveDirectory(GetSysPath(pathName));\r
+  if (::RemoveDirectoryW(pathName))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH\r
+  UString longPath;\r
+  if (GetLongPath(pathName, longPath))\r
+    return BOOLToBool(::RemoveDirectoryW(longPath));\r
+  #endif\r
+  return false;\r
+}\r
+\r
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)\r
+{\r
+  if (!g_IsNT)\r
+    return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));\r
+  if (::MoveFileW(existFileName, newFileName))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH\r
+  UString d1, d2;\r
+  if (GetLongPaths(existFileName, newFileName, d1, d2))\r
+    return BOOLToBool(::MoveFileW(d1, d2));\r
+  #endif\r
+  return false;\r
+}\r
+#endif\r
+\r
+bool MyCreateDirectory(LPCTSTR pathName)\r
+{\r
+  if (::CreateDirectory(pathName, NULL))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH2\r
+  if (::GetLastError() != ERROR_ALREADY_EXISTS)\r
+  {\r
+    UString longPath;\r
+    if (GetLongPath(pathName, longPath))\r
+      return BOOLToBool(::CreateDirectoryW(longPath, NULL));\r
+  }\r
+  #endif\r
+  return false;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MyCreateDirectory(LPCWSTR pathName)\r
+{\r
+  if (!g_IsNT)\r
+    return MyCreateDirectory(GetSysPath(pathName));\r
+  if (::CreateDirectoryW(pathName, NULL))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH\r
+  if (::GetLastError() != ERROR_ALREADY_EXISTS)\r
+  {\r
+    UString longPath;\r
+    if (GetLongPath(pathName, longPath))\r
+      return BOOLToBool(::CreateDirectoryW(longPath, NULL));\r
+  }\r
+  #endif\r
+  return false;\r
+}\r
+#endif\r
+\r
+/*\r
+bool CreateComplexDirectory(LPCTSTR pathName)\r
+{\r
+  NName::CParsedPath path;\r
+  path.ParsePath(pathName);\r
+  CSysString fullPath = path.Prefix;\r
+  DWORD errorCode = ERROR_SUCCESS;\r
+  for (int i = 0; i < path.PathParts.Size(); i++)\r
+  {\r
+    const CSysString &string = path.PathParts[i];\r
+    if (string.IsEmpty())\r
+    {\r
+      if (i != path.PathParts.Size() - 1)\r
+        return false;\r
+      return true;\r
+    }\r
+    fullPath += path.PathParts[i];\r
+    if (!MyCreateDirectory(fullPath))\r
+    {\r
+      DWORD errorCode = GetLastError();\r
+      if (errorCode != ERROR_ALREADY_EXISTS)\r
+        return false;\r
+    }\r
+    fullPath += NName::kDirDelimiter;\r
+  }\r
+  return true;\r
+}\r
+*/\r
+\r
+bool CreateComplexDirectory(LPCTSTR _aPathName)\r
+{\r
+  CSysString pathName = _aPathName;\r
+  int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));\r
+  if (pos > 0 && pos == pathName.Length() - 1)\r
+  {\r
+    if (pathName.Length() == 3 && pathName[1] == ':')\r
+      return true; // Disk folder;\r
+    pathName.Delete(pos);\r
+  }\r
+  CSysString pathName2 = pathName;\r
+  pos = pathName.Length();\r
+  for (;;)\r
+  {\r
+    if (MyCreateDirectory(pathName))\r
+      break;\r
+    if (::GetLastError() == ERROR_ALREADY_EXISTS)\r
+    {\r
+      NFind::CFileInfo fileInfo;\r
+      if (!fileInfo.Find(pathName)) // For network folders\r
+        return true;\r
+      if (!fileInfo.IsDir())\r
+        return false;\r
+      break;\r
+    }\r
+    pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));\r
+    if (pos < 0 || pos == 0)\r
+      return false;\r
+    if (pathName[pos - 1] == ':')\r
+      return false;\r
+    pathName = pathName.Left(pos);\r
+  }\r
+  pathName = pathName2;\r
+  while (pos < pathName.Length())\r
+  {\r
+    pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);\r
+    if (pos < 0)\r
+      pos = pathName.Length();\r
+    if (!MyCreateDirectory(pathName.Left(pos)))\r
+      return false;\r
+  }\r
+  return true;\r
+}\r
+\r
+#ifndef _UNICODE\r
+\r
+bool CreateComplexDirectory(LPCWSTR _aPathName)\r
+{\r
+  UString pathName = _aPathName;\r
+  int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);\r
+  if (pos > 0 && pos == pathName.Length() - 1)\r
+  {\r
+    if (pathName.Length() == 3 && pathName[1] == L':')\r
+      return true; // Disk folder;\r
+    pathName.Delete(pos);\r
+  }\r
+  UString pathName2 = pathName;\r
+  pos = pathName.Length();\r
+  for (;;)\r
+  {\r
+    if (MyCreateDirectory(pathName))\r
+      break;\r
+    if (::GetLastError() == ERROR_ALREADY_EXISTS)\r
+    {\r
+      NFind::CFileInfoW fileInfo;\r
+      if (!fileInfo.Find(pathName)) // For network folders\r
+        return true;\r
+      if (!fileInfo.IsDir())\r
+        return false;\r
+      break;\r
+    }\r
+    pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);\r
+    if (pos < 0 || pos == 0)\r
+      return false;\r
+    if (pathName[pos - 1] == L':')\r
+      return false;\r
+    pathName = pathName.Left(pos);\r
+  }\r
+  pathName = pathName2;\r
+  while (pos < pathName.Length())\r
+  {\r
+    pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);\r
+    if (pos < 0)\r
+      pos = pathName.Length();\r
+    if (!MyCreateDirectory(pathName.Left(pos)))\r
+      return false;\r
+  }\r
+  return true;\r
+}\r
+\r
+#endif\r
+\r
+bool DeleteFileAlways(LPCTSTR name)\r
+{\r
+  if (!MySetFileAttributes(name, 0))\r
+    return false;\r
+  if (::DeleteFile(name))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH2\r
+  UString longPath;\r
+  if (GetLongPath(name, longPath))\r
+    return BOOLToBool(::DeleteFileW(longPath));\r
+  #endif\r
+  return false;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool DeleteFileAlways(LPCWSTR name)\r
+{\r
+  if (!g_IsNT)\r
+    return DeleteFileAlways(GetSysPath(name));\r
+  if (!MySetFileAttributes(name, 0))\r
+    return false;\r
+  if (::DeleteFileW(name))\r
+    return true;\r
+  #ifdef WIN_LONG_PATH\r
+  UString longPath;\r
+  if (GetLongPath(name, longPath))\r
+    return BOOLToBool(::DeleteFileW(longPath));\r
+  #endif\r
+  return false;\r
+}\r
+#endif\r
+\r
+static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)\r
+{\r
+  if (fileInfo.IsDir())\r
+    return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);\r
+  return DeleteFileAlways(pathPrefix + fileInfo.Name);\r
+}\r
+\r
+bool RemoveDirectoryWithSubItems(const CSysString &path)\r
+{\r
+  NFind::CFileInfo fileInfo;\r
+  CSysString pathPrefix = path + NName::kDirDelimiter;\r
+  {\r
+    NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));\r
+    while (enumerator.Next(fileInfo))\r
+      if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))\r
+        return false;\r
+  }\r
+  if (!MySetFileAttributes(path, 0))\r
+    return false;\r
+  return MyRemoveDirectory(path);\r
+}\r
+\r
+#ifndef _UNICODE\r
+static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)\r
+{\r
+  if (fileInfo.IsDir())\r
+    return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);\r
+  return DeleteFileAlways(pathPrefix + fileInfo.Name);\r
+}\r
+bool RemoveDirectoryWithSubItems(const UString &path)\r
+{\r
+  NFind::CFileInfoW fileInfo;\r
+  UString pathPrefix = path + UString(NName::kDirDelimiter);\r
+  {\r
+    NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));\r
+    while (enumerator.Next(fileInfo))\r
+      if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))\r
+        return false;\r
+  }\r
+  if (!MySetFileAttributes(path, 0))\r
+    return false;\r
+  return MyRemoveDirectory(path);\r
+}\r
+#endif\r
+\r
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)\r
+{\r
+  int index;\r
+  if (!MyGetFullPathName(fileName, resultName, index))\r
+    return false;\r
+  resultName = resultName.Left(index);\r
+  return true;\r
+}\r
+\r
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)\r
+{\r
+  int index;\r
+  if (!MyGetFullPathName(fileName, resultName, index))\r
+    return false;\r
+  resultName = resultName.Mid(index);\r
+  return true;\r
+}\r
+\r
+#ifdef UNDER_CE\r
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath)\r
+{\r
+  resultPath = fileName;\r
+  return true;\r
+}\r
+\r
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)\r
+{\r
+  resultPath = fileName;\r
+  // change it\r
+  fileNamePartStartIndex = resultPath.ReverseFind(WCHAR_PATH_SEPARATOR);\r
+  fileNamePartStartIndex++;\r
+  return true;\r
+}\r
+\r
+#else\r
+\r
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)\r
+{\r
+  DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);\r
+  shortPath.ReleaseBuffer();\r
+  return (needLength > 0 && needLength < MAX_PATH);\r
+}\r
+\r
+#ifdef WIN_LONG_PATH\r
+\r
+static UString GetLastPart(LPCWSTR path)\r
+{\r
+  int i = (int)wcslen(path);\r
+  for (; i > 0; i--)\r
+  {\r
+    WCHAR c = path[i - 1];\r
+    if (c == WCHAR_PATH_SEPARATOR || c == '/')\r
+      break;\r
+  }\r
+  return path + i;\r
+}\r
+\r
+static void AddTrailingDots(LPCWSTR oldPath, UString &newPath)\r
+{\r
+  int len = (int)wcslen(oldPath);\r
+  int i;\r
+  for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);\r
+  if (i == 0 || i == len)\r
+    return;\r
+  UString oldName = GetLastPart(oldPath);\r
+  UString newName = GetLastPart(newPath);\r
+  int nonDotsLen = oldName.Length() - (len - i);\r
+  if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)\r
+    return;\r
+  for (; i != len; i++)\r
+    newPath += '.';\r
+}\r
+\r
+#endif\r
+\r
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)\r
+{\r
+  resultPath.Empty();\r
+  LPTSTR fileNamePointer = 0;\r
+  LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);\r
+  DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);\r
+  resultPath.ReleaseBuffer();\r
+  if (needLength == 0)\r
+    return false;\r
+  if (needLength >= MAX_PATH)\r
+  {\r
+    #ifdef WIN_LONG_PATH2\r
+    needLength++;\r
+    buffer = resultPath.GetBuffer(needLength + 1);\r
+    DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);\r
+    resultPath.ReleaseBuffer();\r
+    if (needLength2 == 0 || needLength2 > needLength)\r
+    #endif\r
+      return false;\r
+  }\r
+  if (fileNamePointer == 0)\r
+    fileNamePartStartIndex = lstrlen(fileName);\r
+  else\r
+    fileNamePartStartIndex = (int)(fileNamePointer - buffer);\r
+  #ifdef _UNICODE\r
+  #ifdef WIN_LONG_PATH\r
+  AddTrailingDots(fileName, resultPath);\r
+  #endif\r
+  #endif\r
+  return true;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)\r
+{\r
+  resultPath.Empty();\r
+  if (g_IsNT)\r
+  {\r
+    LPWSTR fileNamePointer = 0;\r
+    LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);\r
+    DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);\r
+    resultPath.ReleaseBuffer();\r
+    if (needLength == 0)\r
+      return false;\r
+    if (needLength >= MAX_PATH)\r
+    {\r
+      #ifdef WIN_LONG_PATH\r
+      needLength++;\r
+      buffer = resultPath.GetBuffer(needLength + 1);\r
+      DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);\r
+      resultPath.ReleaseBuffer();\r
+      if (needLength2 == 0 || needLength2 > needLength)\r
+      #endif\r
+        return false;\r
+    }\r
+    if (fileNamePointer == 0)\r
+      fileNamePartStartIndex = MyStringLen(fileName);\r
+    else\r
+      fileNamePartStartIndex = (int)(fileNamePointer - buffer);\r
+    #ifdef WIN_LONG_PATH\r
+    AddTrailingDots(fileName, resultPath);\r
+    #endif\r
+  }\r
+  else\r
+  {\r
+    CSysString sysPath;\r
+    if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))\r
+      return false;\r
+    UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));\r
+    UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));\r
+    fileNamePartStartIndex = resultPath1.Length();\r
+    resultPath = resultPath1 + resultPath2;\r
+  }\r
+  return true;\r
+}\r
+#endif\r
+\r
+\r
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)\r
+{\r
+  int index;\r
+  return MyGetFullPathName(fileName, path, index);\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MyGetFullPathName(LPCWSTR fileName, UString &path)\r
+{\r
+  int index;\r
+  return MyGetFullPathName(fileName, path, index);\r
+}\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+bool GetOnlyName(LPCWSTR fileName, UString &resultName)\r
+{\r
+  int index;\r
+  if (!MyGetFullPathName(fileName, resultName, index))\r
+    return false;\r
+  resultName = resultName.Mid(index);\r
+  return true;\r
+}\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)\r
+{\r
+  int index;\r
+  if (!MyGetFullPathName(fileName, resultName, index))\r
+    return false;\r
+  resultName = resultName.Left(index);\r
+  return true;\r
+}\r
+#endif\r
+\r
+bool MyGetCurrentDirectory(CSysString &path)\r
+{\r
+  DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));\r
+  path.ReleaseBuffer();\r
+  return (needLength > 0 && needLength <= MAX_PATH);\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MySetCurrentDirectory(LPCWSTR path)\r
+{\r
+  if (g_IsNT)\r
+    return BOOLToBool(::SetCurrentDirectoryW(path));\r
+  return MySetCurrentDirectory(GetSysPath(path));\r
+}\r
+bool MyGetCurrentDirectory(UString &path)\r
+{\r
+  if (g_IsNT)\r
+  {\r
+    DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));\r
+    path.ReleaseBuffer();\r
+    return (needLength > 0 && needLength <= MAX_PATH);\r
+  }\r
+  CSysString sysPath;\r
+  if (!MyGetCurrentDirectory(sysPath))\r
+    return false;\r
+  path = GetUnicodePath(sysPath);\r
+  return true;\r
+}\r
+#endif\r
+\r
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,\r
+  CSysString &resultPath, UINT32 &filePart)\r
+{\r
+  LPTSTR filePartPointer;\r
+  DWORD value = ::SearchPath(path, fileName, extension,\r
+    MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);\r
+  filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);\r
+  resultPath.ReleaseBuffer();\r
+  return (value > 0 && value <= MAX_PATH);\r
+}\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,\r
+  UString &resultPath, UINT32 &filePart)\r
+{\r
+  if (g_IsNT)\r
+  {\r
+    LPWSTR filePartPointer = 0;\r
+    DWORD value = ::SearchPathW(path, fileName, extension,\r
+        MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);\r
+    filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);\r
+    resultPath.ReleaseBuffer();\r
+    return (value > 0 && value <= MAX_PATH);\r
+  }\r
+  \r
+  CSysString sysPath;\r
+  if (!MySearchPath(\r
+      path != 0 ? (LPCTSTR)GetSysPath(path): 0,\r
+      fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,\r
+      extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,\r
+      sysPath, filePart))\r
+    return false;\r
+  UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));\r
+  UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));\r
+  filePart = resultPath1.Length();\r
+  resultPath = resultPath1 + resultPath2;\r
+  return true;\r
+}\r
+#endif\r
+\r
+bool MyGetTempPath(CSysString &path)\r
+{\r
+  DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));\r
+  path.ReleaseBuffer();\r
+  return (needLength > 0 && needLength <= MAX_PATH);\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MyGetTempPath(UString &path)\r
+{\r
+  path.Empty();\r
+  if (g_IsNT)\r
+  {\r
+    DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));\r
+    path.ReleaseBuffer();\r
+    return (needLength > 0 && needLength <= MAX_PATH);\r
+  }\r
+  CSysString sysPath;\r
+  if (!MyGetTempPath(sysPath))\r
+    return false;\r
+  path = GetUnicodePath(sysPath);\r
+  return true;\r
+}\r
+#endif\r
+\r
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)\r
+{\r
+  UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));\r
+  path.ReleaseBuffer();\r
+  return number;\r
+}\r
+\r
+#ifndef _UNICODE\r
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)\r
+{\r
+  if (g_IsNT)\r
+  {\r
+    UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));\r
+    path.ReleaseBuffer();\r
+    return number;\r
+  }\r
+  CSysString sysPath;\r
+  UINT number = MyGetTempFileName(\r
+      dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,\r
+      prefix ? (LPCTSTR)GetSysPath(prefix): 0,\r
+      sysPath);\r
+  path = GetUnicodePath(sysPath);\r
+  return number;\r
+}\r
+#endif\r
+\r
+UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)\r
+{\r
+  Remove();\r
+  UINT number = MyGetTempFileName(dirPath, prefix, resultPath);\r
+  if (number != 0)\r
+  {\r
+    _fileName = resultPath;\r
+    _mustBeDeleted = true;\r
+  }\r
+  return number;\r
+}\r
+\r
+bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)\r
+{\r
+  CSysString tempPath;\r
+  if (!MyGetTempPath(tempPath))\r
+    return false;\r
+  if (Create(tempPath, prefix, resultPath) != 0)\r
+    return true;\r
+  #ifdef UNDER_CE\r
+  return false;\r
+  #else\r
+  if (!MyGetWindowsDirectory(tempPath))\r
+    return false;\r
+  return (Create(tempPath, prefix, resultPath) != 0);\r
+  #endif\r
+}\r
+\r
+bool CTempFile::Remove()\r
+{\r
+  if (!_mustBeDeleted)\r
+    return true;\r
+  _mustBeDeleted = !DeleteFileAlways(_fileName);\r
+  return !_mustBeDeleted;\r
+}\r
+\r
+#ifndef _UNICODE\r
+\r
+UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)\r
+{\r
+  Remove();\r
+  UINT number = MyGetTempFileName(dirPath, prefix, resultPath);\r
+  if (number != 0)\r
+  {\r
+    _fileName = resultPath;\r
+    _mustBeDeleted = true;\r
+  }\r
+  return number;\r
+}\r
+\r
+bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)\r
+{\r
+  UString tempPath;\r
+  if (!MyGetTempPath(tempPath))\r
+    return false;\r
+  if (Create(tempPath, prefix, resultPath) != 0)\r
+    return true;\r
+  if (!MyGetWindowsDirectory(tempPath))\r
+    return false;\r
+  return (Create(tempPath, prefix, resultPath) != 0);\r
+}\r
+\r
+bool CTempFileW::Remove()\r
+{\r
+  if (!_mustBeDeleted)\r
+    return true;\r
+  _mustBeDeleted = !DeleteFileAlways(_fileName);\r
+  return !_mustBeDeleted;\r
+}\r
+\r
+#endif\r
+\r
+bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)\r
+{\r
+  /*\r
+  CSysString prefix = tempPath + prefixChars;\r
+  CRandom random;\r
+  random.Init();\r
+  */\r
+  for (;;)\r
+  {\r
+    {\r
+      CTempFile tempFile;\r
+      if (!tempFile.Create(prefix, dirName))\r
+        return false;\r
+      if (!tempFile.Remove())\r
+        return false;\r
+    }\r
+    /*\r
+    UINT32 randomNumber = random.Generate();\r
+    TCHAR randomNumberString[32];\r
+    _stprintf(randomNumberString, _T("%04X"), randomNumber);\r
+    dirName = prefix + randomNumberString;\r
+    */\r
+    if (NFind::DoesFileOrDirExist(dirName))\r
+      continue;\r
+    if (MyCreateDirectory(dirName))\r
+      return true;\r
+    if (::GetLastError() != ERROR_ALREADY_EXISTS)\r
+      return false;\r
+  }\r
+}\r
+\r
+bool CTempDirectory::Create(LPCTSTR prefix)\r
+{\r
+  Remove();\r
+  return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));\r
+}\r
+\r
+#ifndef _UNICODE\r
+\r
+bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)\r
+{\r
+  /*\r
+  CSysString prefix = tempPath + prefixChars;\r
+  CRandom random;\r
+  random.Init();\r
+  */\r
+  for (;;)\r
+  {\r
+    {\r
+      CTempFileW tempFile;\r
+      if (!tempFile.Create(prefix, dirName))\r
+        return false;\r
+      if (!tempFile.Remove())\r
+        return false;\r
+    }\r
+    /*\r
+    UINT32 randomNumber = random.Generate();\r
+    TCHAR randomNumberString[32];\r
+    _stprintf(randomNumberString, _T("%04X"), randomNumber);\r
+    dirName = prefix + randomNumberString;\r
+    */\r
+    if (NFind::DoesFileOrDirExist(dirName))\r
+      continue;\r
+    if (MyCreateDirectory(dirName))\r
+      return true;\r
+    if (::GetLastError() != ERROR_ALREADY_EXISTS)\r
+      return false;\r
+  }\r
+}\r
+\r
+bool CTempDirectoryW::Create(LPCWSTR prefix)\r
+{\r
+  Remove();\r
+  return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));\r
+}\r
+\r
+#endif\r
+\r
+}}}\r
diff --git a/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h
new file mode 100755 (executable)
index 0000000..2c15071
--- /dev/null
@@ -0,0 +1,177 @@
+// Windows/FileDir.h\r
+\r
+#ifndef __WINDOWS_FILEDIR_H\r
+#define __WINDOWS_FILEDIR_H\r
+\r
+#include "../Common/MyString.h"\r
+#include "Defs.h"\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+namespace NDirectory {\r
+\r
+#ifdef WIN_LONG_PATH\r
+bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2);\r
+#endif\r
+\r
+bool MyGetWindowsDirectory(CSysString &path);\r
+bool MyGetSystemDirectory(CSysString &path);\r
+#ifndef _UNICODE\r
+bool MyGetWindowsDirectory(UString &path);\r
+bool MyGetSystemDirectory(UString &path);\r
+#endif\r
+\r
+bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);\r
+\r
+bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);\r
+bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);\r
+bool MyRemoveDirectory(LPCTSTR pathName);\r
+bool MyCreateDirectory(LPCTSTR pathName);\r
+bool CreateComplexDirectory(LPCTSTR pathName);\r
+bool DeleteFileAlways(LPCTSTR name);\r
+bool RemoveDirectoryWithSubItems(const CSysString &path);\r
+\r
+#ifndef _UNICODE\r
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);\r
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);\r
+bool MyRemoveDirectory(LPCWSTR pathName);\r
+bool MyCreateDirectory(LPCWSTR pathName);\r
+bool CreateComplexDirectory(LPCWSTR pathName);\r
+bool DeleteFileAlways(LPCWSTR name);\r
+bool RemoveDirectoryWithSubItems(const UString &path);\r
+#endif\r
+\r
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);\r
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);\r
+#ifdef UNDER_CE\r
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);\r
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex);\r
+#else\r
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);\r
+\r
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex);\r
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);\r
+#ifndef _UNICODE\r
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,\r
+    int &fileNamePartStartIndex);\r
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);\r
+bool GetOnlyName(LPCWSTR fileName, UString &resultName);\r
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);\r
+#endif\r
+\r
+inline bool MySetCurrentDirectory(LPCTSTR path)\r
+  { return BOOLToBool(::SetCurrentDirectory(path)); }\r
+bool MyGetCurrentDirectory(CSysString &resultPath);\r
+#ifndef _UNICODE\r
+bool MySetCurrentDirectory(LPCWSTR path);\r
+bool MyGetCurrentDirectory(UString &resultPath);\r
+#endif\r
+\r
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, CSysString &resultPath, UINT32 &filePart);\r
+#ifndef _UNICODE\r
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath, UINT32 &filePart);\r
+#endif\r
+\r
+inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, CSysString &resultPath)\r
+{\r
+  UINT32 value;\r
+  return MySearchPath(path, fileName, extension, resultPath, value);\r
+}\r
+\r
+#ifndef _UNICODE\r
+inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath)\r
+{\r
+  UINT32 value;\r
+  return MySearchPath(path, fileName, extension, resultPath, value);\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+bool MyGetTempPath(CSysString &resultPath);\r
+#ifndef _UNICODE\r
+bool MyGetTempPath(UString &resultPath);\r
+#endif\r
+\r
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);\r
+#ifndef _UNICODE\r
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);\r
+#endif\r
+\r
+class CTempFile\r
+{\r
+  bool _mustBeDeleted;\r
+  CSysString _fileName;\r
+public:\r
+  CTempFile(): _mustBeDeleted(false) {}\r
+  ~CTempFile() { Remove(); }\r
+  void DisableDeleting() { _mustBeDeleted = false; }\r
+  UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);\r
+  bool Create(LPCTSTR prefix, CSysString &resultPath);\r
+  bool Remove();\r
+};\r
+\r
+#ifdef _UNICODE\r
+typedef CTempFile CTempFileW;\r
+#else\r
+class CTempFileW\r
+{\r
+  bool _mustBeDeleted;\r
+  UString _fileName;\r
+public:\r
+  CTempFileW(): _mustBeDeleted(false) {}\r
+  ~CTempFileW() { Remove(); }\r
+  void DisableDeleting() { _mustBeDeleted = false; }\r
+  UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);\r
+  bool Create(LPCWSTR prefix, UString &resultPath);\r
+  bool Remove();\r
+};\r
+#endif\r
+\r
+bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);\r
+\r
+class CTempDirectory\r
+{\r
+  bool _mustBeDeleted;\r
+  CSysString _tempDir;\r
+public:\r
+  const CSysString &GetPath() const { return _tempDir; }\r
+  CTempDirectory(): _mustBeDeleted(false) {}\r
+  ~CTempDirectory() { Remove();  }\r
+  bool Create(LPCTSTR prefix) ;\r
+  bool Remove()\r
+  {\r
+    if (!_mustBeDeleted)\r
+      return true;\r
+    _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);\r
+    return (!_mustBeDeleted);\r
+  }\r
+  void DisableDeleting() { _mustBeDeleted = false; }\r
+};\r
+\r
+#ifdef _UNICODE\r
+typedef CTempDirectory CTempDirectoryW;\r
+#else\r
+class CTempDirectoryW\r
+{\r
+  bool _mustBeDeleted;\r
+  UString _tempDir;\r
+public:\r
+  const UString &GetPath() const { return _tempDir; }\r
+  CTempDirectoryW(): _mustBeDeleted(false) {}\r
+  ~CTempDirectoryW() { Remove();  }\r
+  bool Create(LPCWSTR prefix) ;\r
+  bool Remove()\r
+  {\r
+    if (!_mustBeDeleted)\r
+      return true;\r
+    _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);\r
+    return (!_mustBeDeleted);\r
+  }\r
+  void DisableDeleting() { _mustBeDeleted = false; }\r
+};\r
+#endif\r
+\r
+}}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp
new file mode 100755 (executable)
index 0000000..99fb706
--- /dev/null
@@ -0,0 +1,462 @@
+// Windows/FileFind.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "FileFind.h"\r
+#include "FileIO.h"\r
+#ifndef _UNICODE\r
+#include "../Common/StringConvert.h"\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+extern bool g_IsNT;\r
+#endif\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+\r
+#ifdef SUPPORT_DEVICE_FILE\r
+bool IsDeviceName(LPCTSTR n);\r
+#ifndef _UNICODE\r
+bool IsDeviceName(LPCWSTR n);\r
+#endif\r
+#endif\r
+\r
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)\r
+#define WIN_LONG_PATH2\r
+#endif\r
+\r
+bool GetLongPath(LPCWSTR fileName, UString &res);\r
+\r
+namespace NFind {\r
+\r
+static const TCHAR kDot = TEXT('.');\r
+\r
+bool CFileInfo::IsDots() const\r
+{\r
+  if (!IsDir() || Name.IsEmpty())\r
+    return false;\r
+  if (Name[0] != kDot)\r
+    return false;\r
+  return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool CFileInfoW::IsDots() const\r
+{\r
+  if (!IsDir() || Name.IsEmpty())\r
+    return false;\r
+  if (Name[0] != kDot)\r
+    return false;\r
+  return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);\r
+}\r
+#endif\r
+\r
+#define WIN_FD_TO_MY_FI(fi, fd) \\r
+  fi.Attrib = fd.dwFileAttributes; \\r
+  fi.CTime = fd.ftCreationTime; \\r
+  fi.ATime = fd.ftLastAccessTime; \\r
+  fi.MTime = fd.ftLastWriteTime; \\r
+  fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \\r
+  fi.IsDevice = false;\r
+\r
+  /*\r
+  #ifdef UNDER_CE\r
+  fi.ObjectID = fd.dwOID;\r
+  #else\r
+  fi.ReparseTag = fd.dwReserved0;\r
+  #endif\r
+  */\r
+\r
+static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)\r
+{\r
+  WIN_FD_TO_MY_FI(fi, fd);\r
+  fi.Name = fd.cFileName;\r
+}\r
+\r
+#ifndef _UNICODE\r
+\r
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }\r
+\r
+static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfoW &fi)\r
+{\r
+  WIN_FD_TO_MY_FI(fi, fd);\r
+  fi.Name = fd.cFileName;\r
+}\r
+\r
+static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfoW &fi)\r
+{\r
+  WIN_FD_TO_MY_FI(fi, fd);\r
+  fi.Name = GetUnicodeString(fd.cFileName, GetCurrentCodePage());\r
+}\r
+#endif\r
+  \r
+////////////////////////////////\r
+// CFindFile\r
+\r
+bool CFindFile::Close()\r
+{\r
+  if (_handle == INVALID_HANDLE_VALUE)\r
+    return true;\r
+  if (!::FindClose(_handle))\r
+    return false;\r
+  _handle = INVALID_HANDLE_VALUE;\r
+  return true;\r
+}\r
+\r
+          \r
+bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fi)\r
+{\r
+  if (!Close())\r
+    return false;\r
+  WIN32_FIND_DATA fd;\r
+  _handle = ::FindFirstFile(wildcard, &fd);\r
+  #ifdef WIN_LONG_PATH2\r
+  if (_handle == INVALID_HANDLE_VALUE)\r
+  {\r
+    UString longPath;\r
+    if (GetLongPath(wildcard, longPath))\r
+      _handle = ::FindFirstFileW(longPath, &fd);\r
+  }\r
+  #endif\r
+  if (_handle == INVALID_HANDLE_VALUE)\r
+    return false;\r
+  ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);\r
+  return true;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fi)\r
+{\r
+  if (!Close())\r
+    return false;\r
+  if (g_IsNT)\r
+  {\r
+    WIN32_FIND_DATAW fd;\r
+    _handle = ::FindFirstFileW(wildcard, &fd);\r
+    #ifdef WIN_LONG_PATH\r
+    if (_handle == INVALID_HANDLE_VALUE)\r
+    {\r
+      UString longPath;\r
+      if (GetLongPath(wildcard, longPath))\r
+        _handle = ::FindFirstFileW(longPath, &fd);\r
+    }\r
+    #endif\r
+    if (_handle != INVALID_HANDLE_VALUE)\r
+      ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);\r
+  }\r
+  else\r
+  {\r
+    WIN32_FIND_DATAA fd;\r
+    _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,\r
+        GetCurrentCodePage()), &fd);\r
+    if (_handle != INVALID_HANDLE_VALUE)\r
+      ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);\r
+  }\r
+  return (_handle != INVALID_HANDLE_VALUE);\r
+}\r
+#endif\r
+\r
+bool CFindFile::FindNext(CFileInfo &fi)\r
+{\r
+  WIN32_FIND_DATA fd;\r
+  bool result = BOOLToBool(::FindNextFile(_handle, &fd));\r
+  if (result)\r
+    ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);\r
+  return result;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool CFindFile::FindNext(CFileInfoW &fi)\r
+{\r
+  if (g_IsNT)\r
+  {\r
+    WIN32_FIND_DATAW fd;\r
+    if (!::FindNextFileW(_handle, &fd))\r
+      return false;\r
+    ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);\r
+  }\r
+  else\r
+  {\r
+    WIN32_FIND_DATAA fd;\r
+    if (!::FindNextFileA(_handle, &fd))\r
+      return false;\r
+    ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);\r
+  }\r
+  return true;\r
+}\r
+#endif\r
+\r
+#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;\r
+\r
+void CFileInfoBase::Clear()\r
+{\r
+  Size = 0;\r
+  MY_CLEAR_FILETIME(CTime);\r
+  MY_CLEAR_FILETIME(ATime);\r
+  MY_CLEAR_FILETIME(MTime);\r
+  Attrib = 0;\r
+}\r
+  \r
+bool CFileInfo::Find(LPCTSTR wildcard)\r
+{\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  if (IsDeviceName(wildcard))\r
+  {\r
+    Clear();\r
+    IsDevice = true;\r
+    NIO::CInFile inFile;\r
+    if (!inFile.Open(wildcard))\r
+      return false;\r
+    Name = wildcard + 4;\r
+    if (inFile.LengthDefined)\r
+      Size = inFile.Length;\r
+    return true;\r
+  }\r
+  #endif\r
+  CFindFile finder;\r
+  return finder.FindFirst(wildcard, *this);\r
+}\r
+\r
+\r
+#ifndef _UNICODE\r
+bool CFileInfoW::Find(LPCWSTR wildcard)\r
+{\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  if (IsDeviceName(wildcard))\r
+  {\r
+    Clear();\r
+    IsDevice = true;\r
+    NIO::CInFile inFile;\r
+    if (!inFile.Open(wildcard))\r
+      return false;\r
+    Name = wildcard + 4;\r
+    if (inFile.LengthDefined)\r
+      Size = inFile.Length;\r
+    return true;\r
+  }\r
+  #endif\r
+  CFindFile finder;\r
+  return finder.FindFirst(wildcard, *this);\r
+}\r
+#endif\r
+\r
+bool DoesFileExist(LPCTSTR name)\r
+{\r
+  CFileInfo fi;\r
+  return fi.Find(name) && !fi.IsDir();\r
+}\r
+\r
+bool DoesDirExist(LPCTSTR name)\r
+{\r
+  CFileInfo fi;\r
+  return fi.Find(name) && fi.IsDir();\r
+}\r
+\r
+bool DoesFileOrDirExist(LPCTSTR name)\r
+{\r
+  CFileInfo fi;\r
+  return fi.Find(name);\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool DoesFileExist(LPCWSTR name)\r
+{\r
+  CFileInfoW fi;\r
+  return fi.Find(name) && !fi.IsDir();\r
+}\r
+\r
+bool DoesDirExist(LPCWSTR name)\r
+{\r
+  CFileInfoW fi;\r
+  return fi.Find(name) && fi.IsDir();\r
+}\r
+bool DoesFileOrDirExist(LPCWSTR name)\r
+{\r
+  CFileInfoW fi;\r
+  return fi.Find(name);\r
+}\r
+#endif\r
+\r
+/////////////////////////////////////\r
+// CEnumerator\r
+\r
+bool CEnumerator::NextAny(CFileInfo &fi)\r
+{\r
+  if (_findFile.IsHandleAllocated())\r
+    return _findFile.FindNext(fi);\r
+  else\r
+    return _findFile.FindFirst(_wildcard, fi);\r
+}\r
+\r
+bool CEnumerator::Next(CFileInfo &fi)\r
+{\r
+  for (;;)\r
+  {\r
+    if (!NextAny(fi))\r
+      return false;\r
+    if (!fi.IsDots())\r
+      return true;\r
+  }\r
+}\r
+\r
+bool CEnumerator::Next(CFileInfo &fi, bool &found)\r
+{\r
+  if (Next(fi))\r
+  {\r
+    found = true;\r
+    return true;\r
+  }\r
+  found = false;\r
+  return (::GetLastError() == ERROR_NO_MORE_FILES);\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool CEnumeratorW::NextAny(CFileInfoW &fi)\r
+{\r
+  if (_findFile.IsHandleAllocated())\r
+    return _findFile.FindNext(fi);\r
+  else\r
+    return _findFile.FindFirst(_wildcard, fi);\r
+}\r
+\r
+bool CEnumeratorW::Next(CFileInfoW &fi)\r
+{\r
+  for (;;)\r
+  {\r
+    if (!NextAny(fi))\r
+      return false;\r
+    if (!fi.IsDots())\r
+      return true;\r
+  }\r
+}\r
+\r
+bool CEnumeratorW::Next(CFileInfoW &fi, bool &found)\r
+{\r
+  if (Next(fi))\r
+  {\r
+    found = true;\r
+    return true;\r
+  }\r
+  found = false;\r
+  return (::GetLastError() == ERROR_NO_MORE_FILES);\r
+}\r
+\r
+#endif\r
+\r
+////////////////////////////////\r
+// CFindChangeNotification\r
+// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.\r
+\r
+bool CFindChangeNotification::Close()\r
+{\r
+  if (!IsHandleAllocated())\r
+    return true;\r
+  if (!::FindCloseChangeNotification(_handle))\r
+    return false;\r
+  _handle = INVALID_HANDLE_VALUE;\r
+  return true;\r
+}\r
+           \r
+HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter)\r
+{\r
+  _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter);\r
+  #ifdef WIN_LONG_PATH2\r
+  if (!IsHandleAllocated())\r
+  {\r
+    UString longPath;\r
+    if (GetLongPath(pathName, longPath))\r
+      _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);\r
+  }\r
+  #endif\r
+  return _handle;\r
+}\r
+\r
+#ifndef _UNICODE\r
+HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter)\r
+{\r
+  if (!g_IsNT)\r
+    return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);\r
+  _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);\r
+  #ifdef WIN_LONG_PATH\r
+  if (!IsHandleAllocated())\r
+  {\r
+    UString longPath;\r
+    if (GetLongPath(pathName, longPath))\r
+      _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);\r
+  }\r
+  #endif\r
+  return _handle;\r
+}\r
+#endif\r
+\r
+#ifndef UNDER_CE\r
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)\r
+{\r
+  driveStrings.Clear();\r
+  UINT32 size = GetLogicalDriveStrings(0, NULL);\r
+  if (size == 0)\r
+    return false;\r
+  CSysString buffer;\r
+  UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));\r
+  if (newSize == 0)\r
+    return false;\r
+  if (newSize > size)\r
+    return false;\r
+  CSysString string;\r
+  for (UINT32 i = 0; i < newSize; i++)\r
+  {\r
+    TCHAR c = buffer[i];\r
+    if (c == TEXT('\0'))\r
+    {\r
+      driveStrings.Add(string);\r
+      string.Empty();\r
+    }\r
+    else\r
+      string += c;\r
+  }\r
+  if (!string.IsEmpty())\r
+    return false;\r
+  return true;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings)\r
+{\r
+  driveStrings.Clear();\r
+  if (g_IsNT)\r
+  {\r
+    UINT32 size = GetLogicalDriveStringsW(0, NULL);\r
+    if (size == 0)\r
+      return false;\r
+    UString buffer;\r
+    UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));\r
+    if (newSize == 0)\r
+      return false;\r
+    if (newSize > size)\r
+      return false;\r
+    UString string;\r
+    for (UINT32 i = 0; i < newSize; i++)\r
+    {\r
+      WCHAR c = buffer[i];\r
+      if (c == L'\0')\r
+      {\r
+        driveStrings.Add(string);\r
+        string.Empty();\r
+      }\r
+      else\r
+        string += c;\r
+    }\r
+    return string.IsEmpty();\r
+  }\r
+  CSysStringVector driveStringsA;\r
+  bool res = MyGetLogicalDriveStrings(driveStringsA);\r
+  for (int i = 0; i < driveStringsA.Size(); i++)\r
+    driveStrings.Add(GetUnicodeString(driveStringsA[i]));\r
+  return res;\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+}}}\r
diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h
new file mode 100755 (executable)
index 0000000..5affd83
--- /dev/null
@@ -0,0 +1,161 @@
+// Windows/FileFind.h\r
+\r
+#ifndef __WINDOWS_FILEFIND_H\r
+#define __WINDOWS_FILEFIND_H\r
+\r
+#include "../Common/MyString.h"\r
+#include "../Common/Types.h"\r
+#include "Defs.h"\r
+#include "FileName.h"\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+namespace NFind {\r
+\r
+namespace NAttributes\r
+{\r
+  inline bool IsReadOnly(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_READONLY) != 0; }\r
+  inline bool IsHidden(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_HIDDEN) != 0; }\r
+  inline bool IsSystem(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_SYSTEM) != 0; }\r
+  inline bool IsDir(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; }\r
+  inline bool IsArchived(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ARCHIVE) != 0; }\r
+  inline bool IsCompressed(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_COMPRESSED) != 0; }\r
+  inline bool IsEncrypted(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ENCRYPTED) != 0; }\r
+}\r
+\r
+class CFileInfoBase\r
+{\r
+  bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }\r
+protected:\r
+  void Clear();\r
+public:\r
+  UInt64 Size;\r
+  FILETIME CTime;\r
+  FILETIME ATime;\r
+  FILETIME MTime;\r
+  DWORD Attrib;\r
+  bool IsDevice;\r
+\r
+  /*\r
+  #ifdef UNDER_CE\r
+  DWORD ObjectID;\r
+  #else\r
+  UINT32 ReparseTag;\r
+  #endif\r
+  */\r
+\r
+  bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }\r
+  bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }\r
+  bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }\r
+  bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); }\r
+  bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); }\r
+  bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); }\r
+  bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); }\r
+  bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); }\r
+  bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); }\r
+  bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); }\r
+  bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }\r
+  bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }\r
+};\r
+\r
+struct CFileInfo: public CFileInfoBase\r
+{\r
+  CSysString Name;\r
+\r
+  bool IsDots() const;\r
+  bool Find(LPCTSTR wildcard);\r
+};\r
+\r
+#ifdef _UNICODE\r
+typedef CFileInfo CFileInfoW;\r
+#else\r
+struct CFileInfoW: public CFileInfoBase\r
+{\r
+  UString Name;\r
+\r
+  bool IsDots() const;\r
+  bool Find(LPCWSTR wildcard);\r
+};\r
+#endif\r
+\r
+class CFindFile\r
+{\r
+  friend class CEnumerator;\r
+  HANDLE _handle;\r
+public:\r
+  bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }\r
+  CFindFile(): _handle(INVALID_HANDLE_VALUE) {}\r
+  ~CFindFile() {  Close(); }\r
+  bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);\r
+  bool FindNext(CFileInfo &fileInfo);\r
+  #ifndef _UNICODE\r
+  bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);\r
+  bool FindNext(CFileInfoW &fileInfo);\r
+  #endif\r
+  bool Close();\r
+};\r
+\r
+bool DoesFileExist(LPCTSTR name);\r
+bool DoesDirExist(LPCTSTR name);\r
+bool DoesFileOrDirExist(LPCTSTR name);\r
+#ifndef _UNICODE\r
+bool DoesFileExist(LPCWSTR name);\r
+bool DoesDirExist(LPCWSTR name);\r
+bool DoesFileOrDirExist(LPCWSTR name);\r
+#endif\r
+\r
+class CEnumerator\r
+{\r
+  CFindFile _findFile;\r
+  CSysString _wildcard;\r
+  bool NextAny(CFileInfo &fileInfo);\r
+public:\r
+  CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}\r
+  CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}\r
+  bool Next(CFileInfo &fileInfo);\r
+  bool Next(CFileInfo &fileInfo, bool &found);\r
+};\r
+\r
+#ifdef _UNICODE\r
+typedef CEnumerator CEnumeratorW;\r
+#else\r
+class CEnumeratorW\r
+{\r
+  CFindFile _findFile;\r
+  UString _wildcard;\r
+  bool NextAny(CFileInfoW &fileInfo);\r
+public:\r
+  CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}\r
+  CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}\r
+  bool Next(CFileInfoW &fileInfo);\r
+  bool Next(CFileInfoW &fileInfo, bool &found);\r
+};\r
+#endif\r
+\r
+class CFindChangeNotification\r
+{\r
+  HANDLE _handle;\r
+public:\r
+  operator HANDLE () { return _handle; }\r
+  bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }\r
+  CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}\r
+  ~CFindChangeNotification() { Close(); }\r
+  bool Close();\r
+  HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);\r
+  #ifndef _UNICODE\r
+  HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);\r
+  #endif\r
+  bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }\r
+};\r
+\r
+#ifndef UNDER_CE\r
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);\r
+#ifndef _UNICODE\r
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings);\r
+#endif\r
+#endif\r
+\r
+}}}\r
+\r
+#endif\r
+\r
diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp
new file mode 100755 (executable)
index 0000000..a1a1bcc
--- /dev/null
@@ -0,0 +1,434 @@
+// Windows/FileIO.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "FileIO.h"\r
+\r
+#if defined(WIN_LONG_PATH) || defined(SUPPORT_DEVICE_FILE)\r
+#include "../Common/MyString.h"\r
+#endif\r
+#ifndef _UNICODE\r
+#include "../Common/StringConvert.h"\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+extern bool g_IsNT;\r
+#endif\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+\r
+#ifdef SUPPORT_DEVICE_FILE\r
+bool IsDeviceName(LPCTSTR n)\r
+{\r
+  #ifdef UNDER_CE\r
+  int len = (int)MyStringLen(n);\r
+  if (len < 5 || len > 5 || memcmp(n, TEXT("DSK"), 3 * sizeof(TCHAR)) != 0)\r
+    return false;\r
+  if (n[4] != ':')\r
+    return false;\r
+  // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));\r
+  #else\r
+  if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' ||  n[3] != '\\')\r
+    return false;\r
+  int len = (int)MyStringLen(n);\r
+  if (len == 6 && n[5] == ':')\r
+    return true;\r
+  if (len < 18 || len > 22 || memcmp(n + 4, TEXT("PhysicalDrive"), 13 * sizeof(TCHAR)) != 0)\r
+    return false;\r
+  for (int i = 17; i < len; i++)\r
+    if (n[i] < '0' || n[i] > '9')\r
+      return false;\r
+  #endif\r
+  return true;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool IsDeviceName(LPCWSTR n)\r
+{\r
+  if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' ||  n[3] != '\\')\r
+    return false;\r
+  int len = (int)wcslen(n);\r
+  if (len == 6 && n[5] == ':')\r
+    return true;\r
+  if (len < 18 || len > 22 || wcsncmp(n + 4, L"PhysicalDrive", 13) != 0)\r
+    return false;\r
+  for (int i = 17; i < len; i++)\r
+    if (n[i] < '0' || n[i] > '9')\r
+      return false;\r
+  return true;\r
+}\r
+#endif\r
+#endif\r
+\r
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)\r
+#define WIN_LONG_PATH2\r
+#endif\r
+\r
+#ifdef WIN_LONG_PATH\r
+bool GetLongPathBase(LPCWSTR s, UString &res)\r
+{\r
+  res.Empty();\r
+  int len = MyStringLen(s);\r
+  wchar_t c = s[0];\r
+  if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.'))\r
+    return true;\r
+  UString curDir;\r
+  bool isAbs = false;\r
+  if (len > 3)\r
+    isAbs = (s[1] == L':' && s[2] == L'\\' && (c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z'));\r
+\r
+  if (!isAbs)\r
+    {\r
+      DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1));\r
+      curDir.ReleaseBuffer();\r
+      if (needLength == 0 || needLength > MAX_PATH)\r
+        return false;\r
+      if (curDir[curDir.Length() - 1] != L'\\')\r
+        curDir += L'\\';\r
+    }\r
+  res = UString(L"\\\\?\\") + curDir + s;\r
+  return true;\r
+}\r
+\r
+bool GetLongPath(LPCWSTR path, UString &longPath)\r
+{\r
+  if (GetLongPathBase(path, longPath))\r
+    return !longPath.IsEmpty();\r
+  return false;\r
+}\r
+#endif\r
+\r
+namespace NIO {\r
+\r
+CFileBase::~CFileBase() { Close(); }\r
+\r
+bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,\r
+    DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)\r
+{\r
+  if (!Close())\r
+    return false;\r
+  _handle = ::CreateFile(fileName, desiredAccess, shareMode,\r
+      (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,\r
+      flagsAndAttributes, (HANDLE)NULL);\r
+  #ifdef WIN_LONG_PATH2\r
+  if (_handle == INVALID_HANDLE_VALUE)\r
+  {\r
+    UString longPath;\r
+    if (GetLongPath(fileName, longPath))\r
+      _handle = ::CreateFileW(longPath, desiredAccess, shareMode,\r
+        (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,\r
+        flagsAndAttributes, (HANDLE)NULL);\r
+  }\r
+  #endif\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  IsDeviceFile = false;\r
+  #endif\r
+  return (_handle != INVALID_HANDLE_VALUE);\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,\r
+    DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)\r
+{\r
+  if (!g_IsNT)\r
+    return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),\r
+      desiredAccess, shareMode, creationDisposition, flagsAndAttributes);\r
+  if (!Close())\r
+    return false;\r
+  _handle = ::CreateFileW(fileName, desiredAccess, shareMode,\r
+    (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,\r
+    flagsAndAttributes, (HANDLE)NULL);\r
+  #ifdef WIN_LONG_PATH\r
+  if (_handle == INVALID_HANDLE_VALUE)\r
+  {\r
+    UString longPath;\r
+    if (GetLongPath(fileName, longPath))\r
+      _handle = ::CreateFileW(longPath, desiredAccess, shareMode,\r
+        (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,\r
+        flagsAndAttributes, (HANDLE)NULL);\r
+  }\r
+  #endif\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  IsDeviceFile = false;\r
+  #endif\r
+  return (_handle != INVALID_HANDLE_VALUE);\r
+}\r
+#endif\r
+\r
+bool CFileBase::Close()\r
+{\r
+  if (_handle == INVALID_HANDLE_VALUE)\r
+    return true;\r
+  if (!::CloseHandle(_handle))\r
+    return false;\r
+  _handle = INVALID_HANDLE_VALUE;\r
+  return true;\r
+}\r
+\r
+bool CFileBase::GetPosition(UInt64 &position) const\r
+{\r
+  return Seek(0, FILE_CURRENT, position);\r
+}\r
+\r
+bool CFileBase::GetLength(UInt64 &length) const\r
+{\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  if (IsDeviceFile && LengthDefined)\r
+  {\r
+    length = Length;\r
+    return true;\r
+  }\r
+  #endif\r
+\r
+  DWORD sizeHigh;\r
+  DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);\r
+  if (sizeLow == 0xFFFFFFFF)\r
+    if (::GetLastError() != NO_ERROR)\r
+      return false;\r
+  length = (((UInt64)sizeHigh) << 32) + sizeLow;\r
+  return true;\r
+}\r
+\r
+bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const\r
+{\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  if (IsDeviceFile && LengthDefined && moveMethod == FILE_END)\r
+  {\r
+    distanceToMove += Length;\r
+    moveMethod = FILE_BEGIN;\r
+  }\r
+  #endif\r
+\r
+  LARGE_INTEGER value;\r
+  value.QuadPart = distanceToMove;\r
+  value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);\r
+  if (value.LowPart == 0xFFFFFFFF)\r
+    if (::GetLastError() != NO_ERROR)\r
+      return false;\r
+  newPosition = value.QuadPart;\r
+  return true;\r
+}\r
+\r
+bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)\r
+{\r
+  return Seek(position, FILE_BEGIN, newPosition);\r
+}\r
+\r
+bool CFileBase::SeekToBegin()\r
+{\r
+  UInt64 newPosition;\r
+  return Seek(0, newPosition);\r
+}\r
+\r
+bool CFileBase::SeekToEnd(UInt64 &newPosition)\r
+{\r
+  return Seek(0, FILE_END, newPosition);\r
+}\r
+\r
+bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const\r
+{\r
+  BY_HANDLE_FILE_INFORMATION winFileInfo;\r
+  if (!::GetFileInformationByHandle(_handle, &winFileInfo))\r
+    return false;\r
+  fileInfo.Attrib = winFileInfo.dwFileAttributes;\r
+  fileInfo.CTime = winFileInfo.ftCreationTime;\r
+  fileInfo.ATime = winFileInfo.ftLastAccessTime;\r
+  fileInfo.MTime = winFileInfo.ftLastWriteTime;\r
+  fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;\r
+  fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) +  winFileInfo.nFileSizeLow;\r
+  fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;\r
+  fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;\r
+  return true;\r
+}\r
+\r
+/////////////////////////\r
+// CInFile\r
+\r
+#ifdef SUPPORT_DEVICE_FILE\r
+void CInFile::GetDeviceLength()\r
+{\r
+  if (_handle != INVALID_HANDLE_VALUE && IsDeviceFile)\r
+  {\r
+    #ifdef UNDER_CE\r
+    LengthDefined = true;\r
+    Length = 128 << 20;\r
+\r
+    #else\r
+    PARTITION_INFORMATION partInfo;\r
+    LengthDefined = true;\r
+    Length = 0;\r
+\r
+    if (GetPartitionInfo(&partInfo))\r
+      Length = partInfo.PartitionLength.QuadPart;\r
+    else\r
+    {\r
+      DISK_GEOMETRY geom;\r
+      if (!GetGeometry(&geom))\r
+        if (!GetCdRomGeometry(&geom))\r
+          LengthDefined = false;\r
+      if (LengthDefined)\r
+        Length = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector;\r
+    }\r
+    // SeekToBegin();\r
+    #endif\r
+  }\r
+}\r
+\r
+// ((desiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE)) == 0 &&\r
+\r
+#define MY_DEVICE_EXTRA_CODE \\r
+  IsDeviceFile = IsDeviceName(fileName); \\r
+  GetDeviceLength();\r
+#else\r
+#define MY_DEVICE_EXTRA_CODE\r
+#endif\r
+\r
+bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)\r
+{\r
+  bool res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);\r
+  MY_DEVICE_EXTRA_CODE\r
+  return res;\r
+}\r
+\r
+bool CInFile::OpenShared(LPCTSTR fileName, bool shareForWrite)\r
+{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }\r
+\r
+bool CInFile::Open(LPCTSTR fileName)\r
+  { return OpenShared(fileName, false); }\r
+\r
+#ifndef _UNICODE\r
+bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)\r
+{\r
+  bool res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);\r
+  MY_DEVICE_EXTRA_CODE\r
+  return res;\r
+}\r
+\r
+bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite)\r
+{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }\r
+\r
+bool CInFile::Open(LPCWSTR fileName)\r
+  { return OpenShared(fileName, false); }\r
+#endif\r
+\r
+// ReadFile and WriteFile functions in Windows have BUG:\r
+// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)\r
+// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES\r
+// (Insufficient system resources exist to complete the requested service).\r
+\r
+// Probably in some version of Windows there are problems with other sizes:\r
+// for 32 MB (maybe also for 16 MB).\r
+// And message can be "Network connection was lost"\r
+\r
+static UInt32 kChunkSizeMax = (1 << 22);\r
+\r
+bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize)\r
+{\r
+  DWORD processedLoc = 0;\r
+  bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));\r
+  processedSize = (UInt32)processedLoc;\r
+  return res;\r
+}\r
+\r
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)\r
+{\r
+  if (size > kChunkSizeMax)\r
+    size = kChunkSizeMax;\r
+  return Read1(data, size, processedSize);\r
+}\r
+\r
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)\r
+{\r
+  processedSize = 0;\r
+  do\r
+  {\r
+    UInt32 processedLoc = 0;\r
+    bool res = ReadPart(data, size, processedLoc);\r
+    processedSize += processedLoc;\r
+    if (!res)\r
+      return false;\r
+    if (processedLoc == 0)\r
+      return true;\r
+    data = (void *)((unsigned char *)data + processedLoc);\r
+    size -= processedLoc;\r
+  }\r
+  while (size > 0);\r
+  return true;\r
+}\r
+\r
+/////////////////////////\r
+// COutFile\r
+\r
+bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)\r
+  { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }\r
+\r
+static inline DWORD GetCreationDisposition(bool createAlways)\r
+  { return createAlways? CREATE_ALWAYS: CREATE_NEW; }\r
+\r
+bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)\r
+  { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }\r
+\r
+bool COutFile::Create(LPCTSTR fileName, bool createAlways)\r
+  { return Open(fileName, GetCreationDisposition(createAlways)); }\r
+\r
+#ifndef _UNICODE\r
+\r
+bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)\r
+  { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }\r
+\r
+bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)\r
+  { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }\r
+\r
+bool COutFile::Create(LPCWSTR fileName, bool createAlways)\r
+  { return Open(fileName, GetCreationDisposition(createAlways)); }\r
+\r
+#endif\r
+\r
+bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)\r
+  { return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); }\r
+\r
+bool COutFile::SetMTime(const FILETIME *mTime) {  return SetTime(NULL, NULL, mTime); }\r
+\r
+bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)\r
+{\r
+  if (size > kChunkSizeMax)\r
+    size = kChunkSizeMax;\r
+  DWORD processedLoc = 0;\r
+  bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL));\r
+  processedSize = (UInt32)processedLoc;\r
+  return res;\r
+}\r
+\r
+bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)\r
+{\r
+  processedSize = 0;\r
+  do\r
+  {\r
+    UInt32 processedLoc = 0;\r
+    bool res = WritePart(data, size, processedLoc);\r
+    processedSize += processedLoc;\r
+    if (!res)\r
+      return false;\r
+    if (processedLoc == 0)\r
+      return true;\r
+    data = (const void *)((const unsigned char *)data + processedLoc);\r
+    size -= processedLoc;\r
+  }\r
+  while (size > 0);\r
+  return true;\r
+}\r
+\r
+bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }\r
+\r
+bool COutFile::SetLength(UInt64 length)\r
+{\r
+  UInt64 newPosition;\r
+  if (!Seek(length, newPosition))\r
+    return false;\r
+  if (newPosition != length)\r
+    return false;\r
+  return SetEndOfFile();\r
+}\r
+\r
+}}}\r
diff --git a/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h
new file mode 100755 (executable)
index 0000000..6f14817
--- /dev/null
@@ -0,0 +1,136 @@
+// Windows/FileIO.h\r
+\r
+#ifndef __WINDOWS_FILEIO_H\r
+#define __WINDOWS_FILEIO_H\r
+\r
+#include "../Common/Types.h"\r
+\r
+#include "Defs.h"\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+namespace NIO {\r
+\r
+struct CByHandleFileInfo\r
+{\r
+  DWORD Attrib;\r
+  FILETIME CTime;\r
+  FILETIME ATime;\r
+  FILETIME MTime;\r
+  DWORD VolumeSerialNumber;\r
+  UInt64 Size;\r
+  DWORD NumberOfLinks;\r
+  UInt64 FileIndex;\r
+};\r
+\r
+class CFileBase\r
+{\r
+protected:\r
+  HANDLE _handle;\r
+  \r
+  bool Create(LPCTSTR fileName, DWORD desiredAccess,\r
+      DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);\r
+  #ifndef _UNICODE\r
+  bool Create(LPCWSTR fileName, DWORD desiredAccess,\r
+      DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);\r
+  #endif\r
+\r
+public:\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  bool IsDeviceFile;\r
+  bool LengthDefined;\r
+  UInt64 Length;\r
+  #endif\r
+\r
+  CFileBase(): _handle(INVALID_HANDLE_VALUE) {};\r
+  ~CFileBase();\r
+\r
+  bool Close();\r
+\r
+  bool GetPosition(UInt64 &position) const;\r
+  bool GetLength(UInt64 &length) const;\r
+\r
+  bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;\r
+  bool Seek(UInt64 position, UInt64 &newPosition);\r
+  bool SeekToBegin();\r
+  bool SeekToEnd(UInt64 &newPosition);\r
+  \r
+  bool GetFileInformation(CByHandleFileInfo &fileInfo) const;\r
+};\r
+\r
+#define IOCTL_CDROM_BASE  FILE_DEVICE_CD_ROM\r
+#define IOCTL_CDROM_GET_DRIVE_GEOMETRY  CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)\r
+#define IOCTL_CDROM_MEDIA_REMOVAL  CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)\r
+\r
+class CInFile: public CFileBase\r
+{\r
+  #ifdef SUPPORT_DEVICE_FILE\r
+  bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize,\r
+      LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped) const\r
+  {\r
+    return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize,\r
+        outBuffer, outSize, bytesReturned, overlapped));\r
+  }\r
+\r
+  bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer,\r
+      DWORD inSize, LPVOID outBuffer, DWORD outSize) const\r
+  {\r
+    DWORD ret;\r
+    return DeviceIoControl(controlCode, inBuffer, inSize, outBuffer, outSize, &ret, 0);\r
+  }\r
+\r
+  bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const\r
+    { return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize); }\r
+\r
+  #ifndef UNDER_CE\r
+  bool GetGeometry(DISK_GEOMETRY *res) const\r
+    { return DeviceIoControlOut(IOCTL_DISK_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }\r
+\r
+  bool GetCdRomGeometry(DISK_GEOMETRY *res) const\r
+    { return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); }\r
+  \r
+  bool GetPartitionInfo(PARTITION_INFORMATION *res)\r
+    { return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); }\r
+  #endif\r
+\r
+  void GetDeviceLength();\r
+  #endif\r
+\r
+public:\r
+  bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);\r
+  bool OpenShared(LPCTSTR fileName, bool shareForWrite);\r
+  bool Open(LPCTSTR fileName);\r
+  #ifndef _UNICODE\r
+  bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);\r
+  bool OpenShared(LPCWSTR fileName, bool shareForWrite);\r
+  bool Open(LPCWSTR fileName);\r
+  #endif\r
+  bool Read1(void *data, UInt32 size, UInt32 &processedSize);\r
+  bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);\r
+  bool Read(void *data, UInt32 size, UInt32 &processedSize);\r
+};\r
+\r
+class COutFile: public CFileBase\r
+{\r
+public:\r
+  bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);\r
+  bool Open(LPCTSTR fileName, DWORD creationDisposition);\r
+  bool Create(LPCTSTR fileName, bool createAlways);\r
+\r
+  #ifndef _UNICODE\r
+  bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);\r
+  bool Open(LPCWSTR fileName, DWORD creationDisposition);\r
+  bool Create(LPCWSTR fileName, bool createAlways);\r
+  #endif\r
+\r
+  bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);\r
+  bool SetMTime(const FILETIME *mTime);\r
+  bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);\r
+  bool Write(const void *data, UInt32 size, UInt32 &processedSize);\r
+  bool SetEndOfFile();\r
+  bool SetLength(UInt64 length);\r
+};\r
+\r
+}}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/FileMapping.cpp b/CPP/Windows/FileMapping.cpp
new file mode 100755 (executable)
index 0000000..857e70d
--- /dev/null
@@ -0,0 +1,12 @@
+// Windows/FileMapping.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Windows/FileMapping.h"\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+namespace NMapping {\r
+\r
+\r
+}}}\r
diff --git a/CPP/Windows/FileMapping.h b/CPP/Windows/FileMapping.h
new file mode 100755 (executable)
index 0000000..138a175
--- /dev/null
@@ -0,0 +1,62 @@
+// Windows/FileMapping.h\r
+\r
+#ifndef __WINDOWS_FILEMAPPING_H\r
+#define __WINDOWS_FILEMAPPING_H\r
+\r
+#include "Common/Types.h"\r
+\r
+#include "Handle.h"\r
+\r
+namespace NWindows {\r
+\r
+class CFileMapping: public CHandle\r
+{\r
+public:\r
+  WRes Create(DWORD protect, UInt64 maxSize, LPCTSTR name)\r
+  {\r
+    _handle = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, protect, (DWORD)(maxSize >> 32), (DWORD)maxSize, name);\r
+    return ::GetLastError();\r
+  }\r
+\r
+  WRes Open(DWORD desiredAccess, LPCTSTR name)\r
+  {\r
+    #ifdef UNDER_CE\r
+    WRes res = Create(PAGE_READONLY, 0, name);\r
+    if (res == ERROR_ALREADY_EXISTS)\r
+      return 0;\r
+    Close();\r
+    if (res == 0)\r
+      res = ERROR_FILE_NOT_FOUND;\r
+    return res;\r
+    #else\r
+    _handle = ::OpenFileMapping(desiredAccess, FALSE, name);\r
+    if (_handle != 0)\r
+      return 0;\r
+    return ::GetLastError();\r
+    #endif\r
+  }\r
+\r
+  LPVOID Map(DWORD desiredAccess, UInt64 fileOffset, SIZE_T numberOfBytesToMap)\r
+  {\r
+    return ::MapViewOfFile(_handle, desiredAccess, (DWORD)(fileOffset >> 32), (DWORD)fileOffset, numberOfBytesToMap);\r
+  }\r
+\r
+  #ifndef UNDER_CE\r
+  LPVOID Map(DWORD desiredAccess, UInt64 fileOffset, SIZE_T numberOfBytesToMap, LPVOID baseAddress)\r
+  {\r
+    return ::MapViewOfFileEx(_handle, desiredAccess, (DWORD)(fileOffset >> 32), (DWORD)fileOffset, numberOfBytesToMap, baseAddress);\r
+  }\r
+  #endif\r
+};\r
+\r
+class CFileUnmapper\r
+{\r
+  const void *_data;\r
+public:\r
+  CFileUnmapper(const void *data) : _data(data) {}\r
+  ~CFileUnmapper() { ::UnmapViewOfFile(_data); }\r
+};\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp
new file mode 100755 (executable)
index 0000000..4e55a53
--- /dev/null
@@ -0,0 +1,50 @@
+// Windows/FileName.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Windows/FileName.h"\r
+#include "Common/Wildcard.h"\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+namespace NName {\r
+\r
+void NormalizeDirPathPrefix(CSysString &dirPath)\r
+{\r
+  if (dirPath.IsEmpty())\r
+    return;\r
+  if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)\r
+    dirPath += kDirDelimiter;\r
+}\r
+\r
+#ifndef _UNICODE\r
+void NormalizeDirPathPrefix(UString &dirPath)\r
+{\r
+  if (dirPath.IsEmpty())\r
+    return;\r
+  if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)\r
+    dirPath += wchar_t(kDirDelimiter);\r
+}\r
+#endif\r
+\r
+const wchar_t kExtensionDelimiter = L'.';\r
+\r
+void SplitNameToPureNameAndExtension(const UString &fullName,\r
+    UString &pureName, UString &extensionDelimiter, UString &extension)\r
+{\r
+  int index = fullName.ReverseFind(kExtensionDelimiter);\r
+  if (index < 0)\r
+  {\r
+    pureName = fullName;\r
+    extensionDelimiter.Empty();\r
+    extension.Empty();\r
+  }\r
+  else\r
+  {\r
+    pureName = fullName.Left(index);\r
+    extensionDelimiter = kExtensionDelimiter;\r
+    extension = fullName.Mid(index + 1);\r
+  }\r
+}\r
+\r
+}}}\r
diff --git a/CPP/Windows/FileName.h b/CPP/Windows/FileName.h
new file mode 100755 (executable)
index 0000000..b980236
--- /dev/null
@@ -0,0 +1,27 @@
+// Windows/FileName.h\r
+\r
+#ifndef __WINDOWS_FILENAME_H\r
+#define __WINDOWS_FILENAME_H\r
+\r
+#include "../../C/Types.h"\r
+\r
+#include "../Common/MyString.h"\r
+\r
+namespace NWindows {\r
+namespace NFile {\r
+namespace NName {\r
+\r
+const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;\r
+const TCHAR kAnyStringWildcard = '*';\r
+\r
+void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'\r
+#ifndef _UNICODE\r
+void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'\r
+#endif\r
+\r
+void SplitNameToPureNameAndExtension(const UString &fullName,\r
+    UString &pureName, UString &extensionDelimiter, UString &extension);\r
+\r
+}}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/Handle.h b/CPP/Windows/Handle.h
new file mode 100755 (executable)
index 0000000..755eeb8
--- /dev/null
@@ -0,0 +1,37 @@
+// Windows/Handle.h\r
+\r
+#ifndef __WINDOWS_HANDLE_H\r
+#define __WINDOWS_HANDLE_H\r
+\r
+namespace NWindows {\r
+\r
+class CHandle\r
+{\r
+protected:\r
+  HANDLE _handle;\r
+public:\r
+  operator HANDLE() { return _handle; }\r
+  CHandle(): _handle(NULL) {}\r
+  ~CHandle() { Close(); }\r
+  bool IsCreated() const { return (_handle != NULL); }\r
+  bool Close()\r
+  {\r
+    if (_handle == NULL)\r
+      return true;\r
+    if (!::CloseHandle(_handle))\r
+      return false;\r
+    _handle = NULL;\r
+    return true;\r
+  }\r
+  void Attach(HANDLE handle) { _handle = handle; }\r
+  HANDLE Detach()\r
+  {\r
+    HANDLE handle = _handle;\r
+    _handle = NULL;\r
+    return handle;\r
+  }\r
+};\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp
new file mode 100755 (executable)
index 0000000..9b2ffb8
--- /dev/null
@@ -0,0 +1,82 @@
+// Common/MemoryLock.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+namespace NWindows {\r
+namespace NSecurity {\r
+\r
+#ifndef UNDER_CE\r
+\r
+#ifndef _UNICODE\r
+typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);\r
+typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID  lpLuid);\r
+typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges,\r
+    PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);\r
+#endif\r
+\r
+#ifdef _UNICODE\r
+bool EnableLockMemoryPrivilege(\r
+#else\r
+static bool EnableLockMemoryPrivilege2(HMODULE hModule,\r
+#endif\r
+bool enable)\r
+{\r
+  #ifndef _UNICODE\r
+  if (hModule == NULL)\r
+    return false;\r
+  OpenProcessTokenP openProcessToken = (OpenProcessTokenP)GetProcAddress(hModule, "OpenProcessToken");\r
+  LookupPrivilegeValueP lookupPrivilegeValue = (LookupPrivilegeValueP)GetProcAddress(hModule, "LookupPrivilegeValueA" );\r
+  AdjustTokenPrivilegesP adjustTokenPrivileges = (AdjustTokenPrivilegesP)GetProcAddress(hModule, "AdjustTokenPrivileges");\r
+  if (openProcessToken == NULL || adjustTokenPrivileges == NULL || lookupPrivilegeValue == NULL)\r
+    return false;\r
+  #endif\r
+\r
+  HANDLE token;\r
+  if (!\r
+    #ifdef _UNICODE\r
+    ::OpenProcessToken\r
+    #else\r
+    openProcessToken\r
+    #endif\r
+    (::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))\r
+    return false;\r
+  TOKEN_PRIVILEGES tp;\r
+  bool res = false;\r
+  if (\r
+    #ifdef _UNICODE\r
+    ::LookupPrivilegeValue\r
+    #else\r
+    lookupPrivilegeValue\r
+    #endif\r
+    (NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)))\r
+  {\r
+    tp.PrivilegeCount = 1;\r
+    tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED: 0;\r
+    if (\r
+      #ifdef _UNICODE\r
+      ::AdjustTokenPrivileges\r
+      #else\r
+      adjustTokenPrivileges\r
+      #endif\r
+      (token, FALSE, &tp, 0, NULL, NULL))\r
+      res = (GetLastError() == ERROR_SUCCESS);\r
+  }\r
+  ::CloseHandle(token);\r
+  return res;\r
+}\r
+\r
+#ifndef _UNICODE\r
+bool EnableLockMemoryPrivilege(bool enable)\r
+{\r
+  HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll"));\r
+  if (hModule == NULL)\r
+    return false;\r
+  bool res = EnableLockMemoryPrivilege2(hModule, enable);\r
+  ::FreeLibrary(hModule);\r
+  return res;\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+}}\r
diff --git a/CPP/Windows/MemoryLock.h b/CPP/Windows/MemoryLock.h
new file mode 100755 (executable)
index 0000000..f2e574b
--- /dev/null
@@ -0,0 +1,15 @@
+// Windows/MemoryLock.h\r
+\r
+#ifndef __WINDOWS_MEMORYLOCK_H\r
+#define __WINDOWS_MEMORYLOCK_H\r
+\r
+namespace NWindows {\r
+namespace NSecurity {\r
+\r
+#ifndef UNDER_CE\r
+bool EnableLockMemoryPrivilege(bool enable = true);\r
+#endif\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/NtCheck.h b/CPP/Windows/NtCheck.h
new file mode 100755 (executable)
index 0000000..b8fa99b
--- /dev/null
@@ -0,0 +1,44 @@
+// Windows/NtCheck.h\r
+\r
+#ifndef __WINDOWS_NT_CHECK_H\r
+#define __WINDOWS_NT_CHECK_H\r
+\r
+#ifdef _WIN32\r
+\r
+#if !defined(_WIN64) && !defined(UNDER_CE)\r
+static inline bool IsItWindowsNT()\r
+{\r
+  OSVERSIONINFO vi;\r
+  vi.dwOSVersionInfoSize = sizeof(vi);\r
+  return (::GetVersionEx(&vi) && vi.dwPlatformId == VER_PLATFORM_WIN32_NT);\r
+}\r
+#endif\r
+\r
+#ifndef _UNICODE\r
+  #if defined(_WIN64) || defined(UNDER_CE)\r
+    bool g_IsNT = true;\r
+    #define SET_IS_NT\r
+  #else\r
+    bool g_IsNT = false;\r
+    #define SET_IS_NT g_IsNT = IsItWindowsNT();\r
+  #endif\r
+  #define NT_CHECK_ACTION\r
+  // #define NT_CHECK_ACTION { NT_CHECK_FAIL_ACTION }\r
+#else\r
+  #if !defined(_WIN64) && !defined(UNDER_CE)\r
+    #define NT_CHECK_ACTION if (!IsItWindowsNT()) { NT_CHECK_FAIL_ACTION }\r
+  #else\r
+    #define NT_CHECK_ACTION\r
+  #endif\r
+  #define SET_IS_NT\r
+#endif\r
+\r
+#define NT_CHECK  NT_CHECK_ACTION SET_IS_NT\r
+\r
+#else\r
+\r
+#define NT_CHECK\r
+\r
+#endif\r
+\r
+#endif\r
diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp
new file mode 100755 (executable)
index 0000000..bcd85a5
--- /dev/null
@@ -0,0 +1,243 @@
+// Windows/PropVariant.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "PropVariant.h"\r
+\r
+#include "../Common/Defs.h"\r
+\r
+namespace NWindows {\r
+namespace NCOM {\r
+\r
+CPropVariant::CPropVariant(const PROPVARIANT &varSrc)\r
+{\r
+  vt = VT_EMPTY;\r
+  InternalCopy(&varSrc);\r
+}\r
+\r
+CPropVariant::CPropVariant(const CPropVariant &varSrc)\r
+{\r
+  vt = VT_EMPTY;\r
+  InternalCopy(&varSrc);\r
+}\r
+\r
+CPropVariant::CPropVariant(BSTR bstrSrc)\r
+{\r
+  vt = VT_EMPTY;\r
+  *this = bstrSrc;\r
+}\r
+\r
+CPropVariant::CPropVariant(LPCOLESTR lpszSrc)\r
+{\r
+  vt = VT_EMPTY;\r
+  *this = lpszSrc;\r
+}\r
+\r
+CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc)\r
+{\r
+  InternalCopy(&varSrc);\r
+  return *this;\r
+}\r
+CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc)\r
+{\r
+  InternalCopy(&varSrc);\r
+  return *this;\r
+}\r
+\r
+CPropVariant& CPropVariant::operator=(BSTR bstrSrc)\r
+{\r
+  *this = (LPCOLESTR)bstrSrc;\r
+  return *this;\r
+}\r
+\r
+static const char *kMemException = "out of memory";\r
+\r
+CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)\r
+{\r
+  InternalClear();\r
+  vt = VT_BSTR;\r
+  wReserved1 = 0;\r
+  bstrVal = ::SysAllocString(lpszSrc);\r
+  if (bstrVal == NULL && lpszSrc != NULL)\r
+  {\r
+    throw kMemException;\r
+    // vt = VT_ERROR;\r
+    // scode = E_OUTOFMEMORY;\r
+  }\r
+  return *this;\r
+}\r
+\r
+\r
+CPropVariant& CPropVariant::operator=(const char *s)\r
+{\r
+  InternalClear();\r
+  vt = VT_BSTR;\r
+  wReserved1 = 0;\r
+  UINT len = (UINT)strlen(s);\r
+  bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR));\r
+  if (bstrVal == NULL)\r
+  {\r
+    throw kMemException;\r
+    // vt = VT_ERROR;\r
+    // scode = E_OUTOFMEMORY;\r
+  }\r
+  else\r
+  {\r
+    for (UINT i = 0; i <= len; i++)\r
+      bstrVal[i] = s[i];\r
+  }\r
+  return *this;\r
+}\r
+\r
+CPropVariant& CPropVariant::operator=(bool bSrc)\r
+{\r
+  if (vt != VT_BOOL)\r
+  {\r
+    InternalClear();\r
+    vt = VT_BOOL;\r
+  }\r
+  boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;\r
+  return *this;\r
+}\r
+\r
+#define SET_PROP_FUNC(type, id, dest) \\r
+  CPropVariant& CPropVariant::operator=(type value) \\r
+  { if (vt != id) { InternalClear(); vt = id; } \\r
+    dest = value; return *this; }\r
+\r
+SET_PROP_FUNC(Byte, VT_UI1, bVal)\r
+SET_PROP_FUNC(Int16, VT_I2, iVal)\r
+SET_PROP_FUNC(Int32, VT_I4, lVal)\r
+SET_PROP_FUNC(UInt32, VT_UI4, ulVal)\r
+SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)\r
+SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)\r
+\r
+static HRESULT MyPropVariantClear(PROPVARIANT *prop)\r
+{\r
+  switch(prop->vt)\r
+  {\r
+    case VT_UI1:\r
+    case VT_I1:\r
+    case VT_I2:\r
+    case VT_UI2:\r
+    case VT_BOOL:\r
+    case VT_I4:\r
+    case VT_UI4:\r
+    case VT_R4:\r
+    case VT_INT:\r
+    case VT_UINT:\r
+    case VT_ERROR:\r
+    case VT_FILETIME:\r
+    case VT_UI8:\r
+    case VT_R8:\r
+    case VT_CY:\r
+    case VT_DATE:\r
+      prop->vt = VT_EMPTY;\r
+      prop->wReserved1 = 0;\r
+      return S_OK;\r
+  }\r
+  return ::VariantClear((VARIANTARG *)prop);\r
+}\r
+\r
+HRESULT CPropVariant::Clear()\r
+{\r
+  return MyPropVariantClear(this);\r
+}\r
+\r
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)\r
+{\r
+  ::VariantClear((tagVARIANT *)this);\r
+  switch(pSrc->vt)\r
+  {\r
+    case VT_UI1:\r
+    case VT_I1:\r
+    case VT_I2:\r
+    case VT_UI2:\r
+    case VT_BOOL:\r
+    case VT_I4:\r
+    case VT_UI4:\r
+    case VT_R4:\r
+    case VT_INT:\r
+    case VT_UINT:\r
+    case VT_ERROR:\r
+    case VT_FILETIME:\r
+    case VT_UI8:\r
+    case VT_R8:\r
+    case VT_CY:\r
+    case VT_DATE:\r
+      memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));\r
+      return S_OK;\r
+  }\r
+  return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast<PROPVARIANT *>(pSrc));\r
+}\r
+\r
+\r
+HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)\r
+{\r
+  HRESULT hr = Clear();\r
+  if (FAILED(hr))\r
+    return hr;\r
+  memcpy(this, pSrc, sizeof(PROPVARIANT));\r
+  pSrc->vt = VT_EMPTY;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CPropVariant::Detach(PROPVARIANT *pDest)\r
+{\r
+  HRESULT hr = MyPropVariantClear(pDest);\r
+  if (FAILED(hr))\r
+    return hr;\r
+  memcpy(pDest, this, sizeof(PROPVARIANT));\r
+  vt = VT_EMPTY;\r
+  return S_OK;\r
+}\r
+\r
+HRESULT CPropVariant::InternalClear()\r
+{\r
+  HRESULT hr = Clear();\r
+  if (FAILED(hr))\r
+  {\r
+    vt = VT_ERROR;\r
+    scode = hr;\r
+  }\r
+  return hr;\r
+}\r
+\r
+void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)\r
+{\r
+  HRESULT hr = Copy(pSrc);\r
+  if (FAILED(hr))\r
+  {\r
+    if (hr == E_OUTOFMEMORY)\r
+      throw kMemException;\r
+    vt = VT_ERROR;\r
+    scode = hr;\r
+  }\r
+}\r
+\r
+int CPropVariant::Compare(const CPropVariant &a)\r
+{\r
+  if (vt != a.vt)\r
+    return MyCompare(vt, a.vt);\r
+  switch (vt)\r
+  {\r
+    case VT_EMPTY: return 0;\r
+    // case VT_I1: return MyCompare(cVal, a.cVal);\r
+    case VT_UI1: return MyCompare(bVal, a.bVal);\r
+    case VT_I2: return MyCompare(iVal, a.iVal);\r
+    case VT_UI2: return MyCompare(uiVal, a.uiVal);\r
+    case VT_I4: return MyCompare(lVal, a.lVal);\r
+    case VT_UI4: return MyCompare(ulVal, a.ulVal);\r
+    // case VT_UINT: return MyCompare(uintVal, a.uintVal);\r
+    case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart);\r
+    case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);\r
+    case VT_BOOL: return -MyCompare(boolVal, a.boolVal);\r
+    case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);\r
+    case VT_BSTR:\r
+      return 0; // Not implemented\r
+      // return MyCompare(aPropVarint.cVal);\r
+    default: return 0;\r
+  }\r
+}\r
+\r
+}}\r
diff --git a/CPP/Windows/PropVariant.h b/CPP/Windows/PropVariant.h
new file mode 100755 (executable)
index 0000000..1605eec
--- /dev/null
@@ -0,0 +1,56 @@
+// Windows/PropVariant.h\r
+\r
+#ifndef __WINDOWS_PROPVARIANT_H\r
+#define __WINDOWS_PROPVARIANT_H\r
+\r
+#include "../Common/MyWindows.h"\r
+#include "../Common/Types.h"\r
+\r
+namespace NWindows {\r
+namespace NCOM {\r
+\r
+class CPropVariant : public tagPROPVARIANT\r
+{\r
+public:\r
+  CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }\r
+  ~CPropVariant() { Clear(); }\r
+  CPropVariant(const PROPVARIANT &varSrc);\r
+  CPropVariant(const CPropVariant &varSrc);\r
+  CPropVariant(BSTR bstrSrc);\r
+  CPropVariant(LPCOLESTR lpszSrc);\r
+  CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };\r
+  CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }\r
+  CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }\r
+  CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }\r
+  CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }\r
+  CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; }\r
+  CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }\r
+\r
+  CPropVariant& operator=(const CPropVariant &varSrc);\r
+  CPropVariant& operator=(const PROPVARIANT &varSrc);\r
+  CPropVariant& operator=(BSTR bstrSrc);\r
+  CPropVariant& operator=(LPCOLESTR lpszSrc);\r
+  CPropVariant& operator=(const char *s);\r
+  CPropVariant& operator=(bool bSrc);\r
+  CPropVariant& operator=(Byte value);\r
+  CPropVariant& operator=(Int16 value);\r
+  CPropVariant& operator=(Int32 value);\r
+  CPropVariant& operator=(UInt32 value);\r
+  CPropVariant& operator=(Int64 value);\r
+  CPropVariant& operator=(UInt64 value);\r
+  CPropVariant& operator=(const FILETIME &value);\r
+\r
+  HRESULT Clear();\r
+  HRESULT Copy(const PROPVARIANT *pSrc);\r
+  HRESULT Attach(PROPVARIANT *pSrc);\r
+  HRESULT Detach(PROPVARIANT *pDest);\r
+\r
+  HRESULT InternalClear();\r
+  void InternalCopy(const PROPVARIANT *pSrc);\r
+\r
+  int Compare(const CPropVariant &a1);\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/PropVariantConversions.cpp b/CPP/Windows/PropVariantConversions.cpp
new file mode 100755 (executable)
index 0000000..9d7c2a2
--- /dev/null
@@ -0,0 +1,105 @@
+// PropVariantConversions.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Common/IntToString.h"\r
+#include "Common/StringConvert.h"\r
+\r
+#include "Windows/Defs.h"\r
+\r
+#include "PropVariantConversions.h"\r
+\r
+static UString ConvertUInt64ToString(UInt64 value)\r
+{\r
+  wchar_t buffer[32];\r
+  ConvertUInt64ToString(value, buffer);\r
+  return buffer;\r
+}\r
+\r
+static UString ConvertInt64ToString(Int64 value)\r
+{\r
+  wchar_t buffer[32];\r
+  ConvertInt64ToString(value, buffer);\r
+  return buffer;\r
+}\r
+\r
+static char *UIntToStringSpec(char c, UInt32 value, char *s, int numPos)\r
+{\r
+  if (c != 0)\r
+    *s++ = c;\r
+  char temp[16];\r
+  int pos = 0;\r
+  do\r
+  {\r
+    temp[pos++] = (char)('0' + value % 10);\r
+    value /= 10;\r
+  }\r
+  while (value != 0);\r
+  int i;\r
+  for (i = 0; i < numPos - pos; i++)\r
+    *s++ = '0';\r
+  do\r
+    *s++ = temp[--pos];\r
+  while (pos > 0);\r
+  *s = '\0';\r
+  return s;\r
+}\r
+\r
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)\r
+{\r
+  s[0] = '\0';\r
+  SYSTEMTIME st;\r
+  if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))\r
+    return false;\r
+  s = UIntToStringSpec(0, st.wYear, s, 4);\r
+  s = UIntToStringSpec('-', st.wMonth, s, 2);\r
+  s = UIntToStringSpec('-', st.wDay, s, 2);\r
+  if (includeTime)\r
+  {\r
+    s = UIntToStringSpec(' ', st.wHour, s, 2);\r
+    s = UIntToStringSpec(':', st.wMinute, s, 2);\r
+    if (includeSeconds)\r
+      UIntToStringSpec(':', st.wSecond, s, 2);\r
+  }\r
+  return true;\r
+}\r
+\r
+UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime, bool includeSeconds)\r
+{\r
+  char s[32];\r
+  ConvertFileTimeToString(ft, s, includeTime, includeSeconds);\r
+  return GetUnicodeString(s);\r
+}\r
\r
+\r
+UString ConvertPropVariantToString(const PROPVARIANT &prop)\r
+{\r
+  switch (prop.vt)\r
+  {\r
+    case VT_EMPTY: return UString();\r
+    case VT_BSTR: return prop.bstrVal;\r
+    case VT_UI1: return ConvertUInt64ToString(prop.bVal);\r
+    case VT_UI2: return ConvertUInt64ToString(prop.uiVal);\r
+    case VT_UI4: return ConvertUInt64ToString(prop.ulVal);\r
+    case VT_UI8: return ConvertUInt64ToString(prop.uhVal.QuadPart);\r
+    case VT_FILETIME: return ConvertFileTimeToString(prop.filetime, true, true);\r
+    // case VT_I1: return ConvertInt64ToString(prop.cVal);\r
+    case VT_I2: return ConvertInt64ToString(prop.iVal);\r
+    case VT_I4: return ConvertInt64ToString(prop.lVal);\r
+    case VT_I8: return ConvertInt64ToString(prop.hVal.QuadPart);\r
+    case VT_BOOL: return VARIANT_BOOLToBool(prop.boolVal) ? L"+" : L"-";\r
+    default: throw 150245;\r
+  }\r
+}\r
+\r
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop)\r
+{\r
+  switch (prop.vt)\r
+  {\r
+    case VT_UI1: return prop.bVal;\r
+    case VT_UI2: return prop.uiVal;\r
+    case VT_UI4: return prop.ulVal;\r
+    case VT_UI8: return (UInt64)prop.uhVal.QuadPart;\r
+    default: throw 151199;\r
+  }\r
+}\r
diff --git a/CPP/Windows/PropVariantConversions.h b/CPP/Windows/PropVariantConversions.h
new file mode 100755 (executable)
index 0000000..74139a4
--- /dev/null
@@ -0,0 +1,14 @@
+// Windows/PropVariantConversions.h\r
+\r
+#ifndef __PROP_VARIANT_CONVERSIONS_H\r
+#define __PROP_VARIANT_CONVERSIONS_H\r
+\r
+#include "Common/MyString.h"\r
+#include "Common/Types.h"\r
+\r
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);\r
+UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);\r
+UString ConvertPropVariantToString(const PROPVARIANT &prop);\r
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop);\r
+\r
+#endif\r
diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp
new file mode 100755 (executable)
index 0000000..3db00ea
--- /dev/null
@@ -0,0 +1,369 @@
+// Windows/Registry.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#ifndef _UNICODE\r
+#include "Common/StringConvert.h"\r
+#endif\r
+#include "Windows/Registry.h"\r
+\r
+#ifndef _UNICODE\r
+extern bool g_IsNT;\r
+#endif\r
+\r
+namespace NWindows {\r
+namespace NRegistry {\r
+\r
+#define MYASSERT(expr) // _ASSERTE(expr)\r
+\r
+LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,\r
+    LPTSTR keyClass, DWORD options, REGSAM accessMask,\r
+    LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition)\r
+{\r
+  MYASSERT(parentKey != NULL);\r
+  DWORD dispositionReal;\r
+  HKEY key = NULL;\r
+  LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass,\r
+      options, accessMask, securityAttributes, &key, &dispositionReal);\r
+  if (disposition != NULL)\r
+    *disposition = dispositionReal;\r
+  if (res == ERROR_SUCCESS)\r
+  {\r
+    res = Close();\r
+    _object = key;\r
+  }\r
+  return res;\r
+}\r
+\r
+LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)\r
+{\r
+  MYASSERT(parentKey != NULL);\r
+  HKEY key = NULL;\r
+  LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key);\r
+  if (res == ERROR_SUCCESS)\r
+  {\r
+    res = Close();\r
+    MYASSERT(res == ERROR_SUCCESS);\r
+    _object = key;\r
+  }\r
+  return res;\r
+}\r
+\r
+LONG CKey::Close()\r
+{\r
+  LONG res = ERROR_SUCCESS;\r
+  if (_object != NULL)\r
+  {\r
+    res = RegCloseKey(_object);\r
+    _object = NULL;\r
+  }\r
+  return res;\r
+}\r
+\r
+// win95, win98: deletes sunkey and all its subkeys\r
+// winNT to be deleted must not have subkeys\r
+LONG CKey::DeleteSubKey(LPCTSTR subKeyName)\r
+{\r
+  MYASSERT(_object != NULL);\r
+  return RegDeleteKey(_object, subKeyName);\r
+}\r
+\r
+LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName)\r
+{\r
+  CKey key;\r
+  LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);\r
+  if (res != ERROR_SUCCESS)\r
+    return res;\r
+  FILETIME fileTime;\r
+  const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL\r
+  DWORD size = kBufferSize;\r
+  TCHAR buffer[kBufferSize];\r
+  while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)\r
+  {\r
+    res = key.RecurseDeleteKey(buffer);\r
+    if (res != ERROR_SUCCESS)\r
+      return res;\r
+    size = kBufferSize;\r
+  }\r
+  key.Close();\r
+  return DeleteSubKey(subKeyName);\r
+}\r
+\r
+\r
+/////////////////////////\r
+// Value Functions\r
+\r
+static inline UInt32 BoolToUINT32(bool value) {  return (value ? 1: 0); }\r
+static inline bool UINT32ToBool(UInt32 value) {  return (value != 0); }\r
+\r
+\r
+LONG CKey::DeleteValue(LPCTSTR name)\r
+{\r
+  MYASSERT(_object != NULL);\r
+  return ::RegDeleteValue(_object, name);\r
+}\r
+\r
+#ifndef _UNICODE\r
+LONG CKey::DeleteValue(LPCWSTR name)\r
+{\r
+  MYASSERT(_object != NULL);\r
+  if (g_IsNT)\r
+    return ::RegDeleteValueW(_object, name);\r
+  return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name));\r
+}\r
+#endif\r
+\r
+LONG CKey::SetValue(LPCTSTR name, UInt32 value)\r
+{\r
+  MYASSERT(_object != NULL);\r
+  return RegSetValueEx(_object, name, NULL, REG_DWORD,\r
+      (BYTE * const)&value, sizeof(UInt32));\r
+}\r
+\r
+LONG CKey::SetValue(LPCTSTR name, bool value)\r
+{\r
+  return SetValue(name, BoolToUINT32(value));\r
+}\r
+\r
+LONG CKey::SetValue(LPCTSTR name, LPCTSTR value)\r
+{\r
+  MYASSERT(value != NULL);\r
+  MYASSERT(_object != NULL);\r
+  return RegSetValueEx(_object, name, NULL, REG_SZ,\r
+      (const BYTE * )value, (lstrlen(value) + 1) * sizeof(TCHAR));\r
+}\r
+\r
+/*\r
+LONG CKey::SetValue(LPCTSTR name, const CSysString &value)\r
+{\r
+  MYASSERT(value != NULL);\r
+  MYASSERT(_object != NULL);\r
+  return RegSetValueEx(_object, name, NULL, REG_SZ,\r
+      (const BYTE *)(const TCHAR *)value, (value.Length() + 1) * sizeof(TCHAR));\r
+}\r
+*/\r
+\r
+#ifndef _UNICODE\r
+\r
+LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)\r
+{\r
+  MYASSERT(value != NULL);\r
+  MYASSERT(_object != NULL);\r
+  if (g_IsNT)\r
+    return RegSetValueExW(_object, name, NULL, REG_SZ,\r
+      (const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t)));\r
+  return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name),\r
+    value == 0 ? 0 : (LPCSTR)GetSystemString(value));\r
+}\r
+\r
+#endif\r
+\r
+\r
+LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size)\r
+{\r
+  MYASSERT(value != NULL);\r
+  MYASSERT(_object != NULL);\r
+  return RegSetValueEx(_object, name, NULL, REG_BINARY,\r
+      (const BYTE *)value, size);\r
+}\r
+\r
+LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)\r
+{\r
+  MYASSERT(value != NULL);\r
+  CKey key;\r
+  LONG res = key.Create(parentKey, keyName);\r
+  if (res == ERROR_SUCCESS)\r
+    res = key.SetValue(valueName, value);\r
+  return res;\r
+}\r
+\r
+LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)\r
+{\r
+  MYASSERT(value != NULL);\r
+  CKey key;\r
+  LONG res = key.Create(_object, keyName);\r
+  if (res == ERROR_SUCCESS)\r
+    res = key.SetValue(valueName, value);\r
+  return res;\r
+}\r
+\r
+LONG CKey::QueryValue(LPCTSTR name, UInt32 &value)\r
+{\r
+  DWORD type = NULL;\r
+  DWORD count = sizeof(DWORD);\r
+  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type,\r
+    (LPBYTE)&value, &count);\r
+  MYASSERT((res!=ERROR_SUCCESS) || (type == REG_DWORD));\r
+  MYASSERT((res!=ERROR_SUCCESS) || (count == sizeof(UInt32)));\r
+  return res;\r
+}\r
+\r
+LONG CKey::QueryValue(LPCTSTR name, bool &value)\r
+{\r
+  UInt32 uintValue = BoolToUINT32(value);\r
+  LONG res = QueryValue(name, uintValue);\r
+  value = UINT32ToBool(uintValue);\r
+  return res;\r
+}\r
+\r
+LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value)\r
+{\r
+  UInt32 newVal;\r
+  LONG res = QueryValue(name, newVal);\r
+  if (res == ERROR_SUCCESS)\r
+    value = newVal;\r
+  return res;\r
+}\r
+\r
+LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value)\r
+{\r
+  bool newVal;\r
+  LONG res = QueryValue(name, newVal);\r
+  if (res == ERROR_SUCCESS)\r
+    value = newVal;\r
+  return res;\r
+}\r
+\r
+LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count)\r
+{\r
+  MYASSERT(count != NULL);\r
+  DWORD type = NULL;\r
+  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);\r
+  MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));\r
+  return res;\r
+}\r
+\r
+LONG CKey::QueryValue(LPCTSTR name, CSysString &value)\r
+{\r
+  value.Empty();\r
+  DWORD type = NULL;\r
+  UInt32 currentSize = 0;\r
+  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&currentSize);\r
+  if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)\r
+    return res;\r
+  res = QueryValue(name, value.GetBuffer(currentSize), currentSize);\r
+  value.ReleaseBuffer();\r
+  return res;\r
+}\r
+\r
+#ifndef _UNICODE\r
+LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count)\r
+{\r
+  MYASSERT(count != NULL);\r
+  DWORD type = NULL;\r
+  LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);\r
+  MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));\r
+  return res;\r
+}\r
+LONG CKey::QueryValue(LPCWSTR name, UString &value)\r
+{\r
+  value.Empty();\r
+  DWORD type = NULL;\r
+  UInt32 currentSize = 0;\r
+\r
+  LONG res;\r
+  if (g_IsNT)\r
+  {\r
+    res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&currentSize);\r
+    if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)\r
+      return res;\r
+    res = QueryValue(name, value.GetBuffer(currentSize), currentSize);\r
+    value.ReleaseBuffer();\r
+  }\r
+  else\r
+  {\r
+    AString vTemp;\r
+    res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp);\r
+    value = GetUnicodeString(vTemp);\r
+  }\r
+  return res;\r
+}\r
+#endif\r
+\r
+LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count)\r
+{\r
+  DWORD type = NULL;\r
+  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);\r
+  MYASSERT((res!=ERROR_SUCCESS) || (type == REG_BINARY));\r
+  return res;\r
+}\r
+\r
+\r
+LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)\r
+{\r
+  DWORD type = NULL;\r
+  dataSize = 0;\r
+  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&dataSize);\r
+  if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)\r
+    return res;\r
+  value.SetCapacity(dataSize);\r
+  return QueryValue(name, (BYTE *)value, dataSize);\r
+}\r
+\r
+LONG CKey::EnumKeys(CSysStringVector &keyNames)\r
+{\r
+  keyNames.Clear();\r
+  CSysString keyName;\r
+  for (UInt32 index = 0; ; index++)\r
+  {\r
+    const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL\r
+    FILETIME lastWriteTime;\r
+    UInt32 nameSize = kBufferSize;\r
+    LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuffer(kBufferSize),\r
+        (DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime);\r
+    keyName.ReleaseBuffer();\r
+    if (result == ERROR_NO_MORE_ITEMS)\r
+      break;\r
+    if (result != ERROR_SUCCESS)\r
+      return result;\r
+    keyNames.Add(keyName);\r
+  }\r
+  return ERROR_SUCCESS;\r
+}\r
+\r
+LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)\r
+{\r
+  UInt32 numChars = 0;\r
+  int i;\r
+  for (i = 0; i < strings.Size(); i++)\r
+    numChars += strings[i].Length() + 1;\r
+  CBuffer<wchar_t> buffer;\r
+  buffer.SetCapacity(numChars);\r
+  int pos = 0;\r
+  for (i = 0; i < strings.Size(); i++)\r
+  {\r
+    const UString &s = strings[i];\r
+    MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)s);\r
+    pos += s.Length() + 1;\r
+  }\r
+  return SetValue(valueName, buffer, numChars * sizeof(wchar_t));\r
+}\r
+\r
+LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)\r
+{\r
+  strings.Clear();\r
+  CByteBuffer buffer;\r
+  UInt32 dataSize;\r
+  LONG res = QueryValue(valueName, buffer, dataSize);\r
+  if (res != ERROR_SUCCESS)\r
+    return res;\r
+  if (dataSize % sizeof(wchar_t) != 0)\r
+    return E_FAIL;\r
+  const wchar_t *data = (const wchar_t *)(const Byte  *)buffer;\r
+  int numChars = dataSize / sizeof(wchar_t);\r
+  UString s;\r
+  for (int i = 0; i < numChars; i++)\r
+  {\r
+    wchar_t c = data[i];\r
+    if (c == 0)\r
+    {\r
+      strings.Add(s);\r
+      s.Empty();\r
+    }\r
+    else\r
+      s += c;\r
+  }\r
+  return res;\r
+}\r
+\r
+}}\r
diff --git a/CPP/Windows/Registry.h b/CPP/Windows/Registry.h
new file mode 100755 (executable)
index 0000000..8f4ede3
--- /dev/null
@@ -0,0 +1,85 @@
+// Windows/Registry.h\r
+\r
+#ifndef __WINDOWS_REGISTRY_H\r
+#define __WINDOWS_REGISTRY_H\r
+\r
+#include "Common/Buffer.h"\r
+#include "Common/MyString.h"\r
+#include "Common/Types.h"\r
+\r
+namespace NWindows {\r
+namespace NRegistry {\r
+\r
+LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);\r
+\r
+class CKey\r
+{\r
+  HKEY _object;\r
+public:\r
+  CKey(): _object(NULL) {}\r
+  ~CKey() { Close(); }\r
+\r
+  operator HKEY() const { return _object; }\r
+  void Attach(HKEY key) { _object = key; }\r
+  HKEY Detach()\r
+  {\r
+    HKEY key = _object;\r
+    _object = NULL;\r
+    return key;\r
+  }\r
+\r
+  LONG Create(HKEY parentKey, LPCTSTR keyName,\r
+      LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE,\r
+      REGSAM accessMask = KEY_ALL_ACCESS,\r
+      LPSECURITY_ATTRIBUTES securityAttributes = NULL,\r
+      LPDWORD disposition = NULL);\r
+  LONG Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask = KEY_ALL_ACCESS);\r
+\r
+  LONG Close();\r
+\r
+  LONG DeleteSubKey(LPCTSTR subKeyName);\r
+  LONG RecurseDeleteKey(LPCTSTR subKeyName);\r
+\r
+  LONG DeleteValue(LPCTSTR name);\r
+  #ifndef _UNICODE\r
+  LONG DeleteValue(LPCWSTR name);\r
+  #endif\r
+\r
+  LONG SetValue(LPCTSTR valueName, UInt32 value);\r
+  LONG SetValue(LPCTSTR valueName, bool value);\r
+  LONG SetValue(LPCTSTR valueName, LPCTSTR value);\r
+  // LONG SetValue(LPCTSTR valueName, const CSysString &value);\r
+  #ifndef _UNICODE\r
+  LONG SetValue(LPCWSTR name, LPCWSTR value);\r
+  // LONG SetValue(LPCWSTR name, const UString &value);\r
+  #endif\r
+\r
+  LONG SetValue(LPCTSTR name, const void *value, UInt32 size);\r
+\r
+  LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings);\r
+  LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings);\r
+\r
+  LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);\r
+\r
+  LONG QueryValue(LPCTSTR name, UInt32 &value);\r
+  LONG QueryValue(LPCTSTR name, bool &value);\r
+  LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize);\r
+  LONG QueryValue(LPCTSTR name, CSysString &value);\r
+\r
+  LONG GetValue_IfOk(LPCTSTR name, UInt32 &value);\r
+  LONG GetValue_IfOk(LPCTSTR name, bool &value);\r
+\r
+  #ifndef _UNICODE\r
+  LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize);\r
+  LONG QueryValue(LPCWSTR name, UString &value);\r
+  #endif\r
+\r
+  LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize);\r
+  LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize);\r
+\r
+  LONG EnumKeys(CSysStringVector &keyNames);\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/StdAfx.h b/CPP/Windows/StdAfx.h
new file mode 100755 (executable)
index 0000000..5308d63
--- /dev/null
@@ -0,0 +1,9 @@
+// StdAfx.h\r
+\r
+#ifndef __STDAFX_H\r
+#define __STDAFX_H\r
+\r
+#include "../Common/MyWindows.h"\r
+#include "../Common/NewHandler.h"\r
+\r
+#endif\r
diff --git a/CPP/Windows/Synchronization.cpp b/CPP/Windows/Synchronization.cpp
new file mode 100755 (executable)
index 0000000..01f1ad9
--- /dev/null
@@ -0,0 +1,10 @@
+// Windows/Synchronization.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Synchronization.h"\r
+\r
+namespace NWindows {\r
+namespace NSynchronization {\r
+\r
+}}\r
diff --git a/CPP/Windows/Synchronization.h b/CPP/Windows/Synchronization.h
new file mode 100755 (executable)
index 0000000..786da00
--- /dev/null
@@ -0,0 +1,164 @@
+// Windows/Synchronization.h\r
+\r
+#ifndef __WINDOWS_SYNCHRONIZATION_H\r
+#define __WINDOWS_SYNCHRONIZATION_H\r
+\r
+#include "../../C/Threads.h"\r
+\r
+#include "Defs.h"\r
+\r
+#ifdef _WIN32\r
+#include "Handle.h"\r
+#endif\r
+\r
+namespace NWindows {\r
+namespace NSynchronization {\r
+\r
+class CBaseEvent\r
+{\r
+protected:\r
+  ::CEvent _object;\r
+public:\r
+  bool IsCreated() { return Event_IsCreated(&_object) != 0; }\r
+  operator HANDLE() { return _object; }\r
+  CBaseEvent() { Event_Construct(&_object); }\r
+  ~CBaseEvent() { Close(); }\r
+  WRes Close() { return Event_Close(&_object); }\r
+  #ifdef _WIN32\r
+  WRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL)\r
+  {\r
+    _object = ::CreateEvent(sa, BoolToBOOL(manualReset), BoolToBOOL(initiallyOwn), name);\r
+    if (name == NULL && _object != 0)\r
+      return 0;\r
+    return ::GetLastError();\r
+  }\r
+  WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)\r
+  {\r
+    _object = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);\r
+    if (_object != 0)\r
+      return 0;\r
+    return ::GetLastError();\r
+  }\r
+  #endif\r
+\r
+  WRes Set() { return Event_Set(&_object); }\r
+  // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }\r
+  WRes Reset() { return Event_Reset(&_object); }\r
+  WRes Lock() { return Event_Wait(&_object); }\r
+};\r
+\r
+class CManualResetEvent: public CBaseEvent\r
+{\r
+public:\r
+  WRes Create(bool initiallyOwn = false)\r
+  {\r
+    return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0);\r
+  }\r
+  WRes CreateIfNotCreated()\r
+  {\r
+    if (IsCreated())\r
+      return 0;\r
+    return ManualResetEvent_CreateNotSignaled(&_object);\r
+  }\r
+  #ifdef _WIN32\r
+  WRes CreateWithName(bool initiallyOwn, LPCTSTR name)\r
+  {\r
+    return CBaseEvent::Create(true, initiallyOwn, name);\r
+  }\r
+  #endif\r
+};\r
+\r
+class CAutoResetEvent: public CBaseEvent\r
+{\r
+public:\r
+  WRes Create()\r
+  {\r
+    return AutoResetEvent_CreateNotSignaled(&_object);\r
+  }\r
+  WRes CreateIfNotCreated()\r
+  {\r
+    if (IsCreated())\r
+      return 0;\r
+    return AutoResetEvent_CreateNotSignaled(&_object);\r
+  }\r
+};\r
+\r
+#ifdef _WIN32\r
+class CObject: public CHandle\r
+{\r
+public:\r
+  WRes Lock(DWORD timeoutInterval = INFINITE)\r
+    { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); }\r
+};\r
+class CMutex: public CObject\r
+{\r
+public:\r
+  WRes Create(bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL)\r
+  {\r
+    _handle = ::CreateMutex(sa, BoolToBOOL(initiallyOwn), name);\r
+    if (name == NULL && _handle != 0)\r
+      return 0;\r
+    return ::GetLastError();\r
+  }\r
+  #ifndef UNDER_CE\r
+  WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)\r
+  {\r
+    _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);\r
+    if (_handle != 0)\r
+      return 0;\r
+    return ::GetLastError();\r
+  }\r
+  #endif\r
+  WRes Release()\r
+  {\r
+    return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();\r
+  }\r
+};\r
+class CMutexLock\r
+{\r
+  CMutex *_object;\r
+public:\r
+  CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }\r
+  ~CMutexLock() { _object->Release(); }\r
+};\r
+#endif\r
+\r
+class CSemaphore\r
+{\r
+  ::CSemaphore _object;\r
+public:\r
+  CSemaphore() { Semaphore_Construct(&_object); }\r
+  ~CSemaphore() { Close(); }\r
+  WRes Close() {  return Semaphore_Close(&_object); }\r
+  operator HANDLE() { return _object; }\r
+  WRes Create(UInt32 initiallyCount, UInt32 maxCount)\r
+  {\r
+    return Semaphore_Create(&_object, initiallyCount, maxCount);\r
+  }\r
+  WRes Release() { return Semaphore_Release1(&_object); }\r
+  WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }\r
+  WRes Lock() { return Semaphore_Wait(&_object); }\r
+};\r
+\r
+class CCriticalSection\r
+{\r
+  ::CCriticalSection _object;\r
+public:\r
+  CCriticalSection() { CriticalSection_Init(&_object); }\r
+  ~CCriticalSection() { CriticalSection_Delete(&_object); }\r
+  void Enter() { CriticalSection_Enter(&_object); }\r
+  void Leave() { CriticalSection_Leave(&_object); }\r
+};\r
+\r
+class CCriticalSectionLock\r
+{\r
+  CCriticalSection *_object;\r
+  void Unlock()  { _object->Leave(); }\r
+public:\r
+  CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }\r
+  ~CCriticalSectionLock() { Unlock(); }\r
+};\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp
new file mode 100755 (executable)
index 0000000..545ea0e
--- /dev/null
@@ -0,0 +1,72 @@
+// Windows/System.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "../Common/Defs.h"\r
+\r
+#include "System.h"\r
+\r
+namespace NWindows {\r
+namespace NSystem {\r
+\r
+UInt32 GetNumberOfProcessors()\r
+{\r
+  SYSTEM_INFO systemInfo;\r
+  GetSystemInfo(&systemInfo);\r
+  return (UInt32)systemInfo.dwNumberOfProcessors;\r
+}\r
+\r
+#ifndef UNDER_CE\r
+\r
+#if !defined(_WIN64) && defined(__GNUC__)\r
+\r
+typedef struct _MY_MEMORYSTATUSEX {\r
+  DWORD dwLength;\r
+  DWORD dwMemoryLoad;\r
+  DWORDLONG ullTotalPhys;\r
+  DWORDLONG ullAvailPhys;\r
+  DWORDLONG ullTotalPageFile;\r
+  DWORDLONG ullAvailPageFile;\r
+  DWORDLONG ullTotalVirtual;\r
+  DWORDLONG ullAvailVirtual;\r
+  DWORDLONG ullAvailExtendedVirtual;\r
+} MY_MEMORYSTATUSEX, *MY_LPMEMORYSTATUSEX;\r
+\r
+#else\r
+\r
+#define MY_MEMORYSTATUSEX MEMORYSTATUSEX\r
+#define MY_LPMEMORYSTATUSEX LPMEMORYSTATUSEX\r
+\r
+#endif\r
+\r
+typedef BOOL (WINAPI *GlobalMemoryStatusExP)(MY_LPMEMORYSTATUSEX lpBuffer);\r
+\r
+#endif\r
+\r
+UInt64 GetRamSize()\r
+{\r
+  #ifndef UNDER_CE\r
+  MY_MEMORYSTATUSEX stat;\r
+  stat.dwLength = sizeof(stat);\r
+  #endif\r
+  #ifdef _WIN64\r
+  if (!::GlobalMemoryStatusEx(&stat))\r
+    return 0;\r
+  return MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);\r
+  #else\r
+  #ifndef UNDER_CE\r
+  GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)\r
+      ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GlobalMemoryStatusEx");\r
+  if (globalMemoryStatusEx != 0 && globalMemoryStatusEx(&stat))\r
+    return MyMin(stat.ullTotalVirtual, stat.ullTotalPhys);\r
+  #endif\r
+  {\r
+    MEMORYSTATUS stat;\r
+    stat.dwLength = sizeof(stat);\r
+    ::GlobalMemoryStatus(&stat);\r
+    return MyMin(stat.dwTotalVirtual, stat.dwTotalPhys);\r
+  }\r
+  #endif\r
+}\r
+\r
+}}\r
diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h
new file mode 100755 (executable)
index 0000000..49a4fe7
--- /dev/null
@@ -0,0 +1,16 @@
+// Windows/System.h\r
+\r
+#ifndef __WINDOWS_SYSTEM_H\r
+#define __WINDOWS_SYSTEM_H\r
+\r
+#include "../Common/Types.h"\r
+\r
+namespace NWindows {\r
+namespace NSystem {\r
+\r
+UInt32 GetNumberOfProcessors();\r
+UInt64 GetRamSize();\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CPP/Windows/Thread.h b/CPP/Windows/Thread.h
new file mode 100755 (executable)
index 0000000..1b5863c
--- /dev/null
@@ -0,0 +1,38 @@
+// Windows/Thread.h\r
+\r
+#ifndef __WINDOWS_THREAD_H\r
+#define __WINDOWS_THREAD_H\r
+\r
+#include "../../C/Threads.h"\r
+\r
+#include "Defs.h"\r
+\r
+namespace NWindows {\r
+\r
+class CThread\r
+{\r
+  ::CThread thread;\r
+public:\r
+  CThread() { Thread_Construct(&thread); }\r
+  ~CThread() { Close(); }\r
+  bool IsCreated() { return Thread_WasCreated(&thread) != 0; }\r
+  WRes Close()  { return Thread_Close(&thread); }\r
+  WRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)\r
+    { return Thread_Create(&thread, startAddress, parameter); }\r
+  WRes Wait() { return Thread_Wait(&thread); }\r
+  \r
+  #ifdef _WIN32\r
+  operator HANDLE() { return thread; }\r
+  void Attach(HANDLE handle) { thread = handle; }\r
+  HANDLE Detach() { HANDLE h = thread; thread = NULL; return h; }\r
+  DWORD Resume() { return ::ResumeThread(thread); }\r
+  DWORD Suspend() { return ::SuspendThread(thread); }\r
+  bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread, exitCode)); }\r
+  int GetPriority() { return ::GetThreadPriority(thread); }\r
+  bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread, priority)); }\r
+  #endif\r
+};\r
+\r
+}\r
+\r
+#endif\r
diff --git a/CPP/Windows/Time.cpp b/CPP/Windows/Time.cpp
new file mode 100755 (executable)
index 0000000..0504cdf
--- /dev/null
@@ -0,0 +1,170 @@
+// Windows/Time.cpp\r
+\r
+#include "StdAfx.h"\r
+\r
+#include "Windows/Defs.h"\r
+\r
+#include "Time.h"\r
+\r
+namespace NWindows {\r
+namespace NTime {\r
+\r
+static const UInt32 kNumTimeQuantumsInSecond = 10000000;\r
+static const UInt32 kFileTimeStartYear = 1601;\r
+static const UInt32 kDosTimeStartYear = 1980;\r
+static const UInt32 kUnixTimeStartYear = 1970;\r
+static const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) *\r
+    60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));\r
+\r
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft)\r
+{\r
+  #if defined(_WIN32) && !defined(UNDER_CE)\r
+  return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));\r
+  #else\r
+  ft.dwLowDateTime = 0;\r
+  ft.dwHighDateTime = 0;\r
+  UInt64 res;\r
+  if (!GetSecondsSince1601(kDosTimeStartYear + (dosTime >> 25), (dosTime >> 21) & 0xF, (dosTime >> 16) & 0x1F,\r
+      (dosTime >> 11) & 0x1F, (dosTime >> 5) & 0x3F, (dosTime & 0x1F) * 2, res))\r
+    return false;\r
+  res *= kNumTimeQuantumsInSecond;\r
+  ft.dwLowDateTime = (UInt32)res;\r
+  ft.dwHighDateTime = (UInt32)(res >> 32);\r
+  return true;\r
+  #endif\r
+}\r
+\r
+static const UInt32 kHighDosTime = 0xFF9FBF7D;\r
+static const UInt32 kLowDosTime = 0x210000;\r
+\r
+#define PERIOD_4 (4 * 365 + 1)\r
+#define PERIOD_100 (PERIOD_4 * 25 - 1)\r
+#define PERIOD_400 (PERIOD_100 * 4 + 1)\r
+\r
+bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)\r
+{\r
+  #if defined(_WIN32) && !defined(UNDER_CE)\r
+\r
+  WORD datePart, timePart;\r
+  if (!::FileTimeToDosDateTime(&ft, &datePart, &timePart))\r
+  {\r
+    dosTime = (ft.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime;\r
+    return false;\r
+  }\r
+  dosTime = (((UInt32)datePart) << 16) + timePart;\r
+\r
+  #else\r
+\r
+  unsigned year, mon, day, hour, min, sec;\r
+  UInt64 v64 = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32);\r
+  Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
+  unsigned temp;\r
+  UInt32 v;\r
+  v64 += (kNumTimeQuantumsInSecond * 2 - 1);\r
+  v64 /= kNumTimeQuantumsInSecond;\r
+  sec = (unsigned)(v64 % 60);\r
+  v64 /= 60;\r
+  min = (unsigned)(v64 % 60);\r
+  v64 /= 60;\r
+  hour = (unsigned)(v64 % 24);\r
+  v64 /= 24;\r
+\r
+  v = (UInt32)v64;\r
+\r
+  year = (unsigned)(kFileTimeStartYear + v / PERIOD_400 * 400);\r
+  v %= PERIOD_400;\r
+\r
+  temp = (unsigned)(v / PERIOD_100);\r
+  if (temp == 4)\r
+    temp = 3;\r
+  year += temp * 100;\r
+  v -= temp * PERIOD_100;\r
+\r
+  temp = v / PERIOD_4;\r
+  if (temp == 25)\r
+    temp = 24;\r
+  year += temp * 4;\r
+  v -= temp * PERIOD_4;\r
+\r
+  temp = v / 365;\r
+  if (temp == 4)\r
+    temp = 3;\r
+  year += temp;\r
+  v -= temp * 365;\r
+\r
+  if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))\r
+    ms[1] = 29;\r
+  for (mon = 1; mon <= 12; mon++)\r
+  {\r
+    unsigned s = ms[mon - 1];\r
+    if (v < s)\r
+      break;\r
+    v -= s;\r
+  }\r
+  day = (unsigned)v + 1;\r
+\r
+  dosTime = kLowDosTime;\r
+  if (year < kDosTimeStartYear)\r
+    return false;\r
+  year -= kDosTimeStartYear;\r
+  dosTime = kHighDosTime;\r
+  if (year >= 128)\r
+    return false;\r
+  dosTime = (year << 25) | (mon << 21) | (day << 16) | (hour << 11) | (min << 5) | (sec >> 1);\r
+  #endif\r
+  return true;\r
+}\r
+\r
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft)\r
+{\r
+  UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;\r
+  ft.dwLowDateTime = (DWORD)v;\r
+  ft.dwHighDateTime = (DWORD)(v >> 32);\r
+}\r
+\r
+bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)\r
+{\r
+  UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;\r
+  if (winTime < kUnixTimeStartValue)\r
+  {\r
+    unixTime = 0;\r
+    return false;\r
+  }\r
+  winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;\r
+  if (winTime > 0xFFFFFFFF)\r
+  {\r
+    unixTime = 0xFFFFFFFF;\r
+    return false;\r
+  }\r
+  unixTime = (UInt32)winTime;\r
+  return true;\r
+}\r
+\r
+bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,\r
+  unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds)\r
+{\r
+  resSeconds = 0;\r
+  if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 ||\r
+      day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59)\r
+    return false;\r
+  UInt32 numYears = year - kFileTimeStartYear;\r
+  UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400;\r
+  Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
+  if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))\r
+    ms[1] = 29;\r
+  month--;\r
+  for (unsigned i = 0; i < month; i++)\r
+    numDays += ms[i];\r
+  numDays += day - 1;\r
+  resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec;\r
+  return true;\r
+}\r
+\r
+void GetCurUtcFileTime(FILETIME &ft)\r
+{\r
+  SYSTEMTIME st;\r
+  GetSystemTime(&st);\r
+  SystemTimeToFileTime(&st, &ft);\r
+}\r
+\r
+}}\r
diff --git a/CPP/Windows/Time.h b/CPP/Windows/Time.h
new file mode 100755 (executable)
index 0000000..7ecb204
--- /dev/null
@@ -0,0 +1,21 @@
+// Windows/Time.h\r
+\r
+#ifndef __WINDOWS_TIME_H\r
+#define __WINDOWS_TIME_H\r
+\r
+#include "Common/Types.h"\r
+\r
+namespace NWindows {\r
+namespace NTime {\r
+\r
+bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime);\r
+bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime);\r
+void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime);\r
+bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime);\r
+bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,\r
+  unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds);\r
+void GetCurUtcFileTime(FILETIME &ft);\r
+\r
+}}\r
+\r
+#endif\r
diff --git a/CS/7zip/Common/CRC.cs b/CS/7zip/Common/CRC.cs
new file mode 100755 (executable)
index 0000000..62bb847
--- /dev/null
@@ -0,0 +1,55 @@
+// Common/CRC.cs\r
+\r
+namespace SevenZip\r
+{\r
+       class CRC\r
+       {\r
+               public static readonly uint[] Table;\r
+\r
+               static CRC()\r
+               {\r
+                       Table = new uint[256];\r
+                       const uint kPoly = 0xEDB88320;\r
+                       for (uint i = 0; i < 256; i++)\r
+                       {\r
+                               uint r = i;\r
+                               for (int j = 0; j < 8; j++)\r
+                                       if ((r & 1) != 0)\r
+                                               r = (r >> 1) ^ kPoly;\r
+                                       else\r
+                                               r >>= 1;\r
+                               Table[i] = r;\r
+                       }\r
+               }\r
+\r
+               uint _value = 0xFFFFFFFF;\r
+\r
+               public void Init() { _value = 0xFFFFFFFF; }\r
+\r
+               public void UpdateByte(byte b)\r
+               {\r
+                       _value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);\r
+               }\r
+\r
+               public void Update(byte[] data, uint offset, uint size)\r
+               {\r
+                       for (uint i = 0; i < size; i++)\r
+                               _value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);\r
+               }\r
+\r
+               public uint GetDigest() { return _value ^ 0xFFFFFFFF; }\r
+\r
+               static uint CalculateDigest(byte[] data, uint offset, uint size)\r
+               {\r
+                       CRC crc = new CRC();\r
+                       // crc.Init();\r
+                       crc.Update(data, offset, size);\r
+                       return crc.GetDigest();\r
+               }\r
+\r
+               static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)\r
+               {\r
+                       return (CalculateDigest(data, offset, size) == digest);\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Common/CommandLineParser.cs b/CS/7zip/Common/CommandLineParser.cs
new file mode 100755 (executable)
index 0000000..b46f6f2
--- /dev/null
@@ -0,0 +1,274 @@
+// CommandLineParser.cs\r
+\r
+using System;\r
+using System.Collections;\r
+\r
+namespace SevenZip.CommandLineParser\r
+{\r
+       public enum SwitchType\r
+       {\r
+               Simple,\r
+               PostMinus,\r
+               LimitedPostString,\r
+               UnLimitedPostString,\r
+               PostChar\r
+       }\r
+\r
+       public class SwitchForm\r
+       {\r
+               public string IDString;\r
+               public SwitchType Type;\r
+               public bool Multi;\r
+               public int MinLen;\r
+               public int MaxLen;\r
+               public string PostCharSet;\r
+\r
+               public SwitchForm(string idString, SwitchType type, bool multi,\r
+                       int minLen, int maxLen, string postCharSet)\r
+               {\r
+                       IDString = idString;\r
+                       Type = type;\r
+                       Multi = multi;\r
+                       MinLen = minLen;\r
+                       MaxLen = maxLen;\r
+                       PostCharSet = postCharSet;\r
+               }\r
+               public SwitchForm(string idString, SwitchType type, bool multi, int minLen):\r
+                       this(idString, type, multi, minLen, 0, "")\r
+               {\r
+               }\r
+               public SwitchForm(string idString, SwitchType type, bool multi):\r
+                       this(idString, type, multi, 0)\r
+               {\r
+               }\r
+       }\r
+\r
+       public class SwitchResult\r
+       {\r
+               public bool ThereIs;\r
+               public bool WithMinus;\r
+               public ArrayList PostStrings = new ArrayList();\r
+               public int PostCharIndex;\r
+               public SwitchResult()\r
+               {\r
+                       ThereIs = false;\r
+               }\r
+       }\r
+\r
+       public class Parser\r
+       {\r
+               public ArrayList NonSwitchStrings = new ArrayList();\r
+               SwitchResult[] _switches;\r
+\r
+               public Parser(int numSwitches)\r
+               {\r
+                       _switches = new SwitchResult[numSwitches];\r
+                       for (int i = 0; i < numSwitches; i++)\r
+                               _switches[i] = new SwitchResult();\r
+               }\r
+\r
+               bool ParseString(string srcString, SwitchForm[] switchForms)\r
+               {\r
+                       int len = srcString.Length;\r
+                       if (len == 0)\r
+                               return false;\r
+                       int pos = 0;\r
+                       if (!IsItSwitchChar(srcString[pos]))\r
+                               return false;\r
+                       while (pos < len)\r
+                       {\r
+                               if (IsItSwitchChar(srcString[pos]))\r
+                                       pos++;\r
+                               const int kNoLen = -1;\r
+                               int matchedSwitchIndex = 0;\r
+                               int maxLen = kNoLen;\r
+                               for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++)\r
+                               {\r
+                                       int switchLen = switchForms[switchIndex].IDString.Length;\r
+                                       if (switchLen <= maxLen || pos + switchLen > len)\r
+                                               continue;\r
+                                       if (String.Compare(switchForms[switchIndex].IDString, 0,\r
+                                                       srcString, pos, switchLen, true) == 0)\r
+                                       {\r
+                                               matchedSwitchIndex = switchIndex;\r
+                                               maxLen = switchLen;\r
+                                       }\r
+                               }\r
+                               if (maxLen == kNoLen)\r
+                                       throw new Exception("maxLen == kNoLen");\r
+                               SwitchResult matchedSwitch = _switches[matchedSwitchIndex];\r
+                               SwitchForm switchForm = switchForms[matchedSwitchIndex];\r
+                               if ((!switchForm.Multi) && matchedSwitch.ThereIs)\r
+                                       throw new Exception("switch must be single");\r
+                               matchedSwitch.ThereIs = true;\r
+                               pos += maxLen;\r
+                               int tailSize = len - pos;\r
+                               SwitchType type = switchForm.Type;\r
+                               switch (type)\r
+                               {\r
+                                       case SwitchType.PostMinus:\r
+                                               {\r
+                                                       if (tailSize == 0)\r
+                                                               matchedSwitch.WithMinus = false;\r
+                                                       else\r
+                                                       {\r
+                                                               matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus);\r
+                                                               if (matchedSwitch.WithMinus)\r
+                                                                       pos++;\r
+                                                       }\r
+                                                       break;\r
+                                               }\r
+                                       case SwitchType.PostChar:\r
+                                               {\r
+                                                       if (tailSize < switchForm.MinLen)\r
+                                                               throw new Exception("switch is not full");\r
+                                                       string charSet = switchForm.PostCharSet;\r
+                                                       const int kEmptyCharValue = -1;\r
+                                                       if (tailSize == 0)\r
+                                                               matchedSwitch.PostCharIndex = kEmptyCharValue;\r
+                                                       else\r
+                                                       {\r
+                                                               int index = charSet.IndexOf(srcString[pos]);\r
+                                                               if (index < 0)\r
+                                                                       matchedSwitch.PostCharIndex = kEmptyCharValue;\r
+                                                               else\r
+                                                               {\r
+                                                                       matchedSwitch.PostCharIndex = index;\r
+                                                                       pos++;\r
+                                                               }\r
+                                                       }\r
+                                                       break;\r
+                                               }\r
+                                       case SwitchType.LimitedPostString:\r
+                                       case SwitchType.UnLimitedPostString:\r
+                                               {\r
+                                                       int minLen = switchForm.MinLen;\r
+                                                       if (tailSize < minLen)\r
+                                                               throw new Exception("switch is not full");\r
+                                                       if (type == SwitchType.UnLimitedPostString)\r
+                                                       {\r
+                                                               matchedSwitch.PostStrings.Add(srcString.Substring(pos));\r
+                                                               return true;\r
+                                                       }\r
+                                                       String stringSwitch = srcString.Substring(pos, minLen);\r
+                                                       pos += minLen;\r
+                                                       for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++)\r
+                                                       {\r
+                                                               char c = srcString[pos];\r
+                                                               if (IsItSwitchChar(c))\r
+                                                                       break;\r
+                                                               stringSwitch += c;\r
+                                                       }\r
+                                                       matchedSwitch.PostStrings.Add(stringSwitch);\r
+                                                       break;\r
+                                               }\r
+                               }\r
+                       }\r
+                       return true;\r
+\r
+               }\r
+\r
+               public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings)\r
+               {\r
+                       int numCommandStrings = commandStrings.Length;\r
+                       bool stopSwitch = false;\r
+                       for (int i = 0; i < numCommandStrings; i++)\r
+                       {\r
+                               string s = commandStrings[i];\r
+                               if (stopSwitch)\r
+                                       NonSwitchStrings.Add(s);\r
+                               else\r
+                                       if (s == kStopSwitchParsing)\r
+                                       stopSwitch = true;\r
+                               else\r
+                                       if (!ParseString(s, switchForms))\r
+                                       NonSwitchStrings.Add(s);\r
+                       }\r
+               }\r
+\r
+               public SwitchResult this[int index] { get { return _switches[index]; } }\r
+\r
+               public static int ParseCommand(CommandForm[] commandForms, string commandString,\r
+                       out string postString)\r
+               {\r
+                       for (int i = 0; i < commandForms.Length; i++)\r
+                       {\r
+                               string id = commandForms[i].IDString;\r
+                               if (commandForms[i].PostStringMode)\r
+                               {\r
+                                       if (commandString.IndexOf(id) == 0)\r
+                                       {\r
+                                               postString = commandString.Substring(id.Length);\r
+                                               return i;\r
+                                       }\r
+                               }\r
+                               else\r
+                                       if (commandString == id)\r
+                               {\r
+                                       postString = "";\r
+                                       return i;\r
+                               }\r
+                       }\r
+                       postString = "";\r
+                       return -1;\r
+               }\r
+\r
+               static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms,\r
+                       string commandString, ArrayList indices)\r
+               {\r
+                       indices.Clear();\r
+                       int numUsedChars = 0;\r
+                       for (int i = 0; i < numForms; i++)\r
+                       {\r
+                               CommandSubCharsSet charsSet = forms[i];\r
+                               int currentIndex = -1;\r
+                               int len = charsSet.Chars.Length;\r
+                               for (int j = 0; j < len; j++)\r
+                               {\r
+                                       char c = charsSet.Chars[j];\r
+                                       int newIndex = commandString.IndexOf(c);\r
+                                       if (newIndex >= 0)\r
+                                       {\r
+                                               if (currentIndex >= 0)\r
+                                                       return false;\r
+                                               if (commandString.IndexOf(c, newIndex + 1) >= 0)\r
+                                                       return false;\r
+                                               currentIndex = j;\r
+                                               numUsedChars++;\r
+                                       }\r
+                               }\r
+                               if (currentIndex == -1 && !charsSet.EmptyAllowed)\r
+                                       return false;\r
+                               indices.Add(currentIndex);\r
+                       }\r
+                       return (numUsedChars == commandString.Length);\r
+               }\r
+               const char kSwitchID1 = '-';\r
+               const char kSwitchID2 = '/';\r
+\r
+               const char kSwitchMinus = '-';\r
+               const string kStopSwitchParsing = "--";\r
+\r
+               static bool IsItSwitchChar(char c)\r
+               {\r
+                       return (c == kSwitchID1 || c == kSwitchID2);\r
+               }\r
+       }\r
+\r
+       public class CommandForm\r
+       {\r
+               public string IDString = "";\r
+               public bool PostStringMode = false;\r
+               public CommandForm(string idString, bool postStringMode)\r
+               {\r
+                       IDString = idString;\r
+                       PostStringMode = postStringMode;\r
+               }\r
+       }\r
+\r
+       class CommandSubCharsSet\r
+       {\r
+               public string Chars = "";\r
+               public bool EmptyAllowed = false;\r
+       }\r
+}\r
diff --git a/CS/7zip/Common/InBuffer.cs b/CS/7zip/Common/InBuffer.cs
new file mode 100755 (executable)
index 0000000..9c47c73
--- /dev/null
@@ -0,0 +1,72 @@
+// InBuffer.cs\r
+\r
+namespace SevenZip.Buffer\r
+{\r
+       public class InBuffer\r
+       {\r
+               byte[] m_Buffer;\r
+               uint m_Pos;\r
+               uint m_Limit;\r
+               uint m_BufferSize;\r
+               System.IO.Stream m_Stream;\r
+               bool m_StreamWasExhausted;\r
+               ulong m_ProcessedSize;\r
+\r
+               public InBuffer(uint bufferSize)\r
+               {\r
+                       m_Buffer = new byte[bufferSize];\r
+                       m_BufferSize = bufferSize;\r
+               }\r
+\r
+               public void Init(System.IO.Stream stream)\r
+               {\r
+                       m_Stream = stream;\r
+                       m_ProcessedSize = 0;\r
+                       m_Limit = 0;\r
+                       m_Pos = 0;\r
+                       m_StreamWasExhausted = false;\r
+               }\r
+\r
+               public bool ReadBlock()\r
+               {\r
+                       if (m_StreamWasExhausted)\r
+                               return false;\r
+                       m_ProcessedSize += m_Pos;\r
+                       int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize);\r
+                       m_Pos = 0;\r
+                       m_Limit = (uint)aNumProcessedBytes;\r
+                       m_StreamWasExhausted = (aNumProcessedBytes == 0);\r
+                       return (!m_StreamWasExhausted);\r
+               }\r
+\r
+\r
+               public void ReleaseStream()\r
+               {\r
+                       // m_Stream.Close(); \r
+                       m_Stream = null;\r
+               }\r
+\r
+               public bool ReadByte(byte b) // check it\r
+               {\r
+                       if (m_Pos >= m_Limit)\r
+                               if (!ReadBlock())\r
+                                       return false;\r
+                       b = m_Buffer[m_Pos++];\r
+                       return true;\r
+               }\r
+\r
+               public byte ReadByte()\r
+               {\r
+                       // return (byte)m_Stream.ReadByte();\r
+                       if (m_Pos >= m_Limit)\r
+                               if (!ReadBlock())\r
+                                       return 0xFF;\r
+                       return m_Buffer[m_Pos++];\r
+               }\r
+\r
+               public ulong GetProcessedSize()\r
+               {\r
+                       return m_ProcessedSize + m_Pos;\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Common/OutBuffer.cs b/CS/7zip/Common/OutBuffer.cs
new file mode 100755 (executable)
index 0000000..c205aa6
--- /dev/null
@@ -0,0 +1,47 @@
+// OutBuffer.cs\r
+\r
+namespace SevenZip.Buffer\r
+{\r
+       public class OutBuffer\r
+       {\r
+               byte[] m_Buffer;\r
+               uint m_Pos;\r
+               uint m_BufferSize;\r
+               System.IO.Stream m_Stream;\r
+               ulong m_ProcessedSize;\r
+\r
+               public OutBuffer(uint bufferSize)\r
+               {\r
+                       m_Buffer = new byte[bufferSize];\r
+                       m_BufferSize = bufferSize;\r
+               }\r
+\r
+               public void SetStream(System.IO.Stream stream) { m_Stream = stream; }\r
+               public void FlushStream() { m_Stream.Flush(); }\r
+               public void CloseStream() { m_Stream.Close(); }\r
+               public void ReleaseStream() { m_Stream = null; }\r
+\r
+               public void Init()\r
+               {\r
+                       m_ProcessedSize = 0;\r
+                       m_Pos = 0;\r
+               }\r
+\r
+               public void WriteByte(byte b)\r
+               {\r
+                       m_Buffer[m_Pos++] = b;\r
+                       if (m_Pos >= m_BufferSize)\r
+                               FlushData();\r
+               }\r
+\r
+               public void FlushData()\r
+               {\r
+                       if (m_Pos == 0)\r
+                               return;\r
+                       m_Stream.Write(m_Buffer, 0, (int)m_Pos);\r
+                       m_Pos = 0;\r
+               }\r
+\r
+               public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LZ/IMatchFinder.cs b/CS/7zip/Compress/LZ/IMatchFinder.cs
new file mode 100755 (executable)
index 0000000..30fab86
--- /dev/null
@@ -0,0 +1,24 @@
+// IMatchFinder.cs\r
+\r
+using System;\r
+\r
+namespace SevenZip.Compression.LZ\r
+{\r
+       interface IInWindowStream\r
+       {\r
+               void SetStream(System.IO.Stream inStream);\r
+               void Init();\r
+               void ReleaseStream();\r
+               Byte GetIndexByte(Int32 index);\r
+               UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit);\r
+               UInt32 GetNumAvailableBytes();\r
+       }\r
+\r
+       interface IMatchFinder : IInWindowStream\r
+       {\r
+               void Create(UInt32 historySize, UInt32 keepAddBufferBefore,\r
+                               UInt32 matchMaxLen, UInt32 keepAddBufferAfter);\r
+               UInt32 GetMatches(UInt32[] distances);\r
+               void Skip(UInt32 num);\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LZ/LzBinTree.cs b/CS/7zip/Compress/LZ/LzBinTree.cs
new file mode 100755 (executable)
index 0000000..7a9ca20
--- /dev/null
@@ -0,0 +1,367 @@
+// LzBinTree.cs\r
+\r
+using System;\r
+\r
+namespace SevenZip.Compression.LZ\r
+{\r
+       public class BinTree : InWindow, IMatchFinder\r
+       {\r
+               UInt32 _cyclicBufferPos;\r
+               UInt32 _cyclicBufferSize = 0;\r
+               UInt32 _matchMaxLen;\r
+\r
+               UInt32[] _son;\r
+               UInt32[] _hash;\r
+\r
+               UInt32 _cutValue = 0xFF;\r
+               UInt32 _hashMask;\r
+               UInt32 _hashSizeSum = 0;\r
+\r
+               bool HASH_ARRAY = true;\r
+\r
+               const UInt32 kHash2Size = 1 << 10;\r
+               const UInt32 kHash3Size = 1 << 16;\r
+               const UInt32 kBT2HashSize = 1 << 16;\r
+               const UInt32 kStartMaxLen = 1;\r
+               const UInt32 kHash3Offset = kHash2Size;\r
+               const UInt32 kEmptyHashValue = 0;\r
+               const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1;\r
+       \r
+               UInt32 kNumHashDirectBytes = 0;\r
+               UInt32 kMinMatchCheck = 4;\r
+               UInt32 kFixHashSize = kHash2Size + kHash3Size;\r
+               \r
+               public void SetType(int numHashBytes)\r
+               {\r
+                       HASH_ARRAY = (numHashBytes > 2);\r
+                       if (HASH_ARRAY)\r
+                       {\r
+                               kNumHashDirectBytes = 0;\r
+                               kMinMatchCheck = 4;\r
+                               kFixHashSize = kHash2Size + kHash3Size;\r
+                       }\r
+                       else\r
+                       {\r
+                               kNumHashDirectBytes = 2;\r
+                               kMinMatchCheck = 2 + 1;\r
+                               kFixHashSize = 0;\r
+                       }\r
+               }\r
+\r
+               public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); }\r
+               public new void ReleaseStream() { base.ReleaseStream(); }\r
+               \r
+               public new void Init()\r
+               {\r
+                       base.Init();\r
+                       for (UInt32 i = 0; i < _hashSizeSum; i++)\r
+                               _hash[i] = kEmptyHashValue;\r
+                       _cyclicBufferPos = 0;\r
+                       ReduceOffsets(-1);\r
+               }\r
+\r
+               public new void MovePos()\r
+               {\r
+                       if (++_cyclicBufferPos >= _cyclicBufferSize)\r
+                               _cyclicBufferPos = 0;\r
+                       base.MovePos();\r
+                       if (_pos == kMaxValForNormalize)\r
+                               Normalize();\r
+               }\r
+\r
+               public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); }\r
+\r
+               public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)\r
+               { return base.GetMatchLen(index, distance, limit); }\r
+\r
+               public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); }\r
+\r
+               public void Create(UInt32 historySize, UInt32 keepAddBufferBefore,\r
+                               UInt32 matchMaxLen, UInt32 keepAddBufferAfter)\r
+               {\r
+                       if (historySize > kMaxValForNormalize - 256)\r
+                               throw new Exception();\r
+                       _cutValue = 16 + (matchMaxLen >> 1);\r
+                               \r
+                       UInt32 windowReservSize = (historySize + keepAddBufferBefore +\r
+                                       matchMaxLen + keepAddBufferAfter) / 2 + 256;\r
+\r
+                       base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);\r
+\r
+                       _matchMaxLen = matchMaxLen;\r
+\r
+                       UInt32 cyclicBufferSize = historySize + 1;\r
+                       if (_cyclicBufferSize != cyclicBufferSize)\r
+                               _son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2];\r
+\r
+                       UInt32 hs = kBT2HashSize;\r
+\r
+                       if (HASH_ARRAY)\r
+                       {\r
+                               hs = historySize - 1;\r
+                               hs |= (hs >> 1);\r
+                               hs |= (hs >> 2);\r
+                               hs |= (hs >> 4);\r
+                               hs |= (hs >> 8);\r
+                               hs >>= 1;\r
+                               hs |= 0xFFFF;\r
+                               if (hs > (1 << 24))\r
+                                       hs >>= 1;\r
+                               _hashMask = hs;\r
+                               hs++;\r
+                               hs += kFixHashSize;\r
+                       }\r
+                       if (hs != _hashSizeSum)\r
+                               _hash = new UInt32[_hashSizeSum = hs];\r
+               }\r
+\r
+               public UInt32 GetMatches(UInt32[] distances)\r
+               {\r
+                       UInt32 lenLimit;\r
+                       if (_pos + _matchMaxLen <= _streamPos)\r
+                               lenLimit = _matchMaxLen;\r
+                       else\r
+                       {\r
+                               lenLimit = _streamPos - _pos;\r
+                               if (lenLimit < kMinMatchCheck)\r
+                               {\r
+                                       MovePos();\r
+                                       return 0;\r
+                               }\r
+                       }\r
+\r
+                       UInt32 offset = 0;\r
+                       UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;\r
+                       UInt32 cur = _bufferOffset + _pos;\r
+                       UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;\r
+                       UInt32 hashValue, hash2Value = 0, hash3Value = 0;\r
+\r
+                       if (HASH_ARRAY)\r
+                       {\r
+                               UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];\r
+                               hash2Value = temp & (kHash2Size - 1);\r
+                               temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);\r
+                               hash3Value = temp & (kHash3Size - 1);\r
+                               hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;\r
+                       }\r
+                       else\r
+                               hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);\r
+\r
+                       UInt32 curMatch = _hash[kFixHashSize + hashValue];\r
+                       if (HASH_ARRAY)\r
+                       {\r
+                               UInt32 curMatch2 = _hash[hash2Value];\r
+                               UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];\r
+                               _hash[hash2Value] = _pos;\r
+                               _hash[kHash3Offset + hash3Value] = _pos;\r
+                               if (curMatch2 > matchMinPos)\r
+                                       if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])\r
+                                       {\r
+                                               distances[offset++] = maxLen = 2;\r
+                                               distances[offset++] = _pos - curMatch2 - 1;\r
+                                       }\r
+                               if (curMatch3 > matchMinPos)\r
+                                       if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])\r
+                                       {\r
+                                               if (curMatch3 == curMatch2)\r
+                                                       offset -= 2;\r
+                                               distances[offset++] = maxLen = 3;\r
+                                               distances[offset++] = _pos - curMatch3 - 1;\r
+                                               curMatch2 = curMatch3;\r
+                                       }\r
+                               if (offset != 0 && curMatch2 == curMatch)\r
+                               {\r
+                                       offset -= 2;\r
+                                       maxLen = kStartMaxLen;\r
+                               }\r
+                       }\r
+\r
+                       _hash[kFixHashSize + hashValue] = _pos;\r
+\r
+                       UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;\r
+                       UInt32 ptr1 = (_cyclicBufferPos << 1);\r
+\r
+                       UInt32 len0, len1;\r
+                       len0 = len1 = kNumHashDirectBytes;\r
+                       \r
+                       if (kNumHashDirectBytes != 0)\r
+                       {\r
+                               if (curMatch > matchMinPos)\r
+                               {\r
+                                       if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=\r
+                                                       _bufferBase[cur + kNumHashDirectBytes])\r
+                                       {\r
+                                               distances[offset++] = maxLen = kNumHashDirectBytes;\r
+                                               distances[offset++] = _pos - curMatch - 1;\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
+                       UInt32 count = _cutValue;\r
+                       \r
+                       while(true)\r
+                       {\r
+                               if(curMatch <= matchMinPos || count-- == 0)\r
+                               {\r
+                                       _son[ptr0] = _son[ptr1] = kEmptyHashValue;\r
+                                       break;\r
+                               }\r
+                               UInt32 delta = _pos - curMatch;\r
+                               UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?\r
+                                                       (_cyclicBufferPos - delta) :\r
+                                                       (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;\r
+\r
+                               UInt32 pby1 = _bufferOffset + curMatch;\r
+                               UInt32 len = Math.Min(len0, len1);\r
+                               if (_bufferBase[pby1 + len] == _bufferBase[cur + len])\r
+                               {\r
+                                       while(++len != lenLimit)\r
+                                               if (_bufferBase[pby1 + len] != _bufferBase[cur + len])\r
+                                                       break;\r
+                                       if (maxLen < len)\r
+                                       {\r
+                                               distances[offset++] = maxLen = len;\r
+                                               distances[offset++] = delta - 1;\r
+                                               if (len == lenLimit)\r
+                                               {\r
+                                                       _son[ptr1] = _son[cyclicPos];\r
+                                                       _son[ptr0] = _son[cyclicPos + 1];\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               if (_bufferBase[pby1 + len] < _bufferBase[cur + len])\r
+                               {\r
+                                       _son[ptr1] = curMatch;\r
+                                       ptr1 = cyclicPos + 1;\r
+                                       curMatch = _son[ptr1];\r
+                                       len1 = len;\r
+                               }\r
+                               else\r
+                               {\r
+                                       _son[ptr0] = curMatch;\r
+                                       ptr0 = cyclicPos;\r
+                                       curMatch = _son[ptr0];\r
+                                       len0 = len;\r
+                               }\r
+                       }\r
+                       MovePos();\r
+                       return offset;\r
+               }\r
+\r
+               public void Skip(UInt32 num)\r
+               {\r
+                       do\r
+                       {\r
+                               UInt32 lenLimit;\r
+                               if (_pos + _matchMaxLen <= _streamPos)\r
+                                       lenLimit = _matchMaxLen;\r
+                               else\r
+                               {\r
+                                       lenLimit = _streamPos - _pos;\r
+                                       if (lenLimit < kMinMatchCheck)\r
+                                       {\r
+                                               MovePos();\r
+                                               continue;\r
+                                       }\r
+                               }\r
+\r
+                               UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;\r
+                               UInt32 cur = _bufferOffset + _pos;\r
+\r
+                               UInt32 hashValue;\r
+\r
+                               if (HASH_ARRAY)\r
+                               {\r
+                                       UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];\r
+                                       UInt32 hash2Value = temp & (kHash2Size - 1);\r
+                                       _hash[hash2Value] = _pos;\r
+                                       temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);\r
+                                       UInt32 hash3Value = temp & (kHash3Size - 1);\r
+                                       _hash[kHash3Offset + hash3Value] = _pos;\r
+                                       hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;\r
+                               }\r
+                               else\r
+                                       hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);\r
+\r
+                               UInt32 curMatch = _hash[kFixHashSize + hashValue];\r
+                               _hash[kFixHashSize + hashValue] = _pos;\r
+\r
+                               UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;\r
+                               UInt32 ptr1 = (_cyclicBufferPos << 1);\r
+\r
+                               UInt32 len0, len1;\r
+                               len0 = len1 = kNumHashDirectBytes;\r
+\r
+                               UInt32 count = _cutValue;\r
+                               while (true)\r
+                               {\r
+                                       if (curMatch <= matchMinPos || count-- == 0)\r
+                                       {\r
+                                               _son[ptr0] = _son[ptr1] = kEmptyHashValue;\r
+                                               break;\r
+                                       }\r
+\r
+                                       UInt32 delta = _pos - curMatch;\r
+                                       UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?\r
+                                                               (_cyclicBufferPos - delta) :\r
+                                                               (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;\r
+\r
+                                       UInt32 pby1 = _bufferOffset + curMatch;\r
+                                       UInt32 len = Math.Min(len0, len1);\r
+                                       if (_bufferBase[pby1 + len] == _bufferBase[cur + len])\r
+                                       {\r
+                                               while (++len != lenLimit)\r
+                                                       if (_bufferBase[pby1 + len] != _bufferBase[cur + len])\r
+                                                               break;\r
+                                               if (len == lenLimit)\r
+                                               {\r
+                                                       _son[ptr1] = _son[cyclicPos];\r
+                                                       _son[ptr0] = _son[cyclicPos + 1];\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       if (_bufferBase[pby1 + len] < _bufferBase[cur + len])\r
+                                       {\r
+                                               _son[ptr1] = curMatch;\r
+                                               ptr1 = cyclicPos + 1;\r
+                                               curMatch = _son[ptr1];\r
+                                               len1 = len;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               _son[ptr0] = curMatch;\r
+                                               ptr0 = cyclicPos;\r
+                                               curMatch = _son[ptr0];\r
+                                               len0 = len;\r
+                                       }\r
+                               }\r
+                               MovePos();\r
+                       }\r
+                       while (--num != 0);\r
+               }\r
+\r
+               void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue)\r
+               {\r
+                       for (UInt32 i = 0; i < numItems; i++)\r
+                       {\r
+                               UInt32 value = items[i];\r
+                               if (value <= subValue)\r
+                                       value = kEmptyHashValue;\r
+                               else\r
+                                       value -= subValue;\r
+                               items[i] = value;\r
+                       }\r
+               }\r
+\r
+               void Normalize()\r
+               {\r
+                       UInt32 subValue = _pos - _cyclicBufferSize;\r
+                       NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);\r
+                       NormalizeLinks(_hash, _hashSizeSum, subValue);\r
+                       ReduceOffsets((Int32)subValue);\r
+               }\r
+\r
+               public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LZ/LzInWindow.cs b/CS/7zip/Compress/LZ/LzInWindow.cs
new file mode 100755 (executable)
index 0000000..f1974ce
--- /dev/null
@@ -0,0 +1,132 @@
+// LzInWindow.cs\r
+\r
+using System;\r
+\r
+namespace SevenZip.Compression.LZ\r
+{\r
+       public class InWindow\r
+       {\r
+               public Byte[] _bufferBase = null; // pointer to buffer with data\r
+               System.IO.Stream _stream;\r
+               UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done\r
+               bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream\r
+\r
+               UInt32 _pointerToLastSafePosition;\r
+\r
+               public UInt32 _bufferOffset;\r
+\r
+               public UInt32 _blockSize; // Size of Allocated memory block\r
+               public UInt32 _pos; // offset (from _buffer) of curent byte\r
+               UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos\r
+               UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos\r
+               public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream\r
+\r
+               public void MoveBlock()\r
+               {\r
+                       UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore;\r
+                       // we need one additional byte, since MovePos moves on 1 byte.\r
+                       if (offset > 0)\r
+                               offset--;\r
+                       \r
+                       UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset;\r
+\r
+                       // check negative offset ????\r
+                       for (UInt32 i = 0; i < numBytes; i++)\r
+                               _bufferBase[i] = _bufferBase[offset + i];\r
+                       _bufferOffset -= offset;\r
+               }\r
+\r
+               public virtual void ReadBlock()\r
+               {\r
+                       if (_streamEndWasReached)\r
+                               return;\r
+                       while (true)\r
+                       {\r
+                               int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos);\r
+                               if (size == 0)\r
+                                       return;\r
+                               int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size);\r
+                               if (numReadBytes == 0)\r
+                               {\r
+                                       _posLimit = _streamPos;\r
+                                       UInt32 pointerToPostion = _bufferOffset + _posLimit;\r
+                                       if (pointerToPostion > _pointerToLastSafePosition)\r
+                                               _posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset);\r
+\r
+                                       _streamEndWasReached = true;\r
+                                       return;\r
+                               }\r
+                               _streamPos += (UInt32)numReadBytes;\r
+                               if (_streamPos >= _pos + _keepSizeAfter)\r
+                                       _posLimit = _streamPos - _keepSizeAfter;\r
+                       }\r
+               }\r
+\r
+               void Free() { _bufferBase = null; }\r
+\r
+               public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)\r
+               {\r
+                       _keepSizeBefore = keepSizeBefore;\r
+                       _keepSizeAfter = keepSizeAfter;\r
+                       UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;\r
+                       if (_bufferBase == null || _blockSize != blockSize)\r
+                       {\r
+                               Free();\r
+                               _blockSize = blockSize;\r
+                               _bufferBase = new Byte[_blockSize];\r
+                       }\r
+                       _pointerToLastSafePosition = _blockSize - keepSizeAfter;\r
+               }\r
+\r
+               public void SetStream(System.IO.Stream stream) { _stream = stream; }\r
+               public void ReleaseStream() { _stream = null; }\r
+\r
+               public void Init()\r
+               {\r
+                       _bufferOffset = 0;\r
+                       _pos = 0;\r
+                       _streamPos = 0;\r
+                       _streamEndWasReached = false;\r
+                       ReadBlock();\r
+               }\r
+\r
+               public void MovePos()\r
+               {\r
+                       _pos++;\r
+                       if (_pos > _posLimit)\r
+                       {\r
+                               UInt32 pointerToPostion = _bufferOffset + _pos;\r
+                               if (pointerToPostion > _pointerToLastSafePosition)\r
+                                       MoveBlock();\r
+                               ReadBlock();\r
+                       }\r
+               }\r
+\r
+               public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; }\r
+\r
+               // index + limit have not to exceed _keepSizeAfter;\r
+               public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)\r
+               {\r
+                       if (_streamEndWasReached)\r
+                               if ((_pos + index) + limit > _streamPos)\r
+                                       limit = _streamPos - (UInt32)(_pos + index);\r
+                       distance++;\r
+                       // Byte *pby = _buffer + (size_t)_pos + index;\r
+                       UInt32 pby = _bufferOffset + _pos + (UInt32)index;\r
+\r
+                       UInt32 i;\r
+                       for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);\r
+                       return i;\r
+               }\r
+\r
+               public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; }\r
+\r
+               public void ReduceOffsets(Int32 subValue)\r
+               {\r
+                       _bufferOffset += (UInt32)subValue;\r
+                       _posLimit -= (UInt32)subValue;\r
+                       _pos -= (UInt32)subValue;\r
+                       _streamPos -= (UInt32)subValue;\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LZ/LzOutWindow.cs b/CS/7zip/Compress/LZ/LzOutWindow.cs
new file mode 100755 (executable)
index 0000000..84914f0
--- /dev/null
@@ -0,0 +1,110 @@
+// LzOutWindow.cs\r
+\r
+namespace SevenZip.Compression.LZ\r
+{\r
+       public class OutWindow\r
+       {\r
+               byte[] _buffer = null;\r
+               uint _pos;\r
+               uint _windowSize = 0;\r
+               uint _streamPos;\r
+               System.IO.Stream _stream;\r
+\r
+               public uint TrainSize = 0;\r
+\r
+               public void Create(uint windowSize)\r
+               {\r
+                       if (_windowSize != windowSize)\r
+                       {\r
+                               // System.GC.Collect();\r
+                               _buffer = new byte[windowSize];\r
+                       }\r
+                       _windowSize = windowSize;\r
+                       _pos = 0;\r
+                       _streamPos = 0;\r
+               }\r
+\r
+               public void Init(System.IO.Stream stream, bool solid)\r
+               {\r
+                       ReleaseStream();\r
+                       _stream = stream;\r
+                       if (!solid)\r
+                       {\r
+                               _streamPos = 0;\r
+                               _pos = 0;\r
+                               TrainSize = 0;\r
+                       }\r
+               }\r
+       \r
+               public bool Train(System.IO.Stream stream)\r
+               {\r
+                       long len = stream.Length;\r
+                       uint size = (len < _windowSize) ? (uint)len : _windowSize;\r
+                       TrainSize = size;\r
+                       stream.Position = len - size;\r
+                       _streamPos = _pos = 0;\r
+                       while (size > 0)\r
+                       {\r
+                               uint curSize = _windowSize - _pos;\r
+                               if (size < curSize)\r
+                                       curSize = size;\r
+                               int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize);\r
+                               if (numReadBytes == 0)\r
+                                       return false;\r
+                               size -= (uint)numReadBytes;\r
+                               _pos += (uint)numReadBytes;\r
+                               _streamPos += (uint)numReadBytes;\r
+                               if (_pos == _windowSize)\r
+                                       _streamPos = _pos = 0;\r
+                       }\r
+                       return true;\r
+               }\r
+\r
+               public void ReleaseStream()\r
+               {\r
+                       Flush();\r
+                       _stream = null;\r
+               }\r
+\r
+               public void Flush()\r
+               {\r
+                       uint size = _pos - _streamPos;\r
+                       if (size == 0)\r
+                               return;\r
+                       _stream.Write(_buffer, (int)_streamPos, (int)size);\r
+                       if (_pos >= _windowSize)\r
+                               _pos = 0;\r
+                       _streamPos = _pos;\r
+               }\r
+\r
+               public void CopyBlock(uint distance, uint len)\r
+               {\r
+                       uint pos = _pos - distance - 1;\r
+                       if (pos >= _windowSize)\r
+                               pos += _windowSize;\r
+                       for (; len > 0; len--)\r
+                       {\r
+                               if (pos >= _windowSize)\r
+                                       pos = 0;\r
+                               _buffer[_pos++] = _buffer[pos++];\r
+                               if (_pos >= _windowSize)\r
+                                       Flush();\r
+                       }\r
+               }\r
+\r
+               public void PutByte(byte b)\r
+               {\r
+                       _buffer[_pos++] = b;\r
+                       if (_pos >= _windowSize)\r
+                               Flush();\r
+               }\r
+\r
+               public byte GetByte(uint distance)\r
+               {\r
+                       uint pos = _pos - distance - 1;\r
+                       if (pos >= _windowSize)\r
+                               pos += _windowSize;\r
+                       return _buffer[pos];\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LZMA/LzmaBase.cs b/CS/7zip/Compress/LZMA/LzmaBase.cs
new file mode 100755 (executable)
index 0000000..8447a2a
--- /dev/null
@@ -0,0 +1,76 @@
+// LzmaBase.cs\r
+\r
+namespace SevenZip.Compression.LZMA\r
+{\r
+       internal abstract class Base\r
+       {\r
+               public const uint kNumRepDistances = 4;\r
+               public const uint kNumStates = 12;\r
+\r
+               // static byte []kLiteralNextStates  = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};\r
+               // static byte []kMatchNextStates    = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};\r
+               // static byte []kRepNextStates      = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};\r
+               // static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};\r
+\r
+               public struct State\r
+               {\r
+                       public uint Index;\r
+                       public void Init() { Index = 0; }\r
+                       public void UpdateChar()\r
+                       {\r
+                               if (Index < 4) Index = 0;\r
+                               else if (Index < 10) Index -= 3;\r
+                               else Index -= 6;\r
+                       }\r
+                       public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); }\r
+                       public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); }\r
+                       public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); }\r
+                       public bool IsCharState() { return Index < 7; }\r
+               }\r
+\r
+               public const int kNumPosSlotBits = 6;\r
+               public const int kDicLogSizeMin = 0;\r
+               // public const int kDicLogSizeMax = 30;\r
+               // public const uint kDistTableSizeMax = kDicLogSizeMax * 2;\r
+\r
+               public const int kNumLenToPosStatesBits = 2; // it's for speed optimization\r
+               public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits;\r
+\r
+               public const uint kMatchMinLen = 2;\r
+\r
+               public static uint GetLenToPosState(uint len)\r
+               {\r
+                       len -= kMatchMinLen;\r
+                       if (len < kNumLenToPosStates)\r
+                               return len;\r
+                       return (uint)(kNumLenToPosStates - 1);\r
+               }\r
+\r
+               public const int kNumAlignBits = 4;\r
+               public const uint kAlignTableSize = 1 << kNumAlignBits;\r
+               public const uint kAlignMask = (kAlignTableSize - 1);\r
+\r
+               public const uint kStartPosModelIndex = 4;\r
+               public const uint kEndPosModelIndex = 14;\r
+               public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;\r
+\r
+               public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2);\r
+\r
+               public const uint kNumLitPosStatesBitsEncodingMax = 4;\r
+               public const uint kNumLitContextBitsMax = 8;\r
+\r
+               public const int kNumPosStatesBitsMax = 4;\r
+               public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax);\r
+               public const int kNumPosStatesBitsEncodingMax = 4;\r
+               public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);\r
+\r
+               public const int kNumLowLenBits = 3;\r
+               public const int kNumMidLenBits = 3;\r
+               public const int kNumHighLenBits = 8;\r
+               public const uint kNumLowLenSymbols = 1 << kNumLowLenBits;\r
+               public const uint kNumMidLenSymbols = 1 << kNumMidLenBits;\r
+               public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +\r
+                               (1 << kNumHighLenBits);\r
+               public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LZMA/LzmaDecoder.cs b/CS/7zip/Compress/LZMA/LzmaDecoder.cs
new file mode 100755 (executable)
index 0000000..00bfe63
--- /dev/null
@@ -0,0 +1,398 @@
+// LzmaDecoder.cs\r
+\r
+using System;\r
+\r
+namespace SevenZip.Compression.LZMA\r
+{\r
+       using RangeCoder;\r
+\r
+       public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream\r
+       {\r
+               class LenDecoder\r
+               {\r
+                       BitDecoder m_Choice = new BitDecoder();\r
+                       BitDecoder m_Choice2 = new BitDecoder();\r
+                       BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];\r
+                       BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];\r
+                       BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);\r
+                       uint m_NumPosStates = 0;\r
+\r
+                       public void Create(uint numPosStates)\r
+                       {\r
+                               for (uint posState = m_NumPosStates; posState < numPosStates; posState++)\r
+                               {\r
+                                       m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);\r
+                                       m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);\r
+                               }\r
+                               m_NumPosStates = numPosStates;\r
+                       }\r
+\r
+                       public void Init()\r
+                       {\r
+                               m_Choice.Init();\r
+                               for (uint posState = 0; posState < m_NumPosStates; posState++)\r
+                               {\r
+                                       m_LowCoder[posState].Init();\r
+                                       m_MidCoder[posState].Init();\r
+                               }\r
+                               m_Choice2.Init();\r
+                               m_HighCoder.Init();\r
+                       }\r
+\r
+                       public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)\r
+                       {\r
+                               if (m_Choice.Decode(rangeDecoder) == 0)\r
+                                       return m_LowCoder[posState].Decode(rangeDecoder);\r
+                               else\r
+                               {\r
+                                       uint symbol = Base.kNumLowLenSymbols;\r
+                                       if (m_Choice2.Decode(rangeDecoder) == 0)\r
+                                               symbol += m_MidCoder[posState].Decode(rangeDecoder);\r
+                                       else\r
+                                       {\r
+                                               symbol += Base.kNumMidLenSymbols;\r
+                                               symbol += m_HighCoder.Decode(rangeDecoder);\r
+                                       }\r
+                                       return symbol;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               class LiteralDecoder\r
+               {\r
+                       struct Decoder2\r
+                       {\r
+                               BitDecoder[] m_Decoders;\r
+                               public void Create() { m_Decoders = new BitDecoder[0x300]; }\r
+                               public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }\r
+\r
+                               public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)\r
+                               {\r
+                                       uint symbol = 1;\r
+                                       do\r
+                                               symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);\r
+                                       while (symbol < 0x100);\r
+                                       return (byte)symbol;\r
+                               }\r
+\r
+                               public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)\r
+                               {\r
+                                       uint symbol = 1;\r
+                                       do\r
+                                       {\r
+                                               uint matchBit = (uint)(matchByte >> 7) & 1;\r
+                                               matchByte <<= 1;\r
+                                               uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);\r
+                                               symbol = (symbol << 1) | bit;\r
+                                               if (matchBit != bit)\r
+                                               {\r
+                                                       while (symbol < 0x100)\r
+                                                               symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       while (symbol < 0x100);\r
+                                       return (byte)symbol;\r
+                               }\r
+                       }\r
+\r
+                       Decoder2[] m_Coders;\r
+                       int m_NumPrevBits;\r
+                       int m_NumPosBits;\r
+                       uint m_PosMask;\r
+\r
+                       public void Create(int numPosBits, int numPrevBits)\r
+                       {\r
+                               if (m_Coders != null && m_NumPrevBits == numPrevBits &&\r
+                                       m_NumPosBits == numPosBits)\r
+                                       return;\r
+                               m_NumPosBits = numPosBits;\r
+                               m_PosMask = ((uint)1 << numPosBits) - 1;\r
+                               m_NumPrevBits = numPrevBits;\r
+                               uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);\r
+                               m_Coders = new Decoder2[numStates];\r
+                               for (uint i = 0; i < numStates; i++)\r
+                                       m_Coders[i].Create();\r
+                       }\r
+\r
+                       public void Init()\r
+                       {\r
+                               uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);\r
+                               for (uint i = 0; i < numStates; i++)\r
+                                       m_Coders[i].Init();\r
+                       }\r
+\r
+                       uint GetState(uint pos, byte prevByte)\r
+                       { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }\r
+\r
+                       public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)\r
+                       { return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }\r
+\r
+                       public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)\r
+                       { return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }\r
+               };\r
+\r
+               LZ.OutWindow m_OutWindow = new LZ.OutWindow();\r
+               RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();\r
+\r
+               BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];\r
+               BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];\r
+               BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];\r
+               BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];\r
+               BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];\r
+               BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];\r
+\r
+               BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];\r
+               BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];\r
+\r
+               BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);\r
+\r
+               LenDecoder m_LenDecoder = new LenDecoder();\r
+               LenDecoder m_RepLenDecoder = new LenDecoder();\r
+\r
+               LiteralDecoder m_LiteralDecoder = new LiteralDecoder();\r
+\r
+               uint m_DictionarySize;\r
+               uint m_DictionarySizeCheck;\r
+\r
+               uint m_PosStateMask;\r
+\r
+               public Decoder()\r
+               {\r
+                       m_DictionarySize = 0xFFFFFFFF;\r
+                       for (int i = 0; i < Base.kNumLenToPosStates; i++)\r
+                               m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);\r
+               }\r
+\r
+               void SetDictionarySize(uint dictionarySize)\r
+               {\r
+                       if (m_DictionarySize != dictionarySize)\r
+                       {\r
+                               m_DictionarySize = dictionarySize;\r
+                               m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);\r
+                               uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));\r
+                               m_OutWindow.Create(blockSize);\r
+                       }\r
+               }\r
+\r
+               void SetLiteralProperties(int lp, int lc)\r
+               {\r
+                       if (lp > 8)\r
+                               throw new InvalidParamException();\r
+                       if (lc > 8)\r
+                               throw new InvalidParamException();\r
+                       m_LiteralDecoder.Create(lp, lc);\r
+               }\r
+\r
+               void SetPosBitsProperties(int pb)\r
+               {\r
+                       if (pb > Base.kNumPosStatesBitsMax)\r
+                               throw new InvalidParamException();\r
+                       uint numPosStates = (uint)1 << pb;\r
+                       m_LenDecoder.Create(numPosStates);\r
+                       m_RepLenDecoder.Create(numPosStates);\r
+                       m_PosStateMask = numPosStates - 1;\r
+               }\r
+\r
+               bool _solid = false;\r
+               void Init(System.IO.Stream inStream, System.IO.Stream outStream)\r
+               {\r
+                       m_RangeDecoder.Init(inStream);\r
+                       m_OutWindow.Init(outStream, _solid);\r
+\r
+                       uint i;\r
+                       for (i = 0; i < Base.kNumStates; i++)\r
+                       {\r
+                               for (uint j = 0; j <= m_PosStateMask; j++)\r
+                               {\r
+                                       uint index = (i << Base.kNumPosStatesBitsMax) + j;\r
+                                       m_IsMatchDecoders[index].Init();\r
+                                       m_IsRep0LongDecoders[index].Init();\r
+                               }\r
+                               m_IsRepDecoders[i].Init();\r
+                               m_IsRepG0Decoders[i].Init();\r
+                               m_IsRepG1Decoders[i].Init();\r
+                               m_IsRepG2Decoders[i].Init();\r
+                       }\r
+\r
+                       m_LiteralDecoder.Init();\r
+                       for (i = 0; i < Base.kNumLenToPosStates; i++)\r
+                               m_PosSlotDecoder[i].Init();\r
+                       // m_PosSpecDecoder.Init();\r
+                       for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)\r
+                               m_PosDecoders[i].Init();\r
+\r
+                       m_LenDecoder.Init();\r
+                       m_RepLenDecoder.Init();\r
+                       m_PosAlignDecoder.Init();\r
+               }\r
+\r
+               public void Code(System.IO.Stream inStream, System.IO.Stream outStream,\r
+                       Int64 inSize, Int64 outSize, ICodeProgress progress)\r
+               {\r
+                       Init(inStream, outStream);\r
+\r
+                       Base.State state = new Base.State();\r
+                       state.Init();\r
+                       uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;\r
+\r
+                       UInt64 nowPos64 = 0;\r
+                       UInt64 outSize64 = (UInt64)outSize;\r
+                       if (nowPos64 < outSize64)\r
+                       {\r
+                               if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)\r
+                                       throw new DataErrorException();\r
+                               state.UpdateChar();\r
+                               byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);\r
+                               m_OutWindow.PutByte(b);\r
+                               nowPos64++;\r
+                       }\r
+                       while (nowPos64 < outSize64)\r
+                       {\r
+                               // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);\r
+                                       // while(nowPos64 < next)\r
+                               {\r
+                                       uint posState = (uint)nowPos64 & m_PosStateMask;\r
+                                       if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)\r
+                                       {\r
+                                               byte b;\r
+                                               byte prevByte = m_OutWindow.GetByte(0);\r
+                                               if (!state.IsCharState())\r
+                                                       b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,\r
+                                                               (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));\r
+                                               else\r
+                                                       b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);\r
+                                               m_OutWindow.PutByte(b);\r
+                                               state.UpdateChar();\r
+                                               nowPos64++;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               uint len;\r
+                                               if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)\r
+                                               {\r
+                                                       if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)\r
+                                                       {\r
+                                                               if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)\r
+                                                               {\r
+                                                                       state.UpdateShortRep();\r
+                                                                       m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));\r
+                                                                       nowPos64++;\r
+                                                                       continue;\r
+                                                               }\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               UInt32 distance;\r
+                                                               if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)\r
+                                                               {\r
+                                                                       distance = rep1;\r
+                                                               }\r
+                                                               else\r
+                                                               {\r
+                                                                       if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)\r
+                                                                               distance = rep2;\r
+                                                                       else\r
+                                                                       {\r
+                                                                               distance = rep3;\r
+                                                                               rep3 = rep2;\r
+                                                                       }\r
+                                                                       rep2 = rep1;\r
+                                                               }\r
+                                                               rep1 = rep0;\r
+                                                               rep0 = distance;\r
+                                                       }\r
+                                                       len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;\r
+                                                       state.UpdateRep();\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       rep3 = rep2;\r
+                                                       rep2 = rep1;\r
+                                                       rep1 = rep0;\r
+                                                       len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);\r
+                                                       state.UpdateMatch();\r
+                                                       uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);\r
+                                                       if (posSlot >= Base.kStartPosModelIndex)\r
+                                                       {\r
+                                                               int numDirectBits = (int)((posSlot >> 1) - 1);\r
+                                                               rep0 = ((2 | (posSlot & 1)) << numDirectBits);\r
+                                                               if (posSlot < Base.kEndPosModelIndex)\r
+                                                                       rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,\r
+                                                                                       rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);\r
+                                                               else\r
+                                                               {\r
+                                                                       rep0 += (m_RangeDecoder.DecodeDirectBits(\r
+                                                                               numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);\r
+                                                                       rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);\r
+                                                               }\r
+                                                       }\r
+                                                       else\r
+                                                               rep0 = posSlot;\r
+                                               }\r
+                                               if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)\r
+                                               {\r
+                                                       if (rep0 == 0xFFFFFFFF)\r
+                                                               break;\r
+                                                       throw new DataErrorException();\r
+                                               }\r
+                                               m_OutWindow.CopyBlock(rep0, len);\r
+                                               nowPos64 += len;\r
+                                       }\r
+                               }\r
+                       }\r
+                       m_OutWindow.Flush();\r
+                       m_OutWindow.ReleaseStream();\r
+                       m_RangeDecoder.ReleaseStream();\r
+               }\r
+\r
+               public void SetDecoderProperties(byte[] properties)\r
+               {\r
+                       if (properties.Length < 5)\r
+                               throw new InvalidParamException();\r
+                       int lc = properties[0] % 9;\r
+                       int remainder = properties[0] / 9;\r
+                       int lp = remainder % 5;\r
+                       int pb = remainder / 5;\r
+                       if (pb > Base.kNumPosStatesBitsMax)\r
+                               throw new InvalidParamException();\r
+                       UInt32 dictionarySize = 0;\r
+                       for (int i = 0; i < 4; i++)\r
+                               dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);\r
+                       SetDictionarySize(dictionarySize);\r
+                       SetLiteralProperties(lp, lc);\r
+                       SetPosBitsProperties(pb);\r
+               }\r
+\r
+               public bool Train(System.IO.Stream stream)\r
+               {\r
+                       _solid = true;\r
+                       return m_OutWindow.Train(stream);\r
+               }\r
+\r
+               /*\r
+               public override bool CanRead { get { return true; }}\r
+               public override bool CanWrite { get { return true; }}\r
+               public override bool CanSeek { get { return true; }}\r
+               public override long Length { get { return 0; }}\r
+               public override long Position\r
+               {\r
+                       get { return 0; }\r
+                       set { }\r
+               }\r
+               public override void Flush() { }\r
+               public override int Read(byte[] buffer, int offset, int count) \r
+               {\r
+                       return 0;\r
+               }\r
+               public override void Write(byte[] buffer, int offset, int count)\r
+               {\r
+               }\r
+               public override long Seek(long offset, System.IO.SeekOrigin origin)\r
+               {\r
+                       return 0;\r
+               }\r
+               public override void SetLength(long value) {}\r
+               */\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LZMA/LzmaEncoder.cs b/CS/7zip/Compress/LZMA/LzmaEncoder.cs
new file mode 100755 (executable)
index 0000000..6dc2708
--- /dev/null
@@ -0,0 +1,1480 @@
+// LzmaEncoder.cs\r
+\r
+using System;\r
+\r
+namespace SevenZip.Compression.LZMA\r
+{\r
+       using RangeCoder;\r
+\r
+       public class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties\r
+       {\r
+               enum EMatchFinderType\r
+               {\r
+                       BT2,\r
+                       BT4,\r
+               };\r
+\r
+               const UInt32 kIfinityPrice = 0xFFFFFFF;\r
+\r
+               static Byte[] g_FastPos = new Byte[1 << 11];\r
+\r
+               static Encoder()\r
+               {\r
+                       const Byte kFastSlots = 22;\r
+                       int c = 2;\r
+                       g_FastPos[0] = 0;\r
+                       g_FastPos[1] = 1;\r
+                       for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)\r
+                       {\r
+                               UInt32 k = ((UInt32)1 << ((slotFast >> 1) - 1));\r
+                               for (UInt32 j = 0; j < k; j++, c++)\r
+                                       g_FastPos[c] = slotFast;\r
+                       }\r
+               }\r
+\r
+               static UInt32 GetPosSlot(UInt32 pos)\r
+               {\r
+                       if (pos < (1 << 11))\r
+                               return g_FastPos[pos];\r
+                       if (pos < (1 << 21))\r
+                               return (UInt32)(g_FastPos[pos >> 10] + 20);\r
+                       return (UInt32)(g_FastPos[pos >> 20] + 40);\r
+               }\r
+\r
+               static UInt32 GetPosSlot2(UInt32 pos)\r
+               {\r
+                       if (pos < (1 << 17))\r
+                               return (UInt32)(g_FastPos[pos >> 6] + 12);\r
+                       if (pos < (1 << 27))\r
+                               return (UInt32)(g_FastPos[pos >> 16] + 32);\r
+                       return (UInt32)(g_FastPos[pos >> 26] + 52);\r
+               }\r
+\r
+               Base.State _state = new Base.State();\r
+               Byte _previousByte;\r
+               UInt32[] _repDistances = new UInt32[Base.kNumRepDistances];\r
+\r
+               void BaseInit()\r
+               {\r
+                       _state.Init();\r
+                       _previousByte = 0;\r
+                       for (UInt32 i = 0; i < Base.kNumRepDistances; i++)\r
+                               _repDistances[i] = 0;\r
+               }\r
+\r
+               const int kDefaultDictionaryLogSize = 22;\r
+               const UInt32 kNumFastBytesDefault = 0x20;\r
+\r
+               class LiteralEncoder\r
+               {\r
+                       public struct Encoder2\r
+                       {\r
+                               BitEncoder[] m_Encoders;\r
+\r
+                               public void Create() { m_Encoders = new BitEncoder[0x300]; }\r
+\r
+                               public void Init() { for (int i = 0; i < 0x300; i++) m_Encoders[i].Init(); }\r
+\r
+                               public void Encode(RangeCoder.Encoder rangeEncoder, byte symbol)\r
+                               {\r
+                                       uint context = 1;\r
+                                       for (int i = 7; i >= 0; i--)\r
+                                       {\r
+                                               uint bit = (uint)((symbol >> i) & 1);\r
+                                               m_Encoders[context].Encode(rangeEncoder, bit);\r
+                                               context = (context << 1) | bit;\r
+                                       }\r
+                               }\r
+\r
+                               public void EncodeMatched(RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol)\r
+                               {\r
+                                       uint context = 1;\r
+                                       bool same = true;\r
+                                       for (int i = 7; i >= 0; i--)\r
+                                       {\r
+                                               uint bit = (uint)((symbol >> i) & 1);\r
+                                               uint state = context;\r
+                                               if (same)\r
+                                               {\r
+                                                       uint matchBit = (uint)((matchByte >> i) & 1);\r
+                                                       state += ((1 + matchBit) << 8);\r
+                                                       same = (matchBit == bit);\r
+                                               }\r
+                                               m_Encoders[state].Encode(rangeEncoder, bit);\r
+                                               context = (context << 1) | bit;\r
+                                       }\r
+                               }\r
+\r
+                               public uint GetPrice(bool matchMode, byte matchByte, byte symbol)\r
+                               {\r
+                                       uint price = 0;\r
+                                       uint context = 1;\r
+                                       int i = 7;\r
+                                       if (matchMode)\r
+                                       {\r
+                                               for (; i >= 0; i--)\r
+                                               {\r
+                                                       uint matchBit = (uint)(matchByte >> i) & 1;\r
+                                                       uint bit = (uint)(symbol >> i) & 1;\r
+                                                       price += m_Encoders[((1 + matchBit) << 8) + context].GetPrice(bit);\r
+                                                       context = (context << 1) | bit;\r
+                                                       if (matchBit != bit)\r
+                                                       {\r
+                                                               i--;\r
+                                                               break;\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       for (; i >= 0; i--)\r
+                                       {\r
+                                               uint bit = (uint)(symbol >> i) & 1;\r
+                                               price += m_Encoders[context].GetPrice(bit);\r
+                                               context = (context << 1) | bit;\r
+                                       }\r
+                                       return price;\r
+                               }\r
+                       }\r
+\r
+                       Encoder2[] m_Coders;\r
+                       int m_NumPrevBits;\r
+                       int m_NumPosBits;\r
+                       uint m_PosMask;\r
+\r
+                       public void Create(int numPosBits, int numPrevBits)\r
+                       {\r
+                               if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)\r
+                                       return;\r
+                               m_NumPosBits = numPosBits;\r
+                               m_PosMask = ((uint)1 << numPosBits) - 1;\r
+                               m_NumPrevBits = numPrevBits;\r
+                               uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);\r
+                               m_Coders = new Encoder2[numStates];\r
+                               for (uint i = 0; i < numStates; i++)\r
+                                       m_Coders[i].Create();\r
+                       }\r
+\r
+                       public void Init()\r
+                       {\r
+                               uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);\r
+                               for (uint i = 0; i < numStates; i++)\r
+                                       m_Coders[i].Init();\r
+                       }\r
+\r
+                       public Encoder2 GetSubCoder(UInt32 pos, Byte prevByte)\r
+                       { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits))]; }\r
+               }\r
+\r
+               class LenEncoder\r
+               {\r
+                       RangeCoder.BitEncoder _choice = new RangeCoder.BitEncoder();\r
+                       RangeCoder.BitEncoder _choice2 = new RangeCoder.BitEncoder();\r
+                       RangeCoder.BitTreeEncoder[] _lowCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax];\r
+                       RangeCoder.BitTreeEncoder[] _midCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax];\r
+                       RangeCoder.BitTreeEncoder _highCoder = new RangeCoder.BitTreeEncoder(Base.kNumHighLenBits);\r
+\r
+                       public LenEncoder()\r
+                       {\r
+                               for (UInt32 posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)\r
+                               {\r
+                                       _lowCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumLowLenBits);\r
+                                       _midCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumMidLenBits);\r
+                               }\r
+                       }\r
+\r
+                       public void Init(UInt32 numPosStates)\r
+                       {\r
+                               _choice.Init();\r
+                               _choice2.Init();\r
+                               for (UInt32 posState = 0; posState < numPosStates; posState++)\r
+                               {\r
+                                       _lowCoder[posState].Init();\r
+                                       _midCoder[posState].Init();\r
+                               }\r
+                               _highCoder.Init();\r
+                       }\r
+\r
+                       public void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)\r
+                       {\r
+                               if (symbol < Base.kNumLowLenSymbols)\r
+                               {\r
+                                       _choice.Encode(rangeEncoder, 0);\r
+                                       _lowCoder[posState].Encode(rangeEncoder, symbol);\r
+                               }\r
+                               else\r
+                               {\r
+                                       symbol -= Base.kNumLowLenSymbols;\r
+                                       _choice.Encode(rangeEncoder, 1);\r
+                                       if (symbol < Base.kNumMidLenSymbols)\r
+                                       {\r
+                                               _choice2.Encode(rangeEncoder, 0);\r
+                                               _midCoder[posState].Encode(rangeEncoder, symbol);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               _choice2.Encode(rangeEncoder, 1);\r
+                                               _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       public void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32[] prices, UInt32 st)\r
+                       {\r
+                               UInt32 a0 = _choice.GetPrice0();\r
+                               UInt32 a1 = _choice.GetPrice1();\r
+                               UInt32 b0 = a1 + _choice2.GetPrice0();\r
+                               UInt32 b1 = a1 + _choice2.GetPrice1();\r
+                               UInt32 i = 0;\r
+                               for (i = 0; i < Base.kNumLowLenSymbols; i++)\r
+                               {\r
+                                       if (i >= numSymbols)\r
+                                               return;\r
+                                       prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);\r
+                               }\r
+                               for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)\r
+                               {\r
+                                       if (i >= numSymbols)\r
+                                               return;\r
+                                       prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);\r
+                               }\r
+                               for (; i < numSymbols; i++)\r
+                                       prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);\r
+                       }\r
+               };\r
+\r
+               const UInt32 kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;\r
+\r
+               class LenPriceTableEncoder : LenEncoder\r
+               {\r
+                       UInt32[] _prices = new UInt32[Base.kNumLenSymbols << Base.kNumPosStatesBitsEncodingMax];\r
+                       UInt32 _tableSize;\r
+                       UInt32[] _counters = new UInt32[Base.kNumPosStatesEncodingMax];\r
+\r
+                       public void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }\r
+\r
+                       public UInt32 GetPrice(UInt32 symbol, UInt32 posState)\r
+                       {\r
+                               return _prices[posState * Base.kNumLenSymbols + symbol];\r
+                       }\r
+\r
+                       void UpdateTable(UInt32 posState)\r
+                       {\r
+                               SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);\r
+                               _counters[posState] = _tableSize;\r
+                       }\r
+\r
+                       public void UpdateTables(UInt32 numPosStates)\r
+                       {\r
+                               for (UInt32 posState = 0; posState < numPosStates; posState++)\r
+                                       UpdateTable(posState);\r
+                       }\r
+\r
+                       public new void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)\r
+                       {\r
+                               base.Encode(rangeEncoder, symbol, posState);\r
+                               if (--_counters[posState] == 0)\r
+                                       UpdateTable(posState);\r
+                       }\r
+               }\r
+\r
+               const UInt32 kNumOpts = 1 << 12;\r
+               class Optimal\r
+               {\r
+                       public Base.State State;\r
+\r
+                       public bool Prev1IsChar;\r
+                       public bool Prev2;\r
+\r
+                       public UInt32 PosPrev2;\r
+                       public UInt32 BackPrev2;\r
+\r
+                       public UInt32 Price;\r
+                       public UInt32 PosPrev;\r
+                       public UInt32 BackPrev;\r
+\r
+                       public UInt32 Backs0;\r
+                       public UInt32 Backs1;\r
+                       public UInt32 Backs2;\r
+                       public UInt32 Backs3;\r
+\r
+                       public void MakeAsChar() { BackPrev = 0xFFFFFFFF; Prev1IsChar = false; }\r
+                       public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }\r
+                       public bool IsShortRep() { return (BackPrev == 0); }\r
+               };\r
+               Optimal[] _optimum = new Optimal[kNumOpts];\r
+               LZ.IMatchFinder _matchFinder = null;\r
+               RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder();\r
+\r
+               RangeCoder.BitEncoder[] _isMatch = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax];\r
+               RangeCoder.BitEncoder[] _isRep = new RangeCoder.BitEncoder[Base.kNumStates];\r
+               RangeCoder.BitEncoder[] _isRepG0 = new RangeCoder.BitEncoder[Base.kNumStates];\r
+               RangeCoder.BitEncoder[] _isRepG1 = new RangeCoder.BitEncoder[Base.kNumStates];\r
+               RangeCoder.BitEncoder[] _isRepG2 = new RangeCoder.BitEncoder[Base.kNumStates];\r
+               RangeCoder.BitEncoder[] _isRep0Long = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax];\r
+\r
+               RangeCoder.BitTreeEncoder[] _posSlotEncoder = new RangeCoder.BitTreeEncoder[Base.kNumLenToPosStates];\r
+               \r
+               RangeCoder.BitEncoder[] _posEncoders = new RangeCoder.BitEncoder[Base.kNumFullDistances - Base.kEndPosModelIndex];\r
+               RangeCoder.BitTreeEncoder _posAlignEncoder = new RangeCoder.BitTreeEncoder(Base.kNumAlignBits);\r
+\r
+               LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();\r
+               LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();\r
+\r
+               LiteralEncoder _literalEncoder = new LiteralEncoder();\r
+\r
+               UInt32[] _matchDistances = new UInt32[Base.kMatchMaxLen * 2 + 2];\r
+               \r
+               UInt32 _numFastBytes = kNumFastBytesDefault;\r
+               UInt32 _longestMatchLength;\r
+               UInt32 _numDistancePairs;\r
+\r
+               UInt32 _additionalOffset;\r
+\r
+               UInt32 _optimumEndIndex;\r
+               UInt32 _optimumCurrentIndex;\r
+\r
+               bool _longestMatchWasFound;\r
+\r
+               UInt32[] _posSlotPrices = new UInt32[1 << (Base.kNumPosSlotBits + Base.kNumLenToPosStatesBits)];\r
+               UInt32[] _distancesPrices = new UInt32[Base.kNumFullDistances << Base.kNumLenToPosStatesBits];\r
+               UInt32[] _alignPrices = new UInt32[Base.kAlignTableSize];\r
+               UInt32 _alignPriceCount;\r
+\r
+               UInt32 _distTableSize = (kDefaultDictionaryLogSize * 2);\r
+\r
+               int _posStateBits = 2;\r
+               UInt32 _posStateMask = (4 - 1);\r
+               int _numLiteralPosStateBits = 0;\r
+               int _numLiteralContextBits = 3;\r
+\r
+               UInt32 _dictionarySize = (1 << kDefaultDictionaryLogSize);\r
+               UInt32 _dictionarySizePrev = 0xFFFFFFFF;\r
+               UInt32 _numFastBytesPrev = 0xFFFFFFFF;\r
+\r
+               Int64 nowPos64;\r
+               bool _finished;\r
+               System.IO.Stream _inStream;\r
+\r
+               EMatchFinderType _matchFinderType = EMatchFinderType.BT4;\r
+               bool _writeEndMark = false;\r
+               \r
+               bool _needReleaseMFStream;\r
+\r
+               void Create()\r
+               {\r
+                       if (_matchFinder == null)\r
+                       {\r
+                               LZ.BinTree bt = new LZ.BinTree();\r
+                               int numHashBytes = 4;\r
+                               if (_matchFinderType == EMatchFinderType.BT2)\r
+                                       numHashBytes = 2;\r
+                               bt.SetType(numHashBytes);\r
+                               _matchFinder = bt;\r
+                       }\r
+                       _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);\r
+\r
+                       if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)\r
+                               return;\r
+                       _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);\r
+                       _dictionarySizePrev = _dictionarySize;\r
+                       _numFastBytesPrev = _numFastBytes;\r
+               }\r
+\r
+               public Encoder()\r
+               {\r
+                       for (int i = 0; i < kNumOpts; i++)\r
+                               _optimum[i] = new Optimal();\r
+                       for (int i = 0; i < Base.kNumLenToPosStates; i++)\r
+                               _posSlotEncoder[i] = new RangeCoder.BitTreeEncoder(Base.kNumPosSlotBits);\r
+               }\r
+\r
+               void SetWriteEndMarkerMode(bool writeEndMarker)\r
+               {\r
+                       _writeEndMark = writeEndMarker;\r
+               }\r
+\r
+               void Init()\r
+               {\r
+                       BaseInit();\r
+                       _rangeEncoder.Init();\r
+\r
+                       uint i;\r
+                       for (i = 0; i < Base.kNumStates; i++)\r
+                       {\r
+                               for (uint j = 0; j <= _posStateMask; j++)\r
+                               {\r
+                                       uint complexState = (i << Base.kNumPosStatesBitsMax) + j;\r
+                                       _isMatch[complexState].Init();\r
+                                       _isRep0Long[complexState].Init();\r
+                               }\r
+                               _isRep[i].Init();\r
+                               _isRepG0[i].Init();\r
+                               _isRepG1[i].Init();\r
+                               _isRepG2[i].Init();\r
+                       }\r
+                       _literalEncoder.Init();\r
+                       for (i = 0; i < Base.kNumLenToPosStates; i++)\r
+                               _posSlotEncoder[i].Init();\r
+                       for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)\r
+                               _posEncoders[i].Init();\r
+\r
+                       _lenEncoder.Init((UInt32)1 << _posStateBits);\r
+                       _repMatchLenEncoder.Init((UInt32)1 << _posStateBits);\r
+\r
+                       _posAlignEncoder.Init();\r
+\r
+                       _longestMatchWasFound = false;\r
+                       _optimumEndIndex = 0;\r
+                       _optimumCurrentIndex = 0;\r
+                       _additionalOffset = 0;\r
+               }\r
+\r
+               void ReadMatchDistances(out UInt32 lenRes, out UInt32 numDistancePairs)\r
+               {\r
+                       lenRes = 0;\r
+                       numDistancePairs = _matchFinder.GetMatches(_matchDistances);\r
+                       if (numDistancePairs > 0)\r
+                       {\r
+                               lenRes = _matchDistances[numDistancePairs - 2];\r
+                               if (lenRes == _numFastBytes)\r
+                                       lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[numDistancePairs - 1],\r
+                                               Base.kMatchMaxLen - lenRes);\r
+                       }\r
+                       _additionalOffset++;\r
+               }\r
+\r
+\r
+               void MovePos(UInt32 num)\r
+               {\r
+                       if (num > 0)\r
+                       {\r
+                               _matchFinder.Skip(num);\r
+                               _additionalOffset += num;\r
+                       }\r
+               }\r
+\r
+               UInt32 GetRepLen1Price(Base.State state, UInt32 posState)\r
+               {\r
+                       return _isRepG0[state.Index].GetPrice0() +\r
+                                       _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0();\r
+               }\r
+\r
+               UInt32 GetPureRepPrice(UInt32 repIndex, Base.State state, UInt32 posState)\r
+               {\r
+                       UInt32 price;\r
+                       if (repIndex == 0)\r
+                       {\r
+                               price = _isRepG0[state.Index].GetPrice0();\r
+                               price += _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();\r
+                       }\r
+                       else\r
+                       {\r
+                               price = _isRepG0[state.Index].GetPrice1();\r
+                               if (repIndex == 1)\r
+                                       price += _isRepG1[state.Index].GetPrice0();\r
+                               else\r
+                               {\r
+                                       price += _isRepG1[state.Index].GetPrice1();\r
+                                       price += _isRepG2[state.Index].GetPrice(repIndex - 2);\r
+                               }\r
+                       }\r
+                       return price;\r
+               }\r
+\r
+               UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, Base.State state, UInt32 posState)\r
+               {\r
+                       UInt32 price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);\r
+                       return price + GetPureRepPrice(repIndex, state, posState);\r
+               }\r
+       \r
+               UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState)\r
+               {\r
+                       UInt32 price;\r
+                       UInt32 lenToPosState = Base.GetLenToPosState(len);\r
+                       if (pos < Base.kNumFullDistances)\r
+                               price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];\r
+                       else\r
+                               price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] +\r
+                                       _alignPrices[pos & Base.kAlignMask];\r
+                       return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);\r
+               }\r
+\r
+               UInt32 Backward(out UInt32 backRes, UInt32 cur)\r
+               {\r
+                       _optimumEndIndex = cur;\r
+                       UInt32 posMem = _optimum[cur].PosPrev;\r
+                       UInt32 backMem = _optimum[cur].BackPrev;\r
+                       do\r
+                       {\r
+                               if (_optimum[cur].Prev1IsChar)\r
+                               {\r
+                                       _optimum[posMem].MakeAsChar();\r
+                                       _optimum[posMem].PosPrev = posMem - 1;\r
+                                       if (_optimum[cur].Prev2)\r
+                                       {\r
+                                               _optimum[posMem - 1].Prev1IsChar = false;\r
+                                               _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;\r
+                                               _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;\r
+                                       }\r
+                               }\r
+                               UInt32 posPrev = posMem;\r
+                               UInt32 backCur = backMem;\r
+\r
+                               backMem = _optimum[posPrev].BackPrev;\r
+                               posMem = _optimum[posPrev].PosPrev;\r
+\r
+                               _optimum[posPrev].BackPrev = backCur;\r
+                               _optimum[posPrev].PosPrev = cur;\r
+                               cur = posPrev;\r
+                       }\r
+                       while (cur > 0);\r
+                       backRes = _optimum[0].BackPrev;\r
+                       _optimumCurrentIndex = _optimum[0].PosPrev;\r
+                       return _optimumCurrentIndex;\r
+               }\r
+\r
+               UInt32[] reps = new UInt32[Base.kNumRepDistances];\r
+               UInt32[] repLens = new UInt32[Base.kNumRepDistances];\r
+\r
+\r
+               UInt32 GetOptimum(UInt32 position, out UInt32 backRes)\r
+               {\r
+                       if (_optimumEndIndex != _optimumCurrentIndex)\r
+                       {\r
+                               UInt32 lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;\r
+                               backRes = _optimum[_optimumCurrentIndex].BackPrev;\r
+                               _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;\r
+                               return lenRes;\r
+                       }\r
+                       _optimumCurrentIndex = _optimumEndIndex = 0;\r
+\r
+                       UInt32 lenMain, numDistancePairs;\r
+                       if (!_longestMatchWasFound)\r
+                       {\r
+                               ReadMatchDistances(out lenMain, out numDistancePairs);\r
+                       }\r
+                       else\r
+                       {\r
+                               lenMain = _longestMatchLength;\r
+                               numDistancePairs = _numDistancePairs;\r
+                               _longestMatchWasFound = false;\r
+                       }\r
+\r
+                       UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;\r
+                       if (numAvailableBytes < 2)\r
+                       {\r
+                               backRes = 0xFFFFFFFF;\r
+                               return 1;\r
+                       }\r
+                       if (numAvailableBytes > Base.kMatchMaxLen)\r
+                               numAvailableBytes = Base.kMatchMaxLen;\r
+\r
+                       UInt32 repMaxIndex = 0;\r
+                       UInt32 i;                       \r
+                       for (i = 0; i < Base.kNumRepDistances; i++)\r
+                       {\r
+                               reps[i] = _repDistances[i];\r
+                               repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);\r
+                               if (repLens[i] > repLens[repMaxIndex])\r
+                                       repMaxIndex = i;\r
+                       }\r
+                       if (repLens[repMaxIndex] >= _numFastBytes)\r
+                       {\r
+                               backRes = repMaxIndex;\r
+                               UInt32 lenRes = repLens[repMaxIndex];\r
+                               MovePos(lenRes - 1);\r
+                               return lenRes;\r
+                       }\r
+\r
+                       if (lenMain >= _numFastBytes)\r
+                       {\r
+                               backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;\r
+                               MovePos(lenMain - 1);\r
+                               return lenMain;\r
+                       }\r
+                       \r
+                       Byte currentByte = _matchFinder.GetIndexByte(0 - 1);\r
+                       Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - 1));\r
+\r
+                       if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)\r
+                       {\r
+                               backRes = (UInt32)0xFFFFFFFF;\r
+                               return 1;\r
+                       }\r
+\r
+                       _optimum[0].State = _state;\r
+\r
+                       UInt32 posState = (position & _posStateMask);\r
+\r
+                       _optimum[1].Price = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() +\r
+                                       _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!_state.IsCharState(), matchByte, currentByte);\r
+                       _optimum[1].MakeAsChar();\r
+\r
+                       UInt32 matchPrice = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();\r
+                       UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();\r
+\r
+                       if (matchByte == currentByte)\r
+                       {\r
+                               UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);\r
+                               if (shortRepPrice < _optimum[1].Price)\r
+                               {\r
+                                       _optimum[1].Price = shortRepPrice;\r
+                                       _optimum[1].MakeAsShortRep();\r
+                               }\r
+                       }\r
+\r
+                       UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);\r
+\r
+                       if(lenEnd < 2)\r
+                       {\r
+                               backRes = _optimum[1].BackPrev;\r
+                               return 1;\r
+                       }\r
+                       \r
+                       _optimum[1].PosPrev = 0;\r
+\r
+                       _optimum[0].Backs0 = reps[0];\r
+                       _optimum[0].Backs1 = reps[1];\r
+                       _optimum[0].Backs2 = reps[2];\r
+                       _optimum[0].Backs3 = reps[3];\r
+\r
+                       UInt32 len = lenEnd;\r
+                       do\r
+                               _optimum[len--].Price = kIfinityPrice;\r
+                       while (len >= 2);\r
+\r
+                       for (i = 0; i < Base.kNumRepDistances; i++)\r
+                       {\r
+                               UInt32 repLen = repLens[i];\r
+                               if (repLen < 2)\r
+                                       continue;\r
+                               UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);\r
+                               do\r
+                               {\r
+                                       UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);\r
+                                       Optimal optimum = _optimum[repLen];\r
+                                       if (curAndLenPrice < optimum.Price)\r
+                                       {\r
+                                               optimum.Price = curAndLenPrice;\r
+                                               optimum.PosPrev = 0;\r
+                                               optimum.BackPrev = i;\r
+                                               optimum.Prev1IsChar = false;\r
+                                       }\r
+                               }\r
+                               while (--repLen >= 2);\r
+                       }\r
+\r
+                       UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();\r
+                       \r
+                       len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);\r
+                       if (len <= lenMain)\r
+                       {\r
+                               UInt32 offs = 0;\r
+                               while (len > _matchDistances[offs])\r
+                                       offs += 2;\r
+                               for (; ; len++)\r
+                               {\r
+                                       UInt32 distance = _matchDistances[offs + 1];\r
+                                       UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);\r
+                                       Optimal optimum = _optimum[len];\r
+                                       if (curAndLenPrice < optimum.Price)\r
+                                       {\r
+                                               optimum.Price = curAndLenPrice;\r
+                                               optimum.PosPrev = 0;\r
+                                               optimum.BackPrev = distance + Base.kNumRepDistances;\r
+                                               optimum.Prev1IsChar = false;\r
+                                       }\r
+                                       if (len == _matchDistances[offs])\r
+                                       {\r
+                                               offs += 2;\r
+                                               if (offs == numDistancePairs)\r
+                                                       break;\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       UInt32 cur = 0;\r
+\r
+                       while (true)\r
+                       {\r
+                               cur++;\r
+                               if (cur == lenEnd)\r
+                                       return Backward(out backRes, cur);\r
+                               UInt32 newLen;\r
+                               ReadMatchDistances(out newLen, out numDistancePairs);\r
+                               if (newLen >= _numFastBytes)\r
+                               {\r
+                                       _numDistancePairs = numDistancePairs;\r
+                                       _longestMatchLength = newLen;\r
+                                       _longestMatchWasFound = true;\r
+                                       return Backward(out backRes, cur);\r
+                               }\r
+                               position++;\r
+                               UInt32 posPrev = _optimum[cur].PosPrev;\r
+                               Base.State state;\r
+                               if (_optimum[cur].Prev1IsChar)\r
+                               {\r
+                                       posPrev--;\r
+                                       if (_optimum[cur].Prev2)\r
+                                       {\r
+                                               state = _optimum[_optimum[cur].PosPrev2].State;\r
+                                               if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)\r
+                                                       state.UpdateRep();\r
+                                               else\r
+                                                       state.UpdateMatch();\r
+                                       }\r
+                                       else\r
+                                               state = _optimum[posPrev].State;\r
+                                       state.UpdateChar();\r
+                               }\r
+                               else\r
+                                       state = _optimum[posPrev].State;\r
+                               if (posPrev == cur - 1)\r
+                               {\r
+                                       if (_optimum[cur].IsShortRep())\r
+                                               state.UpdateShortRep();\r
+                                       else\r
+                                               state.UpdateChar();\r
+                               }\r
+                               else\r
+                               {\r
+                                       UInt32 pos;\r
+                                       if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)\r
+                                       {\r
+                                               posPrev = _optimum[cur].PosPrev2;\r
+                                               pos = _optimum[cur].BackPrev2;\r
+                                               state.UpdateRep();\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               pos = _optimum[cur].BackPrev;\r
+                                               if (pos < Base.kNumRepDistances)\r
+                                                       state.UpdateRep();\r
+                                               else\r
+                                                       state.UpdateMatch();\r
+                                       }\r
+                                       Optimal opt = _optimum[posPrev];\r
+                                       if (pos < Base.kNumRepDistances)\r
+                                       {\r
+                                               if (pos == 0)\r
+                                               {\r
+                                                       reps[0] = opt.Backs0;\r
+                                                       reps[1] = opt.Backs1;\r
+                                                       reps[2] = opt.Backs2;\r
+                                                       reps[3] = opt.Backs3;\r
+                                               }\r
+                                               else if (pos == 1)\r
+                                               {\r
+                                                       reps[0] = opt.Backs1;\r
+                                                       reps[1] = opt.Backs0;\r
+                                                       reps[2] = opt.Backs2;\r
+                                                       reps[3] = opt.Backs3;\r
+                                               }\r
+                                               else if (pos == 2)\r
+                                               {\r
+                                                       reps[0] = opt.Backs2;\r
+                                                       reps[1] = opt.Backs0;\r
+                                                       reps[2] = opt.Backs1;\r
+                                                       reps[3] = opt.Backs3;\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       reps[0] = opt.Backs3;\r
+                                                       reps[1] = opt.Backs0;\r
+                                                       reps[2] = opt.Backs1;\r
+                                                       reps[3] = opt.Backs2;\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               reps[0] = (pos - Base.kNumRepDistances);\r
+                                               reps[1] = opt.Backs0;\r
+                                               reps[2] = opt.Backs1;\r
+                                               reps[3] = opt.Backs2;\r
+                                       }\r
+                               }\r
+                               _optimum[cur].State = state;\r
+                               _optimum[cur].Backs0 = reps[0];\r
+                               _optimum[cur].Backs1 = reps[1];\r
+                               _optimum[cur].Backs2 = reps[2];\r
+                               _optimum[cur].Backs3 = reps[3];\r
+                               UInt32 curPrice = _optimum[cur].Price;\r
+\r
+                               currentByte = _matchFinder.GetIndexByte(0 - 1);\r
+                               matchByte = _matchFinder.GetIndexByte((Int32)(0 - reps[0] - 1 - 1));\r
+\r
+                               posState = (position & _posStateMask);\r
+\r
+                               UInt32 curAnd1Price = curPrice +\r
+                                       _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() +\r
+                                       _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)).\r
+                                       GetPrice(!state.IsCharState(), matchByte, currentByte);\r
+\r
+                               Optimal nextOptimum = _optimum[cur + 1];\r
+\r
+                               bool nextIsChar = false;\r
+                               if (curAnd1Price < nextOptimum.Price)\r
+                               {\r
+                                       nextOptimum.Price = curAnd1Price;\r
+                                       nextOptimum.PosPrev = cur;\r
+                                       nextOptimum.MakeAsChar();\r
+                                       nextIsChar = true;\r
+                               }\r
+\r
+                               matchPrice = curPrice + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();\r
+                               repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();\r
+\r
+                               if (matchByte == currentByte &&\r
+                                       !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))\r
+                               {\r
+                                       UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);\r
+                                       if (shortRepPrice <= nextOptimum.Price)\r
+                                       {\r
+                                               nextOptimum.Price = shortRepPrice;\r
+                                               nextOptimum.PosPrev = cur;\r
+                                               nextOptimum.MakeAsShortRep();\r
+                                               nextIsChar = true;\r
+                                       }\r
+                               }\r
+\r
+                               UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;\r
+                               numAvailableBytesFull = Math.Min(kNumOpts - 1 - cur, numAvailableBytesFull);\r
+                               numAvailableBytes = numAvailableBytesFull;\r
+\r
+                               if (numAvailableBytes < 2)\r
+                                       continue;\r
+                               if (numAvailableBytes > _numFastBytes)\r
+                                       numAvailableBytes = _numFastBytes;\r
+                               if (!nextIsChar && matchByte != currentByte)\r
+                               {\r
+                                       // try Literal + rep0\r
+                                       UInt32 t = Math.Min(numAvailableBytesFull - 1, _numFastBytes);\r
+                                       UInt32 lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);\r
+                                       if (lenTest2 >= 2)\r
+                                       {\r
+                                               Base.State state2 = state;\r
+                                               state2.UpdateChar();\r
+                                               UInt32 posStateNext = (position + 1) & _posStateMask;\r
+                                               UInt32 nextRepMatchPrice = curAnd1Price +\r
+                                                       _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1() +\r
+                                                       _isRep[state2.Index].GetPrice1();\r
+                                               {\r
+                                                       UInt32 offset = cur + 1 + lenTest2;\r
+                                                       while (lenEnd < offset)\r
+                                                               _optimum[++lenEnd].Price = kIfinityPrice;\r
+                                                       UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(\r
+                                                               0, lenTest2, state2, posStateNext);\r
+                                                       Optimal optimum = _optimum[offset];\r
+                                                       if (curAndLenPrice < optimum.Price)\r
+                                                       {\r
+                                                               optimum.Price = curAndLenPrice;\r
+                                                               optimum.PosPrev = cur + 1;\r
+                                                               optimum.BackPrev = 0;\r
+                                                               optimum.Prev1IsChar = true;\r
+                                                               optimum.Prev2 = false;\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               UInt32 startLen = 2; // speed optimization \r
+\r
+                               for (UInt32 repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)\r
+                               {\r
+                                       UInt32 lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes);\r
+                                       if (lenTest < 2)\r
+                                               continue;\r
+                                       UInt32 lenTestTemp = lenTest;\r
+                                       do\r
+                                       {\r
+                                               while (lenEnd < cur + lenTest)\r
+                                                       _optimum[++lenEnd].Price = kIfinityPrice;\r
+                                               UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);\r
+                                               Optimal optimum = _optimum[cur + lenTest];\r
+                                               if (curAndLenPrice < optimum.Price)\r
+                                               {\r
+                                                       optimum.Price = curAndLenPrice;\r
+                                                       optimum.PosPrev = cur;\r
+                                                       optimum.BackPrev = repIndex;\r
+                                                       optimum.Prev1IsChar = false;\r
+                                               }\r
+                                       }\r
+                                       while(--lenTest >= 2);\r
+                                       lenTest = lenTestTemp;\r
+\r
+                                       if (repIndex == 0)\r
+                                               startLen = lenTest + 1;\r
+\r
+                                       // if (_maxMode)\r
+                                       if (lenTest < numAvailableBytesFull)\r
+                                       {\r
+                                               UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);\r
+                                               UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, reps[repIndex], t);\r
+                                               if (lenTest2 >= 2)\r
+                                               {\r
+                                                       Base.State state2 = state;\r
+                                                       state2.UpdateRep();\r
+                                                       UInt32 posStateNext = (position + lenTest) & _posStateMask;\r
+                                                       UInt32 curAndLenCharPrice = \r
+                                                                       repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) + \r
+                                                                       _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() +\r
+                                                                       _literalEncoder.GetSubCoder(position + lenTest, \r
+                                                                       _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).GetPrice(true,\r
+                                                                       _matchFinder.GetIndexByte((Int32)((Int32)lenTest - 1 - (Int32)(reps[repIndex] + 1))), \r
+                                                                       _matchFinder.GetIndexByte((Int32)lenTest - 1));\r
+                                                       state2.UpdateChar();\r
+                                                       posStateNext = (position + lenTest + 1) & _posStateMask;\r
+                                                       UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1();\r
+                                                       UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();\r
+                                                       \r
+                                                       // for(; lenTest2 >= 2; lenTest2--)\r
+                                                       {\r
+                                                               UInt32 offset = lenTest + 1 + lenTest2;\r
+                                                               while(lenEnd < cur + offset)\r
+                                                                       _optimum[++lenEnd].Price = kIfinityPrice;\r
+                                                               UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);\r
+                                                               Optimal optimum = _optimum[cur + offset];\r
+                                                               if (curAndLenPrice < optimum.Price) \r
+                                                               {\r
+                                                                       optimum.Price = curAndLenPrice;\r
+                                                                       optimum.PosPrev = cur + lenTest + 1;\r
+                                                                       optimum.BackPrev = 0;\r
+                                                                       optimum.Prev1IsChar = true;\r
+                                                                       optimum.Prev2 = true;\r
+                                                                       optimum.PosPrev2 = cur;\r
+                                                                       optimum.BackPrev2 = repIndex;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               if (newLen > numAvailableBytes)\r
+                               {\r
+                                       newLen = numAvailableBytes;\r
+                                       for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ;\r
+                                       _matchDistances[numDistancePairs] = newLen;\r
+                                       numDistancePairs += 2;\r
+                               }\r
+                               if (newLen >= startLen)\r
+                               {\r
+                                       normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();\r
+                                       while (lenEnd < cur + newLen)\r
+                                               _optimum[++lenEnd].Price = kIfinityPrice;\r
+\r
+                                       UInt32 offs = 0;\r
+                                       while (startLen > _matchDistances[offs])\r
+                                               offs += 2;\r
+\r
+                                       for (UInt32 lenTest = startLen; ; lenTest++)\r
+                                       {\r
+                                               UInt32 curBack = _matchDistances[offs + 1];\r
+                                               UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);\r
+                                               Optimal optimum = _optimum[cur + lenTest];\r
+                                               if (curAndLenPrice < optimum.Price)\r
+                                               {\r
+                                                       optimum.Price = curAndLenPrice;\r
+                                                       optimum.PosPrev = cur;\r
+                                                       optimum.BackPrev = curBack + Base.kNumRepDistances;\r
+                                                       optimum.Prev1IsChar = false;\r
+                                               }\r
+\r
+                                               if (lenTest == _matchDistances[offs])\r
+                                               {\r
+                                                       if (lenTest < numAvailableBytesFull)\r
+                                                       {\r
+                                                               UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);\r
+                                                               UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, curBack, t);\r
+                                                               if (lenTest2 >= 2)\r
+                                                               {\r
+                                                                       Base.State state2 = state;\r
+                                                                       state2.UpdateMatch();\r
+                                                                       UInt32 posStateNext = (position + lenTest) & _posStateMask;\r
+                                                                       UInt32 curAndLenCharPrice = curAndLenPrice +\r
+                                                                               _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() +\r
+                                                                               _literalEncoder.GetSubCoder(position + lenTest,\r
+                                                                               _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).\r
+                                                                               GetPrice(true,\r
+                                                                               _matchFinder.GetIndexByte((Int32)lenTest - (Int32)(curBack + 1) - 1),\r
+                                                                               _matchFinder.GetIndexByte((Int32)lenTest - 1));\r
+                                                                       state2.UpdateChar();\r
+                                                                       posStateNext = (position + lenTest + 1) & _posStateMask;\r
+                                                                       UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1();\r
+                                                                       UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();\r
+\r
+                                                                       UInt32 offset = lenTest + 1 + lenTest2;\r
+                                                                       while (lenEnd < cur + offset)\r
+                                                                               _optimum[++lenEnd].Price = kIfinityPrice;\r
+                                                                       curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);\r
+                                                                       optimum = _optimum[cur + offset];\r
+                                                                       if (curAndLenPrice < optimum.Price)\r
+                                                                       {\r
+                                                                               optimum.Price = curAndLenPrice;\r
+                                                                               optimum.PosPrev = cur + lenTest + 1;\r
+                                                                               optimum.BackPrev = 0;\r
+                                                                               optimum.Prev1IsChar = true;\r
+                                                                               optimum.Prev2 = true;\r
+                                                                               optimum.PosPrev2 = cur;\r
+                                                                               optimum.BackPrev2 = curBack + Base.kNumRepDistances;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                                       offs += 2;\r
+                                                       if (offs == numDistancePairs)\r
+                                                               break;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               bool ChangePair(UInt32 smallDist, UInt32 bigDist)\r
+               {\r
+                       const int kDif = 7;\r
+                       return (smallDist < ((UInt32)(1) << (32 - kDif)) && bigDist >= (smallDist << kDif));\r
+               }\r
+\r
+               void WriteEndMarker(UInt32 posState)\r
+               {\r
+                       if (!_writeEndMark)\r
+                               return;\r
+\r
+                       _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 1);\r
+                       _isRep[_state.Index].Encode(_rangeEncoder, 0);\r
+                       _state.UpdateMatch();\r
+                       UInt32 len = Base.kMatchMinLen;\r
+                       _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);\r
+                       UInt32 posSlot = (1 << Base.kNumPosSlotBits) - 1;\r
+                       UInt32 lenToPosState = Base.GetLenToPosState(len);\r
+                       _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);\r
+                       int footerBits = 30;\r
+                       UInt32 posReduced = (((UInt32)1) << footerBits) - 1;\r
+                       _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);\r
+                       _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);\r
+               }\r
+\r
+               void Flush(UInt32 nowPos)\r
+               {\r
+                       ReleaseMFStream();\r
+                       WriteEndMarker(nowPos & _posStateMask);\r
+                       _rangeEncoder.FlushData();\r
+                       _rangeEncoder.FlushStream();\r
+               }\r
+\r
+               public void CodeOneBlock(out Int64 inSize, out Int64 outSize, out bool finished)\r
+               {\r
+                       inSize = 0;\r
+                       outSize = 0;\r
+                       finished = true;\r
+\r
+                       if (_inStream != null)\r
+                       {\r
+                               _matchFinder.SetStream(_inStream);\r
+                               _matchFinder.Init();\r
+                               _needReleaseMFStream = true;\r
+                               _inStream = null;\r
+                               if (_trainSize > 0)\r
+                                       _matchFinder.Skip(_trainSize);\r
+                       }\r
+\r
+                       if (_finished)\r
+                               return;\r
+                       _finished = true;\r
+\r
+\r
+                       Int64 progressPosValuePrev = nowPos64;\r
+                       if (nowPos64 == 0)\r
+                       {\r
+                               if (_matchFinder.GetNumAvailableBytes() == 0)\r
+                               {\r
+                                       Flush((UInt32)nowPos64);\r
+                                       return;\r
+                               }\r
+                               UInt32 len, numDistancePairs; // it's not used\r
+                               ReadMatchDistances(out len, out numDistancePairs);\r
+                               UInt32 posState = (UInt32)(nowPos64) & _posStateMask;\r
+                               _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 0);\r
+                               _state.UpdateChar();\r
+                               Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset));\r
+                               _literalEncoder.GetSubCoder((UInt32)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);\r
+                               _previousByte = curByte;\r
+                               _additionalOffset--;\r
+                               nowPos64++;\r
+                       }\r
+                       if (_matchFinder.GetNumAvailableBytes() == 0)\r
+                       {\r
+                               Flush((UInt32)nowPos64);\r
+                               return;\r
+                       }\r
+                       while (true)\r
+                       {\r
+                               UInt32 pos;\r
+                               UInt32 len = GetOptimum((UInt32)nowPos64, out pos);\r
+                               \r
+                               UInt32 posState = ((UInt32)nowPos64) & _posStateMask;\r
+                               UInt32 complexState = (_state.Index << Base.kNumPosStatesBitsMax) + posState;\r
+                               if (len == 1 && pos == 0xFFFFFFFF)\r
+                               {\r
+                                       _isMatch[complexState].Encode(_rangeEncoder, 0);\r
+                                       Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset));\r
+                                       LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((UInt32)nowPos64, _previousByte);\r
+                                       if (!_state.IsCharState())\r
+                                       {\r
+                                               Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - _additionalOffset));\r
+                                               subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);\r
+                                       }\r
+                                       else\r
+                                               subCoder.Encode(_rangeEncoder, curByte);\r
+                                       _previousByte = curByte;\r
+                                       _state.UpdateChar();\r
+                               }\r
+                               else\r
+                               {\r
+                                       _isMatch[complexState].Encode(_rangeEncoder, 1);\r
+                                       if (pos < Base.kNumRepDistances)\r
+                                       {\r
+                                               _isRep[_state.Index].Encode(_rangeEncoder, 1);\r
+                                               if (pos == 0)\r
+                                               {\r
+                                                       _isRepG0[_state.Index].Encode(_rangeEncoder, 0);\r
+                                                       if (len == 1)\r
+                                                               _isRep0Long[complexState].Encode(_rangeEncoder, 0);\r
+                                                       else\r
+                                                               _isRep0Long[complexState].Encode(_rangeEncoder, 1);\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       _isRepG0[_state.Index].Encode(_rangeEncoder, 1);\r
+                                                       if (pos == 1)\r
+                                                               _isRepG1[_state.Index].Encode(_rangeEncoder, 0);\r
+                                                       else\r
+                                                       {\r
+                                                               _isRepG1[_state.Index].Encode(_rangeEncoder, 1);\r
+                                                               _isRepG2[_state.Index].Encode(_rangeEncoder, pos - 2);\r
+                                                       }\r
+                                               }\r
+                                               if (len == 1)\r
+                                                       _state.UpdateShortRep();\r
+                                               else\r
+                                               {\r
+                                                       _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);\r
+                                                       _state.UpdateRep();\r
+                                               }\r
+                                               UInt32 distance = _repDistances[pos];\r
+                                               if (pos != 0)\r
+                                               {\r
+                                                       for (UInt32 i = pos; i >= 1; i--)\r
+                                                               _repDistances[i] = _repDistances[i - 1];\r
+                                                       _repDistances[0] = distance;\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               _isRep[_state.Index].Encode(_rangeEncoder, 0);\r
+                                               _state.UpdateMatch();\r
+                                               _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);\r
+                                               pos -= Base.kNumRepDistances;\r
+                                               UInt32 posSlot = GetPosSlot(pos);\r
+                                               UInt32 lenToPosState = Base.GetLenToPosState(len);\r
+                                               _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);\r
+\r
+                                               if (posSlot >= Base.kStartPosModelIndex)\r
+                                               {\r
+                                                       int footerBits = (int)((posSlot >> 1) - 1);\r
+                                                       UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits);\r
+                                                       UInt32 posReduced = pos - baseVal;\r
+\r
+                                                       if (posSlot < Base.kEndPosModelIndex)\r
+                                                               RangeCoder.BitTreeEncoder.ReverseEncode(_posEncoders,\r
+                                                                               baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);\r
+                                                       else\r
+                                                       {\r
+                                                               _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);\r
+                                                               _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);\r
+                                                               _alignPriceCount++;\r
+                                                       }\r
+                                               }\r
+                                               UInt32 distance = pos;\r
+                                               for (UInt32 i = Base.kNumRepDistances - 1; i >= 1; i--)\r
+                                                       _repDistances[i] = _repDistances[i - 1];\r
+                                               _repDistances[0] = distance;\r
+                                               _matchPriceCount++;\r
+                                       }\r
+                                       _previousByte = _matchFinder.GetIndexByte((Int32)(len - 1 - _additionalOffset));\r
+                               }\r
+                               _additionalOffset -= len;\r
+                               nowPos64 += len;\r
+                               if (_additionalOffset == 0)\r
+                               {\r
+                                       // if (!_fastMode)\r
+                                       if (_matchPriceCount >= (1 << 7))\r
+                                               FillDistancesPrices();\r
+                                       if (_alignPriceCount >= Base.kAlignTableSize)\r
+                                               FillAlignPrices();\r
+                                       inSize = nowPos64;\r
+                                       outSize = _rangeEncoder.GetProcessedSizeAdd();\r
+                                       if (_matchFinder.GetNumAvailableBytes() == 0)\r
+                                       {\r
+                                               Flush((UInt32)nowPos64);\r
+                                               return;\r
+                                       }\r
+\r
+                                       if (nowPos64 - progressPosValuePrev >= (1 << 12))\r
+                                       {\r
+                                               _finished = false;\r
+                                               finished = false;\r
+                                               return;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               void ReleaseMFStream()\r
+               {\r
+                       if (_matchFinder != null && _needReleaseMFStream)\r
+                       {\r
+                               _matchFinder.ReleaseStream();\r
+                               _needReleaseMFStream = false;\r
+                       }\r
+               }\r
+\r
+               void SetOutStream(System.IO.Stream outStream) { _rangeEncoder.SetStream(outStream); }\r
+               void ReleaseOutStream() { _rangeEncoder.ReleaseStream(); }\r
+\r
+               void ReleaseStreams()\r
+               {\r
+                       ReleaseMFStream();\r
+                       ReleaseOutStream();\r
+               }\r
+\r
+               void SetStreams(System.IO.Stream inStream, System.IO.Stream outStream,\r
+                               Int64 inSize, Int64 outSize)\r
+               {\r
+                       _inStream = inStream;\r
+                       _finished = false;\r
+                       Create();\r
+                       SetOutStream(outStream);\r
+                       Init();\r
+\r
+                       // if (!_fastMode)\r
+                       {\r
+                               FillDistancesPrices();\r
+                               FillAlignPrices();\r
+                       }\r
+\r
+                       _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);\r
+                       _lenEncoder.UpdateTables((UInt32)1 << _posStateBits);\r
+                       _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);\r
+                       _repMatchLenEncoder.UpdateTables((UInt32)1 << _posStateBits);\r
+\r
+                       nowPos64 = 0;\r
+               }\r
+\r
+\r
+               public void Code(System.IO.Stream inStream, System.IO.Stream outStream,\r
+                       Int64 inSize, Int64 outSize, ICodeProgress progress)\r
+               {\r
+                       _needReleaseMFStream = false;\r
+                       try\r
+                       {\r
+                               SetStreams(inStream, outStream, inSize, outSize);\r
+                               while (true)\r
+                               {\r
+                                       Int64 processedInSize;\r
+                                       Int64 processedOutSize;\r
+                                       bool finished;\r
+                                       CodeOneBlock(out processedInSize, out processedOutSize, out finished);\r
+                                       if (finished)\r
+                                               return;\r
+                                       if (progress != null)\r
+                                       {\r
+                                               progress.SetProgress(processedInSize, processedOutSize);\r
+                                       }\r
+                               }\r
+                       }\r
+                       finally\r
+                       {\r
+                               ReleaseStreams();\r
+                       }\r
+               }\r
+\r
+               const int kPropSize = 5;\r
+               Byte[] properties = new Byte[kPropSize];\r
+\r
+               public void WriteCoderProperties(System.IO.Stream outStream)\r
+               {\r
+                       properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);\r
+                       for (int i = 0; i < 4; i++)\r
+                               properties[1 + i] = (Byte)((_dictionarySize >> (8 * i)) & 0xFF);\r
+                       outStream.Write(properties, 0, kPropSize);\r
+               }\r
+               \r
+               UInt32[] tempPrices = new UInt32[Base.kNumFullDistances];\r
+               UInt32 _matchPriceCount;\r
+\r
+               void FillDistancesPrices()\r
+               {\r
+                       for (UInt32 i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)\r
+                       { \r
+                               UInt32 posSlot = GetPosSlot(i);\r
+                               int footerBits = (int)((posSlot >> 1) - 1);\r
+                               UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits);\r
+                               tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders, \r
+                                       baseVal - posSlot - 1, footerBits, i - baseVal);\r
+                       }\r
+\r
+                       for (UInt32 lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)\r
+                       {\r
+                               UInt32 posSlot;\r
+                               RangeCoder.BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];\r
+                       \r
+                               UInt32 st = (lenToPosState << Base.kNumPosSlotBits);\r
+                               for (posSlot = 0; posSlot < _distTableSize; posSlot++)\r
+                                       _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);\r
+                               for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)\r
+                                       _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << RangeCoder.BitEncoder.kNumBitPriceShiftBits);\r
+\r
+                               UInt32 st2 = lenToPosState * Base.kNumFullDistances;\r
+                               UInt32 i;\r
+                               for (i = 0; i < Base.kStartPosModelIndex; i++)\r
+                                       _distancesPrices[st2 + i] = _posSlotPrices[st + i];\r
+                               for (; i < Base.kNumFullDistances; i++)\r
+                                       _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];\r
+                       }\r
+                       _matchPriceCount = 0;\r
+               }\r
+\r
+               void FillAlignPrices()\r
+               {\r
+                       for (UInt32 i = 0; i < Base.kAlignTableSize; i++)\r
+                               _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);\r
+                       _alignPriceCount = 0;\r
+               }\r
+\r
+\r
+               static string[] kMatchFinderIDs = \r
+               {\r
+                       "BT2",\r
+                       "BT4",\r
+               };\r
+\r
+               static int FindMatchFinder(string s)\r
+               {\r
+                       for (int m = 0; m < kMatchFinderIDs.Length; m++)\r
+                               if (s == kMatchFinderIDs[m])\r
+                                       return m;\r
+                       return -1;\r
+               }\r
+       \r
+               public void SetCoderProperties(CoderPropID[] propIDs, object[] properties)\r
+               {\r
+                       for (UInt32 i = 0; i < properties.Length; i++)\r
+                       {\r
+                               object prop = properties[i];\r
+                               switch (propIDs[i])\r
+                               {\r
+                                       case CoderPropID.NumFastBytes:\r
+                                       {\r
+                                               if (!(prop is Int32))\r
+                                                       throw new InvalidParamException();\r
+                                               Int32 numFastBytes = (Int32)prop;\r
+                                               if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)\r
+                                                       throw new InvalidParamException();\r
+                                               _numFastBytes = (UInt32)numFastBytes;\r
+                                               break;\r
+                                       }\r
+                                       case CoderPropID.Algorithm:\r
+                                       {\r
+                                               /*\r
+                                               if (!(prop is Int32))\r
+                                                       throw new InvalidParamException();\r
+                                               Int32 maximize = (Int32)prop;\r
+                                               _fastMode = (maximize == 0);\r
+                                               _maxMode = (maximize >= 2);\r
+                                               */\r
+                                               break;\r
+                                       }\r
+                                       case CoderPropID.MatchFinder:\r
+                                       {\r
+                                               if (!(prop is String))\r
+                                                       throw new InvalidParamException();\r
+                                               EMatchFinderType matchFinderIndexPrev = _matchFinderType;\r
+                                               int m = FindMatchFinder(((string)prop).ToUpper());\r
+                                               if (m < 0)\r
+                                                       throw new InvalidParamException();\r
+                                               _matchFinderType = (EMatchFinderType)m;\r
+                                               if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)\r
+                                                       {\r
+                                                       _dictionarySizePrev = 0xFFFFFFFF;\r
+                                                       _matchFinder = null;\r
+                                                       }\r
+                                               break;\r
+                                       }\r
+                                       case CoderPropID.DictionarySize:\r
+                                       {\r
+                                               const int kDicLogSizeMaxCompress = 30;\r
+                                               if (!(prop is Int32))\r
+                                                       throw new InvalidParamException(); ;\r
+                                               Int32 dictionarySize = (Int32)prop;\r
+                                               if (dictionarySize < (UInt32)(1 << Base.kDicLogSizeMin) ||\r
+                                                       dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress))\r
+                                                       throw new InvalidParamException();\r
+                                               _dictionarySize = (UInt32)dictionarySize;\r
+                                               int dicLogSize;\r
+                                               for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)\r
+                                                       if (dictionarySize <= ((UInt32)(1) << dicLogSize))\r
+                                                               break;\r
+                                               _distTableSize = (UInt32)dicLogSize * 2;\r
+                                               break;\r
+                                       }\r
+                                       case CoderPropID.PosStateBits:\r
+                                       {\r
+                                               if (!(prop is Int32))\r
+                                                       throw new InvalidParamException();\r
+                                               Int32 v = (Int32)prop;\r
+                                               if (v < 0 || v > (UInt32)Base.kNumPosStatesBitsEncodingMax)\r
+                                                       throw new InvalidParamException();\r
+                                               _posStateBits = (int)v;\r
+                                               _posStateMask = (((UInt32)1) << (int)_posStateBits) - 1;\r
+                                               break;\r
+                                       }\r
+                                       case CoderPropID.LitPosBits:\r
+                                       {\r
+                                               if (!(prop is Int32))\r
+                                                       throw new InvalidParamException();\r
+                                               Int32 v = (Int32)prop;\r
+                                               if (v < 0 || v > (UInt32)Base.kNumLitPosStatesBitsEncodingMax)\r
+                                                       throw new InvalidParamException();\r
+                                               _numLiteralPosStateBits = (int)v;\r
+                                               break;\r
+                                       }\r
+                                       case CoderPropID.LitContextBits:\r
+                                       {\r
+                                               if (!(prop is Int32))\r
+                                                       throw new InvalidParamException();\r
+                                               Int32 v = (Int32)prop;\r
+                                               if (v < 0 || v > (UInt32)Base.kNumLitContextBitsMax)\r
+                                                       throw new InvalidParamException(); ;\r
+                                               _numLiteralContextBits = (int)v;\r
+                                               break;\r
+                                       }\r
+                                       case CoderPropID.EndMarker:\r
+                                       {\r
+                                               if (!(prop is Boolean))\r
+                                                       throw new InvalidParamException();\r
+                                               SetWriteEndMarkerMode((Boolean)prop);\r
+                                               break;\r
+                                       }\r
+                                       default:\r
+                                               throw new InvalidParamException();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               uint _trainSize = 0;\r
+               public void SetTrainSize(uint trainSize)\r
+               {\r
+                       _trainSize = trainSize;\r
+               }\r
+               \r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs b/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
new file mode 100755 (executable)
index 0000000..8aa4462
--- /dev/null
@@ -0,0 +1,364 @@
+using System;\r
+using System.IO;\r
+namespace SevenZip\r
+{\r
+       using CommandLineParser;\r
+       \r
+       public class CDoubleStream: Stream\r
+       {\r
+               public System.IO.Stream s1;\r
+               public System.IO.Stream s2;\r
+               public int fileIndex;\r
+               public long skipSize;\r
+               \r
+               public override bool CanRead { get { return true; }}\r
+               public override bool CanWrite { get { return false; }}\r
+               public override bool CanSeek { get { return false; }}\r
+               public override long Length { get { return s1.Length + s2.Length - skipSize; } }\r
+               public override long Position\r
+               {\r
+                       get { return 0; }\r
+                       set { }\r
+               }\r
+               public override void Flush() { }\r
+               public override int Read(byte[] buffer, int offset, int count) \r
+               {\r
+                       int numTotal = 0;\r
+                       while (count > 0)\r
+                       {\r
+                               if (fileIndex == 0)\r
+                               {\r
+                                       int num = s1.Read(buffer, offset, count);\r
+                                       offset += num;\r
+                                       count -= num;\r
+                                       numTotal += num;\r
+                                       if (num == 0)\r
+                                               fileIndex++;\r
+                               }\r
+                               if (fileIndex == 1)\r
+                               {\r
+                                       numTotal += s2.Read(buffer, offset, count);\r
+                                       return numTotal;\r
+                               }\r
+                       }\r
+                       return numTotal;\r
+               }\r
+               public override void Write(byte[] buffer, int offset, int count)\r
+               {\r
+                       throw (new Exception("can't Write"));\r
+               }\r
+               public override long Seek(long offset, System.IO.SeekOrigin origin)\r
+               {\r
+                       throw (new Exception("can't Seek"));\r
+               }\r
+               public override void SetLength(long value)\r
+               {\r
+                       throw (new Exception("can't SetLength"));\r
+               }\r
+       }\r
+       \r
+       class LzmaAlone\r
+       {\r
+               enum Key\r
+               {\r
+                       Help1 = 0,\r
+                       Help2,\r
+                       Mode,\r
+                       Dictionary,\r
+                       FastBytes,\r
+                       LitContext,\r
+                       LitPos,\r
+                       PosBits,\r
+                       MatchFinder,\r
+                       EOS,\r
+                       StdIn,\r
+                       StdOut,\r
+                       Train\r
+               };\r
+\r
+               static void PrintHelp()\r
+               {\r
+                       System.Console.WriteLine("\nUsage:  LZMA <e|d> [<switches>...] inputFile outputFile\n" +\r
+                               "  e: encode file\n" +\r
+                               "  d: decode file\n" +\r
+                               "  b: Benchmark\n" +\r
+                               "<Switches>\n" +\r
+                               // "  -a{N}:  set compression mode - [0, 1], default: 1 (max)\n" +\r
+                               "  -d{N}:  set dictionary - [0, 29], default: 23 (8MB)\n" +\r
+                               "  -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +\r
+                               "  -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +\r
+                               "  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +\r
+                               "  -pb{N}: set number of pos bits - [0, 4], default: 2\n" +\r
+                               "  -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +\r
+                               "  -eos:   write End Of Stream marker\n"\r
+                               // + "  -si:    read data from stdin\n"\r
+                               // + "  -so:    write data to stdout\n"\r
+                               );\r
+               }\r
+\r
+               static bool GetNumber(string s, out Int32 v)\r
+               {\r
+                       v = 0;\r
+                       for (int i = 0; i < s.Length; i++)\r
+                       {\r
+                               char c = s[i];\r
+                               if (c < '0' || c > '9')\r
+                                       return false;\r
+                               v *= 10;\r
+                               v += (Int32)(c - '0');\r
+                       }\r
+                       return true;\r
+               }\r
+\r
+               static int IncorrectCommand()\r
+               {\r
+                       throw (new Exception("Command line error"));\r
+                       // System.Console.WriteLine("\nCommand line error\n");\r
+                       // return 1;\r
+               }\r
+               static int Main2(string[] args)\r
+               {\r
+                       System.Console.WriteLine("\nLZMA# 4.61  2008-11-23\n");\r
+\r
+                       if (args.Length == 0)\r
+                       {\r
+                               PrintHelp();\r
+                               return 0;\r
+                       }\r
+\r
+                       SwitchForm[] kSwitchForms = new SwitchForm[13];\r
+                       int sw = 0;\r
+                       kSwitchForms[sw++] = new SwitchForm("?", SwitchType.Simple, false);\r
+                       kSwitchForms[sw++] = new SwitchForm("H", SwitchType.Simple, false);\r
+                       kSwitchForms[sw++] = new SwitchForm("A", SwitchType.UnLimitedPostString, false, 1);\r
+                       kSwitchForms[sw++] = new SwitchForm("D", SwitchType.UnLimitedPostString, false, 1);\r
+                       kSwitchForms[sw++] = new SwitchForm("FB", SwitchType.UnLimitedPostString, false, 1);\r
+                       kSwitchForms[sw++] = new SwitchForm("LC", SwitchType.UnLimitedPostString, false, 1);\r
+                       kSwitchForms[sw++] = new SwitchForm("LP", SwitchType.UnLimitedPostString, false, 1);\r
+                       kSwitchForms[sw++] = new SwitchForm("PB", SwitchType.UnLimitedPostString, false, 1);\r
+                       kSwitchForms[sw++] = new SwitchForm("MF", SwitchType.UnLimitedPostString, false, 1);\r
+                       kSwitchForms[sw++] = new SwitchForm("EOS", SwitchType.Simple, false);\r
+                       kSwitchForms[sw++] = new SwitchForm("SI", SwitchType.Simple, false);\r
+                       kSwitchForms[sw++] = new SwitchForm("SO", SwitchType.Simple, false);\r
+                       kSwitchForms[sw++] = new SwitchForm("T", SwitchType.UnLimitedPostString, false, 1);\r
+\r
+\r
+                       Parser parser = new Parser(sw);\r
+                       try\r
+                       {\r
+                               parser.ParseStrings(kSwitchForms, args);\r
+                       }\r
+                       catch\r
+                       {\r
+                               return IncorrectCommand();\r
+                       }\r
+\r
+                       if (parser[(int)Key.Help1].ThereIs || parser[(int)Key.Help2].ThereIs)\r
+                       {\r
+                               PrintHelp();\r
+                               return 0;\r
+                       }\r
+\r
+                       System.Collections.ArrayList nonSwitchStrings = parser.NonSwitchStrings;\r
+\r
+                       int paramIndex = 0;\r
+                       if (paramIndex >= nonSwitchStrings.Count)\r
+                               return IncorrectCommand();\r
+                       string command = (string)nonSwitchStrings[paramIndex++];\r
+                       command = command.ToLower();\r
+\r
+                       bool dictionaryIsDefined = false;\r
+                       Int32 dictionary = 1 << 21;\r
+                       if (parser[(int)Key.Dictionary].ThereIs)\r
+                       {\r
+                               Int32 dicLog;\r
+                               if (!GetNumber((string)parser[(int)Key.Dictionary].PostStrings[0], out dicLog))\r
+                                       IncorrectCommand();\r
+                               dictionary = (Int32)1 << dicLog;\r
+                               dictionaryIsDefined = true;\r
+                       }\r
+                       string mf = "bt4";\r
+                       if (parser[(int)Key.MatchFinder].ThereIs)\r
+                               mf = (string)parser[(int)Key.MatchFinder].PostStrings[0];\r
+                       mf = mf.ToLower();\r
+\r
+                       if (command == "b")\r
+                       {\r
+                               const Int32 kNumDefaultItereations = 10;\r
+                               Int32 numIterations = kNumDefaultItereations;\r
+                               if (paramIndex < nonSwitchStrings.Count)\r
+                                       if (!GetNumber((string)nonSwitchStrings[paramIndex++], out numIterations))\r
+                                               numIterations = kNumDefaultItereations;\r
+                               return LzmaBench.LzmaBenchmark(numIterations, (UInt32)dictionary);\r
+                       }\r
+\r
+                       string train = "";\r
+                       if (parser[(int)Key.Train].ThereIs)\r
+                               train = (string)parser[(int)Key.Train].PostStrings[0];\r
+\r
+                       bool encodeMode = false;\r
+                       if (command == "e")\r
+                               encodeMode = true;\r
+                       else if (command == "d")\r
+                               encodeMode = false;\r
+                       else\r
+                               IncorrectCommand();\r
+\r
+                       bool stdInMode = parser[(int)Key.StdIn].ThereIs;\r
+                       bool stdOutMode = parser[(int)Key.StdOut].ThereIs;\r
+\r
+                       Stream inStream = null;\r
+                       if (stdInMode)\r
+                       {\r
+                               throw (new Exception("Not implemeted"));\r
+                       }\r
+                       else\r
+                       {\r
+                               if (paramIndex >= nonSwitchStrings.Count)\r
+                                       IncorrectCommand();\r
+                               string inputName = (string)nonSwitchStrings[paramIndex++];\r
+                               inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read);\r
+                       }\r
+\r
+                       FileStream outStream = null;\r
+                       if (stdOutMode)\r
+                       {\r
+                               throw (new Exception("Not implemeted"));\r
+                       }\r
+                       else\r
+                       {\r
+                               if (paramIndex >= nonSwitchStrings.Count)\r
+                                       IncorrectCommand();\r
+                               string outputName = (string)nonSwitchStrings[paramIndex++];\r
+                               outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write);\r
+                       }\r
+\r
+                       FileStream trainStream = null;\r
+                       if (train.Length != 0)\r
+                               trainStream = new FileStream(train, FileMode.Open, FileAccess.Read);\r
+\r
+                       if (encodeMode)\r
+                       {\r
+                               if (!dictionaryIsDefined)\r
+                                       dictionary = 1 << 23;\r
+\r
+                               Int32 posStateBits = 2;\r
+                               Int32 litContextBits = 3; // for normal files\r
+                               // UInt32 litContextBits = 0; // for 32-bit data\r
+                               Int32 litPosBits = 0;\r
+                               // UInt32 litPosBits = 2; // for 32-bit data\r
+                               Int32 algorithm = 2;\r
+                               Int32 numFastBytes = 128;\r
+\r
+                               bool eos = parser[(int)Key.EOS].ThereIs || stdInMode;\r
+\r
+                               if (parser[(int)Key.Mode].ThereIs)\r
+                                       if (!GetNumber((string)parser[(int)Key.Mode].PostStrings[0], out algorithm))\r
+                                               IncorrectCommand();\r
+\r
+                               if (parser[(int)Key.FastBytes].ThereIs)\r
+                                       if (!GetNumber((string)parser[(int)Key.FastBytes].PostStrings[0], out numFastBytes))\r
+                                               IncorrectCommand();\r
+                               if (parser[(int)Key.LitContext].ThereIs)\r
+                                       if (!GetNumber((string)parser[(int)Key.LitContext].PostStrings[0], out litContextBits))\r
+                                               IncorrectCommand();\r
+                               if (parser[(int)Key.LitPos].ThereIs)\r
+                                       if (!GetNumber((string)parser[(int)Key.LitPos].PostStrings[0], out litPosBits))\r
+                                               IncorrectCommand();\r
+                               if (parser[(int)Key.PosBits].ThereIs)\r
+                                       if (!GetNumber((string)parser[(int)Key.PosBits].PostStrings[0], out posStateBits))\r
+                                               IncorrectCommand();\r
+\r
+                               CoderPropID[] propIDs = \r
+                               {\r
+                                       CoderPropID.DictionarySize,\r
+                                       CoderPropID.PosStateBits,\r
+                                       CoderPropID.LitContextBits,\r
+                                       CoderPropID.LitPosBits,\r
+                                       CoderPropID.Algorithm,\r
+                                       CoderPropID.NumFastBytes,\r
+                                       CoderPropID.MatchFinder,\r
+                                       CoderPropID.EndMarker\r
+                               };\r
+                               object[] properties = \r
+                               {\r
+                                       (Int32)(dictionary),\r
+                                       (Int32)(posStateBits),\r
+                                       (Int32)(litContextBits),\r
+                                       (Int32)(litPosBits),\r
+                                       (Int32)(algorithm),\r
+                                       (Int32)(numFastBytes),\r
+                                       mf,\r
+                                       eos\r
+                               };\r
+\r
+                               Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();\r
+                               encoder.SetCoderProperties(propIDs, properties);\r
+                               encoder.WriteCoderProperties(outStream);\r
+                               Int64 fileSize;\r
+                               if (eos || stdInMode)\r
+                                       fileSize = -1;\r
+                               else\r
+                                       fileSize = inStream.Length;\r
+                               for (int i = 0; i < 8; i++)\r
+                                       outStream.WriteByte((Byte)(fileSize >> (8 * i)));\r
+                               if (trainStream != null)\r
+                               {\r
+                                       CDoubleStream doubleStream = new CDoubleStream();\r
+                                       doubleStream.s1 = trainStream;\r
+                                       doubleStream.s2 = inStream;\r
+                                       doubleStream.fileIndex = 0;\r
+                                       inStream = doubleStream;\r
+                                       long trainFileSize = trainStream.Length;\r
+                                       doubleStream.skipSize = 0;\r
+                                       if (trainFileSize > dictionary)\r
+                                               doubleStream.skipSize = trainFileSize - dictionary;\r
+                                       trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin);\r
+                                       encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize));\r
+                               }\r
+                               encoder.Code(inStream, outStream, -1, -1, null);\r
+                       }\r
+                       else if (command == "d")\r
+                       {\r
+                               byte[] properties = new byte[5];\r
+                               if (inStream.Read(properties, 0, 5) != 5)\r
+                                       throw (new Exception("input .lzma is too short"));\r
+                               Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();\r
+                               decoder.SetDecoderProperties(properties);\r
+                               if (trainStream != null)\r
+                               {\r
+                                       if (!decoder.Train(trainStream))\r
+                                               throw (new Exception("can't train"));\r
+                               }\r
+                               long outSize = 0;\r
+                               for (int i = 0; i < 8; i++)\r
+                               {\r
+                                       int v = inStream.ReadByte();\r
+                                       if (v < 0)\r
+                                               throw (new Exception("Can't Read 1"));\r
+                                       outSize |= ((long)(byte)v) << (8 * i);\r
+                               }\r
+                               long compressedSize = inStream.Length - inStream.Position;\r
+                               decoder.Code(inStream, outStream, compressedSize, outSize, null);\r
+                       }\r
+                       else\r
+                               throw (new Exception("Command Error"));\r
+                       return 0;\r
+               }\r
+\r
+               [STAThread]\r
+               static int Main(string[] args)\r
+               {\r
+                       try\r
+                       {\r
+                               return Main2(args);\r
+                       }\r
+                       catch (Exception e)\r
+                       {\r
+                               Console.WriteLine("{0} Caught exception #1.", e);\r
+                               // throw e;\r
+                               return 1;\r
+                       }\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj b/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj
new file mode 100755 (executable)
index 0000000..ceb7073
--- /dev/null
@@ -0,0 +1,90 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>8.0.50727</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}</ProjectGuid>\r
+    <OutputType>Exe</OutputType>\r
+    <RootNamespace>LzmaAlone</RootNamespace>\r
+    <AssemblyName>Lzma#</AssemblyName>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <OutputPath>.\bin\Debug\</OutputPath>\r
+    <DefineConstants>DEBUG;TRACE</DefineConstants>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugSymbols>false</DebugSymbols>\r
+    <Optimize>true</Optimize>\r
+    <OutputPath>.\bin\Release\</OutputPath>\r
+    <DefineConstants>TRACE</DefineConstants>\r
+    <PlatformTarget>AnyCPU</PlatformTarget>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="System" />\r
+    <Reference Include="System.Data" />\r
+    <Reference Include="System.Xml" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Compile Include="..\..\Common\CommandLineParser.cs">\r
+      <Link>Common\CommandLineParser.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\..\Common\CRC.cs">\r
+      <Link>Common\CRC.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\..\ICoder.cs">\r
+      <Link>ICoder.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\LZ\IMatchFinder.cs">\r
+      <Link>LZ\IMatchFinder.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\LZ\LzBinTree.cs">\r
+      <Link>LZ\LzBinTree.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\LZ\LzInWindow.cs">\r
+      <Link>LZ\LzInWindow.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\LZ\LzOutWindow.cs">\r
+      <Link>LZ\LzOutWindow.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\LZMA\LzmaBase.cs">\r
+      <Link>LZMA\LzmaBase.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\LZMA\LzmaDecoder.cs">\r
+      <Link>LZMA\LzmaDecoder.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\LZMA\LzmaEncoder.cs">\r
+      <Link>LZMA\LzmaEncoder.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\RangeCoder\RangeCoder.cs">\r
+      <Link>RangeCoder\RangeCoder.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\RangeCoder\RangeCoderBit.cs">\r
+      <Link>RangeCoder\RangeCoderBit.cs</Link>\r
+    </Compile>\r
+    <Compile Include="..\RangeCoder\RangeCoderBitTree.cs">\r
+      <Link>RangeCoder\RangeCoderBitTree.cs</Link>\r
+    </Compile>\r
+    <Compile Include="LzmaAlone.cs">\r
+      <SubType>Code</SubType>\r
+    </Compile>\r
+    <Compile Include="LzmaBench.cs">\r
+      <SubType>Code</SubType>\r
+    </Compile>\r
+    <Compile Include="Properties\AssemblyInfo.cs" />\r
+    <Compile Include="Properties\Settings.cs">\r
+      <AutoGen>True</AutoGen>\r
+      <DependentUpon>Settings.settings</DependentUpon>\r
+    </Compile>\r
+    <None Include="Properties\Settings.settings">\r
+      <Generator>SettingsSingleFileGenerator</Generator>\r
+      <LastGenOutput>Settings.cs</LastGenOutput>\r
+    </None>\r
+    <AppDesigner Include="Properties\" />\r
+  </ItemGroup>\r
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />\r
+</Project>
\ No newline at end of file
diff --git a/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln b/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln
new file mode 100755 (executable)
index 0000000..a96ee3e
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual C# Express 2005\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LzmaAlone", "LzmaAlone.csproj", "{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Any CPU = Debug|Any CPU\r
+               Release|Any CPU = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+               {CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+               {CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Release|Any CPU.Build.0 = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/CS/7zip/Compress/LzmaAlone/LzmaBench.cs b/CS/7zip/Compress/LzmaAlone/LzmaBench.cs
new file mode 100755 (executable)
index 0000000..6a1ffe2
--- /dev/null
@@ -0,0 +1,340 @@
+// LzmaBench.cs\r
+\r
+using System;\r
+using System.IO;\r
+\r
+namespace SevenZip\r
+{\r
+       /// <summary>\r
+       /// LZMA Benchmark\r
+       /// </summary>\r
+       internal abstract class LzmaBench\r
+       {\r
+               const UInt32 kAdditionalSize = (6 << 20);\r
+               const UInt32 kCompressedAdditionalSize = (1 << 10);\r
+               const UInt32 kMaxLzmaPropSize = 10;\r
+\r
+               class CRandomGenerator\r
+               {\r
+                       UInt32 A1;\r
+                       UInt32 A2;\r
+                       public CRandomGenerator() { Init(); }\r
+                       public void Init() { A1 = 362436069; A2 = 521288629; }\r
+                       public UInt32 GetRnd()\r
+                       {\r
+                               return\r
+                                       ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^\r
+                                       ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)));\r
+                       }\r
+               };\r
+\r
+               class CBitRandomGenerator\r
+               {\r
+                       CRandomGenerator RG = new CRandomGenerator();\r
+                       UInt32 Value;\r
+                       int NumBits;\r
+                       public void Init()\r
+                       {\r
+                               Value = 0;\r
+                               NumBits = 0;\r
+                       }\r
+                       public UInt32 GetRnd(int numBits)\r
+                       {\r
+                               UInt32 result;\r
+                               if (NumBits > numBits)\r
+                               {\r
+                                       result = Value & (((UInt32)1 << numBits) - 1);\r
+                                       Value >>= numBits;\r
+                                       NumBits -= numBits;\r
+                                       return result;\r
+                               }\r
+                               numBits -= NumBits;\r
+                               result = (Value << numBits);\r
+                               Value = RG.GetRnd();\r
+                               result |= Value & (((UInt32)1 << numBits) - 1);\r
+                               Value >>= numBits;\r
+                               NumBits = 32 - numBits;\r
+                               return result;\r
+                       }\r
+               };\r
+\r
+               class CBenchRandomGenerator\r
+               {\r
+                       CBitRandomGenerator RG = new CBitRandomGenerator();\r
+                       UInt32 Pos;\r
+                       UInt32 Rep0;\r
+                       \r
+                       public UInt32 BufferSize;\r
+                       public Byte[] Buffer = null;\r
+\r
+                       public CBenchRandomGenerator() { }\r
+\r
+                       public void Set(UInt32 bufferSize)\r
+                       {\r
+                               Buffer = new Byte[bufferSize];\r
+                               Pos = 0;\r
+                               BufferSize = bufferSize;\r
+                       }\r
+                       UInt32 GetRndBit() { return RG.GetRnd(1); }\r
+                       UInt32 GetLogRandBits(int numBits)\r
+                       {\r
+                               UInt32 len = RG.GetRnd(numBits);\r
+                               return RG.GetRnd((int)len);\r
+                       }\r
+                       UInt32 GetOffset()\r
+                       {\r
+                               if (GetRndBit() == 0)\r
+                                       return GetLogRandBits(4);\r
+                               return (GetLogRandBits(4) << 10) | RG.GetRnd(10);\r
+                       }\r
+                       UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }\r
+                       UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }\r
+                       public void Generate()\r
+                       {\r
+                               RG.Init();\r
+                               Rep0 = 1;\r
+                               while (Pos < BufferSize)\r
+                               {\r
+                                       if (GetRndBit() == 0 || Pos < 1)\r
+                                               Buffer[Pos++] = (Byte)RG.GetRnd(8);\r
+                                       else\r
+                                       {\r
+                                               UInt32 len;\r
+                                               if (RG.GetRnd(3) == 0)\r
+                                                       len = 1 + GetLen1();\r
+                                               else\r
+                                               {\r
+                                                       do\r
+                                                               Rep0 = GetOffset();\r
+                                                       while (Rep0 >= Pos);\r
+                                                       Rep0++;\r
+                                                       len = 2 + GetLen2();\r
+                                               }\r
+                                               for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++)\r
+                                                       Buffer[Pos] = Buffer[Pos - Rep0];\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
+\r
+               class CrcOutStream : System.IO.Stream\r
+               {\r
+                       public CRC CRC = new CRC();\r
+                       public void Init() { CRC.Init(); }\r
+                       public UInt32 GetDigest() { return CRC.GetDigest(); }\r
+\r
+                       public override bool CanRead { get { return false; } }\r
+                       public override bool CanSeek { get { return false; } }\r
+                       public override bool CanWrite { get { return true; } }\r
+                       public override Int64 Length { get { return 0; } }\r
+                       public override Int64 Position { get { return 0; } set { } }\r
+                       public override void Flush() { }\r
+                       public override long Seek(long offset, SeekOrigin origin) { return 0; }\r
+                       public override void SetLength(long value) { }\r
+                       public override int Read(byte[] buffer, int offset, int count) { return 0; }\r
+\r
+                       public override void WriteByte(byte b)\r
+                       {\r
+                               CRC.UpdateByte(b);\r
+                       }\r
+                       public override void Write(byte[] buffer, int offset, int count)\r
+                       {\r
+                               CRC.Update(buffer, (uint)offset, (uint)count);\r
+                       }\r
+               };\r
+\r
+               class CProgressInfo : ICodeProgress\r
+               {\r
+                       public Int64 ApprovedStart;\r
+                       public Int64 InSize;\r
+                       public System.DateTime Time;\r
+                       public void Init() { InSize = 0; }\r
+                       public void SetProgress(Int64 inSize, Int64 outSize)\r
+                       {\r
+                               if (inSize >= ApprovedStart && InSize == 0)\r
+                               {\r
+                                       Time = DateTime.UtcNow;\r
+                                       InSize = inSize;\r
+                               }\r
+                       }\r
+               }\r
+               const int kSubBits = 8;\r
+\r
+               static UInt32 GetLogSize(UInt32 size)\r
+               {\r
+                       for (int i = kSubBits; i < 32; i++)\r
+                               for (UInt32 j = 0; j < (1 << kSubBits); j++)\r
+                                       if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))\r
+                                               return (UInt32)(i << kSubBits) + j;\r
+                       return (32 << kSubBits);\r
+               }\r
+\r
+               static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime)\r
+               {\r
+                       UInt64 freq = TimeSpan.TicksPerSecond;\r
+                       UInt64 elTime = elapsedTime;\r
+                       while (freq > 1000000)\r
+                       {\r
+                               freq >>= 1;\r
+                               elTime >>= 1;\r
+                       }\r
+                       if (elTime == 0)\r
+                               elTime = 1;\r
+                       return value * freq / elTime;\r
+               }\r
+\r
+               static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 size)\r
+               {\r
+                       UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits);\r
+                       UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));\r
+                       UInt64 numCommands = (UInt64)(size) * numCommandsForOne;\r
+                       return MyMultDiv64(numCommands, elapsedTime);\r
+               }\r
+\r
+               static UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 outSize, UInt64 inSize)\r
+               {\r
+                       UInt64 numCommands = inSize * 220 + outSize * 20;\r
+                       return MyMultDiv64(numCommands, elapsedTime);\r
+               }\r
+\r
+               static UInt64 GetTotalRating(\r
+                       UInt32 dictionarySize,\r
+                       UInt64 elapsedTimeEn, UInt64 sizeEn,\r
+                       UInt64 elapsedTimeDe,\r
+                       UInt64 inSizeDe, UInt64 outSizeDe)\r
+               {\r
+                       return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +\r
+                               GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;\r
+               }\r
+\r
+               static void PrintValue(UInt64 v)\r
+               {\r
+                       string s = v.ToString();\r
+                       for (int i = 0; i + s.Length < 6; i++)\r
+                               System.Console.Write(" ");\r
+                       System.Console.Write(s);\r
+               }\r
+\r
+               static void PrintRating(UInt64 rating)\r
+               {\r
+                       PrintValue(rating / 1000000);\r
+                       System.Console.Write(" MIPS");\r
+               }\r
+\r
+               static void PrintResults(\r
+                       UInt32 dictionarySize,\r
+                       UInt64 elapsedTime,\r
+                       UInt64 size,\r
+                       bool decompressMode, UInt64 secondSize)\r
+               {\r
+                       UInt64 speed = MyMultDiv64(size, elapsedTime);\r
+                       PrintValue(speed / 1024);\r
+                       System.Console.Write(" KB/s  ");\r
+                       UInt64 rating;\r
+                       if (decompressMode)\r
+                               rating = GetDecompressRating(elapsedTime, size, secondSize);\r
+                       else\r
+                               rating = GetCompressRating(dictionarySize, elapsedTime, size);\r
+                       PrintRating(rating);\r
+               }\r
+\r
+               static public int LzmaBenchmark(Int32 numIterations, UInt32 dictionarySize)\r
+               {\r
+                       if (numIterations <= 0)\r
+                               return 0;\r
+                       if (dictionarySize < (1 << 18))\r
+                       {\r
+                               System.Console.WriteLine("\nError: dictionary size for benchmark must be >= 19 (512 KB)");\r
+                               return 1;\r
+                       }\r
+                       System.Console.Write("\n       Compressing                Decompressing\n\n");\r
+\r
+                       Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();\r
+                       Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();\r
+\r
+\r
+                       CoderPropID[] propIDs = \r
+                       { \r
+                               CoderPropID.DictionarySize,\r
+                       };\r
+                       object[] properties = \r
+                       {\r
+                               (Int32)(dictionarySize),\r
+                       };\r
+\r
+                       UInt32 kBufferSize = dictionarySize + kAdditionalSize;\r
+                       UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;\r
+\r
+                       encoder.SetCoderProperties(propIDs, properties);\r
+                       System.IO.MemoryStream propStream = new System.IO.MemoryStream();\r
+                       encoder.WriteCoderProperties(propStream);\r
+                       byte[] propArray = propStream.ToArray();\r
+\r
+                       CBenchRandomGenerator rg = new CBenchRandomGenerator();\r
+\r
+                       rg.Set(kBufferSize);\r
+                       rg.Generate();\r
+                       CRC crc = new CRC();\r
+                       crc.Init();\r
+                       crc.Update(rg.Buffer, 0, rg.BufferSize);\r
+\r
+                       CProgressInfo progressInfo = new CProgressInfo();\r
+                       progressInfo.ApprovedStart = dictionarySize;\r
+\r
+                       UInt64 totalBenchSize = 0;\r
+                       UInt64 totalEncodeTime = 0;\r
+                       UInt64 totalDecodeTime = 0;\r
+                       UInt64 totalCompressedSize = 0;\r
+\r
+                       MemoryStream inStream = new MemoryStream(rg.Buffer, 0, (int)rg.BufferSize);\r
+                       MemoryStream compressedStream = new MemoryStream((int)kCompressedBufferSize);\r
+                       CrcOutStream crcOutStream = new CrcOutStream();\r
+                       for (Int32 i = 0; i < numIterations; i++)\r
+                       {\r
+                               progressInfo.Init();\r
+                               inStream.Seek(0, SeekOrigin.Begin);\r
+                               compressedStream.Seek(0, SeekOrigin.Begin);\r
+                               encoder.Code(inStream, compressedStream, -1, -1, progressInfo);\r
+                               TimeSpan sp2 = DateTime.UtcNow - progressInfo.Time;\r
+                               UInt64 encodeTime = (UInt64)sp2.Ticks;\r
+\r
+                               long compressedSize = compressedStream.Position;\r
+                               if (progressInfo.InSize == 0)\r
+                                       throw (new Exception("Internal ERROR 1282"));\r
+\r
+                               UInt64 decodeTime = 0;\r
+                               for (int j = 0; j < 2; j++)\r
+                               {\r
+                                       compressedStream.Seek(0, SeekOrigin.Begin);\r
+                                       crcOutStream.Init();\r
+\r
+                                       decoder.SetDecoderProperties(propArray);\r
+                                       UInt64 outSize = kBufferSize;\r
+                                       System.DateTime startTime = DateTime.UtcNow;\r
+                                       decoder.Code(compressedStream, crcOutStream, 0, (Int64)outSize, null);\r
+                                       TimeSpan sp = (DateTime.UtcNow - startTime);\r
+                                       decodeTime = (ulong)sp.Ticks;\r
+                                       if (crcOutStream.GetDigest() != crc.GetDigest())\r
+                                               throw (new Exception("CRC Error"));\r
+                               }\r
+                               UInt64 benchSize = kBufferSize - (UInt64)progressInfo.InSize;\r
+                               PrintResults(dictionarySize, encodeTime, benchSize, false, 0);\r
+                               System.Console.Write("     ");\r
+                               PrintResults(dictionarySize, decodeTime, kBufferSize, true, (ulong)compressedSize);\r
+                               System.Console.WriteLine();\r
+\r
+                               totalBenchSize += benchSize;\r
+                               totalEncodeTime += encodeTime;\r
+                               totalDecodeTime += decodeTime;\r
+                               totalCompressedSize += (ulong)compressedSize;\r
+                       }\r
+                       System.Console.WriteLine("---------------------------------------------------");\r
+                       PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);\r
+                       System.Console.Write("     ");\r
+                       PrintResults(dictionarySize, totalDecodeTime,\r
+                                       kBufferSize * (UInt64)numIterations, true, totalCompressedSize);\r
+                       System.Console.WriteLine("    Average");\r
+                       return 0;\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs b/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs
new file mode 100755 (executable)
index 0000000..a394aee
--- /dev/null
@@ -0,0 +1,29 @@
+#region Using directives\r
+\r
+using System.Reflection;\r
+using System.Runtime.CompilerServices;\r
+\r
+#endregion\r
+\r
+// General Information about an assembly is controlled through the following \r
+// set of attributes. Change these attribute values to modify the information\r
+// associated with an assembly.\r
+[assembly: AssemblyTitle("LZMA#")]\r
+[assembly: AssemblyDescription("")]\r
+[assembly: AssemblyConfiguration("")]\r
+[assembly: AssemblyCompany("Igor Pavlov")]\r
+[assembly: AssemblyProduct("LZMA# SDK")]\r
+[assembly: AssemblyCopyright("Copyright @ Igor Pavlov 1999-2004")]\r
+[assembly: AssemblyTrademark("")]\r
+[assembly: AssemblyCulture("")]\r
+\r
+// Version information for an assembly consists of the following four values:\r
+//\r
+//      Major Version\r
+//      Minor Version \r
+//      Build Number\r
+//      Revision\r
+//\r
+// You can specify all the values or you can default the Revision and Build Numbers \r
+// by using the '*' as shown below:\r
+[assembly: AssemblyVersion("4.12.*")]\r
diff --git a/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs b/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs
new file mode 100755 (executable)
index 0000000..efe4ee9
--- /dev/null
@@ -0,0 +1,70 @@
+//------------------------------------------------------------------------------\r
+// <autogenerated>\r
+//     This code was generated by a tool.\r
+//     Runtime Version:2.0.40607.42\r
+//\r
+//     Changes to this file may cause incorrect behavior and will be lost if\r
+//     the code is regenerated.\r
+// </autogenerated>\r
+//------------------------------------------------------------------------------\r
+\r
+namespace LzmaAlone.Properties\r
+{\r
+       using System;\r
+       using System.IO;\r
+       using System.Resources;\r
+\r
+       /// <summary>\r
+       ///    A strongly-typed resource class, for looking up localized strings, etc.\r
+       /// </summary>\r
+       // This class was auto-generated by the Strongly Typed Resource Builder\r
+       // class via a tool like ResGen or Visual Studio.NET.\r
+       // To add or remove a member, edit your .ResX file then rerun ResGen\r
+       // with the /str option, or rebuild your VS project.\r
+       class Resources\r
+       {\r
+\r
+               private static System.Resources.ResourceManager _resMgr;\r
+\r
+               private static System.Globalization.CultureInfo _resCulture;\r
+\r
+               /*FamANDAssem*/\r
+               internal Resources()\r
+               {\r
+               }\r
+\r
+               /// <summary>\r
+               ///    Returns the cached ResourceManager instance used by this class.\r
+               /// </summary>\r
+               [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]\r
+               public static System.Resources.ResourceManager ResourceManager\r
+               {\r
+                       get\r
+                       {\r
+                               if ((_resMgr == null))\r
+                               {\r
+                                       System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Resources", typeof(Resources).Assembly);\r
+                                       _resMgr = temp;\r
+                               }\r
+                               return _resMgr;\r
+                       }\r
+               }\r
+\r
+               /// <summary>\r
+               ///    Overrides the current thread's CurrentUICulture property for all\r
+               ///    resource lookups using this strongly typed resource class.\r
+               /// </summary>\r
+               [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]\r
+               public static System.Globalization.CultureInfo Culture\r
+               {\r
+                       get\r
+                       {\r
+                               return _resCulture;\r
+                       }\r
+                       set\r
+                       {\r
+                               _resCulture = value;\r
+                       }\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs b/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs
new file mode 100755 (executable)
index 0000000..1281fd2
--- /dev/null
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------\r
+// <autogenerated>\r
+//     This code was generated by a tool.\r
+//     Runtime Version:2.0.40607.42\r
+//\r
+//     Changes to this file may cause incorrect behavior and will be lost if\r
+//     the code is regenerated.\r
+// </autogenerated>\r
+//------------------------------------------------------------------------------\r
+\r
+namespace LzmaAlone.Properties\r
+{\r
+       public partial class Settings : System.Configuration.ApplicationSettingsBase\r
+       {\r
+               private static Settings m_Value;\r
+\r
+               private static object m_SyncObject = new object();\r
+\r
+               public static Settings Value\r
+               {\r
+                       get\r
+                       {\r
+                               if ((Settings.m_Value == null))\r
+                               {\r
+                                       System.Threading.Monitor.Enter(Settings.m_SyncObject);\r
+                                       if ((Settings.m_Value == null))\r
+                                       {\r
+                                               try\r
+                                               {\r
+                                                       Settings.m_Value = new Settings();\r
+                                               }\r
+                                               finally\r
+                                               {\r
+                                                       System.Threading.Monitor.Exit(Settings.m_SyncObject);\r
+                                               }\r
+                                       }\r
+                               }\r
+                               return Settings.m_Value;\r
+                       }\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/RangeCoder/RangeCoder.cs b/CS/7zip/Compress/RangeCoder/RangeCoder.cs
new file mode 100755 (executable)
index 0000000..4ced247
--- /dev/null
@@ -0,0 +1,234 @@
+using System;\r
+\r
+namespace SevenZip.Compression.RangeCoder\r
+{\r
+       class Encoder\r
+       {\r
+               public const uint kTopValue = (1 << 24);\r
+\r
+               System.IO.Stream Stream;\r
+\r
+               public UInt64 Low;\r
+               public uint Range;\r
+               uint _cacheSize;\r
+               byte _cache;\r
+\r
+               long StartPosition;\r
+\r
+               public void SetStream(System.IO.Stream stream)\r
+               {\r
+                       Stream = stream;\r
+               }\r
+\r
+               public void ReleaseStream()\r
+               {\r
+                       Stream = null;\r
+               }\r
+\r
+               public void Init()\r
+               {\r
+                       StartPosition = Stream.Position;\r
+\r
+                       Low = 0;\r
+                       Range = 0xFFFFFFFF;\r
+                       _cacheSize = 1;\r
+                       _cache = 0;\r
+               }\r
+\r
+               public void FlushData()\r
+               {\r
+                       for (int i = 0; i < 5; i++)\r
+                               ShiftLow();\r
+               }\r
+\r
+               public void FlushStream()\r
+               {\r
+                       Stream.Flush();\r
+               }\r
+\r
+               public void CloseStream()\r
+               {\r
+                       Stream.Close();\r
+               }\r
+\r
+               public void Encode(uint start, uint size, uint total)\r
+               {\r
+                       Low += start * (Range /= total);\r
+                       Range *= size;\r
+                       while (Range < kTopValue)\r
+                       {\r
+                               Range <<= 8;\r
+                               ShiftLow();\r
+                       }\r
+               }\r
+\r
+               public void ShiftLow()\r
+               {\r
+                       if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1)\r
+                       {\r
+                               byte temp = _cache;\r
+                               do\r
+                               {\r
+                                       Stream.WriteByte((byte)(temp + (Low >> 32)));\r
+                                       temp = 0xFF;\r
+                               }\r
+                               while (--_cacheSize != 0);\r
+                               _cache = (byte)(((uint)Low) >> 24);\r
+                       }\r
+                       _cacheSize++;\r
+                       Low = ((uint)Low) << 8;\r
+               }\r
+\r
+               public void EncodeDirectBits(uint v, int numTotalBits)\r
+               {\r
+                       for (int i = numTotalBits - 1; i >= 0; i--)\r
+                       {\r
+                               Range >>= 1;\r
+                               if (((v >> i) & 1) == 1)\r
+                                       Low += Range;\r
+                               if (Range < kTopValue)\r
+                               {\r
+                                       Range <<= 8;\r
+                                       ShiftLow();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               public void EncodeBit(uint size0, int numTotalBits, uint symbol)\r
+               {\r
+                       uint newBound = (Range >> numTotalBits) * size0;\r
+                       if (symbol == 0)\r
+                               Range = newBound;\r
+                       else\r
+                       {\r
+                               Low += newBound;\r
+                               Range -= newBound;\r
+                       }\r
+                       while (Range < kTopValue)\r
+                       {\r
+                               Range <<= 8;\r
+                               ShiftLow();\r
+                       }\r
+               }\r
+\r
+               public long GetProcessedSizeAdd()\r
+               {\r
+                       return _cacheSize +\r
+                               Stream.Position - StartPosition + 4;\r
+                       // (long)Stream.GetProcessedSize();\r
+               }\r
+       }\r
+\r
+       class Decoder\r
+       {\r
+               public const uint kTopValue = (1 << 24);\r
+               public uint Range;\r
+               public uint Code;\r
+               // public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);\r
+               public System.IO.Stream Stream;\r
+\r
+               public void Init(System.IO.Stream stream)\r
+               {\r
+                       // Stream.Init(stream);\r
+                       Stream = stream;\r
+\r
+                       Code = 0;\r
+                       Range = 0xFFFFFFFF;\r
+                       for (int i = 0; i < 5; i++)\r
+                               Code = (Code << 8) | (byte)Stream.ReadByte();\r
+               }\r
+\r
+               public void ReleaseStream()\r
+               {\r
+                       // Stream.ReleaseStream();\r
+                       Stream = null;\r
+               }\r
+\r
+               public void CloseStream()\r
+               {\r
+                       Stream.Close();\r
+               }\r
+\r
+               public void Normalize()\r
+               {\r
+                       while (Range < kTopValue)\r
+                       {\r
+                               Code = (Code << 8) | (byte)Stream.ReadByte();\r
+                               Range <<= 8;\r
+                       }\r
+               }\r
+\r
+               public void Normalize2()\r
+               {\r
+                       if (Range < kTopValue)\r
+                       {\r
+                               Code = (Code << 8) | (byte)Stream.ReadByte();\r
+                               Range <<= 8;\r
+                       }\r
+               }\r
+\r
+               public uint GetThreshold(uint total)\r
+               {\r
+                       return Code / (Range /= total);\r
+               }\r
+\r
+               public void Decode(uint start, uint size, uint total)\r
+               {\r
+                       Code -= start * Range;\r
+                       Range *= size;\r
+                       Normalize();\r
+               }\r
+\r
+               public uint DecodeDirectBits(int numTotalBits)\r
+               {\r
+                       uint range = Range;\r
+                       uint code = Code;\r
+                       uint result = 0;\r
+                       for (int i = numTotalBits; i > 0; i--)\r
+                       {\r
+                               range >>= 1;\r
+                               /*\r
+                               result <<= 1;\r
+                               if (code >= range)\r
+                               {\r
+                                       code -= range;\r
+                                       result |= 1;\r
+                               }\r
+                               */\r
+                               uint t = (code - range) >> 31;\r
+                               code -= range & (t - 1);\r
+                               result = (result << 1) | (1 - t);\r
+\r
+                               if (range < kTopValue)\r
+                               {\r
+                                       code = (code << 8) | (byte)Stream.ReadByte();\r
+                                       range <<= 8;\r
+                               }\r
+                       }\r
+                       Range = range;\r
+                       Code = code;\r
+                       return result;\r
+               }\r
+\r
+               public uint DecodeBit(uint size0, int numTotalBits)\r
+               {\r
+                       uint newBound = (Range >> numTotalBits) * size0;\r
+                       uint symbol;\r
+                       if (Code < newBound)\r
+                       {\r
+                               symbol = 0;\r
+                               Range = newBound;\r
+                       }\r
+                       else\r
+                       {\r
+                               symbol = 1;\r
+                               Code -= newBound;\r
+                               Range -= newBound;\r
+                       }\r
+                       Normalize();\r
+                       return symbol;\r
+               }\r
+\r
+               // ulong GetProcessedSize() {return Stream.GetProcessedSize(); }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs b/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs
new file mode 100755 (executable)
index 0000000..000a5a0
--- /dev/null
@@ -0,0 +1,117 @@
+using System;\r
+\r
+namespace SevenZip.Compression.RangeCoder\r
+{\r
+       struct BitEncoder\r
+       {\r
+               public const int kNumBitModelTotalBits = 11;\r
+               public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);\r
+               const int kNumMoveBits = 5;\r
+               const int kNumMoveReducingBits = 2;\r
+               public const int kNumBitPriceShiftBits = 6;\r
+\r
+               uint Prob;\r
+\r
+               public void Init() { Prob = kBitModelTotal >> 1; }\r
+\r
+               public void UpdateModel(uint symbol)\r
+               {\r
+                       if (symbol == 0)\r
+                               Prob += (kBitModelTotal - Prob) >> kNumMoveBits;\r
+                       else\r
+                               Prob -= (Prob) >> kNumMoveBits;\r
+               }\r
+\r
+               public void Encode(Encoder encoder, uint symbol)\r
+               {\r
+                       // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);\r
+                       // UpdateModel(symbol);\r
+                       uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob;\r
+                       if (symbol == 0)\r
+                       {\r
+                               encoder.Range = newBound;\r
+                               Prob += (kBitModelTotal - Prob) >> kNumMoveBits;\r
+                       }\r
+                       else\r
+                       {\r
+                               encoder.Low += newBound;\r
+                               encoder.Range -= newBound;\r
+                               Prob -= (Prob) >> kNumMoveBits;\r
+                       }\r
+                       if (encoder.Range < Encoder.kTopValue)\r
+                       {\r
+                               encoder.Range <<= 8;\r
+                               encoder.ShiftLow();\r
+                       }\r
+               }\r
+\r
+               private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits];\r
+\r
+               static BitEncoder()\r
+               {\r
+                       const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);\r
+                       for (int i = kNumBits - 1; i >= 0; i--)\r
+                       {\r
+                               UInt32 start = (UInt32)1 << (kNumBits - i - 1);\r
+                               UInt32 end = (UInt32)1 << (kNumBits - i);\r
+                               for (UInt32 j = start; j < end; j++)\r
+                                       ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) +\r
+                                               (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));\r
+                       }\r
+               }\r
+\r
+               public uint GetPrice(uint symbol)\r
+               {\r
+                       return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];\r
+               }\r
+         public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; }\r
+               public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; }\r
+       }\r
+\r
+       struct BitDecoder\r
+       {\r
+               public const int kNumBitModelTotalBits = 11;\r
+               public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);\r
+               const int kNumMoveBits = 5;\r
+\r
+               uint Prob;\r
+\r
+               public void UpdateModel(int numMoveBits, uint symbol)\r
+               {\r
+                       if (symbol == 0)\r
+                               Prob += (kBitModelTotal - Prob) >> numMoveBits;\r
+                       else\r
+                               Prob -= (Prob) >> numMoveBits;\r
+               }\r
+\r
+               public void Init() { Prob = kBitModelTotal >> 1; }\r
+\r
+               public uint Decode(RangeCoder.Decoder rangeDecoder)\r
+               {\r
+                       uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob;\r
+                       if (rangeDecoder.Code < newBound)\r
+                       {\r
+                               rangeDecoder.Range = newBound;\r
+                               Prob += (kBitModelTotal - Prob) >> kNumMoveBits;\r
+                               if (rangeDecoder.Range < Decoder.kTopValue)\r
+                               {\r
+                                       rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();\r
+                                       rangeDecoder.Range <<= 8;\r
+                               }\r
+                               return 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               rangeDecoder.Range -= newBound;\r
+                               rangeDecoder.Code -= newBound;\r
+                               Prob -= (Prob) >> kNumMoveBits;\r
+                               if (rangeDecoder.Range < Decoder.kTopValue)\r
+                               {\r
+                                       rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();\r
+                                       rangeDecoder.Range <<= 8;\r
+                               }\r
+                               return 1;\r
+                       }\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs b/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
new file mode 100755 (executable)
index 0000000..3309c14
--- /dev/null
@@ -0,0 +1,157 @@
+using System;\r
+\r
+namespace SevenZip.Compression.RangeCoder\r
+{\r
+       struct BitTreeEncoder\r
+       {\r
+               BitEncoder[] Models;\r
+               int NumBitLevels;\r
+\r
+               public BitTreeEncoder(int numBitLevels)\r
+               {\r
+                       NumBitLevels = numBitLevels;\r
+                       Models = new BitEncoder[1 << numBitLevels];\r
+               }\r
+\r
+               public void Init()\r
+               {\r
+                       for (uint i = 1; i < (1 << NumBitLevels); i++)\r
+                               Models[i].Init();\r
+               }\r
+\r
+               public void Encode(Encoder rangeEncoder, UInt32 symbol)\r
+               {\r
+                       UInt32 m = 1;\r
+                       for (int bitIndex = NumBitLevels; bitIndex > 0; )\r
+                       {\r
+                               bitIndex--;\r
+                               UInt32 bit = (symbol >> bitIndex) & 1;\r
+                               Models[m].Encode(rangeEncoder, bit);\r
+                               m = (m << 1) | bit;\r
+                       }\r
+               }\r
+\r
+               public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)\r
+               {\r
+                       UInt32 m = 1;\r
+                       for (UInt32 i = 0; i < NumBitLevels; i++)\r
+                       {\r
+                               UInt32 bit = symbol & 1;\r
+                               Models[m].Encode(rangeEncoder, bit);\r
+                               m = (m << 1) | bit;\r
+                               symbol >>= 1;\r
+                       }\r
+               }\r
+\r
+               public UInt32 GetPrice(UInt32 symbol)\r
+               {\r
+                       UInt32 price = 0;\r
+                       UInt32 m = 1;\r
+                       for (int bitIndex = NumBitLevels; bitIndex > 0; )\r
+                       {\r
+                               bitIndex--;\r
+                               UInt32 bit = (symbol >> bitIndex) & 1;\r
+                               price += Models[m].GetPrice(bit);\r
+                               m = (m << 1) + bit;\r
+                       }\r
+                       return price;\r
+               }\r
+\r
+               public UInt32 ReverseGetPrice(UInt32 symbol)\r
+               {\r
+                       UInt32 price = 0;\r
+                       UInt32 m = 1;\r
+                       for (int i = NumBitLevels; i > 0; i--)\r
+                       {\r
+                               UInt32 bit = symbol & 1;\r
+                               symbol >>= 1;\r
+                               price += Models[m].GetPrice(bit);\r
+                               m = (m << 1) | bit;\r
+                       }\r
+                       return price;\r
+               }\r
+\r
+               public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex,\r
+                       int NumBitLevels, UInt32 symbol)\r
+               {\r
+                       UInt32 price = 0;\r
+                       UInt32 m = 1;\r
+                       for (int i = NumBitLevels; i > 0; i--)\r
+                       {\r
+                               UInt32 bit = symbol & 1;\r
+                               symbol >>= 1;\r
+                               price += Models[startIndex + m].GetPrice(bit);\r
+                               m = (m << 1) | bit;\r
+                       }\r
+                       return price;\r
+               }\r
+\r
+               public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex,\r
+                       Encoder rangeEncoder, int NumBitLevels, UInt32 symbol)\r
+               {\r
+                       UInt32 m = 1;\r
+                       for (int i = 0; i < NumBitLevels; i++)\r
+                       {\r
+                               UInt32 bit = symbol & 1;\r
+                               Models[startIndex + m].Encode(rangeEncoder, bit);\r
+                               m = (m << 1) | bit;\r
+                               symbol >>= 1;\r
+                       }\r
+               }\r
+       }\r
+\r
+       struct BitTreeDecoder\r
+       {\r
+               BitDecoder[] Models;\r
+               int NumBitLevels;\r
+\r
+               public BitTreeDecoder(int numBitLevels)\r
+               {\r
+                       NumBitLevels = numBitLevels;\r
+                       Models = new BitDecoder[1 << numBitLevels];\r
+               }\r
+\r
+               public void Init()\r
+               {\r
+                       for (uint i = 1; i < (1 << NumBitLevels); i++)\r
+                               Models[i].Init();\r
+               }\r
+\r
+               public uint Decode(RangeCoder.Decoder rangeDecoder)\r
+               {\r
+                       uint m = 1;\r
+                       for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)\r
+                               m = (m << 1) + Models[m].Decode(rangeDecoder);\r
+                       return m - ((uint)1 << NumBitLevels);\r
+               }\r
+\r
+               public uint ReverseDecode(RangeCoder.Decoder rangeDecoder)\r
+               {\r
+                       uint m = 1;\r
+                       uint symbol = 0;\r
+                       for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)\r
+                       {\r
+                               uint bit = Models[m].Decode(rangeDecoder);\r
+                               m <<= 1;\r
+                               m += bit;\r
+                               symbol |= (bit << bitIndex);\r
+                       }\r
+                       return symbol;\r
+               }\r
+\r
+               public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,\r
+                       RangeCoder.Decoder rangeDecoder, int NumBitLevels)\r
+               {\r
+                       uint m = 1;\r
+                       uint symbol = 0;\r
+                       for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)\r
+                       {\r
+                               uint bit = Models[startIndex + m].Decode(rangeDecoder);\r
+                               m <<= 1;\r
+                               m += bit;\r
+                               symbol |= (bit << bitIndex);\r
+                       }\r
+                       return symbol;\r
+               }\r
+       }\r
+}\r
diff --git a/CS/7zip/ICoder.cs b/CS/7zip/ICoder.cs
new file mode 100755 (executable)
index 0000000..875cb27
--- /dev/null
@@ -0,0 +1,157 @@
+// ICoder.h\r
+\r
+using System;\r
+\r
+namespace SevenZip\r
+{\r
+       /// <summary>\r
+       /// The exception that is thrown when an error in input stream occurs during decoding.\r
+       /// </summary>\r
+       class DataErrorException : ApplicationException\r
+       {\r
+               public DataErrorException(): base("Data Error") { }\r
+       }\r
+\r
+       /// <summary>\r
+       /// The exception that is thrown when the value of an argument is outside the allowable range.\r
+       /// </summary>\r
+       class InvalidParamException : ApplicationException\r
+       {\r
+               public InvalidParamException(): base("Invalid Parameter") { }\r
+       }\r
+\r
+       public interface ICodeProgress\r
+       {\r
+               /// <summary>\r
+               /// Callback progress.\r
+               /// </summary>\r
+               /// <param name="inSize">\r
+               /// input size. -1 if unknown.\r
+               /// </param>\r
+               /// <param name="outSize">\r
+               /// output size. -1 if unknown.\r
+               /// </param>\r
+               void SetProgress(Int64 inSize, Int64 outSize);\r
+       };\r
+\r
+       public interface ICoder\r
+       {\r
+               /// <summary>\r
+               /// Codes streams.\r
+               /// </summary>\r
+               /// <param name="inStream">\r
+               /// input Stream.\r
+               /// </param>\r
+               /// <param name="outStream">\r
+               /// output Stream.\r
+               /// </param>\r
+               /// <param name="inSize">\r
+               /// input Size. -1 if unknown.\r
+               /// </param>\r
+               /// <param name="outSize">\r
+               /// output Size. -1 if unknown.\r
+               /// </param>\r
+               /// <param name="progress">\r
+               /// callback progress reference.\r
+               /// </param>\r
+               /// <exception cref="SevenZip.DataErrorException">\r
+               /// if input stream is not valid\r
+               /// </exception>\r
+               void Code(System.IO.Stream inStream, System.IO.Stream outStream,\r
+                       Int64 inSize, Int64 outSize, ICodeProgress progress);\r
+       };\r
+\r
+       /*\r
+       public interface ICoder2\r
+       {\r
+                void Code(ISequentialInStream []inStreams,\r
+                               const UInt64 []inSizes, \r
+                               ISequentialOutStream []outStreams, \r
+                               UInt64 []outSizes,\r
+                               ICodeProgress progress);\r
+       };\r
+  */\r
+\r
+       /// <summary>\r
+       /// Provides the fields that represent properties idenitifiers for compressing.\r
+       /// </summary>\r
+       public enum CoderPropID\r
+       {\r
+               /// <summary>\r
+               /// Specifies default property.\r
+               /// </summary>\r
+               DefaultProp = 0,\r
+               /// <summary>\r
+               /// Specifies size of dictionary.\r
+               /// </summary>\r
+               DictionarySize,\r
+               /// <summary>\r
+               /// Specifies size of memory for PPM*.\r
+               /// </summary>\r
+               UsedMemorySize,\r
+               /// <summary>\r
+               /// Specifies order for PPM methods.\r
+               /// </summary>\r
+               Order,\r
+               /// <summary>\r
+               /// Specifies Block Size.\r
+               /// </summary>\r
+               BlockSize,\r
+               /// <summary>\r
+               /// Specifies number of postion state bits for LZMA (0 <= x <= 4).\r
+               /// </summary>\r
+               PosStateBits,\r
+               /// <summary>\r
+               /// Specifies number of literal context bits for LZMA (0 <= x <= 8).\r
+               /// </summary>\r
+               LitContextBits,\r
+               /// <summary>\r
+               /// Specifies number of literal position bits for LZMA (0 <= x <= 4).\r
+               /// </summary>\r
+               LitPosBits,\r
+               /// <summary>\r
+               /// Specifies number of fast bytes for LZ*.\r
+               /// </summary>\r
+               NumFastBytes,\r
+               /// <summary>\r
+               /// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".\r
+               /// </summary>\r
+               MatchFinder,\r
+               /// <summary>\r
+               /// Specifies the number of match finder cyckes.\r
+               /// </summary>\r
+               MatchFinderCycles,\r
+               /// <summary>\r
+               /// Specifies number of passes.\r
+               /// </summary>\r
+               NumPasses,\r
+               /// <summary>\r
+               /// Specifies number of algorithm.\r
+               /// </summary>\r
+               Algorithm,\r
+               /// <summary>\r
+               /// Specifies the number of threads.\r
+               /// </summary>\r
+               NumThreads,\r
+               /// <summary>\r
+               /// Specifies mode with end marker.\r
+               /// </summary>\r
+               EndMarker\r
+       };\r
+\r
+\r
+       public interface ISetCoderProperties\r
+       {\r
+               void SetCoderProperties(CoderPropID[] propIDs, object[] properties);\r
+       };\r
+\r
+       public interface IWriteCoderProperties\r
+       {\r
+               void WriteCoderProperties(System.IO.Stream outStream);\r
+       }\r
+\r
+       public interface ISetDecoderProperties\r
+       {\r
+               void SetDecoderProperties(byte[] properties);\r
+       }\r
+}\r
diff --git a/Java/SevenZip/CRC.java b/Java/SevenZip/CRC.java
new file mode 100755 (executable)
index 0000000..f2f791f
--- /dev/null
@@ -0,0 +1,52 @@
+// SevenZip/CRC.java\r
+\r
+package SevenZip;\r
+\r
+public class CRC\r
+{\r
+       static public int[] Table = new int[256];\r
+       \r
+       static\r
+       {\r
+               for (int i = 0; i < 256; i++)\r
+               {\r
+                       int r = i;\r
+                       for (int j = 0; j < 8; j++)\r
+                               if ((r & 1) != 0)\r
+                                       r = (r >>> 1) ^ 0xEDB88320;\r
+                               else\r
+                                       r >>>= 1;\r
+                       Table[i] = r;\r
+               }\r
+       }\r
+       \r
+       int _value = -1;\r
+       \r
+       public void Init()\r
+       {\r
+               _value = -1;\r
+       }\r
+       \r
+       public void Update(byte[] data, int offset, int size)\r
+       {\r
+               for (int i = 0; i < size; i++)\r
+                       _value = Table[(_value ^ data[offset + i]) & 0xFF] ^ (_value >>> 8);\r
+       }\r
+       \r
+       public void Update(byte[] data)\r
+       {\r
+               int size = data.length;\r
+               for (int i = 0; i < size; i++)\r
+                       _value = Table[(_value ^ data[i]) & 0xFF] ^ (_value >>> 8);\r
+       }\r
+       \r
+       public void UpdateByte(int b)\r
+       {\r
+               _value = Table[(_value ^ b) & 0xFF] ^ (_value >>> 8);\r
+       }\r
+       \r
+       public int GetDigest()\r
+       {\r
+               return _value ^ (-1);\r
+       }\r
+}\r
diff --git a/Java/SevenZip/Compression/LZ/BinTree.java b/Java/SevenZip/Compression/LZ/BinTree.java
new file mode 100755 (executable)
index 0000000..63d58c0
--- /dev/null
@@ -0,0 +1,382 @@
+// LZ.BinTree\r
+\r
+package SevenZip.Compression.LZ;\r
+import java.io.IOException;\r
+\r
+\r
+public class BinTree extends InWindow\r
+{\r
+       int _cyclicBufferPos;\r
+       int _cyclicBufferSize = 0;\r
+       int _matchMaxLen;\r
+       \r
+       int[] _son;\r
+       int[] _hash;\r
+       \r
+       int _cutValue = 0xFF;\r
+       int _hashMask;\r
+       int _hashSizeSum = 0;\r
+       \r
+       boolean HASH_ARRAY = true;\r
+\r
+       static final int kHash2Size = 1 << 10;\r
+       static final int kHash3Size = 1 << 16;\r
+       static final int kBT2HashSize = 1 << 16;\r
+       static final int kStartMaxLen = 1;\r
+       static final int kHash3Offset = kHash2Size;\r
+       static final int kEmptyHashValue = 0;\r
+       static final int kMaxValForNormalize = (1 << 30) - 1;\r
+       \r
+       int kNumHashDirectBytes = 0;\r
+       int kMinMatchCheck = 4;\r
+       int kFixHashSize = kHash2Size + kHash3Size;\r
+\r
+       public void SetType(int numHashBytes)\r
+       {\r
+               HASH_ARRAY = (numHashBytes > 2);\r
+               if (HASH_ARRAY)\r
+               {\r
+                       kNumHashDirectBytes = 0;\r
+                       kMinMatchCheck = 4;\r
+                       kFixHashSize = kHash2Size + kHash3Size;\r
+               }\r
+               else\r
+               {\r
+                       kNumHashDirectBytes = 2;\r
+                       kMinMatchCheck = 2 + 1;\r
+                       kFixHashSize = 0;\r
+               }\r
+       }\r
+       \r
+\r
+       \r
+\r
+       public void Init() throws IOException\r
+       {\r
+               super.Init();\r
+               for (int i = 0; i < _hashSizeSum; i++)\r
+                       _hash[i] = kEmptyHashValue;\r
+               _cyclicBufferPos = 0;\r
+               ReduceOffsets(-1);\r
+       }\r
+       \r
+       public void MovePos() throws IOException\r
+       {\r
+               if (++_cyclicBufferPos >= _cyclicBufferSize)\r
+                       _cyclicBufferPos = 0;\r
+               super.MovePos();\r
+               if (_pos == kMaxValForNormalize)\r
+                       Normalize();\r
+       }\r
+       \r
+\r
+       \r
+       \r
+       \r
+       \r
+       \r
+       \r
+       public boolean Create(int historySize, int keepAddBufferBefore,\r
+                       int matchMaxLen, int keepAddBufferAfter)\r
+       {\r
+               if (historySize > kMaxValForNormalize - 256)\r
+                       return false;\r
+               _cutValue = 16 + (matchMaxLen >> 1);\r
+\r
+               int windowReservSize = (historySize + keepAddBufferBefore +\r
+                               matchMaxLen + keepAddBufferAfter) / 2 + 256;\r
+               \r
+               super.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);\r
+               \r
+               _matchMaxLen = matchMaxLen;\r
+\r
+               int cyclicBufferSize = historySize + 1;\r
+               if (_cyclicBufferSize != cyclicBufferSize)\r
+                       _son = new int[(_cyclicBufferSize = cyclicBufferSize) * 2];\r
+\r
+               int hs = kBT2HashSize;\r
+\r
+               if (HASH_ARRAY)\r
+               {\r
+                       hs = historySize - 1;\r
+                       hs |= (hs >> 1);\r
+                       hs |= (hs >> 2);\r
+                       hs |= (hs >> 4);\r
+                       hs |= (hs >> 8);\r
+                       hs >>= 1;\r
+                       hs |= 0xFFFF;\r
+                       if (hs > (1 << 24))\r
+                               hs >>= 1;\r
+                       _hashMask = hs;\r
+                       hs++;\r
+                       hs += kFixHashSize;\r
+               }\r
+               if (hs != _hashSizeSum)\r
+                       _hash = new int [_hashSizeSum = hs];\r
+               return true;\r
+       }\r
+       public int GetMatches(int[] distances) throws IOException\r
+       {\r
+               int lenLimit;\r
+               if (_pos + _matchMaxLen <= _streamPos)\r
+                       lenLimit = _matchMaxLen;\r
+               else\r
+               {\r
+                       lenLimit = _streamPos - _pos;\r
+                       if (lenLimit < kMinMatchCheck)\r
+                       {\r
+                               MovePos();\r
+                               return 0;\r
+                       }\r
+               }\r
+\r
+               int offset = 0;\r
+               int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;\r
+               int cur = _bufferOffset + _pos;\r
+               int maxLen = kStartMaxLen; // to avoid items for len < hashSize;\r
+               int hashValue, hash2Value = 0, hash3Value = 0;\r
+               \r
+               if (HASH_ARRAY)\r
+               {\r
+                       int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);\r
+                       hash2Value = temp & (kHash2Size - 1);\r
+                       temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);\r
+                       hash3Value = temp & (kHash3Size - 1);\r
+                       hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;\r
+               }\r
+               else\r
+                       hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));\r
+\r
+               int curMatch = _hash[kFixHashSize + hashValue];\r
+               if (HASH_ARRAY)\r
+               {\r
+                       int curMatch2 = _hash[hash2Value];\r
+                       int curMatch3 = _hash[kHash3Offset + hash3Value];\r
+                       _hash[hash2Value] = _pos;\r
+                       _hash[kHash3Offset + hash3Value] = _pos;\r
+                       if (curMatch2 > matchMinPos)\r
+                               if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])\r
+                               {\r
+                                       distances[offset++] = maxLen = 2;\r
+                                       distances[offset++] = _pos - curMatch2 - 1;\r
+                               }\r
+                       if (curMatch3 > matchMinPos)\r
+                               if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])\r
+                               {\r
+                                       if (curMatch3 == curMatch2)\r
+                                               offset -= 2;\r
+                                       distances[offset++] = maxLen = 3;\r
+                                       distances[offset++] = _pos - curMatch3 - 1;\r
+                                       curMatch2 = curMatch3;\r
+                               }\r
+                       if (offset != 0 && curMatch2 == curMatch)\r
+                       {\r
+                               offset -= 2;\r
+                               maxLen = kStartMaxLen;\r
+                       }\r
+               }\r
+\r
+               _hash[kFixHashSize + hashValue] = _pos;\r
+\r
+               int ptr0 = (_cyclicBufferPos << 1) + 1;\r
+               int ptr1 = (_cyclicBufferPos << 1);\r
+\r
+               int len0, len1;\r
+               len0 = len1 = kNumHashDirectBytes;\r
+\r
+               if (kNumHashDirectBytes != 0)\r
+               {\r
+                       if (curMatch > matchMinPos)\r
+                       {\r
+                               if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=\r
+                                               _bufferBase[cur + kNumHashDirectBytes])\r
+                               {\r
+                                       distances[offset++] = maxLen = kNumHashDirectBytes;\r
+                                       distances[offset++] = _pos - curMatch - 1;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               int count = _cutValue;\r
+\r
+               while (true)\r
+               {\r
+                       if (curMatch <= matchMinPos || count-- == 0)\r
+                       {\r
+                               _son[ptr0] = _son[ptr1] = kEmptyHashValue;\r
+                               break;\r
+                       }\r
+                       int delta = _pos - curMatch;\r
+                       int cyclicPos = ((delta <= _cyclicBufferPos) ?\r
+                               (_cyclicBufferPos - delta) :\r
+                               (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;\r
+\r
+                       int pby1 = _bufferOffset + curMatch;\r
+                       int len = Math.min(len0, len1);\r
+                       if (_bufferBase[pby1 + len] == _bufferBase[cur + len])\r
+                       {\r
+                               while(++len != lenLimit)\r
+                                       if (_bufferBase[pby1 + len] != _bufferBase[cur + len])\r
+                                               break;\r
+                               if (maxLen < len)\r
+                               {\r
+                                       distances[offset++] = maxLen = len;\r
+                                       distances[offset++] = delta - 1;\r
+                                       if (len == lenLimit)\r
+                                       {\r
+                                               _son[ptr1] = _son[cyclicPos];\r
+                                               _son[ptr0] = _son[cyclicPos + 1];\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))\r
+                       {\r
+                               _son[ptr1] = curMatch;\r
+                               ptr1 = cyclicPos + 1;\r
+                               curMatch = _son[ptr1];\r
+                               len1 = len;\r
+                       }\r
+                       else\r
+                       {\r
+                               _son[ptr0] = curMatch;\r
+                               ptr0 = cyclicPos;\r
+                               curMatch = _son[ptr0];\r
+                               len0 = len;\r
+                       }\r
+               }\r
+               MovePos();\r
+               return offset;\r
+       }\r
+\r
+       public void Skip(int num) throws IOException\r
+       {\r
+               do\r
+               {\r
+                       int lenLimit;\r
+                       if (_pos + _matchMaxLen <= _streamPos)\r
+                       lenLimit = _matchMaxLen;\r
+                       else\r
+                       {\r
+                               lenLimit = _streamPos - _pos;\r
+                               if (lenLimit < kMinMatchCheck)\r
+                               {\r
+                                       MovePos();\r
+                                       continue;\r
+                               }\r
+                       }\r
+\r
+                       int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;\r
+                       int cur = _bufferOffset + _pos;\r
+                       \r
+                       int hashValue;\r
+\r
+                       if (HASH_ARRAY)\r
+                       {\r
+                               int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);\r
+                               int hash2Value = temp & (kHash2Size - 1);\r
+                               _hash[hash2Value] = _pos;\r
+                               temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);\r
+                               int hash3Value = temp & (kHash3Size - 1);\r
+                               _hash[kHash3Offset + hash3Value] = _pos;\r
+                               hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;\r
+                       }\r
+                       else\r
+                               hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));\r
+\r
+                       int curMatch = _hash[kFixHashSize + hashValue];\r
+                       _hash[kFixHashSize + hashValue] = _pos;\r
+\r
+                       int ptr0 = (_cyclicBufferPos << 1) + 1;\r
+                       int ptr1 = (_cyclicBufferPos << 1);\r
+\r
+                       int len0, len1;\r
+                       len0 = len1 = kNumHashDirectBytes;\r
+\r
+                       int count = _cutValue;\r
+                       while (true)\r
+                       {\r
+                               if (curMatch <= matchMinPos || count-- == 0)\r
+                               {\r
+                                       _son[ptr0] = _son[ptr1] = kEmptyHashValue;\r
+                                       break;\r
+                               }\r
+\r
+                               int delta = _pos - curMatch;\r
+                               int cyclicPos = ((delta <= _cyclicBufferPos) ?\r
+                                       (_cyclicBufferPos - delta) :\r
+                                       (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;\r
+\r
+                               int pby1 = _bufferOffset + curMatch;\r
+                               int len = Math.min(len0, len1);\r
+                               if (_bufferBase[pby1 + len] == _bufferBase[cur + len])\r
+                               {\r
+                                       while (++len != lenLimit)\r
+                                               if (_bufferBase[pby1 + len] != _bufferBase[cur + len])\r
+                                                       break;\r
+                                       if (len == lenLimit)\r
+                                       {\r
+                                               _son[ptr1] = _son[cyclicPos];\r
+                                               _son[ptr0] = _son[cyclicPos + 1];\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))\r
+                               {\r
+                                       _son[ptr1] = curMatch;\r
+                                       ptr1 = cyclicPos + 1;\r
+                                       curMatch = _son[ptr1];\r
+                                       len1 = len;\r
+                               }\r
+                               else\r
+                               {\r
+                                       _son[ptr0] = curMatch;\r
+                                       ptr0 = cyclicPos;\r
+                                       curMatch = _son[ptr0];\r
+                                       len0 = len;\r
+                               }\r
+                       }\r
+                       MovePos();\r
+               }\r
+               while (--num != 0);\r
+       }\r
+       \r
+       void NormalizeLinks(int[] items, int numItems, int subValue)\r
+       {\r
+               for (int i = 0; i < numItems; i++)\r
+               {\r
+                       int value = items[i];\r
+                       if (value <= subValue)\r
+                               value = kEmptyHashValue;\r
+                       else\r
+                               value -= subValue;\r
+                       items[i] = value;\r
+               }\r
+       }\r
+       \r
+       void Normalize()\r
+       {\r
+               int subValue = _pos - _cyclicBufferSize;\r
+               NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);\r
+               NormalizeLinks(_hash, _hashSizeSum, subValue);\r
+               ReduceOffsets(subValue);\r
+       }\r
+       \r
+       public void SetCutValue(int cutValue) { _cutValue = cutValue; }\r
+\r
+       private static final int[] CrcTable = new int[256];\r
+\r
+       static\r
+       {\r
+               for (int i = 0; i < 256; i++)\r
+               {\r
+                       int r = i;\r
+                       for (int j = 0; j < 8; j++)\r
+                               if ((r & 1) != 0)\r
+                                       r = (r >>> 1) ^ 0xEDB88320;\r
+                               else\r
+                                       r >>>= 1;\r
+                       CrcTable[i] = r;\r
+               }\r
+       }\r
+}\r
diff --git a/Java/SevenZip/Compression/LZ/InWindow.java b/Java/SevenZip/Compression/LZ/InWindow.java
new file mode 100755 (executable)
index 0000000..5f3f0b4
--- /dev/null
@@ -0,0 +1,131 @@
+// LZ.InWindow\r
+\r
+package SevenZip.Compression.LZ;\r
+\r
+import java.io.IOException;\r
+\r
+public class InWindow\r
+{\r
+       public byte[] _bufferBase; // pointer to buffer with data\r
+       java.io.InputStream _stream;\r
+       int _posLimit;  // offset (from _buffer) of first byte when new block reading must be done\r
+       boolean _streamEndWasReached; // if (true) then _streamPos shows real end of stream\r
+       \r
+       int _pointerToLastSafePosition;\r
+       \r
+       public int _bufferOffset;\r
+       \r
+       public int _blockSize;  // Size of Allocated memory block\r
+       public int _pos;             // offset (from _buffer) of curent byte\r
+       int _keepSizeBefore;  // how many BYTEs must be kept in buffer before _pos\r
+       int _keepSizeAfter;   // how many BYTEs must be kept buffer after _pos\r
+       public int _streamPos;   // offset (from _buffer) of first not read byte from Stream\r
+       \r
+       public void MoveBlock()\r
+       {\r
+               int offset = _bufferOffset + _pos - _keepSizeBefore;\r
+               // we need one additional byte, since MovePos moves on 1 byte.\r
+               if (offset > 0)\r
+                       offset--;\r
+\r
+               int numBytes = _bufferOffset + _streamPos - offset;\r
+               \r
+               // check negative offset ????\r
+               for (int i = 0; i < numBytes; i++)\r
+                       _bufferBase[i] = _bufferBase[offset + i];\r
+               _bufferOffset -= offset;\r
+       }\r
+       \r
+       public void ReadBlock() throws IOException\r
+       {\r
+               if (_streamEndWasReached)\r
+                       return;\r
+               while (true)\r
+               {\r
+                       int size = (0 - _bufferOffset) + _blockSize - _streamPos;\r
+                       if (size == 0)\r
+                               return;\r
+                       int numReadBytes = _stream.read(_bufferBase, _bufferOffset + _streamPos, size);\r
+                       if (numReadBytes == -1)\r
+                       {\r
+                               _posLimit = _streamPos;\r
+                               int pointerToPostion = _bufferOffset + _posLimit;\r
+                               if (pointerToPostion > _pointerToLastSafePosition)\r
+                                       _posLimit = _pointerToLastSafePosition - _bufferOffset;\r
+                               \r
+                               _streamEndWasReached = true;\r
+                               return;\r
+                       }\r
+                       _streamPos += numReadBytes;\r
+                       if (_streamPos >= _pos + _keepSizeAfter)\r
+                               _posLimit = _streamPos - _keepSizeAfter;\r
+               }\r
+       }\r
+       \r
+       void Free() { _bufferBase = null; }\r
+       \r
+       public void Create(int keepSizeBefore, int keepSizeAfter, int keepSizeReserv)\r
+       {\r
+               _keepSizeBefore = keepSizeBefore;\r
+               _keepSizeAfter = keepSizeAfter;\r
+               int blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;\r
+               if (_bufferBase == null || _blockSize != blockSize)\r
+               {\r
+                       Free();\r
+                       _blockSize = blockSize;\r
+                       _bufferBase = new byte[_blockSize];\r
+               }\r
+               _pointerToLastSafePosition = _blockSize - keepSizeAfter;\r
+       }\r
+       \r
+       public void SetStream(java.io.InputStream stream) { _stream = stream;   }\r
+       public void ReleaseStream() { _stream = null; }\r
+\r
+       public void Init() throws IOException\r
+       {\r
+               _bufferOffset = 0;\r
+               _pos = 0;\r
+               _streamPos = 0;\r
+               _streamEndWasReached = false;\r
+               ReadBlock();\r
+       }\r
+       \r
+       public void MovePos() throws IOException\r
+       {\r
+               _pos++;\r
+               if (_pos > _posLimit)\r
+               {\r
+                       int pointerToPostion = _bufferOffset + _pos;\r
+                       if (pointerToPostion > _pointerToLastSafePosition)\r
+                               MoveBlock();\r
+                       ReadBlock();\r
+               }\r
+       }\r
+       \r
+       public byte GetIndexByte(int index)     { return _bufferBase[_bufferOffset + _pos + index]; }\r
+       \r
+       // index + limit have not to exceed _keepSizeAfter;\r
+       public int GetMatchLen(int index, int distance, int limit)\r
+       {\r
+               if (_streamEndWasReached)\r
+                       if ((_pos + index) + limit > _streamPos)\r
+                               limit = _streamPos - (_pos + index);\r
+               distance++;\r
+               // Byte *pby = _buffer + (size_t)_pos + index;\r
+               int pby = _bufferOffset + _pos + index;\r
+               \r
+               int i;\r
+               for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);\r
+               return i;\r
+       }\r
+       \r
+       public int GetNumAvailableBytes()       { return _streamPos - _pos; }\r
+       \r
+       public void ReduceOffsets(int subValue)\r
+       {\r
+               _bufferOffset += subValue;\r
+               _posLimit -= subValue;\r
+               _pos -= subValue;\r
+               _streamPos -= subValue;\r
+       }\r
+}\r
diff --git a/Java/SevenZip/Compression/LZ/OutWindow.java b/Java/SevenZip/Compression/LZ/OutWindow.java
new file mode 100755 (executable)
index 0000000..620cb41
--- /dev/null
@@ -0,0 +1,85 @@
+// LZ.OutWindow\r
+\r
+package SevenZip.Compression.LZ;\r
+\r
+import java.io.IOException;\r
+\r
+public class OutWindow\r
+{\r
+       byte[] _buffer;\r
+       int _pos;\r
+       int _windowSize = 0;\r
+       int _streamPos;\r
+       java.io.OutputStream _stream;\r
+       \r
+       public void Create(int windowSize)\r
+       {\r
+               if (_buffer == null || _windowSize != windowSize)\r
+                       _buffer = new byte[windowSize];\r
+               _windowSize = windowSize;\r
+               _pos = 0;\r
+               _streamPos = 0;\r
+       }\r
+       \r
+       public void SetStream(java.io.OutputStream stream) throws IOException\r
+       {\r
+               ReleaseStream();\r
+               _stream = stream;\r
+       }\r
+       \r
+       public void ReleaseStream() throws IOException\r
+       {\r
+               Flush();\r
+               _stream = null;\r
+       }\r
+       \r
+       public void Init(boolean solid)\r
+       {\r
+               if (!solid)\r
+               {\r
+                       _streamPos = 0;\r
+                       _pos = 0;\r
+               }\r
+       }\r
+       \r
+       public void Flush() throws IOException\r
+       {\r
+               int size = _pos - _streamPos;\r
+               if (size == 0)\r
+                       return;\r
+               _stream.write(_buffer, _streamPos, size);\r
+               if (_pos >= _windowSize)\r
+                       _pos = 0;\r
+               _streamPos = _pos;\r
+       }\r
+       \r
+       public void CopyBlock(int distance, int len) throws IOException\r
+       {\r
+               int pos = _pos - distance - 1;\r
+               if (pos < 0)\r
+                       pos += _windowSize;\r
+               for (; len != 0; len--)\r
+               {\r
+                       if (pos >= _windowSize)\r
+                               pos = 0;\r
+                       _buffer[_pos++] = _buffer[pos++];\r
+                       if (_pos >= _windowSize)\r
+                               Flush();\r
+               }\r
+       }\r
+       \r
+       public void PutByte(byte b) throws IOException\r
+       {\r
+               _buffer[_pos++] = b;\r
+               if (_pos >= _windowSize)\r
+                       Flush();\r
+       }\r
+       \r
+       public byte GetByte(int distance)\r
+       {\r
+               int pos = _pos - distance - 1;\r
+               if (pos < 0)\r
+                       pos += _windowSize;\r
+               return _buffer[pos];\r
+       }\r
+}\r
diff --git a/Java/SevenZip/Compression/LZMA/Base.java b/Java/SevenZip/Compression/LZMA/Base.java
new file mode 100755 (executable)
index 0000000..18deed9
--- /dev/null
@@ -0,0 +1,88 @@
+// Base.java\r
+\r
+package SevenZip.Compression.LZMA;\r
+\r
+public class Base\r
+{\r
+       public static final int kNumRepDistances = 4;\r
+       public static final int kNumStates = 12;\r
+       \r
+       public static final int StateInit()\r
+       {\r
+               return 0;\r
+       }\r
+       \r
+       public static final int StateUpdateChar(int index)\r
+       {\r
+               if (index < 4) \r
+                       return 0;\r
+               if (index < 10) \r
+                       return index - 3;\r
+               return index - 6;\r
+       }\r
+       \r
+       public static final int StateUpdateMatch(int index)\r
+       {\r
+               return (index < 7 ? 7 : 10); \r
+       }\r
+\r
+       public static final int StateUpdateRep(int index)\r
+       { \r
+               return (index < 7 ? 8 : 11); \r
+       }\r
+       \r
+       public static final int StateUpdateShortRep(int index)\r
+       { \r
+               return (index < 7 ? 9 : 11); \r
+       }\r
+\r
+       public static final boolean StateIsCharState(int index)\r
+       { \r
+               return index < 7; \r
+       }\r
+       \r
+       public static final int kNumPosSlotBits = 6;\r
+       public static final int kDicLogSizeMin = 0;\r
+       // public static final int kDicLogSizeMax = 28;\r
+       // public static final int kDistTableSizeMax = kDicLogSizeMax * 2;\r
+       \r
+       public static final int kNumLenToPosStatesBits = 2; // it's for speed optimization\r
+       public static final int kNumLenToPosStates = 1 << kNumLenToPosStatesBits;\r
+       \r
+       public static final int kMatchMinLen = 2;\r
+       \r
+       public static final int GetLenToPosState(int len)\r
+       {\r
+               len -= kMatchMinLen;\r
+               if (len < kNumLenToPosStates)\r
+                       return len;\r
+               return (int)(kNumLenToPosStates - 1);\r
+       }\r
+       \r
+       public static final int kNumAlignBits = 4;\r
+       public static final int kAlignTableSize = 1 << kNumAlignBits;\r
+       public static final int kAlignMask = (kAlignTableSize - 1);\r
+       \r
+       public static final int kStartPosModelIndex = 4;\r
+       public static final int kEndPosModelIndex = 14;\r
+       public static final int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;\r
+       \r
+       public static final  int kNumFullDistances = 1 << (kEndPosModelIndex / 2);\r
+       \r
+       public static final  int kNumLitPosStatesBitsEncodingMax = 4;\r
+       public static final  int kNumLitContextBitsMax = 8;\r
+       \r
+       public static final  int kNumPosStatesBitsMax = 4;\r
+       public static final  int kNumPosStatesMax = (1 << kNumPosStatesBitsMax);\r
+       public static final  int kNumPosStatesBitsEncodingMax = 4;\r
+       public static final  int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);\r
+       \r
+       public static final  int kNumLowLenBits = 3;\r
+       public static final  int kNumMidLenBits = 3;\r
+       public static final  int kNumHighLenBits = 8;\r
+       public static final  int kNumLowLenSymbols = 1 << kNumLowLenBits;\r
+       public static final  int kNumMidLenSymbols = 1 << kNumMidLenBits;\r
+       public static final  int kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +\r
+                       (1 << kNumHighLenBits);\r
+       public static final  int kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;\r
+}\r
diff --git a/Java/SevenZip/Compression/LZMA/Decoder.java b/Java/SevenZip/Compression/LZMA/Decoder.java
new file mode 100755 (executable)
index 0000000..4ebd571
--- /dev/null
@@ -0,0 +1,329 @@
+package SevenZip.Compression.LZMA;\r
+\r
+import SevenZip.Compression.RangeCoder.BitTreeDecoder;\r
+import SevenZip.Compression.LZMA.Base;\r
+import SevenZip.Compression.LZ.OutWindow;\r
+import java.io.IOException;\r
+\r
+public class Decoder\r
+{\r
+       class LenDecoder\r
+       {\r
+               short[] m_Choice = new short[2];\r
+               BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];\r
+               BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];\r
+               BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);\r
+               int m_NumPosStates = 0;\r
+               \r
+               public void Create(int numPosStates)\r
+               {\r
+                       for (; m_NumPosStates < numPosStates; m_NumPosStates++)\r
+                       {\r
+                               m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits);\r
+                               m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits);\r
+                       }\r
+               }\r
+               \r
+               public void Init()\r
+               {\r
+                       SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Choice);\r
+                       for (int posState = 0; posState < m_NumPosStates; posState++)\r
+                       {\r
+                               m_LowCoder[posState].Init();\r
+                               m_MidCoder[posState].Init();\r
+                       }\r
+                       m_HighCoder.Init();\r
+               }\r
+               \r
+               public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException\r
+               {\r
+                       if (rangeDecoder.DecodeBit(m_Choice, 0) == 0)\r
+                               return m_LowCoder[posState].Decode(rangeDecoder);\r
+                       int symbol = Base.kNumLowLenSymbols;\r
+                       if (rangeDecoder.DecodeBit(m_Choice, 1) == 0)\r
+                               symbol += m_MidCoder[posState].Decode(rangeDecoder);\r
+                       else\r
+                               symbol += Base.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder);\r
+                       return symbol;\r
+               }\r
+       }\r
+       \r
+       class LiteralDecoder\r
+       {\r
+               class Decoder2\r
+               {\r
+                       short[] m_Decoders = new short[0x300];\r
+                       \r
+                       public void Init()\r
+                       {\r
+                               SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Decoders);\r
+                       }\r
+                       \r
+                       public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException\r
+                       {\r
+                               int symbol = 1;\r
+                               do\r
+                                       symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);\r
+                               while (symbol < 0x100);\r
+                               return (byte)symbol;\r
+                       }\r
+                       \r
+                       public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException\r
+                       {\r
+                               int symbol = 1;\r
+                               do\r
+                               {\r
+                                       int matchBit = (matchByte >> 7) & 1;\r
+                                       matchByte <<= 1;\r
+                                       int bit = rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) << 8) + symbol);\r
+                                       symbol = (symbol << 1) | bit;\r
+                                       if (matchBit != bit)\r
+                                       {\r
+                                               while (symbol < 0x100)\r
+                                                       symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               while (symbol < 0x100);\r
+                               return (byte)symbol;\r
+                       }\r
+               }\r
+               \r
+               Decoder2[] m_Coders;\r
+               int m_NumPrevBits;\r
+               int m_NumPosBits;\r
+               int m_PosMask;\r
+               \r
+               public void Create(int numPosBits, int numPrevBits)\r
+               {\r
+                       if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)\r
+                               return;\r
+                       m_NumPosBits = numPosBits;\r
+                       m_PosMask = (1 << numPosBits) - 1;\r
+                       m_NumPrevBits = numPrevBits;\r
+                       int numStates = 1 << (m_NumPrevBits + m_NumPosBits);\r
+                       m_Coders = new Decoder2[numStates];\r
+                       for (int i = 0; i < numStates; i++)\r
+                               m_Coders[i] = new Decoder2();\r
+               }\r
+               \r
+               public void Init()\r
+               {\r
+                       int numStates = 1 << (m_NumPrevBits + m_NumPosBits);\r
+                       for (int i = 0; i < numStates; i++)\r
+                               m_Coders[i].Init();\r
+               }\r
+               \r
+               Decoder2 GetDecoder(int pos, byte prevByte)\r
+               {\r
+                       return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))];\r
+               }\r
+       }\r
+       \r
+       OutWindow m_OutWindow = new OutWindow();\r
+       SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder();\r
+       \r
+       short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];\r
+       short[] m_IsRepDecoders = new short[Base.kNumStates];\r
+       short[] m_IsRepG0Decoders = new short[Base.kNumStates];\r
+       short[] m_IsRepG1Decoders = new short[Base.kNumStates];\r
+       short[] m_IsRepG2Decoders = new short[Base.kNumStates];\r
+       short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];\r
+       \r
+       BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];\r
+       short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex];\r
+       \r
+       BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);\r
+       \r
+       LenDecoder m_LenDecoder = new LenDecoder();\r
+       LenDecoder m_RepLenDecoder = new LenDecoder();\r
+       \r
+       LiteralDecoder m_LiteralDecoder = new LiteralDecoder();\r
+       \r
+       int m_DictionarySize = -1;\r
+       int m_DictionarySizeCheck =  -1;\r
+       \r
+       int m_PosStateMask;\r
+       \r
+       public Decoder()\r
+       {\r
+               for (int i = 0; i < Base.kNumLenToPosStates; i++)\r
+                       m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);\r
+       }\r
+       \r
+       boolean SetDictionarySize(int dictionarySize)\r
+       {\r
+               if (dictionarySize < 0)\r
+                       return false;\r
+               if (m_DictionarySize != dictionarySize)\r
+               {\r
+                       m_DictionarySize = dictionarySize;\r
+                       m_DictionarySizeCheck = Math.max(m_DictionarySize, 1);\r
+                       m_OutWindow.Create(Math.max(m_DictionarySizeCheck, (1 << 12)));\r
+               }\r
+               return true;\r
+       }\r
+       \r
+       boolean SetLcLpPb(int lc, int lp, int pb)\r
+       {\r
+               if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax)\r
+                       return false;\r
+               m_LiteralDecoder.Create(lp, lc);\r
+               int numPosStates = 1 << pb;\r
+               m_LenDecoder.Create(numPosStates);\r
+               m_RepLenDecoder.Create(numPosStates);\r
+               m_PosStateMask = numPosStates - 1;\r
+               return true;\r
+       }\r
+       \r
+       void Init() throws IOException\r
+       {\r
+               m_OutWindow.Init(false);\r
+               \r
+               SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsMatchDecoders);\r
+               SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0LongDecoders);\r
+               SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDecoders);\r
+               SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0Decoders);\r
+               SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1Decoders);\r
+               SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2Decoders);\r
+               SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecoders);\r
+               \r
+               m_LiteralDecoder.Init();\r
+               int i;\r
+               for (i = 0; i < Base.kNumLenToPosStates; i++)\r
+                       m_PosSlotDecoder[i].Init();\r
+               m_LenDecoder.Init();\r
+               m_RepLenDecoder.Init();\r
+               m_PosAlignDecoder.Init();\r
+               m_RangeDecoder.Init();\r
+       }\r
+       \r
+       public boolean Code(java.io.InputStream inStream, java.io.OutputStream outStream,\r
+                       long outSize) throws IOException\r
+       {\r
+               m_RangeDecoder.SetStream(inStream);\r
+               m_OutWindow.SetStream(outStream);\r
+               Init();\r
+               \r
+               int state = Base.StateInit();\r
+               int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;\r
+               \r
+               long nowPos64 = 0;\r
+               byte prevByte = 0;\r
+               while (outSize < 0 || nowPos64 < outSize)\r
+               {\r
+                       int posState = (int)nowPos64 & m_PosStateMask;\r
+                       if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)\r
+                       {\r
+                               LiteralDecoder.Decoder2 decoder2 = m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte);\r
+                               if (!Base.StateIsCharState(state))\r
+                                       prevByte = decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0));\r
+                               else\r
+                                       prevByte = decoder2.DecodeNormal(m_RangeDecoder);\r
+                               m_OutWindow.PutByte(prevByte);\r
+                               state = Base.StateUpdateChar(state);\r
+                               nowPos64++;\r
+                       }\r
+                       else\r
+                       {\r
+                               int len;\r
+                               if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) == 1)\r
+                               {\r
+                                       len = 0;\r
+                                       if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) == 0)\r
+                                       {\r
+                                               if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)\r
+                                               {\r
+                                                       state = Base.StateUpdateShortRep(state);\r
+                                                       len = 1;\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               int distance;\r
+                                               if (m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) == 0)\r
+                                                       distance = rep1;\r
+                                               else\r
+                                               {\r
+                                                       if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) == 0)\r
+                                                               distance = rep2;\r
+                                                       else\r
+                                                       {\r
+                                                               distance = rep3;\r
+                                                               rep3 = rep2;\r
+                                                       }\r
+                                                       rep2 = rep1;\r
+                                               }\r
+                                               rep1 = rep0;\r
+                                               rep0 = distance;\r
+                                       }\r
+                                       if (len == 0)\r
+                                       {\r
+                                               len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;\r
+                                               state = Base.StateUpdateRep(state);\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       rep3 = rep2;\r
+                                       rep2 = rep1;\r
+                                       rep1 = rep0;\r
+                                       len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);\r
+                                       state = Base.StateUpdateMatch(state);\r
+                                       int posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);\r
+                                       if (posSlot >= Base.kStartPosModelIndex)\r
+                                       {\r
+                                               int numDirectBits = (posSlot >> 1) - 1;\r
+                                               rep0 = ((2 | (posSlot & 1)) << numDirectBits);\r
+                                               if (posSlot < Base.kEndPosModelIndex)\r
+                                                       rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,\r
+                                                                       rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);\r
+                                               else\r
+                                               {\r
+                                                       rep0 += (m_RangeDecoder.DecodeDirectBits(\r
+                                                                       numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);\r
+                                                       rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);\r
+                                                       if (rep0 < 0)\r
+                                                       {\r
+                                                               if (rep0 == -1)\r
+                                                                       break;\r
+                                                               return false;\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                               rep0 = posSlot;\r
+                               }\r
+                               if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck)\r
+                               {\r
+                                       // m_OutWindow.Flush();\r
+                                       return false;\r
+                               }\r
+                               m_OutWindow.CopyBlock(rep0, len);\r
+                               nowPos64 += len;\r
+                               prevByte = m_OutWindow.GetByte(0);\r
+                       }\r
+               }\r
+               m_OutWindow.Flush();\r
+               m_OutWindow.ReleaseStream();\r
+               m_RangeDecoder.ReleaseStream();\r
+               return true;\r
+       }\r
+       \r
+       public boolean SetDecoderProperties(byte[] properties)\r
+       {\r
+               if (properties.length < 5)\r
+                       return false;\r
+               int val = properties[0] & 0xFF;\r
+               int lc = val % 9;\r
+               int remainder = val / 9;\r
+               int lp = remainder % 5;\r
+               int pb = remainder / 5;\r
+               int dictionarySize = 0;\r
+               for (int i = 0; i < 4; i++)\r
+                       dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8);\r
+               if (!SetLcLpPb(lc, lp, pb))\r
+                       return false;\r
+               return SetDictionarySize(dictionarySize);\r
+       }\r
+}\r
diff --git a/Java/SevenZip/Compression/LZMA/Encoder.java b/Java/SevenZip/Compression/LZMA/Encoder.java
new file mode 100755 (executable)
index 0000000..771fb21
--- /dev/null
@@ -0,0 +1,1416 @@
+package SevenZip.Compression.LZMA;\r
+\r
+import SevenZip.Compression.RangeCoder.BitTreeEncoder;\r
+import SevenZip.Compression.LZMA.Base;\r
+import SevenZip.Compression.LZ.BinTree;\r
+import SevenZip.ICodeProgress;\r
+import java.io.IOException;\r
+\r
+public class Encoder\r
+{\r
+       public static final int EMatchFinderTypeBT2 = 0;\r
+       public static final int EMatchFinderTypeBT4 = 1;\r
+\r
+\r
+\r
+\r
+       static final int kIfinityPrice = 0xFFFFFFF;\r
+\r
+       static byte[] g_FastPos = new byte[1 << 11];\r
+\r
+       static\r
+       {\r
+               int kFastSlots = 22;\r
+               int c = 2;\r
+               g_FastPos[0] = 0;\r
+               g_FastPos[1] = 1;\r
+               for (int slotFast = 2; slotFast < kFastSlots; slotFast++)\r
+               {\r
+                       int k = (1 << ((slotFast >> 1) - 1));\r
+                       for (int j = 0; j < k; j++, c++)\r
+                               g_FastPos[c] = (byte)slotFast;\r
+               }\r
+       }\r
+\r
+       static int GetPosSlot(int pos)\r
+       {\r
+               if (pos < (1 << 11))\r
+                       return g_FastPos[pos];\r
+               if (pos < (1 << 21))\r
+                       return (g_FastPos[pos >> 10] + 20);\r
+               return (g_FastPos[pos >> 20] + 40);\r
+       }\r
+\r
+       static int GetPosSlot2(int pos)\r
+       {\r
+               if (pos < (1 << 17))\r
+                       return (g_FastPos[pos >> 6] + 12);\r
+               if (pos < (1 << 27))\r
+                       return (g_FastPos[pos >> 16] + 32);\r
+               return (g_FastPos[pos >> 26] + 52);\r
+       }\r
+\r
+       int _state = Base.StateInit();\r
+       byte _previousByte;\r
+       int[] _repDistances = new int[Base.kNumRepDistances];\r
+\r
+       void BaseInit()\r
+       {\r
+               _state = Base.StateInit();\r
+               _previousByte = 0;\r
+               for (int i = 0; i < Base.kNumRepDistances; i++)\r
+                       _repDistances[i] = 0;\r
+       }\r
+\r
+       static final int kDefaultDictionaryLogSize = 22;\r
+       static final int kNumFastBytesDefault = 0x20;\r
+\r
+       class LiteralEncoder\r
+       {\r
+               class Encoder2\r
+               {\r
+                       short[] m_Encoders = new short[0x300];\r
+\r
+                       public void Init() { SevenZip.Compression.RangeCoder.Encoder.InitBitModels(m_Encoders); }\r
+\r
+\r
+\r
+                       public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte symbol) throws IOException\r
+                       {\r
+                               int context = 1;\r
+                               for (int i = 7; i >= 0; i--)\r
+                               {\r
+                                       int bit = ((symbol >> i) & 1);\r
+                                       rangeEncoder.Encode(m_Encoders, context, bit);\r
+                                       context = (context << 1) | bit;\r
+                               }\r
+                       }\r
+\r
+                       public void EncodeMatched(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) throws IOException\r
+                       {\r
+                               int context = 1;\r
+                               boolean same = true;\r
+                               for (int i = 7; i >= 0; i--)\r
+                               {\r
+                                       int bit = ((symbol >> i) & 1);\r
+                                       int state = context;\r
+                                       if (same)\r
+                                       {\r
+                                               int matchBit = ((matchByte >> i) & 1);\r
+                                               state += ((1 + matchBit) << 8);\r
+                                               same = (matchBit == bit);\r
+                                       }\r
+                                       rangeEncoder.Encode(m_Encoders, state, bit);\r
+                                       context = (context << 1) | bit;\r
+                               }\r
+                       }\r
+\r
+                       public int GetPrice(boolean matchMode, byte matchByte, byte symbol)\r
+                       {\r
+                               int price = 0;\r
+                               int context = 1;\r
+                               int i = 7;\r
+                               if (matchMode)\r
+                               {\r
+                                       for (; i >= 0; i--)\r
+                                       {\r
+                                               int matchBit = (matchByte >> i) & 1;\r
+                                               int bit = (symbol >> i) & 1;\r
+                                               price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[((1 + matchBit) << 8) + context], bit);\r
+                                               context = (context << 1) | bit;\r
+                                               if (matchBit != bit)\r
+                                               {\r
+                                                       i--;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               for (; i >= 0; i--)\r
+                               {\r
+                                       int bit = (symbol >> i) & 1;\r
+                                       price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[context], bit);\r
+                                       context = (context << 1) | bit;\r
+                               }\r
+                               return price;\r
+                       }\r
+               }\r
+\r
+               Encoder2[] m_Coders;\r
+               int m_NumPrevBits;\r
+               int m_NumPosBits;\r
+               int m_PosMask;\r
+\r
+               public void Create(int numPosBits, int numPrevBits)\r
+               {\r
+                       if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)\r
+                               return;\r
+                       m_NumPosBits = numPosBits;\r
+                       m_PosMask = (1 << numPosBits) - 1;\r
+                       m_NumPrevBits = numPrevBits;\r
+                       int numStates = 1 << (m_NumPrevBits + m_NumPosBits);\r
+                       m_Coders = new Encoder2[numStates];\r
+                       for (int i = 0; i < numStates; i++)\r
+                               m_Coders[i] = new Encoder2();\r
+               }\r
+\r
+               public void Init()\r
+               {\r
+                       int numStates = 1 << (m_NumPrevBits + m_NumPosBits);\r
+                       for (int i = 0; i < numStates; i++)\r
+                               m_Coders[i].Init();\r
+               }\r
+\r
+               public Encoder2 GetSubCoder(int pos, byte prevByte)\r
+               { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; }\r
+       }\r
+\r
+       class LenEncoder\r
+       {\r
+               short[] _choice = new short[2];\r
+               BitTreeEncoder[] _lowCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];\r
+               BitTreeEncoder[] _midCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];\r
+               BitTreeEncoder _highCoder = new BitTreeEncoder(Base.kNumHighLenBits);\r
+\r
+\r
+               public LenEncoder()\r
+               {\r
+                       for (int posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)\r
+                       {\r
+                               _lowCoder[posState] = new BitTreeEncoder(Base.kNumLowLenBits);\r
+                               _midCoder[posState] = new BitTreeEncoder(Base.kNumMidLenBits);\r
+                       }\r
+               }\r
+\r
+               public void Init(int numPosStates)\r
+               {\r
+                       SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_choice);\r
+\r
+                       for (int posState = 0; posState < numPosStates; posState++)\r
+                       {\r
+                               _lowCoder[posState].Init();\r
+                               _midCoder[posState].Init();\r
+                       }\r
+                       _highCoder.Init();\r
+               }\r
+\r
+               public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException\r
+               {\r
+                       if (symbol < Base.kNumLowLenSymbols)\r
+                       {\r
+                               rangeEncoder.Encode(_choice, 0, 0);\r
+                               _lowCoder[posState].Encode(rangeEncoder, symbol);\r
+                       }\r
+                       else\r
+                       {\r
+                               symbol -= Base.kNumLowLenSymbols;\r
+                               rangeEncoder.Encode(_choice, 0, 1);\r
+                               if (symbol < Base.kNumMidLenSymbols)\r
+                               {\r
+                                       rangeEncoder.Encode(_choice, 1, 0);\r
+                                       _midCoder[posState].Encode(rangeEncoder, symbol);\r
+                               }\r
+                               else\r
+                               {\r
+                                       rangeEncoder.Encode(_choice, 1, 1);\r
+                                       _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               public void SetPrices(int posState, int numSymbols, int[] prices, int st)\r
+               {\r
+                       int a0 = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[0]);\r
+                       int a1 = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[0]);\r
+                       int b0 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[1]);\r
+                       int b1 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[1]);\r
+                       int i = 0;\r
+                       for (i = 0; i < Base.kNumLowLenSymbols; i++)\r
+                       {\r
+                               if (i >= numSymbols)\r
+                                       return;\r
+                               prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);\r
+                       }\r
+                       for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)\r
+                       {\r
+                               if (i >= numSymbols)\r
+                                       return;\r
+                               prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);\r
+                       }\r
+                       for (; i < numSymbols; i++)\r
+                               prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);\r
+               }\r
+       };\r
+\r
+       public static final int kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;\r
+\r
+       class LenPriceTableEncoder extends LenEncoder\r
+       {\r
+               int[] _prices = new int[Base.kNumLenSymbols<<Base.kNumPosStatesBitsEncodingMax];\r
+               int _tableSize;\r
+               int[] _counters = new int[Base.kNumPosStatesEncodingMax];\r
+\r
+               public void SetTableSize(int tableSize) { _tableSize = tableSize; }\r
+\r
+               public int GetPrice(int symbol, int posState)\r
+               {\r
+                       return _prices[posState * Base.kNumLenSymbols + symbol];\r
+               }\r
+\r
+               void UpdateTable(int posState)\r
+               {\r
+                       SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);\r
+                       _counters[posState] = _tableSize;\r
+               }\r
+\r
+               public void UpdateTables(int numPosStates)\r
+               {\r
+                       for (int posState = 0; posState < numPosStates; posState++)\r
+                               UpdateTable(posState);\r
+               }\r
+\r
+               public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException\r
+               {\r
+                       super.Encode(rangeEncoder, symbol, posState);\r
+                       if (--_counters[posState] == 0)\r
+                               UpdateTable(posState);\r
+               }\r
+       }\r
+\r
+       static final int kNumOpts = 1 << 12;\r
+       class Optimal\r
+       {\r
+               public int State;\r
+\r
+               public boolean Prev1IsChar;\r
+               public boolean Prev2;\r
+\r
+               public int PosPrev2;\r
+               public int BackPrev2;\r
+\r
+               public int Price;\r
+               public int PosPrev;\r
+               public int BackPrev;\r
+\r
+               public int Backs0;\r
+               public int Backs1;\r
+               public int Backs2;\r
+               public int Backs3;\r
+\r
+               public void MakeAsChar() { BackPrev = -1; Prev1IsChar = false; }\r
+               public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }\r
+               public boolean IsShortRep() { return (BackPrev == 0); }\r
+       };\r
+       Optimal[] _optimum = new Optimal[kNumOpts];\r
+       SevenZip.Compression.LZ.BinTree _matchFinder = null;\r
+       SevenZip.Compression.RangeCoder.Encoder _rangeEncoder = new SevenZip.Compression.RangeCoder.Encoder();\r
+\r
+       short[] _isMatch = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];\r
+       short[] _isRep = new short[Base.kNumStates];\r
+       short[] _isRepG0 = new short[Base.kNumStates];\r
+       short[] _isRepG1 = new short[Base.kNumStates];\r
+       short[] _isRepG2 = new short[Base.kNumStates];\r
+       short[] _isRep0Long = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];\r
+\r
+       BitTreeEncoder[] _posSlotEncoder = new BitTreeEncoder[Base.kNumLenToPosStates]; // kNumPosSlotBits\r
+\r
+       short[] _posEncoders = new short[Base.kNumFullDistances-Base.kEndPosModelIndex];\r
+       BitTreeEncoder _posAlignEncoder = new BitTreeEncoder(Base.kNumAlignBits);\r
+\r
+       LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();\r
+       LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();\r
+\r
+       LiteralEncoder _literalEncoder = new LiteralEncoder();\r
+\r
+       int[] _matchDistances = new int[Base.kMatchMaxLen*2+2];\r
+\r
+       int _numFastBytes = kNumFastBytesDefault;\r
+       int _longestMatchLength;\r
+       int _numDistancePairs;\r
+\r
+       int _additionalOffset;\r
+\r
+       int _optimumEndIndex;\r
+       int _optimumCurrentIndex;\r
+\r
+       boolean _longestMatchWasFound;\r
+\r
+       int[] _posSlotPrices = new int[1<<(Base.kNumPosSlotBits+Base.kNumLenToPosStatesBits)];\r
+       int[] _distancesPrices = new int[Base.kNumFullDistances<<Base.kNumLenToPosStatesBits];\r
+       int[] _alignPrices = new int[Base.kAlignTableSize];\r
+       int _alignPriceCount;\r
+\r
+       int _distTableSize = (kDefaultDictionaryLogSize * 2);\r
+\r
+       int _posStateBits = 2;\r
+       int _posStateMask = (4 - 1);\r
+       int _numLiteralPosStateBits = 0;\r
+       int _numLiteralContextBits = 3;\r
+\r
+       int _dictionarySize = (1 << kDefaultDictionaryLogSize);\r
+       int _dictionarySizePrev = -1;\r
+       int _numFastBytesPrev = -1;\r
+\r
+       long nowPos64;\r
+       boolean _finished;\r
+       java.io.InputStream _inStream;\r
+\r
+       int _matchFinderType = EMatchFinderTypeBT4;\r
+       boolean _writeEndMark = false;\r
+\r
+       boolean _needReleaseMFStream = false;\r
+\r
+       void Create()\r
+       {\r
+               if (_matchFinder == null)\r
+               {\r
+                       SevenZip.Compression.LZ.BinTree bt = new SevenZip.Compression.LZ.BinTree();\r
+                       int numHashBytes = 4;\r
+                       if (_matchFinderType == EMatchFinderTypeBT2)\r
+                               numHashBytes = 2;\r
+                       bt.SetType(numHashBytes);\r
+                       _matchFinder = bt;\r
+               }\r
+               _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);\r
+\r
+               if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)\r
+                       return;\r
+               _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);\r
+               _dictionarySizePrev = _dictionarySize;\r
+               _numFastBytesPrev = _numFastBytes;\r
+       }\r
+\r
+       public Encoder()\r
+       {\r
+               for (int i = 0; i < kNumOpts; i++)\r
+                       _optimum[i] = new Optimal();\r
+               for (int i = 0; i < Base.kNumLenToPosStates; i++)\r
+                       _posSlotEncoder[i] = new BitTreeEncoder(Base.kNumPosSlotBits);\r
+       }\r
+\r
+       void SetWriteEndMarkerMode(boolean writeEndMarker)\r
+       {\r
+               _writeEndMark = writeEndMarker;\r
+       }\r
+\r
+       void Init()\r
+       {\r
+               BaseInit();\r
+               _rangeEncoder.Init();\r
+\r
+               SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isMatch);\r
+               SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep0Long);\r
+               SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep);\r
+               SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG0);\r
+               SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG1);\r
+               SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG2);\r
+               SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_posEncoders);\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+               _literalEncoder.Init();\r
+               for (int i = 0; i < Base.kNumLenToPosStates; i++)\r
+                       _posSlotEncoder[i].Init();\r
+\r
+\r
+\r
+               _lenEncoder.Init(1 << _posStateBits);\r
+               _repMatchLenEncoder.Init(1 << _posStateBits);\r
+\r
+               _posAlignEncoder.Init();\r
+\r
+               _longestMatchWasFound = false;\r
+               _optimumEndIndex = 0;\r
+               _optimumCurrentIndex = 0;\r
+               _additionalOffset = 0;\r
+       }\r
+\r
+       int ReadMatchDistances() throws java.io.IOException\r
+       {\r
+               int lenRes = 0;\r
+               _numDistancePairs = _matchFinder.GetMatches(_matchDistances);\r
+               if (_numDistancePairs > 0)\r
+               {\r
+                       lenRes = _matchDistances[_numDistancePairs - 2];\r
+                       if (lenRes == _numFastBytes)\r
+                               lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[_numDistancePairs - 1],\r
+                                       Base.kMatchMaxLen - lenRes);\r
+               }\r
+               _additionalOffset++;\r
+               return lenRes;\r
+       }\r
+\r
+       void MovePos(int num) throws java.io.IOException\r
+       {\r
+               if (num > 0)\r
+               {\r
+                       _matchFinder.Skip(num);\r
+                       _additionalOffset += num;\r
+               }\r
+       }\r
+\r
+       int GetRepLen1Price(int state, int posState)\r
+       {\r
+               return SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]) +\r
+                               SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);\r
+       }\r
+\r
+       int GetPureRepPrice(int repIndex, int state, int posState)\r
+       {\r
+               int price;\r
+               if (repIndex == 0)\r
+               {\r
+                       price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]);\r
+                       price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);\r
+               }\r
+               else\r
+               {\r
+                       price = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG0[state]);\r
+                       if (repIndex == 1)\r
+                               price += SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG1[state]);\r
+                       else\r
+                       {\r
+                               price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG1[state]);\r
+                               price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(_isRepG2[state], repIndex - 2);\r
+                       }\r
+               }\r
+               return price;\r
+       }\r
+\r
+       int GetRepPrice(int repIndex, int len, int state, int posState)\r
+       {\r
+               int price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);\r
+               return price + GetPureRepPrice(repIndex, state, posState);\r
+       }\r
+\r
+       int GetPosLenPrice(int pos, int len, int posState)\r
+       {\r
+               int price;\r
+               int lenToPosState = Base.GetLenToPosState(len);\r
+               if (pos < Base.kNumFullDistances)\r
+                       price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];\r
+               else\r
+                       price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] +\r
+                               _alignPrices[pos & Base.kAlignMask];\r
+               return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);\r
+       }\r
+\r
+       int Backward(int cur)\r
+       {\r
+               _optimumEndIndex = cur;\r
+               int posMem = _optimum[cur].PosPrev;\r
+               int backMem = _optimum[cur].BackPrev;\r
+               do\r
+               {\r
+                       if (_optimum[cur].Prev1IsChar)\r
+                       {\r
+                               _optimum[posMem].MakeAsChar();\r
+                               _optimum[posMem].PosPrev = posMem - 1;\r
+                               if (_optimum[cur].Prev2)\r
+                               {\r
+                                       _optimum[posMem - 1].Prev1IsChar = false;\r
+                                       _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;\r
+                                       _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;\r
+                               }\r
+                       }\r
+                       int posPrev = posMem;\r
+                       int backCur = backMem;\r
+\r
+                       backMem = _optimum[posPrev].BackPrev;\r
+                       posMem = _optimum[posPrev].PosPrev;\r
+\r
+                       _optimum[posPrev].BackPrev = backCur;\r
+                       _optimum[posPrev].PosPrev = cur;\r
+                       cur = posPrev;\r
+               }\r
+               while (cur > 0);\r
+               backRes = _optimum[0].BackPrev;\r
+               _optimumCurrentIndex = _optimum[0].PosPrev;\r
+               return _optimumCurrentIndex;\r
+       }\r
+\r
+       int[] reps = new int[Base.kNumRepDistances];\r
+       int[] repLens = new int[Base.kNumRepDistances];\r
+       int backRes;\r
+\r
+       int GetOptimum(int position) throws IOException\r
+       {\r
+               if (_optimumEndIndex != _optimumCurrentIndex)\r
+               {\r
+                       int lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;\r
+                       backRes = _optimum[_optimumCurrentIndex].BackPrev;\r
+                       _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;\r
+                       return lenRes;\r
+               }\r
+               _optimumCurrentIndex = _optimumEndIndex = 0;\r
+\r
+               int lenMain, numDistancePairs;\r
+               if (!_longestMatchWasFound)\r
+               {\r
+                       lenMain = ReadMatchDistances();\r
+               }\r
+               else\r
+               {\r
+                       lenMain = _longestMatchLength;\r
+                       _longestMatchWasFound = false;\r
+               }\r
+               numDistancePairs = _numDistancePairs;\r
+\r
+               int numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;\r
+               if (numAvailableBytes < 2)\r
+               {\r
+                       backRes = -1;\r
+                       return 1;\r
+               }\r
+               if (numAvailableBytes > Base.kMatchMaxLen)\r
+                       numAvailableBytes = Base.kMatchMaxLen;\r
+\r
+               int repMaxIndex = 0;\r
+               int i;\r
+               for (i = 0; i < Base.kNumRepDistances; i++)\r
+               {\r
+                       reps[i] = _repDistances[i];\r
+                       repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);\r
+                       if (repLens[i] > repLens[repMaxIndex])\r
+                               repMaxIndex = i;\r
+               }\r
+               if (repLens[repMaxIndex] >= _numFastBytes)\r
+               {\r
+                       backRes = repMaxIndex;\r
+                       int lenRes = repLens[repMaxIndex];\r
+                       MovePos(lenRes - 1);\r
+                       return lenRes;\r
+               }\r
+\r
+               if (lenMain >= _numFastBytes)\r
+               {\r
+                       backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;\r
+                       MovePos(lenMain - 1);\r
+                       return lenMain;\r
+               }\r
+\r
+               byte currentByte = _matchFinder.GetIndexByte(0 - 1);\r
+               byte matchByte = _matchFinder.GetIndexByte(0 - _repDistances[0] - 1 - 1);\r
+\r
+               if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)\r
+               {\r
+                       backRes = -1;\r
+                       return 1;\r
+               }\r
+\r
+               _optimum[0].State = _state;\r
+\r
+               int posState = (position & _posStateMask);\r
+\r
+               _optimum[1].Price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]) +\r
+                               _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!Base.StateIsCharState(_state), matchByte, currentByte);\r
+               _optimum[1].MakeAsChar();\r
+\r
+               int matchPrice = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]);\r
+               int repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[_state]);\r
+\r
+               if (matchByte == currentByte)\r
+               {\r
+                       int shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);\r
+                       if (shortRepPrice < _optimum[1].Price)\r
+                       {\r
+                               _optimum[1].Price = shortRepPrice;\r
+                               _optimum[1].MakeAsShortRep();\r
+                       }\r
+               }\r
+\r
+               int lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);\r
+\r
+               if (lenEnd < 2)\r
+               {\r
+                       backRes = _optimum[1].BackPrev;\r
+                       return 1;\r
+               }\r
+\r
+               _optimum[1].PosPrev = 0;\r
+\r
+               _optimum[0].Backs0 = reps[0];\r
+               _optimum[0].Backs1 = reps[1];\r
+               _optimum[0].Backs2 = reps[2];\r
+               _optimum[0].Backs3 = reps[3];\r
+\r
+               int len = lenEnd;\r
+               do\r
+                       _optimum[len--].Price = kIfinityPrice;\r
+               while (len >= 2);\r
+\r
+               for (i = 0; i < Base.kNumRepDistances; i++)\r
+               {\r
+                       int repLen = repLens[i];\r
+                       if (repLen < 2)\r
+                               continue;\r
+                       int price = repMatchPrice + GetPureRepPrice(i, _state, posState);\r
+                       do\r
+                       {\r
+                               int curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);\r
+                               Optimal optimum = _optimum[repLen];\r
+                               if (curAndLenPrice < optimum.Price)\r
+                               {\r
+                                       optimum.Price = curAndLenPrice;\r
+                                       optimum.PosPrev = 0;\r
+                                       optimum.BackPrev = i;\r
+                                       optimum.Prev1IsChar = false;\r
+                               }\r
+                       }\r
+                       while (--repLen >= 2);\r
+               }\r
+\r
+               int normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[_state]);\r
+\r
+               len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);\r
+               if (len <= lenMain)\r
+               {\r
+                       int offs = 0;\r
+                       while (len > _matchDistances[offs])\r
+                               offs += 2;\r
+                       for (; ; len++)\r
+                       {\r
+                               int distance = _matchDistances[offs + 1];\r
+                               int curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);\r
+                               Optimal optimum = _optimum[len];\r
+                               if (curAndLenPrice < optimum.Price)\r
+                               {\r
+                                       optimum.Price = curAndLenPrice;\r
+                                       optimum.PosPrev = 0;\r
+                                       optimum.BackPrev = distance + Base.kNumRepDistances;\r
+                                       optimum.Prev1IsChar = false;\r
+                               }\r
+                               if (len == _matchDistances[offs])\r
+                               {\r
+                                       offs += 2;\r
+                                       if (offs == numDistancePairs)\r
+                                               break;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               int cur = 0;\r
+\r
+               while (true)\r
+               {\r
+                       cur++;\r
+                       if (cur == lenEnd)\r
+                               return Backward(cur);\r
+                       int newLen = ReadMatchDistances();\r
+                       numDistancePairs = _numDistancePairs;\r
+                       if (newLen >= _numFastBytes)\r
+                       {\r
+\r
+                               _longestMatchLength = newLen;\r
+                               _longestMatchWasFound = true;\r
+                               return Backward(cur);\r
+                       }\r
+                       position++;\r
+                       int posPrev = _optimum[cur].PosPrev;\r
+                       int state;\r
+                       if (_optimum[cur].Prev1IsChar)\r
+                       {\r
+                               posPrev--;\r
+                               if (_optimum[cur].Prev2)\r
+                               {\r
+                                       state = _optimum[_optimum[cur].PosPrev2].State;\r
+                                       if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)\r
+                                               state = Base.StateUpdateRep(state);\r
+                                       else\r
+                                               state = Base.StateUpdateMatch(state);\r
+                               }\r
+                               else\r
+                                       state = _optimum[posPrev].State;\r
+                               state = Base.StateUpdateChar(state);\r
+                       }\r
+                       else\r
+                               state = _optimum[posPrev].State;\r
+                       if (posPrev == cur - 1)\r
+                       {\r
+                               if (_optimum[cur].IsShortRep())\r
+                                       state = Base.StateUpdateShortRep(state);\r
+                               else\r
+                                       state = Base.StateUpdateChar(state);\r
+                       }\r
+                       else\r
+                       {\r
+                               int pos;\r
+                               if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)\r
+                               {\r
+                                       posPrev = _optimum[cur].PosPrev2;\r
+                                       pos = _optimum[cur].BackPrev2;\r
+                                       state = Base.StateUpdateRep(state);\r
+                               }\r
+                               else\r
+                               {\r
+                                       pos = _optimum[cur].BackPrev;\r
+                                       if (pos < Base.kNumRepDistances)\r
+                                               state = Base.StateUpdateRep(state);\r
+                                       else\r
+                                               state = Base.StateUpdateMatch(state);\r
+                               }\r
+                               Optimal opt = _optimum[posPrev];\r
+                               if (pos < Base.kNumRepDistances)\r
+                               {\r
+                                       if (pos == 0)\r
+                                       {\r
+                                               reps[0] = opt.Backs0;\r
+                                               reps[1] = opt.Backs1;\r
+                                               reps[2] = opt.Backs2;\r
+                                               reps[3] = opt.Backs3;\r
+                                       }\r
+                                       else if (pos == 1)\r
+                                       {\r
+                                               reps[0] = opt.Backs1;\r
+                                               reps[1] = opt.Backs0;\r
+                                               reps[2] = opt.Backs2;\r
+                                               reps[3] = opt.Backs3;\r
+                                       }\r
+                                       else if (pos == 2)\r
+                                       {\r
+                                               reps[0] = opt.Backs2;\r
+                                               reps[1] = opt.Backs0;\r
+                                               reps[2] = opt.Backs1;\r
+                                               reps[3] = opt.Backs3;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               reps[0] = opt.Backs3;\r
+                                               reps[1] = opt.Backs0;\r
+                                               reps[2] = opt.Backs1;\r
+                                               reps[3] = opt.Backs2;\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       reps[0] = (pos - Base.kNumRepDistances);\r
+                                       reps[1] = opt.Backs0;\r
+                                       reps[2] = opt.Backs1;\r
+                                       reps[3] = opt.Backs2;\r
+                               }\r
+                       }\r
+                       _optimum[cur].State = state;\r
+                       _optimum[cur].Backs0 = reps[0];\r
+                       _optimum[cur].Backs1 = reps[1];\r
+                       _optimum[cur].Backs2 = reps[2];\r
+                       _optimum[cur].Backs3 = reps[3];\r
+                       int curPrice = _optimum[cur].Price;\r
+\r
+                       currentByte = _matchFinder.GetIndexByte(0 - 1);\r
+                       matchByte = _matchFinder.GetIndexByte(0 - reps[0] - 1 - 1);\r
+\r
+                       posState = (position & _posStateMask);\r
+\r
+                       int curAnd1Price = curPrice +\r
+                               SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]) +\r
+                               _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)).\r
+                               GetPrice(!Base.StateIsCharState(state), matchByte, currentByte);\r
+\r
+                       Optimal nextOptimum = _optimum[cur + 1];\r
+\r
+                       boolean nextIsChar = false;\r
+                       if (curAnd1Price < nextOptimum.Price)\r
+                       {\r
+                               nextOptimum.Price = curAnd1Price;\r
+                               nextOptimum.PosPrev = cur;\r
+                               nextOptimum.MakeAsChar();\r
+                               nextIsChar = true;\r
+                       }\r
+\r
+                       matchPrice = curPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]);\r
+                       repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state]);\r
+\r
+                       if (matchByte == currentByte &&\r
+                               !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))\r
+                       {\r
+                               int shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);\r
+                               if (shortRepPrice <= nextOptimum.Price)\r
+                               {\r
+                                       nextOptimum.Price = shortRepPrice;\r
+                                       nextOptimum.PosPrev = cur;\r
+                                       nextOptimum.MakeAsShortRep();\r
+                                       nextIsChar = true;\r
+                               }\r
+                       }\r
+\r
+                       int numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;\r
+                       numAvailableBytesFull = Math.min(kNumOpts - 1 - cur, numAvailableBytesFull);\r
+                       numAvailableBytes = numAvailableBytesFull;\r
+\r
+                       if (numAvailableBytes < 2)\r
+                               continue;\r
+                       if (numAvailableBytes > _numFastBytes)\r
+                               numAvailableBytes = _numFastBytes;\r
+                       if (!nextIsChar && matchByte != currentByte)\r
+                       {\r
+                               // try Literal + rep0\r
+                               int t = Math.min(numAvailableBytesFull - 1, _numFastBytes);\r
+                               int lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);\r
+                               if (lenTest2 >= 2)\r
+                               {\r
+                                       int state2 = Base.StateUpdateChar(state);\r
+\r
+                                       int posStateNext = (position + 1) & _posStateMask;\r
+                                       int nextRepMatchPrice = curAnd1Price +\r
+                                               SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +\r
+                                               SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);\r
+                                       {\r
+                                               int offset = cur + 1 + lenTest2;\r
+                                               while (lenEnd < offset)\r
+                                                       _optimum[++lenEnd].Price = kIfinityPrice;\r
+                                               int curAndLenPrice = nextRepMatchPrice + GetRepPrice(\r
+                                                               0, lenTest2, state2, posStateNext);\r
+                                               Optimal optimum = _optimum[offset];\r
+                                               if (curAndLenPrice < optimum.Price)\r
+                                               {\r
+                                                       optimum.Price = curAndLenPrice;\r
+                                                       optimum.PosPrev = cur + 1;\r
+                                                       optimum.BackPrev = 0;\r
+                                                       optimum.Prev1IsChar = true;\r
+                                                       optimum.Prev2 = false;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       int startLen = 2; // speed optimization \r
+\r
+                       for (int repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)\r
+                       {\r
+                               int lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes);\r
+                               if (lenTest < 2)\r
+                                       continue;\r
+                               int lenTestTemp = lenTest;\r
+                               do\r
+                               {\r
+                                       while (lenEnd < cur + lenTest)\r
+                                               _optimum[++lenEnd].Price = kIfinityPrice;\r
+                                       int curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);\r
+                                       Optimal optimum = _optimum[cur + lenTest];\r
+                                       if (curAndLenPrice < optimum.Price)\r
+                                       {\r
+                                               optimum.Price = curAndLenPrice;\r
+                                               optimum.PosPrev = cur;\r
+                                               optimum.BackPrev = repIndex;\r
+                                               optimum.Prev1IsChar = false;\r
+                                       }\r
+                               }\r
+                               while (--lenTest >= 2);\r
+                               lenTest = lenTestTemp;\r
+\r
+                               if (repIndex == 0)\r
+                                       startLen = lenTest + 1;\r
+\r
+                               // if (_maxMode)\r
+                               if (lenTest < numAvailableBytesFull)\r
+                               {\r
+                                       int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);\r
+                                       int lenTest2 = _matchFinder.GetMatchLen(lenTest, reps[repIndex], t);\r
+                                       if (lenTest2 >= 2)\r
+                                       {\r
+                                               int state2 = Base.StateUpdateRep(state);\r
+\r
+                                               int posStateNext = (position + lenTest) & _posStateMask;\r
+                                               int curAndLenCharPrice =\r
+                                                               repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) +\r
+                                                               SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +\r
+                                                               _literalEncoder.GetSubCoder(position + lenTest,\r
+                                                               _matchFinder.GetIndexByte(lenTest - 1 - 1)).GetPrice(true,\r
+                                                               _matchFinder.GetIndexByte(lenTest - 1 - (reps[repIndex] + 1)),\r
+                                                               _matchFinder.GetIndexByte(lenTest - 1));\r
+                                               state2 = Base.StateUpdateChar(state2);\r
+                                               posStateNext = (position + lenTest + 1) & _posStateMask;\r
+                                               int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);\r
+                                               int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);\r
+\r
+                                               // for(; lenTest2 >= 2; lenTest2--)\r
+                                               {\r
+                                                       int offset = lenTest + 1 + lenTest2;\r
+                                                       while (lenEnd < cur + offset)\r
+                                                               _optimum[++lenEnd].Price = kIfinityPrice;\r
+                                                       int curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);\r
+                                                       Optimal optimum = _optimum[cur + offset];\r
+                                                       if (curAndLenPrice < optimum.Price)\r
+                                                       {\r
+                                                               optimum.Price = curAndLenPrice;\r
+                                                               optimum.PosPrev = cur + lenTest + 1;\r
+                                                               optimum.BackPrev = 0;\r
+                                                               optimum.Prev1IsChar = true;\r
+                                                               optimum.Prev2 = true;\r
+                                                               optimum.PosPrev2 = cur;\r
+                                                               optimum.BackPrev2 = repIndex;\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       if (newLen > numAvailableBytes)\r
+                       {\r
+                               newLen = numAvailableBytes;\r
+                               for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ;\r
+                               _matchDistances[numDistancePairs] = newLen;\r
+                               numDistancePairs += 2;\r
+                       }\r
+                       if (newLen >= startLen)\r
+                       {\r
+                               normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[state]);\r
+                               while (lenEnd < cur + newLen)\r
+                                       _optimum[++lenEnd].Price = kIfinityPrice;\r
+\r
+                               int offs = 0;\r
+                               while (startLen > _matchDistances[offs])\r
+                                       offs += 2;\r
+\r
+                               for (int lenTest = startLen; ; lenTest++)\r
+                               {\r
+                                       int curBack = _matchDistances[offs + 1];\r
+                                       int curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);\r
+                                       Optimal optimum = _optimum[cur + lenTest];\r
+                                       if (curAndLenPrice < optimum.Price)\r
+                                       {\r
+                                               optimum.Price = curAndLenPrice;\r
+                                               optimum.PosPrev = cur;\r
+                                               optimum.BackPrev = curBack + Base.kNumRepDistances;\r
+                                               optimum.Prev1IsChar = false;\r
+                                       }\r
+\r
+                                       if (lenTest == _matchDistances[offs])\r
+                                       {\r
+                                               if (lenTest < numAvailableBytesFull)\r
+                                               {\r
+                                                       int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);\r
+                                                       int lenTest2 = _matchFinder.GetMatchLen(lenTest, curBack, t);\r
+                                                       if (lenTest2 >= 2)\r
+                                                       {\r
+                                                               int state2 = Base.StateUpdateMatch(state);\r
+\r
+                                                               int posStateNext = (position + lenTest) & _posStateMask;\r
+                                                               int curAndLenCharPrice = curAndLenPrice +\r
+                                                                       SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +\r
+                                                                       _literalEncoder.GetSubCoder(position + lenTest,\r
+                                                                       _matchFinder.GetIndexByte(lenTest - 1 - 1)).\r
+                                                                       GetPrice(true,\r
+                                                                       _matchFinder.GetIndexByte(lenTest - (curBack + 1) - 1),\r
+                                                                       _matchFinder.GetIndexByte(lenTest - 1));\r
+                                                               state2 = Base.StateUpdateChar(state2);\r
+                                                               posStateNext = (position + lenTest + 1) & _posStateMask;\r
+                                                               int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);\r
+                                                               int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);\r
+\r
+                                                               int offset = lenTest + 1 + lenTest2;\r
+                                                               while (lenEnd < cur + offset)\r
+                                                                       _optimum[++lenEnd].Price = kIfinityPrice;\r
+                                                               curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);\r
+                                                               optimum = _optimum[cur + offset];\r
+                                                               if (curAndLenPrice < optimum.Price)\r
+                                                               {\r
+                                                                       optimum.Price = curAndLenPrice;\r
+                                                                       optimum.PosPrev = cur + lenTest + 1;\r
+                                                                       optimum.BackPrev = 0;\r
+                                                                       optimum.Prev1IsChar = true;\r
+                                                                       optimum.Prev2 = true;\r
+                                                                       optimum.PosPrev2 = cur;\r
+                                                                       optimum.BackPrev2 = curBack + Base.kNumRepDistances;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                               offs += 2;\r
+                                               if (offs == numDistancePairs)\r
+                                                       break;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       boolean ChangePair(int smallDist, int bigDist)\r
+       {\r
+               int kDif = 7;\r
+               return (smallDist < (1 << (32 - kDif)) && bigDist >= (smallDist << kDif));\r
+       }\r
+\r
+       void WriteEndMarker(int posState) throws IOException\r
+       {\r
+               if (!_writeEndMark)\r
+                       return;\r
+\r
+               _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 1);\r
+               _rangeEncoder.Encode(_isRep, _state, 0);\r
+               _state = Base.StateUpdateMatch(_state);\r
+               int len = Base.kMatchMinLen;\r
+               _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);\r
+               int posSlot = (1 << Base.kNumPosSlotBits) - 1;\r
+               int lenToPosState = Base.GetLenToPosState(len);\r
+               _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);\r
+               int footerBits = 30;\r
+               int posReduced = (1 << footerBits) - 1;\r
+               _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);\r
+               _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);\r
+       }\r
+\r
+       void Flush(int nowPos) throws IOException\r
+       {\r
+               ReleaseMFStream();\r
+               WriteEndMarker(nowPos & _posStateMask);\r
+               _rangeEncoder.FlushData();\r
+               _rangeEncoder.FlushStream();\r
+       }\r
+\r
+       public void CodeOneBlock(long[] inSize, long[] outSize, boolean[] finished) throws IOException\r
+       {\r
+               inSize[0] = 0;\r
+               outSize[0] = 0;\r
+               finished[0] = true;\r
+\r
+               if (_inStream != null)\r
+               {\r
+                       _matchFinder.SetStream(_inStream);\r
+                       _matchFinder.Init();\r
+                       _needReleaseMFStream = true;\r
+                       _inStream = null;\r
+               }\r
+\r
+               if (_finished)\r
+                       return;\r
+               _finished = true;\r
+\r
+\r
+               long progressPosValuePrev = nowPos64;\r
+               if (nowPos64 == 0)\r
+               {\r
+                       if (_matchFinder.GetNumAvailableBytes() == 0)\r
+                       {\r
+                               Flush((int)nowPos64);\r
+                               return;\r
+                       }\r
+\r
+                       ReadMatchDistances();\r
+                       int posState = (int)(nowPos64) & _posStateMask;\r
+                       _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 0);\r
+                       _state = Base.StateUpdateChar(_state);\r
+                       byte curByte = _matchFinder.GetIndexByte(0 - _additionalOffset);\r
+                       _literalEncoder.GetSubCoder((int)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);\r
+                       _previousByte = curByte;\r
+                       _additionalOffset--;\r
+                       nowPos64++;\r
+               }\r
+               if (_matchFinder.GetNumAvailableBytes() == 0)\r
+               {\r
+                       Flush((int)nowPos64);\r
+                       return;\r
+               }\r
+               while (true)\r
+               {\r
+\r
+                       int len = GetOptimum((int)nowPos64);\r
+                       int pos = backRes;\r
+                       int posState = ((int)nowPos64) & _posStateMask;\r
+                       int complexState = (_state << Base.kNumPosStatesBitsMax) + posState;\r
+                       if (len == 1 && pos == -1)\r
+                       {\r
+                               _rangeEncoder.Encode(_isMatch, complexState, 0);\r
+                               byte curByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset));\r
+                               LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((int)nowPos64, _previousByte);\r
+                               if (!Base.StateIsCharState(_state))\r
+                               {\r
+                                       byte matchByte = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - _additionalOffset));\r
+                                       subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);\r
+                               }\r
+                               else\r
+                                       subCoder.Encode(_rangeEncoder, curByte);\r
+                               _previousByte = curByte;\r
+                               _state = Base.StateUpdateChar(_state);\r
+                       }\r
+                       else\r
+                       {\r
+                               _rangeEncoder.Encode(_isMatch, complexState, 1);\r
+                               if (pos < Base.kNumRepDistances)\r
+                               {\r
+                                       _rangeEncoder.Encode(_isRep, _state, 1);\r
+                                       if (pos == 0)\r
+                                       {\r
+                                               _rangeEncoder.Encode(_isRepG0, _state, 0);\r
+                                               if (len == 1)\r
+                                                       _rangeEncoder.Encode(_isRep0Long, complexState, 0);\r
+                                               else\r
+                                                       _rangeEncoder.Encode(_isRep0Long, complexState, 1);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               _rangeEncoder.Encode(_isRepG0, _state, 1);\r
+                                               if (pos == 1)\r
+                                                       _rangeEncoder.Encode(_isRepG1, _state, 0);\r
+                                               else\r
+                                               {\r
+                                                       _rangeEncoder.Encode(_isRepG1, _state, 1);\r
+                                                       _rangeEncoder.Encode(_isRepG2, _state, pos - 2);\r
+                                               }\r
+                                       }\r
+                                       if (len == 1)\r
+                                               _state = Base.StateUpdateShortRep(_state);\r
+                                       else\r
+                                       {\r
+                                               _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);\r
+                                               _state = Base.StateUpdateRep(_state);\r
+                                       }\r
+                                       int distance = _repDistances[pos];\r
+                                       if (pos != 0)\r
+                                       {\r
+                                               for (int i = pos; i >= 1; i--)\r
+                                                       _repDistances[i] = _repDistances[i - 1];\r
+                                               _repDistances[0] = distance;\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       _rangeEncoder.Encode(_isRep, _state, 0);\r
+                                       _state = Base.StateUpdateMatch(_state);\r
+                                       _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);\r
+                                       pos -= Base.kNumRepDistances;\r
+                                       int posSlot = GetPosSlot(pos);\r
+                                       int lenToPosState = Base.GetLenToPosState(len);\r
+                                       _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);\r
+\r
+                                       if (posSlot >= Base.kStartPosModelIndex)\r
+                                       {\r
+                                               int footerBits = (int)((posSlot >> 1) - 1);\r
+                                               int baseVal = ((2 | (posSlot & 1)) << footerBits);\r
+                                               int posReduced = pos - baseVal;\r
+\r
+                                               if (posSlot < Base.kEndPosModelIndex)\r
+                                                       BitTreeEncoder.ReverseEncode(_posEncoders,\r
+                                                                       baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);\r
+                                               else\r
+                                               {\r
+                                                       _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);\r
+                                                       _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);\r
+                                                       _alignPriceCount++;\r
+                                               }\r
+                                       }\r
+                                       int distance = pos;\r
+                                       for (int i = Base.kNumRepDistances - 1; i >= 1; i--)\r
+                                               _repDistances[i] = _repDistances[i - 1];\r
+                                       _repDistances[0] = distance;\r
+                                       _matchPriceCount++;\r
+                               }\r
+                               _previousByte = _matchFinder.GetIndexByte(len - 1 - _additionalOffset);\r
+                       }\r
+                       _additionalOffset -= len;\r
+                       nowPos64 += len;\r
+                       if (_additionalOffset == 0)\r
+                       {\r
+                               // if (!_fastMode)\r
+                               if (_matchPriceCount >= (1 << 7))\r
+                                       FillDistancesPrices();\r
+                               if (_alignPriceCount >= Base.kAlignTableSize)\r
+                                       FillAlignPrices();\r
+                               inSize[0] = nowPos64;\r
+                               outSize[0] = _rangeEncoder.GetProcessedSizeAdd();\r
+                               if (_matchFinder.GetNumAvailableBytes() == 0)\r
+                               {\r
+                                       Flush((int)nowPos64);\r
+                                       return;\r
+                               }\r
+\r
+                               if (nowPos64 - progressPosValuePrev >= (1 << 12))\r
+                               {\r
+                                       _finished = false;\r
+                                       finished[0] = false;\r
+                                       return;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       void ReleaseMFStream()\r
+       {\r
+               if (_matchFinder != null && _needReleaseMFStream)\r
+               {\r
+                       _matchFinder.ReleaseStream();\r
+                       _needReleaseMFStream = false;\r
+               }\r
+       }\r
+\r
+       void SetOutStream(java.io.OutputStream outStream)\r
+       { _rangeEncoder.SetStream(outStream); }\r
+       void ReleaseOutStream()\r
+       { _rangeEncoder.ReleaseStream(); }\r
+\r
+       void ReleaseStreams()\r
+       {\r
+               ReleaseMFStream();\r
+               ReleaseOutStream();\r
+       }\r
+\r
+       void SetStreams(java.io.InputStream inStream, java.io.OutputStream outStream,\r
+                       long inSize, long outSize)\r
+       {\r
+               _inStream = inStream;\r
+               _finished = false;\r
+               Create();\r
+               SetOutStream(outStream);\r
+               Init();\r
+\r
+               // if (!_fastMode)\r
+               {\r
+                       FillDistancesPrices();\r
+                       FillAlignPrices();\r
+               }\r
+\r
+               _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);\r
+               _lenEncoder.UpdateTables(1 << _posStateBits);\r
+               _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);\r
+               _repMatchLenEncoder.UpdateTables(1 << _posStateBits);\r
+\r
+               nowPos64 = 0;\r
+       }\r
+\r
+       long[] processedInSize = new long[1]; long[] processedOutSize = new long[1]; boolean[] finished = new boolean[1];\r
+       public void Code(java.io.InputStream inStream, java.io.OutputStream outStream,\r
+                       long inSize, long outSize, ICodeProgress progress) throws IOException\r
+       {\r
+               _needReleaseMFStream = false;\r
+               try\r
+               {\r
+                       SetStreams(inStream, outStream, inSize, outSize);\r
+                       while (true)\r
+                       {\r
+\r
+\r
+\r
+                               CodeOneBlock(processedInSize, processedOutSize, finished);\r
+                               if (finished[0])\r
+                                       return;\r
+                               if (progress != null)\r
+                               {\r
+                                       progress.SetProgress(processedInSize[0], processedOutSize[0]);\r
+                               }\r
+                       }\r
+               }\r
+               finally\r
+               {\r
+                       ReleaseStreams();\r
+               }\r
+       }\r
+\r
+       public static final int kPropSize = 5;\r
+       byte[] properties = new byte[kPropSize];\r
+\r
+       public void WriteCoderProperties(java.io.OutputStream outStream) throws IOException\r
+       {\r
+               properties[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);\r
+               for (int i = 0; i < 4; i++)\r
+                       properties[1 + i] = (byte)(_dictionarySize >> (8 * i));\r
+               outStream.write(properties, 0, kPropSize);\r
+       }\r
+\r
+       int[] tempPrices = new int[Base.kNumFullDistances];\r
+       int _matchPriceCount;\r
+\r
+       void FillDistancesPrices()\r
+       {\r
+               for (int i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)\r
+               {\r
+                       int posSlot = GetPosSlot(i);\r
+                       int footerBits = (int)((posSlot >> 1) - 1);\r
+                       int baseVal = ((2 | (posSlot & 1)) << footerBits);\r
+                       tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders,\r
+                               baseVal - posSlot - 1, footerBits, i - baseVal);\r
+               }\r
+\r
+               for (int lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)\r
+               {\r
+                       int posSlot;\r
+                       BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];\r
+\r
+                       int st = (lenToPosState << Base.kNumPosSlotBits);\r
+                       for (posSlot = 0; posSlot < _distTableSize; posSlot++)\r
+                               _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);\r
+                       for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)\r
+                               _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << SevenZip.Compression.RangeCoder.Encoder.kNumBitPriceShiftBits);\r
+\r
+                       int st2 = lenToPosState * Base.kNumFullDistances;\r
+                       int i;\r
+                       for (i = 0; i < Base.kStartPosModelIndex; i++)\r
+                               _distancesPrices[st2 + i] = _posSlotPrices[st + i];\r
+                       for (; i < Base.kNumFullDistances; i++)\r
+                               _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];\r
+               }\r
+               _matchPriceCount = 0;\r
+       }\r
+\r
+       void FillAlignPrices()\r
+       {\r
+               for (int i = 0; i < Base.kAlignTableSize; i++)\r
+                       _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);\r
+               _alignPriceCount = 0;\r
+       }\r
+\r
+\r
+       public boolean SetAlgorithm(int algorithm)\r
+       {\r
+               /*\r
+               _fastMode = (algorithm == 0);\r
+               _maxMode = (algorithm >= 2);\r
+               */\r
+               return true;\r
+       }\r
+\r
+       public boolean SetDictionarySize(int dictionarySize)\r
+       {\r
+               int kDicLogSizeMaxCompress = 29;\r
+               if (dictionarySize < (1 << Base.kDicLogSizeMin) || dictionarySize > (1 << kDicLogSizeMaxCompress))\r
+                       return false;\r
+               _dictionarySize = dictionarySize;\r
+               int dicLogSize;\r
+               for (dicLogSize = 0; dictionarySize > (1 << dicLogSize); dicLogSize++) ;\r
+               _distTableSize = dicLogSize * 2;\r
+               return true;\r
+       }\r
+\r
+       public boolean SetNumFastBytes(int numFastBytes)\r
+       {\r
+               if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)\r
+                       return false;\r
+               _numFastBytes = numFastBytes;\r
+               return true;\r
+       }\r
+\r
+       public boolean SetMatchFinder(int matchFinderIndex)\r
+       {\r
+               if (matchFinderIndex < 0 || matchFinderIndex > 2)\r
+                       return false;\r
+               int matchFinderIndexPrev = _matchFinderType;\r
+               _matchFinderType = matchFinderIndex;\r
+               if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)\r
+               {\r
+                       _dictionarySizePrev = -1;\r
+                       _matchFinder = null;\r
+               }\r
+               return true;\r
+       }\r
+\r
+       public boolean SetLcLpPb(int lc, int lp, int pb)\r
+       {\r
+               if (\r
+                               lp < 0 || lp > Base.kNumLitPosStatesBitsEncodingMax ||\r
+                               lc < 0 || lc > Base.kNumLitContextBitsMax ||\r
+                               pb < 0 || pb > Base.kNumPosStatesBitsEncodingMax)\r
+                       return false;\r
+               _numLiteralPosStateBits = lp;\r
+               _numLiteralContextBits = lc;\r
+               _posStateBits = pb;\r
+               _posStateMask = ((1) << _posStateBits) - 1;\r
+               return true;\r
+       }\r
+\r
+       public void SetEndMarkerMode(boolean endMarkerMode)\r
+       {\r
+               _writeEndMark = endMarkerMode;\r
+       }\r
+}\r
+\r
diff --git a/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java b/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java
new file mode 100755 (executable)
index 0000000..6864c69
--- /dev/null
@@ -0,0 +1,55 @@
+package SevenZip.Compression.RangeCoder;\r
+\r
+public class BitTreeDecoder\r
+{\r
+       short[] Models;\r
+       int NumBitLevels;\r
+       \r
+       public BitTreeDecoder(int numBitLevels)\r
+       {\r
+               NumBitLevels = numBitLevels;\r
+               Models = new short[1 << numBitLevels];\r
+       }\r
+       \r
+       public void Init()\r
+       {\r
+               Decoder.InitBitModels(Models);\r
+       }\r
+       \r
+       public int Decode(Decoder rangeDecoder) throws java.io.IOException\r
+       {\r
+               int m = 1;\r
+               for (int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)\r
+                       m = (m << 1) + rangeDecoder.DecodeBit(Models, m);\r
+               return m - (1 << NumBitLevels);\r
+       }\r
+       \r
+       public int ReverseDecode(Decoder rangeDecoder) throws java.io.IOException\r
+       {\r
+               int m = 1;\r
+               int symbol = 0;\r
+               for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)\r
+               {\r
+                       int bit = rangeDecoder.DecodeBit(Models, m);\r
+                       m <<= 1;\r
+                       m += bit;\r
+                       symbol |= (bit << bitIndex);\r
+               }\r
+               return symbol;\r
+       }\r
+       \r
+       public static int ReverseDecode(short[] Models, int startIndex,\r
+                       Decoder rangeDecoder, int NumBitLevels) throws java.io.IOException\r
+       {\r
+               int m = 1;\r
+               int symbol = 0;\r
+               for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)\r
+               {\r
+                       int bit = rangeDecoder.DecodeBit(Models, startIndex + m);\r
+                       m <<= 1;\r
+                       m += bit;\r
+                       symbol |= (bit << bitIndex);\r
+               }\r
+               return symbol;\r
+       }\r
+}\r
diff --git a/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java b/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java
new file mode 100755 (executable)
index 0000000..b4c0a07
--- /dev/null
@@ -0,0 +1,99 @@
+package SevenZip.Compression.RangeCoder;\r
+import java.io.IOException;\r
+\r
+public class BitTreeEncoder\r
+{\r
+       short[] Models;\r
+       int NumBitLevels;\r
+       \r
+       public BitTreeEncoder(int numBitLevels)\r
+       {\r
+               NumBitLevels = numBitLevels;\r
+               Models = new short[1 << numBitLevels];\r
+       }\r
+       \r
+       public void Init()\r
+       {\r
+               Decoder.InitBitModels(Models);\r
+       }\r
+       \r
+       public void Encode(Encoder rangeEncoder, int symbol) throws IOException\r
+       {\r
+               int m = 1;\r
+               for (int bitIndex = NumBitLevels; bitIndex != 0; )\r
+               {\r
+                       bitIndex--;\r
+                       int bit = (symbol >>> bitIndex) & 1;\r
+                       rangeEncoder.Encode(Models, m, bit);\r
+                       m = (m << 1) | bit;\r
+               }\r
+       }\r
+       \r
+       public void ReverseEncode(Encoder rangeEncoder, int symbol) throws IOException\r
+       {\r
+               int m = 1;\r
+               for (int  i = 0; i < NumBitLevels; i++)\r
+               {\r
+                       int bit = symbol & 1;\r
+                       rangeEncoder.Encode(Models, m, bit);\r
+                       m = (m << 1) | bit;\r
+                       symbol >>= 1;\r
+               }\r
+       }\r
+       \r
+       public int GetPrice(int symbol)\r
+       {\r
+               int price = 0;\r
+               int m = 1;\r
+               for (int bitIndex = NumBitLevels; bitIndex != 0; )\r
+               {\r
+                       bitIndex--;\r
+                       int bit = (symbol >>> bitIndex) & 1;\r
+                       price += Encoder.GetPrice(Models[m], bit);\r
+                       m = (m << 1) + bit;\r
+               }\r
+               return price;\r
+       }\r
+       \r
+       public int ReverseGetPrice(int symbol)\r
+       {\r
+               int price = 0;\r
+               int m = 1;\r
+               for (int i = NumBitLevels; i != 0; i--)\r
+               {\r
+                       int bit = symbol & 1;\r
+                       symbol >>>= 1;\r
+                       price += Encoder.GetPrice(Models[m], bit);\r
+                       m = (m << 1) | bit;\r
+               }\r
+               return price;\r
+       }\r
+       \r
+       public static int ReverseGetPrice(short[] Models, int startIndex,\r
+                       int NumBitLevels, int symbol)\r
+       {\r
+               int price = 0;\r
+               int m = 1;\r
+               for (int i = NumBitLevels; i != 0; i--)\r
+               {\r
+                       int bit = symbol & 1;\r
+                       symbol >>>= 1;\r
+                       price += Encoder.GetPrice(Models[startIndex + m], bit);\r
+                       m = (m << 1) | bit;\r
+               }\r
+               return price;\r
+       }\r
+       \r
+       public static void ReverseEncode(short[] Models, int startIndex,\r
+                       Encoder rangeEncoder, int NumBitLevels, int symbol) throws IOException\r
+       {\r
+               int m = 1;\r
+               for (int i = 0; i < NumBitLevels; i++)\r
+               {\r
+                       int bit = symbol & 1;\r
+                       rangeEncoder.Encode(Models, startIndex + m, bit);\r
+                       m = (m << 1) | bit;\r
+                       symbol >>= 1;\r
+               }\r
+       }\r
+}\r
diff --git a/Java/SevenZip/Compression/RangeCoder/Decoder.java b/Java/SevenZip/Compression/RangeCoder/Decoder.java
new file mode 100755 (executable)
index 0000000..7453383
--- /dev/null
@@ -0,0 +1,88 @@
+package SevenZip.Compression.RangeCoder;\r
+import java.io.IOException;\r
+\r
+public class Decoder\r
+{\r
+       static final int kTopMask = ~((1 << 24) - 1);\r
+       \r
+       static final int kNumBitModelTotalBits = 11;\r
+       static final int kBitModelTotal = (1 << kNumBitModelTotalBits);\r
+       static final int kNumMoveBits = 5;\r
+       \r
+       int Range;\r
+       int Code;\r
+\r
+       java.io.InputStream Stream;\r
+       \r
+       public final void SetStream(java.io.InputStream stream)\r
+       { \r
+               Stream = stream; \r
+       }\r
+       \r
+       public final void ReleaseStream()\r
+       { \r
+               Stream = null; \r
+       }\r
+       \r
+       public final void Init() throws IOException\r
+       {\r
+               Code = 0;\r
+               Range = -1;\r
+               for (int i = 0; i < 5; i++)\r
+                       Code = (Code << 8) | Stream.read();\r
+       }\r
+       \r
+       public final int DecodeDirectBits(int numTotalBits) throws IOException\r
+       {\r
+               int result = 0;\r
+               for (int i = numTotalBits; i != 0; i--)\r
+               {\r
+                       Range >>>= 1;\r
+                       int t = ((Code - Range) >>> 31);\r
+                       Code -= Range & (t - 1);\r
+                       result = (result << 1) | (1 - t);\r
+                       \r
+                       if ((Range & kTopMask) == 0)\r
+                       {\r
+                               Code = (Code << 8) | Stream.read();\r
+                               Range <<= 8;\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
+       \r
+       public int DecodeBit(short []probs, int index) throws IOException\r
+       {\r
+               int prob = probs[index];\r
+               int newBound = (Range >>> kNumBitModelTotalBits) * prob;\r
+               if ((Code ^ 0x80000000) < (newBound ^ 0x80000000))\r
+               {\r
+                       Range = newBound;\r
+                       probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));\r
+                       if ((Range & kTopMask) == 0)\r
+                       {\r
+                               Code = (Code << 8) | Stream.read();\r
+                               Range <<= 8;\r
+                       }\r
+                       return 0;\r
+               }\r
+               else\r
+               {\r
+                       Range -= newBound;\r
+                       Code -= newBound;\r
+                       probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));\r
+                       if ((Range & kTopMask) == 0)\r
+                       {\r
+                               Code = (Code << 8) | Stream.read();\r
+                               Range <<= 8;\r
+                       }\r
+                       return 1;\r
+               }\r
+       }\r
+       \r
+       public static void InitBitModels(short []probs)\r
+       {\r
+               for (int i = 0; i < probs.length; i++)\r
+                       probs[i] = (kBitModelTotal >>> 1);\r
+       }\r
+}\r
diff --git a/Java/SevenZip/Compression/RangeCoder/Encoder.java b/Java/SevenZip/Compression/RangeCoder/Encoder.java
new file mode 100755 (executable)
index 0000000..2273e92
--- /dev/null
@@ -0,0 +1,151 @@
+package SevenZip.Compression.RangeCoder;\r
+import java.io.IOException;\r
+\r
+public class Encoder\r
+{\r
+       static final int kTopMask = ~((1 << 24) - 1);\r
+       \r
+       static final int kNumBitModelTotalBits = 11;\r
+       static final int kBitModelTotal = (1 << kNumBitModelTotalBits);\r
+       static final int kNumMoveBits = 5;\r
+       \r
+       java.io.OutputStream Stream;\r
+\r
+       long Low;\r
+       int Range;\r
+       int _cacheSize;\r
+       int _cache;\r
+       \r
+       long _position;\r
+       \r
+       public void SetStream(java.io.OutputStream stream)\r
+       {\r
+               Stream = stream;\r
+       }\r
+       \r
+       public void ReleaseStream()\r
+       {\r
+               Stream = null;\r
+       }\r
+       \r
+       public void Init()\r
+       {\r
+               _position = 0;\r
+               Low = 0;\r
+               Range = -1;\r
+               _cacheSize = 1;\r
+               _cache = 0;\r
+       }\r
+       \r
+       public void FlushData() throws IOException\r
+       {\r
+               for (int i = 0; i < 5; i++)\r
+                       ShiftLow();\r
+       }\r
+       \r
+       public void FlushStream() throws IOException\r
+       {\r
+               Stream.flush();\r
+       }\r
+       \r
+       public void ShiftLow() throws IOException\r
+       {\r
+               int LowHi = (int)(Low >>> 32);\r
+               if (LowHi != 0 || Low < 0xFF000000L)\r
+               {\r
+                       _position += _cacheSize;\r
+                       int temp = _cache;\r
+                       do\r
+                       {\r
+                               Stream.write(temp + LowHi);\r
+                               temp = 0xFF;\r
+                       }\r
+                       while(--_cacheSize != 0);\r
+                       _cache = (((int)Low) >>> 24);\r
+               }\r
+               _cacheSize++;\r
+               Low = (Low & 0xFFFFFF) << 8;\r
+       }\r
+       \r
+       public void EncodeDirectBits(int v, int numTotalBits) throws IOException\r
+       {\r
+               for (int i = numTotalBits - 1; i >= 0; i--)\r
+               {\r
+                       Range >>>= 1;\r
+                       if (((v >>> i) & 1) == 1)\r
+                               Low += Range;\r
+                       if ((Range & Encoder.kTopMask) == 0)\r
+                       {\r
+                               Range <<= 8;\r
+                               ShiftLow();\r
+                       }\r
+               }\r
+       }\r
+       \r
+       \r
+       public long GetProcessedSizeAdd()\r
+       {\r
+               return _cacheSize + _position + 4;\r
+       }\r
+       \r
+       \r
+       \r
+       static final int kNumMoveReducingBits = 2;\r
+       public static final int kNumBitPriceShiftBits = 6;\r
+       \r
+       public static void InitBitModels(short []probs)\r
+       {\r
+               for (int i = 0; i < probs.length; i++)\r
+                       probs[i] = (kBitModelTotal >>> 1);\r
+       }\r
+       \r
+       public void Encode(short []probs, int index, int symbol) throws IOException\r
+       {\r
+               int prob = probs[index];\r
+               int newBound = (Range >>> kNumBitModelTotalBits) * prob;\r
+               if (symbol == 0)\r
+               {\r
+                       Range = newBound;\r
+                       probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));\r
+               }\r
+               else\r
+               {\r
+                       Low += (newBound & 0xFFFFFFFFL);\r
+                       Range -= newBound;\r
+                       probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));\r
+               }\r
+               if ((Range & kTopMask) == 0)\r
+               {\r
+                       Range <<= 8;\r
+                       ShiftLow();\r
+               }\r
+       }\r
+       \r
+       private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];\r
+       \r
+       static\r
+       {\r
+               int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);\r
+               for (int i = kNumBits - 1; i >= 0; i--)\r
+               {\r
+                       int start = 1 << (kNumBits - i - 1);\r
+                       int end = 1 << (kNumBits - i);\r
+                       for (int j = start; j < end; j++)\r
+                               ProbPrices[j] = (i << kNumBitPriceShiftBits) +\r
+                                               (((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));\r
+               }\r
+       }\r
+       \r
+       static public int GetPrice(int Prob, int symbol)\r
+       {\r
+               return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];\r
+       }\r
+       static public int GetPrice0(int Prob)\r
+       { \r
+               return ProbPrices[Prob >>> kNumMoveReducingBits]; \r
+       }\r
+       static public int GetPrice1(int Prob)\r
+       { \r
+               return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits]; \r
+       }\r
+}\r
diff --git a/Java/SevenZip/ICodeProgress.java b/Java/SevenZip/ICodeProgress.java
new file mode 100755 (executable)
index 0000000..290bd2d
--- /dev/null
@@ -0,0 +1,6 @@
+package SevenZip;\r
+\r
+public interface ICodeProgress\r
+{\r
+       public void SetProgress(long inSize, long outSize);\r
+}\r
diff --git a/Java/SevenZip/LzmaAlone.java b/Java/SevenZip/LzmaAlone.java
new file mode 100755 (executable)
index 0000000..de39a22
--- /dev/null
@@ -0,0 +1,253 @@
+package SevenZip;\r
+\r
+public class LzmaAlone\r
+{\r
+       static public class CommandLine\r
+       {\r
+               public static final int kEncode = 0;\r
+               public static final int kDecode = 1;\r
+               public static final int kBenchmak = 2;\r
+               \r
+               public int Command = -1;\r
+               public int NumBenchmarkPasses = 10;\r
+               \r
+               public int DictionarySize = 1 << 23;\r
+               public boolean DictionarySizeIsDefined = false;\r
+               \r
+               public int Lc = 3;\r
+               public int Lp = 0;\r
+               public int Pb = 2;\r
+               \r
+               public int Fb = 128;\r
+               public boolean FbIsDefined = false;\r
+               \r
+               public boolean Eos = false;\r
+               \r
+               public int Algorithm = 2;\r
+               public int MatchFinder = 1;\r
+               \r
+               public String InFile;\r
+               public String OutFile;\r
+               \r
+               boolean ParseSwitch(String s)\r
+               {\r
+                       if (s.startsWith("d"))\r
+                       {\r
+                               DictionarySize = 1 << Integer.parseInt(s.substring(1));\r
+                               DictionarySizeIsDefined = true;\r
+                       }\r
+                       else if (s.startsWith("fb"))\r
+                       {\r
+                               Fb = Integer.parseInt(s.substring(2));\r
+                               FbIsDefined = true;\r
+                       }\r
+                       else if (s.startsWith("a"))\r
+                               Algorithm = Integer.parseInt(s.substring(1));\r
+                       else if (s.startsWith("lc"))\r
+                               Lc = Integer.parseInt(s.substring(2));\r
+                       else if (s.startsWith("lp"))\r
+                               Lp = Integer.parseInt(s.substring(2));\r
+                       else if (s.startsWith("pb"))\r
+                               Pb = Integer.parseInt(s.substring(2));\r
+                       else if (s.startsWith("eos"))\r
+                               Eos = true;\r
+                       else if (s.startsWith("mf"))\r
+                       {\r
+                               String mfs = s.substring(2);\r
+                               if (mfs.equals("bt2"))\r
+                                       MatchFinder = 0;\r
+                               else if (mfs.equals("bt4"))\r
+                                       MatchFinder = 1;\r
+                               else if (mfs.equals("bt4b"))\r
+                                       MatchFinder = 2;\r
+                               else\r
+                                       return false;\r
+                       }\r
+                       else\r
+                               return false;\r
+                       return true;\r
+               }\r
+               \r
+               public boolean Parse(String[] args) throws Exception\r
+               {\r
+                       int pos = 0;\r
+                       boolean switchMode = true;\r
+                       for (int i = 0; i < args.length; i++)\r
+                       {\r
+                               String s = args[i];\r
+                               if (s.length() == 0)\r
+                                       return false;\r
+                               if (switchMode)\r
+                               {\r
+                                       if (s.compareTo("--") == 0)\r
+                                       {\r
+                                               switchMode = false;\r
+                                               continue;\r
+                                       }\r
+                                       if (s.charAt(0) == '-')\r
+                                       {\r
+                                               String sw = s.substring(1).toLowerCase();\r
+                                               if (sw.length() == 0)\r
+                                                       return false;\r
+                                               try\r
+                                               {\r
+                                                       if (!ParseSwitch(sw))\r
+                                                               return false;\r
+                                               }\r
+                                               catch (NumberFormatException e)\r
+                                               {\r
+                                                       return false;\r
+                                               }\r
+                                               continue;\r
+                                       }\r
+                               }\r
+                               if (pos == 0)\r
+                               {\r
+                                       if (s.equalsIgnoreCase("e"))\r
+                                               Command = kEncode;\r
+                                       else if (s.equalsIgnoreCase("d"))\r
+                                               Command = kDecode;\r
+                                       else if (s.equalsIgnoreCase("b"))\r
+                                               Command = kBenchmak;\r
+                                       else\r
+                                               return false;\r
+                               }\r
+                               else if(pos == 1)\r
+                               {\r
+                                       if (Command == kBenchmak)\r
+                                       {\r
+                                               try\r
+                                               {\r
+                                                       NumBenchmarkPasses = Integer.parseInt(s);\r
+                                                       if (NumBenchmarkPasses < 1)\r
+                                                               return false;\r
+                                               }\r
+                                               catch (NumberFormatException e)\r
+                                               {\r
+                                                       return false;\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                               InFile = s;\r
+                               }\r
+                               else if(pos == 2)\r
+                                       OutFile = s;\r
+                               else\r
+                                       return false;\r
+                               pos++;\r
+                               continue;\r
+                       }\r
+                       return true;\r
+               }\r
+       }\r
+       \r
+       \r
+       static void PrintHelp()\r
+       {\r
+               System.out.println(\r
+                               "\nUsage:  LZMA <e|d> [<switches>...] inputFile outputFile\n" +\r
+                               "  e: encode file\n" +\r
+                               "  d: decode file\n" +\r
+                               "  b: Benchmark\n" +\r
+                               "<Switches>\n" +\r
+                               // "  -a{N}:  set compression mode - [0, 1], default: 1 (max)\n" +\r
+                               "  -d{N}:  set dictionary - [0,28], default: 23 (8MB)\n" +\r
+                               "  -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +\r
+                               "  -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +\r
+                               "  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +\r
+                               "  -pb{N}: set number of pos bits - [0, 4], default: 2\n" +\r
+                               "  -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +\r
+                               "  -eos:   write End Of Stream marker\n"\r
+                               );\r
+       }\r
+       \r
+       public static void main(String[] args) throws Exception\r
+       {\r
+               System.out.println("\nLZMA (Java) 4.61  2008-11-23\n");\r
+               \r
+               if (args.length < 1)\r
+               {\r
+                       PrintHelp();\r
+                       return;\r
+               }\r
+               \r
+               CommandLine params = new CommandLine();\r
+               if (!params.Parse(args))\r
+               {\r
+                       System.out.println("\nIncorrect command");\r
+                       return;\r
+               }\r
+               \r
+               if (params.Command == CommandLine.kBenchmak)\r
+               {\r
+                       int dictionary = (1 << 21);\r
+                       if (params.DictionarySizeIsDefined)\r
+                               dictionary = params.DictionarySize;\r
+                       if (params.MatchFinder > 1)\r
+                               throw new Exception("Unsupported match finder");\r
+                       SevenZip.LzmaBench.LzmaBenchmark(params.NumBenchmarkPasses, dictionary);\r
+               }\r
+               else if (params.Command == CommandLine.kEncode || params.Command == CommandLine.kDecode)\r
+               {\r
+                       java.io.File inFile = new java.io.File(params.InFile);\r
+                       java.io.File outFile = new java.io.File(params.OutFile);\r
+                       \r
+                       java.io.BufferedInputStream inStream  = new java.io.BufferedInputStream(new java.io.FileInputStream(inFile));\r
+                       java.io.BufferedOutputStream outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outFile));\r
+                       \r
+                       boolean eos = false;\r
+                       if (params.Eos)\r
+                               eos = true;\r
+                       if (params.Command == CommandLine.kEncode)\r
+                       {\r
+                               SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();\r
+                               if (!encoder.SetAlgorithm(params.Algorithm))\r
+                                       throw new Exception("Incorrect compression mode");\r
+                               if (!encoder.SetDictionarySize(params.DictionarySize))\r
+                                       throw new Exception("Incorrect dictionary size");\r
+                               if (!encoder.SetNumFastBytes(params.Fb))\r
+                                       throw new Exception("Incorrect -fb value");\r
+                               if (!encoder.SetMatchFinder(params.MatchFinder))\r
+                                       throw new Exception("Incorrect -mf value");\r
+                               if (!encoder.SetLcLpPb(params.Lc, params.Lp, params.Pb))\r
+                                       throw new Exception("Incorrect -lc or -lp or -pb value");\r
+                               encoder.SetEndMarkerMode(eos);\r
+                               encoder.WriteCoderProperties(outStream);\r
+                               long fileSize;\r
+                               if (eos)\r
+                                       fileSize = -1;\r
+                               else\r
+                                       fileSize = inFile.length();\r
+                               for (int i = 0; i < 8; i++)\r
+                                       outStream.write((int)(fileSize >>> (8 * i)) & 0xFF);\r
+                               encoder.Code(inStream, outStream, -1, -1, null);\r
+                       }\r
+                       else\r
+                       {\r
+                               int propertiesSize = 5;\r
+                               byte[] properties = new byte[propertiesSize];\r
+                               if (inStream.read(properties, 0, propertiesSize) != propertiesSize)\r
+                                       throw new Exception("input .lzma file is too short");\r
+                               SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();\r
+                               if (!decoder.SetDecoderProperties(properties))\r
+                                       throw new Exception("Incorrect stream properties");\r
+                               long outSize = 0;\r
+                               for (int i = 0; i < 8; i++)\r
+                               {\r
+                                       int v = inStream.read();\r
+                                       if (v < 0)\r
+                                               throw new Exception("Can't read stream size");\r
+                                       outSize |= ((long)v) << (8 * i);\r
+                               }\r
+                               if (!decoder.Code(inStream, outStream, outSize))\r
+                                       throw new Exception("Error in data stream");\r
+                       }\r
+                       outStream.flush();\r
+                       outStream.close();\r
+                       inStream.close();\r
+               }\r
+               else\r
+                       throw new Exception("Incorrect command");\r
+               return;\r
+       }\r
+}\r
diff --git a/Java/SevenZip/LzmaBench.java b/Java/SevenZip/LzmaBench.java
new file mode 100755 (executable)
index 0000000..cceda24
--- /dev/null
@@ -0,0 +1,392 @@
+package SevenZip;\r
+\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.ByteArrayInputStream;\r
+import java.io.IOException;\r
+\r
+public class LzmaBench\r
+{\r
+       static final int kAdditionalSize = (1 << 21);\r
+       static final int kCompressedAdditionalSize = (1 << 10);\r
+       \r
+       static class CRandomGenerator\r
+       {\r
+               int A1;\r
+               int A2;\r
+               public CRandomGenerator() { Init(); }\r
+               public void Init() { A1 = 362436069; A2 = 521288629; }\r
+               public int GetRnd()\r
+               {\r
+                       return\r
+                               ((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 16) ^\r
+                               ((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16)));\r
+               }\r
+       };\r
+       \r
+       static class CBitRandomGenerator\r
+       {\r
+               CRandomGenerator RG = new CRandomGenerator();\r
+               int Value;\r
+               int NumBits;\r
+               public void Init()\r
+               {\r
+                       Value = 0;\r
+                       NumBits = 0;\r
+               }\r
+               public int GetRnd(int numBits)\r
+               {\r
+                       int result;\r
+                       if (NumBits > numBits)\r
+                       {\r
+                               result = Value & ((1 << numBits) - 1);\r
+                               Value >>>= numBits;\r
+                               NumBits -= numBits;\r
+                               return result;\r
+                       }\r
+                       numBits -= NumBits;\r
+                       result = (Value << numBits);\r
+                       Value = RG.GetRnd();\r
+                       result |= Value & (((int)1 << numBits) - 1);\r
+                       Value >>>= numBits;\r
+                       NumBits = 32 - numBits;\r
+                       return result;\r
+               }\r
+       };\r
+       \r
+       static class CBenchRandomGenerator\r
+       {\r
+               CBitRandomGenerator RG = new CBitRandomGenerator();\r
+               int Pos;\r
+               int Rep0;\r
+\r
+               public int BufferSize;\r
+               public byte[] Buffer = null;\r
+\r
+               public CBenchRandomGenerator() { }\r
+               public void Set(int bufferSize)\r
+               {\r
+                       Buffer = new byte[bufferSize];\r
+                       Pos = 0;\r
+                       BufferSize = bufferSize;\r
+               }\r
+               int GetRndBit() { return RG.GetRnd(1); }\r
+               int GetLogRandBits(int numBits)\r
+               {\r
+                       int len = RG.GetRnd(numBits);\r
+                       return RG.GetRnd((int)len);\r
+               }\r
+               int GetOffset()\r
+               {\r
+                       if (GetRndBit() == 0)\r
+                               return GetLogRandBits(4);\r
+                       return (GetLogRandBits(4) << 10) | RG.GetRnd(10);\r
+               }\r
+               int GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }\r
+               int GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }\r
+               public void Generate()\r
+               {\r
+                       RG.Init();\r
+                       Rep0 = 1;\r
+                       while (Pos < BufferSize)\r
+                       {\r
+                               if (GetRndBit() == 0 || Pos < 1)\r
+                                       Buffer[Pos++] = (byte)(RG.GetRnd(8));\r
+                               else\r
+                               {\r
+                                       int len;\r
+                                       if (RG.GetRnd(3) == 0)\r
+                                               len = 1 + GetLen1();\r
+                                       else\r
+                                       {\r
+                                               do\r
+                                                       Rep0 = GetOffset();\r
+                                               while (Rep0 >= Pos);\r
+                                               Rep0++;\r
+                                               len = 2 + GetLen2();\r
+                                       }\r
+                                       for (int i = 0; i < len && Pos < BufferSize; i++, Pos++)\r
+                                               Buffer[Pos] = Buffer[Pos - Rep0];\r
+                               }\r
+                       }\r
+               }\r
+       };\r
+       \r
+       static class CrcOutStream extends java.io.OutputStream\r
+       {\r
+               public CRC CRC = new CRC();\r
+               \r
+               public void Init()\r
+               { \r
+                       CRC.Init(); \r
+               }\r
+               public int GetDigest()\r
+               { \r
+                       return CRC.GetDigest(); \r
+               }\r
+               public void write(byte[] b)\r
+               {\r
+                       CRC.Update(b);\r
+               }\r
+               public void write(byte[] b, int off, int len)\r
+               {\r
+                       CRC.Update(b, off, len);\r
+               }\r
+               public void write(int b)\r
+               {\r
+                       CRC.UpdateByte(b);\r
+               }\r
+       };\r
+\r
+       static class MyOutputStream extends java.io.OutputStream\r
+       {\r
+               byte[] _buffer;\r
+               int _size;\r
+               int _pos;\r
+               \r
+               public MyOutputStream(byte[] buffer)\r
+               {\r
+                       _buffer = buffer;\r
+                       _size = _buffer.length;\r
+               }\r
+               \r
+               public void reset()\r
+               { \r
+                       _pos = 0; \r
+               }\r
+               \r
+               public void write(int b) throws IOException\r
+               {\r
+                       if (_pos >= _size)\r
+                               throw new IOException("Error");\r
+                       _buffer[_pos++] = (byte)b;\r
+               }\r
+               \r
+               public int size()\r
+               {\r
+                       return _pos;\r
+               }\r
+       };\r
+\r
+       static class MyInputStream extends java.io.InputStream\r
+       {\r
+               byte[] _buffer;\r
+               int _size;\r
+               int _pos;\r
+               \r
+               public MyInputStream(byte[] buffer, int size)\r
+               {\r
+                       _buffer = buffer;\r
+                       _size = size;\r
+               }\r
+               \r
+               public void reset()\r
+               { \r
+                       _pos = 0; \r
+               }\r
+               \r
+               public int read()\r
+               {\r
+                       if (_pos >= _size)\r
+                               return -1;\r
+                       return _buffer[_pos++] & 0xFF;\r
+               }\r
+       };\r
+       \r
+       static class CProgressInfo implements ICodeProgress\r
+       {\r
+               public long ApprovedStart;\r
+               public long InSize;\r
+               public long Time;\r
+               public void Init()\r
+               { InSize = 0; }\r
+               public void SetProgress(long inSize, long outSize)\r
+               {\r
+                       if (inSize >= ApprovedStart && InSize == 0)\r
+                       {\r
+                               Time = System.currentTimeMillis();\r
+                               InSize = inSize;\r
+                       }\r
+               }\r
+       }\r
+       static final int kSubBits = 8;\r
+       \r
+       static int GetLogSize(int size)\r
+       {\r
+               for (int i = kSubBits; i < 32; i++)\r
+                       for (int j = 0; j < (1 << kSubBits); j++)\r
+                               if (size <= ((1) << i) + (j << (i - kSubBits)))\r
+                                       return (i << kSubBits) + j;\r
+               return (32 << kSubBits);\r
+       }\r
+       \r
+       static long MyMultDiv64(long value, long elapsedTime)\r
+       {\r
+               long freq = 1000; // ms\r
+               long elTime = elapsedTime;\r
+               while (freq > 1000000)\r
+               {\r
+                       freq >>>= 1;\r
+                       elTime >>>= 1;\r
+               }\r
+               if (elTime == 0)\r
+                       elTime = 1;\r
+               return value * freq / elTime;\r
+       }\r
+       \r
+       static long GetCompressRating(int dictionarySize, long elapsedTime, long size)\r
+       {\r
+               long t = GetLogSize(dictionarySize) - (18 << kSubBits);\r
+               long numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));\r
+               long numCommands = (long)(size) * numCommandsForOne;\r
+               return MyMultDiv64(numCommands, elapsedTime);\r
+       }\r
+       \r
+       static long GetDecompressRating(long elapsedTime, long outSize, long inSize)\r
+       {\r
+               long numCommands = inSize * 220 + outSize * 20;\r
+               return MyMultDiv64(numCommands, elapsedTime);\r
+       }\r
+       \r
+       static long GetTotalRating(\r
+                       int dictionarySize,\r
+                       long elapsedTimeEn, long sizeEn,\r
+                       long elapsedTimeDe,\r
+                       long inSizeDe, long outSizeDe)\r
+       {\r
+               return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +\r
+                               GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;\r
+       }\r
+       \r
+       static void PrintValue(long v)\r
+       {\r
+               String s = "";\r
+               s += v;\r
+               for (int i = 0; i + s.length() < 6; i++)\r
+                       System.out.print(" ");\r
+               System.out.print(s);\r
+       }\r
+       \r
+       static void PrintRating(long rating)\r
+       {\r
+               PrintValue(rating / 1000000);\r
+               System.out.print(" MIPS");\r
+       }\r
+       \r
+       static void PrintResults(\r
+                       int dictionarySize,\r
+                       long elapsedTime,\r
+                       long size,\r
+                       boolean decompressMode, long secondSize)\r
+       {\r
+               long speed = MyMultDiv64(size, elapsedTime);\r
+               PrintValue(speed / 1024);\r
+               System.out.print(" KB/s  ");\r
+               long rating;\r
+               if (decompressMode)\r
+                       rating = GetDecompressRating(elapsedTime, size, secondSize);\r
+               else\r
+                       rating = GetCompressRating(dictionarySize, elapsedTime, size);\r
+               PrintRating(rating);\r
+       }\r
+       \r
+       static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception\r
+       {\r
+               if (numIterations <= 0)\r
+                       return 0;\r
+               if (dictionarySize < (1 << 18))\r
+               {\r
+                       System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)");\r
+                       return 1;\r
+               }\r
+               System.out.print("\n       Compressing                Decompressing\n\n");\r
+               \r
+               SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();\r
+               SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();\r
+               \r
+               if (!encoder.SetDictionarySize(dictionarySize))\r
+                       throw new Exception("Incorrect dictionary size");\r
+               \r
+               int kBufferSize = dictionarySize + kAdditionalSize;\r
+               int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;\r
+               \r
+               ByteArrayOutputStream propStream = new ByteArrayOutputStream();\r
+               encoder.WriteCoderProperties(propStream);\r
+               byte[] propArray = propStream.toByteArray();\r
+               decoder.SetDecoderProperties(propArray);\r
+               \r
+               CBenchRandomGenerator rg = new CBenchRandomGenerator();\r
+\r
+               rg.Set(kBufferSize);\r
+               rg.Generate();\r
+               CRC crc = new CRC();\r
+               crc.Init();\r
+               crc.Update(rg.Buffer, 0, rg.BufferSize);\r
+               \r
+               CProgressInfo progressInfo = new CProgressInfo();\r
+               progressInfo.ApprovedStart = dictionarySize;\r
+               \r
+               long totalBenchSize = 0;\r
+               long totalEncodeTime = 0;\r
+               long totalDecodeTime = 0;\r
+               long totalCompressedSize = 0;\r
+               \r
+               MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferSize);\r
+\r
+               byte[] compressedBuffer = new byte[kCompressedBufferSize];\r
+               MyOutputStream compressedStream = new MyOutputStream(compressedBuffer);\r
+               CrcOutStream crcOutStream = new CrcOutStream();\r
+               MyInputStream inputCompressedStream = null;\r
+               int compressedSize = 0;\r
+               for (int i = 0; i < numIterations; i++)\r
+               {\r
+                       progressInfo.Init();\r
+                       inStream.reset();\r
+                       compressedStream.reset();\r
+                       encoder.Code(inStream, compressedStream, -1, -1, progressInfo);\r
+                       long encodeTime = System.currentTimeMillis() - progressInfo.Time;\r
+                       \r
+                       if (i == 0)\r
+                       {\r
+                               compressedSize = compressedStream.size();\r
+                               inputCompressedStream = new MyInputStream(compressedBuffer, compressedSize);\r
+                       }\r
+                       else if (compressedSize != compressedStream.size())\r
+                               throw (new Exception("Encoding error"));\r
+                               \r
+                       if (progressInfo.InSize == 0)\r
+                               throw (new Exception("Internal ERROR 1282"));\r
+\r
+                       long decodeTime = 0;\r
+                       for (int j = 0; j < 2; j++)\r
+                       {\r
+                               inputCompressedStream.reset();\r
+                               crcOutStream.Init();\r
+                               \r
+                               long outSize = kBufferSize;\r
+                               long startTime = System.currentTimeMillis();\r
+                               if (!decoder.Code(inputCompressedStream, crcOutStream, outSize))\r
+                                       throw (new Exception("Decoding Error"));;\r
+                               decodeTime = System.currentTimeMillis() - startTime;\r
+                               if (crcOutStream.GetDigest() != crc.GetDigest())\r
+                                       throw (new Exception("CRC Error"));\r
+                       }\r
+                       long benchSize = kBufferSize - (long)progressInfo.InSize;\r
+                       PrintResults(dictionarySize, encodeTime, benchSize, false, 0);\r
+                       System.out.print("     ");\r
+                       PrintResults(dictionarySize, decodeTime, kBufferSize, true, compressedSize);\r
+                       System.out.println();\r
+                       \r
+                       totalBenchSize += benchSize;\r
+                       totalEncodeTime += encodeTime;\r
+                       totalDecodeTime += decodeTime;\r
+                       totalCompressedSize += compressedSize;\r
+               }\r
+               System.out.println("---------------------------------------------------");\r
+               PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);\r
+               System.out.print("     ");\r
+               PrintResults(dictionarySize, totalDecodeTime,\r
+                               kBufferSize * (long)numIterations, true, totalCompressedSize);\r
+               System.out.println("    Average");\r
+               return 0;\r
+       }\r
+}\r
diff --git a/Methods.txt b/Methods.txt
new file mode 100755 (executable)
index 0000000..4c3ec68
--- /dev/null
@@ -0,0 +1,152 @@
+7-Zip method IDs (9.18)\r
+-----------------------\r
+\r
+Each compression or crypto method in 7z has unique binary value (ID).\r
+The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes).\r
+\r
+If you want to add some new ID, you have two ways:\r
+1) Write request for allocating IDs to 7-zip developers.\r
+2) Generate 8-bytes ID:\r
+\r
+    3F ZZ ZZ ZZ ZZ ZZ MM MM \r
+\r
+    3F              - Prefix for random IDs (1 byte)\r
+    ZZ ZZ ZZ ZZ ZZ  - Developer ID (5 bytes). Use real random bytes. \r
+                      \r
+    MM MM           - Method ID (2 bytes)\r
+\r
+    You can notify 7-Zip developers about your Developer ID / Method ID.\r
+\r
+    Note: Use new ID only if old codec can not decode data encoded with new version.\r
+\r
+\r
+List of defined IDs\r
+-------------------\r
+      \r
+00 - Copy\r
+\r
+03 - Delta\r
+04 - x86 (BCJ)\r
+05 - PPC (Big Endian)\r
+06 - IA64\r
+07 - ARM (little endian)\r
+08 - ARM Thumb (little endian)\r
+09 - SPARC\r
+21 - LZMA2\r
+          \r
+02.. - Common\r
+   03 Swap\r
+      - 2 Swap2\r
+      - 4 Swap4\r
+\r
+03.. - 7z\r
+   01 - LZMA\r
+      01 - Version\r
+  \r
+   03 - Branch\r
+      01 - x86\r
+         03  - BCJ\r
+         1B  - BCJ2\r
+      02 - PPC\r
+         05 - PPC (Big Endian)\r
+      03 - Alpha\r
+         01 - Alpha\r
+      04 - IA64\r
+         01 - IA64\r
+      05 - ARM\r
+         01 - ARM\r
+      06 - M68\r
+         05 - M68 (Big Endian)\r
+      07 - ARM Thumb\r
+         01 - ARMT\r
+      08 - SPARC\r
+         05 - SPARC\r
+\r
+   04 - PPMD\r
+      01 - Version\r
+\r
+   7F -\r
+      01 - experimental methods.\r
+\r
+\r
+04.. - Misc\r
+   00 - Reserved\r
+   01 - Zip\r
+      00 - Copy (not used). Use {00} instead\r
+      01 - Shrink\r
+      06 - Implode\r
+      08 - Deflate\r
+      09 - Deflate64\r
+      10 - Imploding\r
+      12 - BZip2 (not used). Use {04 02 02} instead\r
+      14 - LZMA\r
+      60 - Jpeg\r
+      61 - WavPack\r
+      62 - PPMd\r
+      63 - wzAES\r
+   02 - BZip\r
+      02 - BZip2\r
+   03 - Rar\r
+      01 - Rar15\r
+      02 - Rar20\r
+      03 - Rar29\r
+   04 - Arj\r
+      01 - Arj (1,2,3)\r
+      02 - Arj 4\r
+   05 - Z\r
+   06 - Lzh\r
+   07 - Reserved for 7z\r
+   08 - Cab\r
+   09 - NSIS\r
+      01 - DeflateNSIS\r
+      02 - BZip2NSIS\r
+\r
+\r
+06.. - Crypto \r
+   00 - \r
+   01 - AES\r
+      0x - AES-128\r
+      4x - AES-192\r
+      8x - AES-256\r
+      Cx - AES\r
+\r
+      x0 - ECB\r
+      x1 - CBC\r
+      x2 - CFB\r
+      x3 - OFB\r
+\r
+   07 - Reserved\r
+   0F - Reserved\r
+\r
+   F0 - Misc Ciphers (Real Ciphers without hashing algo)\r
+\r
+   F1 - Misc Ciphers (Combine)\r
+      01 - Zip\r
+         01 - Main Zip crypto algo\r
+      03 - RAR\r
+         02 - \r
+         03 - Rar29 AES-128 + (modified SHA-1)\r
+      07 - 7z\r
+         01 - AES-256 + SHA-256\r
+\r
+07.. - Hash (subject to change)\r
+   00 - \r
+   01 - CRC\r
+   02 - SHA-1\r
+   03 - SHA-256\r
+   04 - SHA-384\r
+   05 - SHA-512\r
+\r
+   F0 - Misc Hash\r
+\r
+   F1 - Misc\r
+      03 - RAR\r
+         03 - Rar29 Password Hashing (modified SHA1)\r
+      07 - 7z \r
+         01 - SHA-256 Password Hashing\r
+    \r
+   \r
+\r
+\r
+---\r
+End of document\r
diff --git a/history.txt b/history.txt
new file mode 100755 (executable)
index 0000000..50ff40f
--- /dev/null
@@ -0,0 +1,271 @@
+HISTORY of the LZMA SDK\r
+-----------------------\r
+\r
+9.18 beta      2010-11-02\r
+-------------------------      \r
+- New small SFX module for installers (SfxSetup).\r
+\r
+\r
+9.12 beta      2010-03-24\r
+-------------------------\r
+- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work,\r
+  if more than 10 threads were used (or more than 20 threads in some modes).\r
+\r
+\r
+9.11 beta      2010-03-15\r
+-------------------------\r
+- PPMd compression method support\r
+   \r
+\r
+9.09           2009-12-12\r
+-------------------------\r
+- The bug was fixed:\r
+   Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c\r
+   incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8.\r
+- Some bugs were fixed\r
+\r
+\r
+9.06           2009-08-17\r
+-------------------------\r
+- Some changes in ANSI-C 7z Decoder interfaces.\r
+\r
+\r
+9.04           2009-05-30\r
+-------------------------\r
+- LZMA2 compression method support\r
+- xz format support\r
+\r
+\r
+4.65           2009-02-03\r
+-------------------------\r
+- Some minor fixes\r
+\r
+\r
+4.63           2008-12-31\r
+-------------------------\r
+- Some minor fixes\r
+\r
+\r
+4.61 beta      2008-11-23\r
+-------------------------\r
+- The bug in ANSI-C LZMA Decoder was fixed:\r
+    If encoded stream was corrupted, decoder could access memory \r
+    outside of allocated range.\r
+- Some changes in ANSI-C 7z Decoder interfaces.\r
+- LZMA SDK is placed in the public domain.\r
+\r
+\r
+4.60 beta      2008-08-19\r
+-------------------------\r
+- Some minor fixes.\r
+\r
+\r
+4.59 beta      2008-08-13\r
+-------------------------\r
+- The bug was fixed:\r
+    LZMA Encoder in fast compression mode could access memory outside of \r
+    allocated range in some rare cases.\r
+\r
+\r
+4.58 beta      2008-05-05\r
+-------------------------\r
+- ANSI-C LZMA Decoder was rewritten for speed optimizations.\r
+- ANSI-C LZMA Encoder was included to LZMA SDK.\r
+- C++ LZMA code now is just wrapper over ANSI-C code.\r
+\r
+\r
+4.57           2007-12-12\r
+-------------------------\r
+- Speed optimizations in Ã‘++ LZMA Decoder. \r
+- Small changes for more compatibility with some C/C++ compilers.\r
+\r
+\r
+4.49 beta      2007-07-05\r
+-------------------------\r
+- .7z ANSI-C Decoder:\r
+     - now it supports BCJ and BCJ2 filters\r
+     - now it supports files larger than 4 GB.\r
+     - now it supports "Last Write Time" field for files.\r
+- C++ code for .7z archives compressing/decompressing from 7-zip \r
+  was included to LZMA SDK.\r
+  \r
+\r
+4.43           2006-06-04\r
+-------------------------\r
+- Small changes for more compatibility with some C/C++ compilers.\r
+  \r
+\r
+4.42           2006-05-15\r
+-------------------------\r
+- Small changes in .h files in ANSI-C version.\r
+  \r
+\r
+4.39 beta      2006-04-14\r
+-------------------------\r
+- The bug in versions 4.33b:4.38b was fixed:\r
+  C++ version of LZMA encoder could not correctly compress \r
+  files larger than 2 GB with HC4 match finder (-mfhc4).\r
+  \r
+\r
+4.37 beta      2005-04-06\r
+-------------------------\r
+- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined. \r
+\r
+\r
+4.35 beta      2005-03-02\r
+-------------------------\r
+- The bug was fixed in C++ version of LZMA Decoder:\r
+    If encoded stream was corrupted, decoder could access memory \r
+    outside of allocated range.\r
+\r
+\r
+4.34 beta      2006-02-27\r
+-------------------------\r
+- Compressing speed and memory requirements for compressing were increased\r
+- LZMA now can use only these match finders: HC4, BT2, BT3, BT4\r
+\r
+\r
+4.32           2005-12-09\r
+-------------------------\r
+- Java version of LZMA SDK was included\r
+\r
+\r
+4.30           2005-11-20\r
+-------------------------\r
+- Compression ratio was improved in -a2 mode\r
+- Speed optimizations for compressing in -a2 mode\r
+- -fb switch now supports values up to 273\r
+- The bug in 7z_C (7zIn.c) was fixed:\r
+  It used Alloc/Free functions from different memory pools.\r
+  So if program used two memory pools, it worked incorrectly.\r
+- 7z_C: .7z format supporting was improved\r
+- LZMA# SDK (C#.NET version) was included\r
+\r
+\r
+4.27 (Updated) 2005-09-21\r
+-------------------------\r
+- Some GUIDs/interfaces in C++ were changed.\r
+ IStream.h:\r
+   ISequentialInStream::Read now works as old ReadPart\r
+   ISequentialOutStream::Write now works as old WritePart\r
+\r
+\r
+4.27           2005-08-07\r
+-------------------------\r
+- The bug in LzmaDecodeSize.c was fixed:\r
+   if _LZMA_IN_CB and _LZMA_OUT_READ were defined,\r
+   decompressing worked incorrectly.\r
+\r
+\r
+4.26           2005-08-05\r
+-------------------------\r
+- Fixes in 7z_C code and LzmaTest.c:\r
+  previous versions could work incorrectly,\r
+  if malloc(0) returns 0\r
+\r
+\r
+4.23           2005-06-29\r
+-------------------------\r
+- Small fixes in C++ code\r
+\r
+\r
+4.22           2005-06-10\r
+-------------------------\r
+- Small fixes\r
+\r
+\r
+4.21           2005-06-08\r
+-------------------------\r
+- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed\r
+- New additional version of ANSI-C LZMA Decoder with zlib-like interface:\r
+    - LzmaStateDecode.h\r
+    - LzmaStateDecode.c\r
+    - LzmaStateTest.c\r
+- ANSI-C LZMA Decoder now can decompress files larger than 4 GB\r
+\r
+\r
+4.17           2005-04-18\r
+-------------------------\r
+- New example for RAM->RAM compressing/decompressing: \r
+  LZMA + BCJ (filter for x86 code):\r
+    - LzmaRam.h\r
+    - LzmaRam.cpp\r
+    - LzmaRamDecode.h\r
+    - LzmaRamDecode.c\r
+    - -f86 switch for lzma.exe\r
+\r
+\r
+4.16           2005-03-29\r
+-------------------------\r
+- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder): \r
+   If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,\r
+   decoder could access memory outside of allocated range.\r
+- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).\r
+  Old version of LZMA Decoder now is in file LzmaDecodeSize.c. \r
+  LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c\r
+- Small speed optimization in LZMA C++ code\r
+- filter for SPARC's code was added\r
+- Simplified version of .7z ANSI-C Decoder was included\r
+\r
+\r
+4.06           2004-09-05\r
+-------------------------\r
+- The bug in v4.05 was fixed:\r
+    LZMA-Encoder didn't release output stream in some cases.\r
+\r
+\r
+4.05           2004-08-25\r
+-------------------------\r
+- Source code of filters for x86, IA-64, ARM, ARM-Thumb \r
+  and PowerPC code was included to SDK\r
+- Some internal minor changes\r
+\r
+\r
+4.04           2004-07-28\r
+-------------------------\r
+- More compatibility with some C++ compilers\r
+\r
+\r
+4.03           2004-06-18\r
+-------------------------\r
+- "Benchmark" command was added. It measures compressing \r
+  and decompressing speed and shows rating values. \r
+  Also it checks hardware errors.\r
+\r
+\r
+4.02           2004-06-10\r
+-------------------------\r
+- C++ LZMA Encoder/Decoder code now is more portable\r
+  and it can be compiled by GCC on Linux.\r
+\r
+\r
+4.01           2004-02-15\r
+-------------------------\r
+- Some detection of data corruption was enabled.\r
+    LzmaDecode.c / RangeDecoderReadByte\r
+    .....\r
+    {\r
+      rd->ExtraBytes = 1;\r
+      return 0xFF;\r
+    }\r
+\r
+\r
+4.00           2004-02-13\r
+-------------------------\r
+- Original version of LZMA SDK\r
+\r
+\r
+\r
+HISTORY of the LZMA\r
+-------------------\r
+  2001-2008:  Improvements to LZMA compressing/decompressing code, \r
+              keeping compatibility with original LZMA format\r
+  1996-2001:  Development of LZMA compression format\r
+\r
+  Some milestones:\r
+\r
+  2001-08-30: LZMA compression was added to 7-Zip\r
+  1999-01-02: First version of 7-Zip was released\r
+  \r
+\r
+End of document\r
diff --git a/lzma.exe b/lzma.exe
new file mode 100755 (executable)
index 0000000..572d91f
Binary files /dev/null and b/lzma.exe differ
diff --git a/lzma.txt b/lzma.txt
new file mode 100755 (executable)
index 0000000..579f2cc
--- /dev/null
+++ b/lzma.txt
@@ -0,0 +1,598 @@
+LZMA SDK 9.20\r
+-------------\r
+\r
+LZMA SDK provides the documentation, samples, header files, libraries, \r
+and tools you need to develop applications that use LZMA compression.\r
+\r
+LZMA is default and general compression method of 7z format\r
+in 7-Zip compression program (www.7-zip.org). LZMA provides high \r
+compression ratio and very fast decompression.\r
+\r
+LZMA is an improved version of famous LZ77 compression algorithm. \r
+It was improved in way of maximum increasing of compression ratio,\r
+keeping high decompression speed and low memory requirements for \r
+decompressing.\r
+\r
+\r
+\r
+LICENSE\r
+-------\r
+\r
+LZMA SDK is written and placed in the public domain by Igor Pavlov.\r
+\r
+Some code in LZMA SDK is based on public domain code from another developers:\r
+  1) PPMd var.H (2001): Dmitry Shkarin\r
+  2) SHA-256: Wei Dai (Crypto++ library)\r
+\r
+\r
+LZMA SDK Contents\r
+-----------------\r
+\r
+LZMA SDK includes:\r
+\r
+  - ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing\r
+  - Compiled file->file LZMA compressing/decompressing program for Windows system\r
+\r
+\r
+UNIX/Linux version \r
+------------------\r
+To compile C++ version of file->file LZMA encoding, go to directory\r
+CPP/7zip/Bundles/LzmaCon\r
+and call make to recompile it:\r
+  make -f makefile.gcc clean all\r
+\r
+In some UNIX/Linux versions you must compile LZMA with static libraries.\r
+To compile with static libraries, you can use \r
+LIB = -lm -static\r
+\r
+\r
+Files\r
+---------------------\r
+lzma.txt     - LZMA SDK description (this file)\r
+7zFormat.txt - 7z Format description\r
+7zC.txt      - 7z ANSI-C Decoder description\r
+methods.txt  - Compression method IDs for .7z\r
+lzma.exe     - Compiled file->file LZMA encoder/decoder for Windows\r
+7zr.exe      - 7-Zip with 7z/lzma/xz support.\r
+history.txt  - history of the LZMA SDK\r
+\r
+\r
+Source code structure\r
+---------------------\r
+\r
+C/  - C files\r
+        7zCrc*.*   - CRC code\r
+        Alloc.*    - Memory allocation functions\r
+        Bra*.*     - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code\r
+        LzFind.*   - Match finder for LZ (LZMA) encoders \r
+        LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding\r
+        LzHash.h   - Additional file for LZ match finder\r
+        LzmaDec.*  - LZMA decoding\r
+        LzmaEnc.*  - LZMA encoding\r
+        LzmaLib.*  - LZMA Library for DLL calling\r
+        Types.h    - Basic types for another .c files\r
+        Threads.*  - The code for multithreading.\r
+\r
+    LzmaLib  - LZMA Library (.DLL for Windows)\r
+    \r
+    LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).\r
+\r
+    Archive - files related to archiving\r
+      7z     - 7z ANSI-C Decoder\r
+\r
+CPP/ -- CPP files\r
+\r
+  Common  - common files for C++ projects\r
+  Windows - common files for Windows related code\r
+\r
+  7zip    - files related to 7-Zip Project\r
+\r
+    Common   - common files for 7-Zip\r
+\r
+    Compress - files related to compression/decompression\r
+\r
+    Archive - files related to archiving\r
+\r
+      Common   - common files for archive handling\r
+      7z       - 7z C++ Encoder/Decoder\r
+\r
+    Bundles    - Modules that are bundles of other modules\r
+  \r
+      Alone7z           - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2\r
+      LzmaCon           - lzma.exe: LZMA compression/decompression\r
+      Format7zR         - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2\r
+      Format7zExtractR  - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.\r
+\r
+    UI        - User Interface files\r
+         \r
+      Client7z - Test application for 7za.dll,  7zr.dll, 7zxr.dll\r
+      Common   - Common UI files\r
+      Console  - Code for console archiver\r
+\r
+\r
+\r
+CS/ - C# files\r
+  7zip\r
+    Common   - some common files for 7-Zip\r
+    Compress - files related to compression/decompression\r
+      LZ     - files related to LZ (Lempel-Ziv) compression algorithm\r
+      LZMA         - LZMA compression/decompression\r
+      LzmaAlone    - file->file LZMA compression/decompression\r
+      RangeCoder   - Range Coder (special code of compression/decompression)\r
+\r
+Java/  - Java files\r
+  SevenZip\r
+    Compression    - files related to compression/decompression\r
+      LZ           - files related to LZ (Lempel-Ziv) compression algorithm\r
+      LZMA         - LZMA compression/decompression\r
+      RangeCoder   - Range Coder (special code of compression/decompression)\r
+\r
+\r
+C/C++ source code of LZMA SDK is part of 7-Zip project.\r
+7-Zip source code can be downloaded from 7-Zip's SourceForge page:\r
+\r
+  http://sourceforge.net/projects/sevenzip/\r
+\r
+\r
+\r
+LZMA features\r
+-------------\r
+  - Variable dictionary size (up to 1 GB)\r
+  - Estimated compressing speed: about 2 MB/s on 2 GHz CPU\r
+  - Estimated decompressing speed: \r
+      - 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64\r
+      - 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC\r
+  - Small memory requirements for decompressing (16 KB + DictionarySize)\r
+  - Small code size for decompressing: 5-8 KB\r
+\r
+LZMA decoder uses only integer operations and can be \r
+implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).\r
+\r
+Some critical operations that affect the speed of LZMA decompression:\r
+  1) 32*16 bit integer multiply\r
+  2) Misspredicted branches (penalty mostly depends from pipeline length)\r
+  3) 32-bit shift and arithmetic operations\r
+\r
+The speed of LZMA decompressing mostly depends from CPU speed.\r
+Memory speed has no big meaning. But if your CPU has small data cache, \r
+overall weight of memory speed will slightly increase.\r
+\r
+\r
+How To Use\r
+----------\r
+\r
+Using LZMA encoder/decoder executable\r
+--------------------------------------\r
+\r
+Usage:  LZMA <e|d> inputFile outputFile [<switches>...]\r
+\r
+  e: encode file\r
+\r
+  d: decode file\r
+\r
+  b: Benchmark. There are two tests: compressing and decompressing \r
+     with LZMA method. Benchmark shows rating in MIPS (million \r
+     instructions per second). Rating value is calculated from \r
+     measured speed and it is normalized with Intel's Core 2 results.\r
+     Also Benchmark checks possible hardware errors (RAM \r
+     errors in most cases). Benchmark uses these settings:\r
+     (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter. \r
+     Also you can change the number of iterations. Example for 30 iterations:\r
+       LZMA b 30\r
+     Default number of iterations is 10.\r
+\r
+<Switches>\r
+  \r
+\r
+  -a{N}:  set compression mode 0 = fast, 1 = normal\r
+          default: 1 (normal)\r
+\r
+  d{N}:   Sets Dictionary size - [0, 30], default: 23 (8MB)\r
+          The maximum value for dictionary size is 1 GB = 2^30 bytes.\r
+          Dictionary size is calculated as DictionarySize = 2^N bytes. \r
+          For decompressing file compressed by LZMA method with dictionary \r
+          size D = 2^N you need about D bytes of memory (RAM).\r
+\r
+  -fb{N}: set number of fast bytes - [5, 273], default: 128\r
+          Usually big number gives a little bit better compression ratio \r
+          and slower compression process.\r
+\r
+  -lc{N}: set number of literal context bits - [0, 8], default: 3\r
+          Sometimes lc=4 gives gain for big files.\r
+\r
+  -lp{N}: set number of literal pos bits - [0, 4], default: 0\r
+          lp switch is intended for periodical data when period is \r
+          equal 2^N. For example, for 32-bit (4 bytes) \r
+          periodical data you can use lp=2. Often it's better to set lc0, \r
+          if you change lp switch.\r
+\r
+  -pb{N}: set number of pos bits - [0, 4], default: 2\r
+          pb switch is intended for periodical data \r
+          when period is equal 2^N.\r
+\r
+  -mf{MF_ID}: set Match Finder. Default: bt4. \r
+              Algorithms from hc* group doesn't provide good compression \r
+              ratio, but they often works pretty fast in combination with \r
+              fast mode (-a0).\r
+\r
+              Memory requirements depend from dictionary size \r
+              (parameter "d" in table below). \r
+\r
+               MF_ID     Memory                   Description\r
+\r
+                bt2    d *  9.5 + 4MB  Binary Tree with 2 bytes hashing.\r
+                bt3    d * 11.5 + 4MB  Binary Tree with 3 bytes hashing.\r
+                bt4    d * 11.5 + 4MB  Binary Tree with 4 bytes hashing.\r
+                hc4    d *  7.5 + 4MB  Hash Chain with 4 bytes hashing.\r
+\r
+  -eos:   write End Of Stream marker. By default LZMA doesn't write \r
+          eos marker, since LZMA decoder knows uncompressed size \r
+          stored in .lzma file header.\r
+\r
+  -si:    Read data from stdin (it will write End Of Stream marker).\r
+  -so:    Write data to stdout\r
+\r
+\r
+Examples:\r
+\r
+1) LZMA e file.bin file.lzma -d16 -lc0 \r
+\r
+compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)  \r
+and 0 literal context bits. -lc0 allows to reduce memory requirements \r
+for decompression.\r
+\r
+\r
+2) LZMA e file.bin file.lzma -lc0 -lp2\r
+\r
+compresses file.bin to file.lzma with settings suitable \r
+for 32-bit periodical data (for example, ARM or MIPS code).\r
+\r
+3) LZMA d file.lzma file.bin\r
+\r
+decompresses file.lzma to file.bin.\r
+\r
+\r
+Compression ratio hints\r
+-----------------------\r
+\r
+Recommendations\r
+---------------\r
+\r
+To increase the compression ratio for LZMA compressing it's desirable \r
+to have aligned data (if it's possible) and also it's desirable to locate\r
+data in such order, where code is grouped in one place and data is \r
+grouped in other place (it's better than such mixing: code, data, code,\r
+data, ...).\r
+\r
+\r
+Filters\r
+-------\r
+You can increase the compression ratio for some data types, using\r
+special filters before compressing. For example, it's possible to \r
+increase the compression ratio on 5-10% for code for those CPU ISAs: \r
+x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.\r
+\r
+You can find C source code of such filters in C/Bra*.* files\r
+\r
+You can check the compression ratio gain of these filters with such \r
+7-Zip commands (example for ARM code):\r
+No filter:\r
+  7z a a1.7z a.bin -m0=lzma\r
+\r
+With filter for little-endian ARM code:\r
+  7z a a2.7z a.bin -m0=arm -m1=lzma        \r
+\r
+It works in such manner:\r
+Compressing    = Filter_encoding + LZMA_encoding\r
+Decompressing  = LZMA_decoding + Filter_decoding\r
+\r
+Compressing and decompressing speed of such filters is very high,\r
+so it will not increase decompressing time too much.\r
+Moreover, it reduces decompression time for LZMA_decoding, \r
+since compression ratio with filtering is higher.\r
+\r
+These filters convert CALL (calling procedure) instructions \r
+from relative offsets to absolute addresses, so such data becomes more \r
+compressible.\r
+\r
+For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.\r
+\r
+\r
+LZMA compressed file format\r
+---------------------------\r
+Offset Size Description\r
+  0     1   Special LZMA properties (lc,lp, pb in encoded form)\r
+  1     4   Dictionary size (little endian)\r
+  5     8   Uncompressed size (little endian). -1 means unknown size\r
+ 13         Compressed data\r
+\r
+\r
+ANSI-C LZMA Decoder\r
+~~~~~~~~~~~~~~~~~~~\r
+\r
+Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.\r
+If you want to use old interfaces you can download previous version of LZMA SDK\r
+from sourceforge.net site.\r
+\r
+To use ANSI-C LZMA Decoder you need the following files:\r
+1) LzmaDec.h + LzmaDec.c + Types.h\r
+LzmaUtil/LzmaUtil.c is example application that uses these files.\r
+\r
+\r
+Memory requirements for LZMA decoding\r
+-------------------------------------\r
+\r
+Stack usage of LZMA decoding function for local variables is not \r
+larger than 200-400 bytes.\r
+\r
+LZMA Decoder uses dictionary buffer and internal state structure.\r
+Internal state structure consumes\r
+  state_size = (4 + (1.5 << (lc + lp))) KB\r
+by default (lc=3, lp=0), state_size = 16 KB.\r
+\r
+\r
+How To decompress data\r
+----------------------\r
+\r
+LZMA Decoder (ANSI-C version) now supports 2 interfaces:\r
+1) Single-call Decompressing\r
+2) Multi-call State Decompressing (zlib-like interface)\r
+\r
+You must use external allocator:\r
+Example:\r
+void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }\r
+void SzFree(void *p, void *address) { p = p; free(address); }\r
+ISzAlloc alloc = { SzAlloc, SzFree };\r
+\r
+You can use p = p; operator to disable compiler warnings.\r
+\r
+\r
+Single-call Decompressing\r
+-------------------------\r
+When to use: RAM->RAM decompressing\r
+Compile files: LzmaDec.h + LzmaDec.c + Types.h\r
+Compile defines: no defines\r
+Memory Requirements:\r
+  - Input buffer: compressed size\r
+  - Output buffer: uncompressed size\r
+  - LZMA Internal Structures: state_size (16 KB for default settings) \r
+\r
+Interface:\r
+  int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+      const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, \r
+      ELzmaStatus *status, ISzAlloc *alloc);\r
+  In: \r
+    dest     - output data\r
+    destLen  - output data size\r
+    src      - input data\r
+    srcLen   - input data size\r
+    propData - LZMA properties  (5 bytes)\r
+    propSize - size of propData buffer (5 bytes)\r
+    finishMode - It has meaning only if the decoding reaches output limit (*destLen).\r
+         LZMA_FINISH_ANY - Decode just destLen bytes.\r
+         LZMA_FINISH_END - Stream must be finished after (*destLen).\r
+                           You can use LZMA_FINISH_END, when you know that \r
+                           current output buffer covers last bytes of stream. \r
+    alloc    - Memory allocator.\r
+\r
+  Out: \r
+    destLen  - processed output size \r
+    srcLen   - processed input size \r
+\r
+  Output:\r
+    SZ_OK\r
+      status:\r
+        LZMA_STATUS_FINISHED_WITH_MARK\r
+        LZMA_STATUS_NOT_FINISHED \r
+        LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK\r
+    SZ_ERROR_DATA - Data error\r
+    SZ_ERROR_MEM  - Memory allocation error\r
+    SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+    SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).\r
+\r
+  If LZMA decoder sees end_marker before reaching output limit, it returns OK result,\r
+  and output value of destLen will be less than output buffer size limit.\r
+\r
+  You can use multiple checks to test data integrity after full decompression:\r
+    1) Check Result and "status" variable.\r
+    2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.\r
+    3) Check that output(srcLen) = compressedSize, if you know real compressedSize. \r
+       You must use correct finish mode in that case. */ \r
+\r
+\r
+Multi-call State Decompressing (zlib-like interface)\r
+----------------------------------------------------\r
+\r
+When to use: file->file decompressing \r
+Compile files: LzmaDec.h + LzmaDec.c + Types.h\r
+\r
+Memory Requirements:\r
+ - Buffer for input stream: any size (for example, 16 KB)\r
+ - Buffer for output stream: any size (for example, 16 KB)\r
+ - LZMA Internal Structures: state_size (16 KB for default settings) \r
+ - LZMA dictionary (dictionary size is encoded in LZMA properties header)\r
+\r
+1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:\r
+   unsigned char header[LZMA_PROPS_SIZE + 8];\r
+   ReadFile(inFile, header, sizeof(header)\r
+\r
+2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties\r
+\r
+  CLzmaDec state;\r
+  LzmaDec_Constr(&state);\r
+  res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);\r
+  if (res != SZ_OK)\r
+    return res;\r
+\r
+3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop\r
+\r
+  LzmaDec_Init(&state);\r
+  for (;;)\r
+  {\r
+    ... \r
+    int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, \r
+        const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);\r
+    ...\r
+  }\r
+\r
+\r
+4) Free all allocated structures\r
+  LzmaDec_Free(&state, &g_Alloc);\r
+\r
+For full code example, look at C/LzmaUtil/LzmaUtil.c code.\r
+\r
+\r
+How To compress data\r
+--------------------\r
+\r
+Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +\r
+LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h\r
+\r
+Memory Requirements:\r
+  - (dictSize * 11.5 + 6 MB) + state_size\r
+\r
+Lzma Encoder can use two memory allocators:\r
+1) alloc - for small arrays.\r
+2) allocBig - for big arrays.\r
+\r
+For example, you can use Large RAM Pages (2 MB) in allocBig allocator for \r
+better compression speed. Note that Windows has bad implementation for \r
+Large RAM Pages. \r
+It's OK to use same allocator for alloc and allocBig.\r
+\r
+\r
+Single-call Compression with callbacks\r
+--------------------------------------\r
+\r
+Check C/LzmaUtil/LzmaUtil.c as example, \r
+\r
+When to use: file->file decompressing \r
+\r
+1) you must implement callback structures for interfaces:\r
+ISeqInStream\r
+ISeqOutStream\r
+ICompressProgress\r
+ISzAlloc\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) {  p = p; MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+  CFileSeqInStream inStream;\r
+  CFileSeqOutStream outStream;\r
+\r
+  inStream.funcTable.Read = MyRead;\r
+  inStream.file = inFile;\r
+  outStream.funcTable.Write = MyWrite;\r
+  outStream.file = outFile;\r
+\r
+\r
+2) Create CLzmaEncHandle object;\r
+\r
+  CLzmaEncHandle enc;\r
+\r
+  enc = LzmaEnc_Create(&g_Alloc);\r
+  if (enc == 0)\r
+    return SZ_ERROR_MEM;\r
+\r
+\r
+3) initialize CLzmaEncProps properties;\r
+\r
+  LzmaEncProps_Init(&props);\r
+\r
+  Then you can change some properties in that structure.\r
+\r
+4) Send LZMA properties to LZMA Encoder\r
+\r
+  res = LzmaEnc_SetProps(enc, &props);\r
+\r
+5) Write encoded properties to header\r
+\r
+    Byte header[LZMA_PROPS_SIZE + 8];\r
+    size_t headerSize = LZMA_PROPS_SIZE;\r
+    UInt64 fileSize;\r
+    int i;\r
+\r
+    res = LzmaEnc_WriteProperties(enc, header, &headerSize);\r
+    fileSize = MyGetFileLength(inFile);\r
+    for (i = 0; i < 8; i++)\r
+      header[headerSize++] = (Byte)(fileSize >> (8 * i));\r
+    MyWriteFileAndCheck(outFile, header, headerSize)\r
+\r
+6) Call encoding function:\r
+      res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, \r
+        NULL, &g_Alloc, &g_Alloc);\r
+\r
+7) Destroy LZMA Encoder Object\r
+  LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);\r
+\r
+\r
+If callback function return some error code, LzmaEnc_Encode also returns that code\r
+or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.\r
+\r
+\r
+Single-call RAM->RAM Compression\r
+--------------------------------\r
+\r
+Single-call RAM->RAM Compression is similar to Compression with callbacks,\r
+but you provide pointers to buffers instead of pointers to stream callbacks:\r
+\r
+HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
+    CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, \r
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);\r
+\r
+Return code:\r
+  SZ_OK               - OK\r
+  SZ_ERROR_MEM        - Memory allocation error \r
+  SZ_ERROR_PARAM      - Incorrect paramater\r
+  SZ_ERROR_OUTPUT_EOF - output buffer overflow\r
+  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)\r
+\r
+\r
+\r
+Defines\r
+-------\r
+\r
+_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.\r
+\r
+_LZMA_PROB32   - It can increase the speed on some 32-bit CPUs, but memory usage for \r
+                 some structures will be doubled in that case.\r
+\r
+_LZMA_UINT32_IS_ULONG  - Define it if int is 16-bit on your compiler and long is 32-bit.\r
+\r
+_LZMA_NO_SYSTEM_SIZE_T  - Define it if you don't want to use size_t type.\r
+\r
+\r
+_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder.\r
+\r
+\r
+C++ LZMA Encoder/Decoder \r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+C++ LZMA code use COM-like interfaces. So if you want to use it, \r
+you can study basics of COM/OLE.\r
+C++ LZMA code is just wrapper over ANSI-C code.\r
+\r
+\r
+C++ Notes\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),\r
+you must check that you correctly work with "new" operator.\r
+7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.\r
+So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:\r
+operator new(size_t size)\r
+{\r
+  void *p = ::malloc(size);\r
+  if (p == 0)\r
+    throw CNewException();\r
+  return p;\r
+}\r
+If you use MSCV that throws exception for "new" operator, you can compile without \r
+"NewHandler.cpp". So standard exception will be used. Actually some code of \r
+7-Zip catches any exception in internal code and converts it to HRESULT code.\r
+So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.\r
+\r
+---\r
+\r
+http://www.7-zip.org\r
+http://www.7-zip.org/sdk.html\r
+http://www.7-zip.org/support.html\r