r923 - in trunk: . lzma lzma/C lzma/C/Archive lzma/C/Archive/7z lzma/C/Compress lzma/C/Compress/Branch lzma/C/Compress/Huffman lzma/C/Compress/Lz lzma/C/Compress/Lzma lzma/CPP lzma/CPP/7zip lzma/CPP/7zip/Archive lzma/CPP/7zip/Archive/7z lzma/CPP/7zip/Archive/Common lzma/CPP/7zip/Bundles lzma/CPP/7zip/Bundles/Alone7z lzma/CPP/7zip/Bundles/Format7zExtractR lzma/CPP/7zip/Bundles/Format7zR lzma/CPP/7zip/Common lzma/CPP/7zip/Compress lzma/CPP/7zip/Compress/Branch lzma/CPP/7zip/Compress/ByteSwap lzma/CPP/7zip/Compress/Copy lzma/CPP/7zip/Compress/LZ lzma/CPP/7zip/Compress/LZMA lzma/CPP/7zip/Compress/LZMA_Alone lzma/CPP/7zip/Compress/RangeCoder lzma/CPP/7zip/UI lzma/CPP/7zip/UI/Client7z lzma/CPP/7zip/UI/Common lzma/CPP/7zip/UI/Console lzma/CPP/Common lzma/CPP/Windows lzma/CS lzma/CS/7zip lzma/CS/7zip/Common lzma/CS/7zip/Compress lzma/CS/7zip/Compress/LZ lzma/CS/7zip/Compress/LZMA lzma/CS/7zip/Compress/LzmaAlone lzma/CS/7zip/Compress/LzmaAlone/Properties lzma/CS/7zip/Compress/RangeCoder lzma/Java lzma/Java/SevenZip lzma/Java/SevenZip/Compression lzma/Java/SevenZip/Compression/LZ lzma/Java/SevenZip/Compression/LZMA lzma/Java/SevenZip/Compression/RangeCoder
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Tue Jan 22 22:52:36 EST 2008
Author: icculus
Date: 2008-01-22 22:52:35 -0500 (Tue, 22 Jan 2008)
New Revision: 923
Added:
trunk/lzma/
trunk/lzma/7zC.txt
trunk/lzma/7zFormat.txt
trunk/lzma/C/
trunk/lzma/C/7zCrc.c
trunk/lzma/C/7zCrc.h
trunk/lzma/C/7zCrcT8.c
trunk/lzma/C/Alloc.c
trunk/lzma/C/Alloc.h
trunk/lzma/C/Archive/
trunk/lzma/C/Archive/7z/
trunk/lzma/C/Archive/7z/7zAlloc.c
trunk/lzma/C/Archive/7z/7zAlloc.h
trunk/lzma/C/Archive/7z/7zBuffer.c
trunk/lzma/C/Archive/7z/7zBuffer.h
trunk/lzma/C/Archive/7z/7zDecode.c
trunk/lzma/C/Archive/7z/7zDecode.h
trunk/lzma/C/Archive/7z/7zExtract.c
trunk/lzma/C/Archive/7z/7zExtract.h
trunk/lzma/C/Archive/7z/7zHeader.c
trunk/lzma/C/Archive/7z/7zHeader.h
trunk/lzma/C/Archive/7z/7zIn.c
trunk/lzma/C/Archive/7z/7zIn.h
trunk/lzma/C/Archive/7z/7zItem.c
trunk/lzma/C/Archive/7z/7zItem.h
trunk/lzma/C/Archive/7z/7zMain.c
trunk/lzma/C/Archive/7z/7zMethodID.c
trunk/lzma/C/Archive/7z/7zMethodID.h
trunk/lzma/C/Archive/7z/7z_C.dsp
trunk/lzma/C/Archive/7z/7z_C.dsw
trunk/lzma/C/Archive/7z/makefile
trunk/lzma/C/Archive/7z/makefile.gcc
trunk/lzma/C/Compress/
trunk/lzma/C/Compress/Branch/
trunk/lzma/C/Compress/Branch/BranchARM.c
trunk/lzma/C/Compress/Branch/BranchARM.h
trunk/lzma/C/Compress/Branch/BranchARMThumb.c
trunk/lzma/C/Compress/Branch/BranchARMThumb.h
trunk/lzma/C/Compress/Branch/BranchIA64.c
trunk/lzma/C/Compress/Branch/BranchIA64.h
trunk/lzma/C/Compress/Branch/BranchPPC.c
trunk/lzma/C/Compress/Branch/BranchPPC.h
trunk/lzma/C/Compress/Branch/BranchSPARC.c
trunk/lzma/C/Compress/Branch/BranchSPARC.h
trunk/lzma/C/Compress/Branch/BranchTypes.h
trunk/lzma/C/Compress/Branch/BranchX86.c
trunk/lzma/C/Compress/Branch/BranchX86.h
trunk/lzma/C/Compress/Branch/BranchX86_2.c
trunk/lzma/C/Compress/Branch/BranchX86_2.h
trunk/lzma/C/Compress/Huffman/
trunk/lzma/C/Compress/Huffman/HuffmanEncode.c
trunk/lzma/C/Compress/Huffman/HuffmanEncode.h
trunk/lzma/C/Compress/Lz/
trunk/lzma/C/Compress/Lz/LzHash.h
trunk/lzma/C/Compress/Lz/MatchFinder.c
trunk/lzma/C/Compress/Lz/MatchFinder.h
trunk/lzma/C/Compress/Lz/MatchFinderMt.c
trunk/lzma/C/Compress/Lz/MatchFinderMt.h
trunk/lzma/C/Compress/Lzma/
trunk/lzma/C/Compress/Lzma/LzmaDecode.c
trunk/lzma/C/Compress/Lzma/LzmaDecode.h
trunk/lzma/C/Compress/Lzma/LzmaDecodeSize.c
trunk/lzma/C/Compress/Lzma/LzmaStateDecode.c
trunk/lzma/C/Compress/Lzma/LzmaStateDecode.h
trunk/lzma/C/Compress/Lzma/LzmaStateTest.c
trunk/lzma/C/Compress/Lzma/LzmaTest.c
trunk/lzma/C/Compress/Lzma/LzmaTypes.h
trunk/lzma/C/CpuArch.h
trunk/lzma/C/IStream.h
trunk/lzma/C/Sort.c
trunk/lzma/C/Sort.h
trunk/lzma/C/Threads.c
trunk/lzma/C/Threads.h
trunk/lzma/C/Types.h
trunk/lzma/CPP/
trunk/lzma/CPP/7zip/
trunk/lzma/CPP/7zip/Archive/
trunk/lzma/CPP/7zip/Archive/7z/
trunk/lzma/CPP/7zip/Archive/7z/7z.ico
trunk/lzma/CPP/7zip/Archive/7z/7zCompressionMode.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
trunk/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zDecode.h
trunk/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zEncode.h
trunk/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
trunk/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h
trunk/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zHandler.h
trunk/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zHeader.h
trunk/lzma/CPP/7zip/Archive/7z/7zIn.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zIn.h
trunk/lzma/CPP/7zip/Archive/7z/7zItem.h
trunk/lzma/CPP/7zip/Archive/7z/7zOut.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zOut.h
trunk/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zProperties.h
trunk/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
trunk/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
trunk/lzma/CPP/7zip/Archive/7z/7zUpdate.h
trunk/lzma/CPP/7zip/Archive/7z/StdAfx.cpp
trunk/lzma/CPP/7zip/Archive/7z/StdAfx.h
trunk/lzma/CPP/7zip/Archive/Archive.def
trunk/lzma/CPP/7zip/Archive/Archive2.def
trunk/lzma/CPP/7zip/Archive/ArchiveExports.cpp
trunk/lzma/CPP/7zip/Archive/Common/
trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h
trunk/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
trunk/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h
trunk/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
trunk/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
trunk/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
trunk/lzma/CPP/7zip/Archive/Common/HandlerOut.h
trunk/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
trunk/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h
trunk/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
trunk/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
trunk/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
trunk/lzma/CPP/7zip/Archive/Common/MultiStream.h
trunk/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
trunk/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
trunk/lzma/CPP/7zip/Archive/Common/ParseProperties.cpp
trunk/lzma/CPP/7zip/Archive/Common/ParseProperties.h
trunk/lzma/CPP/7zip/Archive/DllExports2.cpp
trunk/lzma/CPP/7zip/Archive/IArchive.h
trunk/lzma/CPP/7zip/Bundles/
trunk/lzma/CPP/7zip/Bundles/Alone7z/
trunk/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp
trunk/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsw
trunk/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
trunk/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h
trunk/lzma/CPP/7zip/Bundles/Alone7z/makefile
trunk/lzma/CPP/7zip/Bundles/Alone7z/resource.rc
trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/
trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile
trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/resource.rc
trunk/lzma/CPP/7zip/Bundles/Format7zR/
trunk/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
trunk/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h
trunk/lzma/CPP/7zip/Bundles/Format7zR/makefile
trunk/lzma/CPP/7zip/Bundles/Format7zR/resource.rc
trunk/lzma/CPP/7zip/Common/
trunk/lzma/CPP/7zip/Common/CreateCoder.cpp
trunk/lzma/CPP/7zip/Common/CreateCoder.h
trunk/lzma/CPP/7zip/Common/FilePathAutoRename.cpp
trunk/lzma/CPP/7zip/Common/FilePathAutoRename.h
trunk/lzma/CPP/7zip/Common/FileStreams.cpp
trunk/lzma/CPP/7zip/Common/FileStreams.h
trunk/lzma/CPP/7zip/Common/FilterCoder.cpp
trunk/lzma/CPP/7zip/Common/FilterCoder.h
trunk/lzma/CPP/7zip/Common/InBuffer.cpp
trunk/lzma/CPP/7zip/Common/InBuffer.h
trunk/lzma/CPP/7zip/Common/InOutTempBuffer.cpp
trunk/lzma/CPP/7zip/Common/InOutTempBuffer.h
trunk/lzma/CPP/7zip/Common/LimitedStreams.cpp
trunk/lzma/CPP/7zip/Common/LimitedStreams.h
trunk/lzma/CPP/7zip/Common/LockedStream.cpp
trunk/lzma/CPP/7zip/Common/LockedStream.h
trunk/lzma/CPP/7zip/Common/MethodId.cpp
trunk/lzma/CPP/7zip/Common/MethodId.h
trunk/lzma/CPP/7zip/Common/MethodProps.cpp
trunk/lzma/CPP/7zip/Common/MethodProps.h
trunk/lzma/CPP/7zip/Common/OffsetStream.cpp
trunk/lzma/CPP/7zip/Common/OffsetStream.h
trunk/lzma/CPP/7zip/Common/OutBuffer.cpp
trunk/lzma/CPP/7zip/Common/OutBuffer.h
trunk/lzma/CPP/7zip/Common/ProgressUtils.cpp
trunk/lzma/CPP/7zip/Common/ProgressUtils.h
trunk/lzma/CPP/7zip/Common/RegisterArc.h
trunk/lzma/CPP/7zip/Common/RegisterCodec.h
trunk/lzma/CPP/7zip/Common/StdAfx.h
trunk/lzma/CPP/7zip/Common/StreamBinder.cpp
trunk/lzma/CPP/7zip/Common/StreamBinder.h
trunk/lzma/CPP/7zip/Common/StreamObjects.cpp
trunk/lzma/CPP/7zip/Common/StreamObjects.h
trunk/lzma/CPP/7zip/Common/StreamUtils.cpp
trunk/lzma/CPP/7zip/Common/StreamUtils.h
trunk/lzma/CPP/7zip/Common/VirtThread.cpp
trunk/lzma/CPP/7zip/Common/VirtThread.h
trunk/lzma/CPP/7zip/Compress/
trunk/lzma/CPP/7zip/Compress/Branch/
trunk/lzma/CPP/7zip/Compress/Branch/ARM.cpp
trunk/lzma/CPP/7zip/Compress/Branch/ARM.h
trunk/lzma/CPP/7zip/Compress/Branch/ARMThumb.cpp
trunk/lzma/CPP/7zip/Compress/Branch/ARMThumb.h
trunk/lzma/CPP/7zip/Compress/Branch/BCJ2Register.cpp
trunk/lzma/CPP/7zip/Compress/Branch/BCJRegister.cpp
trunk/lzma/CPP/7zip/Compress/Branch/BranchCoder.cpp
trunk/lzma/CPP/7zip/Compress/Branch/BranchCoder.h
trunk/lzma/CPP/7zip/Compress/Branch/BranchRegister.cpp
trunk/lzma/CPP/7zip/Compress/Branch/IA64.cpp
trunk/lzma/CPP/7zip/Compress/Branch/IA64.h
trunk/lzma/CPP/7zip/Compress/Branch/PPC.cpp
trunk/lzma/CPP/7zip/Compress/Branch/PPC.h
trunk/lzma/CPP/7zip/Compress/Branch/SPARC.cpp
trunk/lzma/CPP/7zip/Compress/Branch/SPARC.h
trunk/lzma/CPP/7zip/Compress/Branch/StdAfx.cpp
trunk/lzma/CPP/7zip/Compress/Branch/StdAfx.h
trunk/lzma/CPP/7zip/Compress/Branch/x86.cpp
trunk/lzma/CPP/7zip/Compress/Branch/x86.h
trunk/lzma/CPP/7zip/Compress/Branch/x86_2.cpp
trunk/lzma/CPP/7zip/Compress/Branch/x86_2.h
trunk/lzma/CPP/7zip/Compress/ByteSwap/
trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp
trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.h
trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwapRegister.cpp
trunk/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.cpp
trunk/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.h
trunk/lzma/CPP/7zip/Compress/CodecExports.cpp
trunk/lzma/CPP/7zip/Compress/Copy/
trunk/lzma/CPP/7zip/Compress/Copy/CopyCoder.cpp
trunk/lzma/CPP/7zip/Compress/Copy/CopyCoder.h
trunk/lzma/CPP/7zip/Compress/Copy/CopyRegister.cpp
trunk/lzma/CPP/7zip/Compress/Copy/StdAfx.cpp
trunk/lzma/CPP/7zip/Compress/Copy/StdAfx.h
trunk/lzma/CPP/7zip/Compress/LZ/
trunk/lzma/CPP/7zip/Compress/LZ/LZOutWindow.cpp
trunk/lzma/CPP/7zip/Compress/LZ/LZOutWindow.h
trunk/lzma/CPP/7zip/Compress/LZ/StdAfx.h
trunk/lzma/CPP/7zip/Compress/LZMA/
trunk/lzma/CPP/7zip/Compress/LZMA/LZMA.h
trunk/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.cpp
trunk/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.h
trunk/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp
trunk/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.h
trunk/lzma/CPP/7zip/Compress/LZMA/LZMARegister.cpp
trunk/lzma/CPP/7zip/Compress/LZMA/StdAfx.cpp
trunk/lzma/CPP/7zip/Compress/LZMA/StdAfx.h
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.cpp
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.h
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.h
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/makefile
trunk/lzma/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
trunk/lzma/CPP/7zip/Compress/RangeCoder/
trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoder.h
trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp
trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h
trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h
trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h
trunk/lzma/CPP/7zip/Compress/RangeCoder/StdAfx.h
trunk/lzma/CPP/7zip/ICoder.h
trunk/lzma/CPP/7zip/IDecl.h
trunk/lzma/CPP/7zip/IPassword.h
trunk/lzma/CPP/7zip/IProgress.h
trunk/lzma/CPP/7zip/IStream.h
trunk/lzma/CPP/7zip/MyVersion.h
trunk/lzma/CPP/7zip/MyVersionInfo.rc
trunk/lzma/CPP/7zip/PropID.h
trunk/lzma/CPP/7zip/UI/
trunk/lzma/CPP/7zip/UI/Client7z/
trunk/lzma/CPP/7zip/UI/Client7z/Client7z.cpp
trunk/lzma/CPP/7zip/UI/Client7z/Client7z.dsp
trunk/lzma/CPP/7zip/UI/Client7z/Client7z.dsw
trunk/lzma/CPP/7zip/UI/Client7z/StdAfx.cpp
trunk/lzma/CPP/7zip/UI/Client7z/StdAfx.h
trunk/lzma/CPP/7zip/UI/Client7z/makefile
trunk/lzma/CPP/7zip/UI/Common/
trunk/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
trunk/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h
trunk/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
trunk/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h
trunk/lzma/CPP/7zip/UI/Common/ArchiveName.cpp
trunk/lzma/CPP/7zip/UI/Common/ArchiveName.h
trunk/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
trunk/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h
trunk/lzma/CPP/7zip/UI/Common/DefaultName.cpp
trunk/lzma/CPP/7zip/UI/Common/DefaultName.h
trunk/lzma/CPP/7zip/UI/Common/DirItem.h
trunk/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp
trunk/lzma/CPP/7zip/UI/Common/EnumDirItems.h
trunk/lzma/CPP/7zip/UI/Common/ExitCode.h
trunk/lzma/CPP/7zip/UI/Common/Extract.cpp
trunk/lzma/CPP/7zip/UI/Common/Extract.h
trunk/lzma/CPP/7zip/UI/Common/ExtractMode.h
trunk/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp
trunk/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h
trunk/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h
trunk/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp
trunk/lzma/CPP/7zip/UI/Common/LoadCodecs.h
trunk/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
trunk/lzma/CPP/7zip/UI/Common/OpenArchive.h
trunk/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp
trunk/lzma/CPP/7zip/UI/Common/PropIDUtils.h
trunk/lzma/CPP/7zip/UI/Common/Property.h
trunk/lzma/CPP/7zip/UI/Common/SetProperties.cpp
trunk/lzma/CPP/7zip/UI/Common/SetProperties.h
trunk/lzma/CPP/7zip/UI/Common/SortUtils.cpp
trunk/lzma/CPP/7zip/UI/Common/SortUtils.h
trunk/lzma/CPP/7zip/UI/Common/TempFiles.cpp
trunk/lzma/CPP/7zip/UI/Common/TempFiles.h
trunk/lzma/CPP/7zip/UI/Common/Update.cpp
trunk/lzma/CPP/7zip/UI/Common/Update.h
trunk/lzma/CPP/7zip/UI/Common/UpdateAction.cpp
trunk/lzma/CPP/7zip/UI/Common/UpdateAction.h
trunk/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
trunk/lzma/CPP/7zip/UI/Common/UpdateCallback.h
trunk/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
trunk/lzma/CPP/7zip/UI/Common/UpdatePair.h
trunk/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp
trunk/lzma/CPP/7zip/UI/Common/UpdateProduce.h
trunk/lzma/CPP/7zip/UI/Common/WorkDir.cpp
trunk/lzma/CPP/7zip/UI/Common/WorkDir.h
trunk/lzma/CPP/7zip/UI/Common/ZipRegistry.h
trunk/lzma/CPP/7zip/UI/Console/
trunk/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp
trunk/lzma/CPP/7zip/UI/Console/ConsoleClose.h
trunk/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
trunk/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h
trunk/lzma/CPP/7zip/UI/Console/List.cpp
trunk/lzma/CPP/7zip/UI/Console/List.h
trunk/lzma/CPP/7zip/UI/Console/Main.cpp
trunk/lzma/CPP/7zip/UI/Console/MainAr.cpp
trunk/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
trunk/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h
trunk/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp
trunk/lzma/CPP/7zip/UI/Console/PercentPrinter.h
trunk/lzma/CPP/7zip/UI/Console/StdAfx.cpp
trunk/lzma/CPP/7zip/UI/Console/StdAfx.h
trunk/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
trunk/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h
trunk/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp
trunk/lzma/CPP/7zip/UI/Console/UserInputUtils.h
trunk/lzma/CPP/7zip/UI/Console/afxres.h
trunk/lzma/CPP/Build.mak
trunk/lzma/CPP/Common/
trunk/lzma/CPP/Common/AutoPtr.h
trunk/lzma/CPP/Common/Buffer.h
trunk/lzma/CPP/Common/CRC.cpp
trunk/lzma/CPP/Common/C_FileIO.cpp
trunk/lzma/CPP/Common/C_FileIO.h
trunk/lzma/CPP/Common/ComTry.h
trunk/lzma/CPP/Common/CommandLineParser.cpp
trunk/lzma/CPP/Common/CommandLineParser.h
trunk/lzma/CPP/Common/Defs.h
trunk/lzma/CPP/Common/DynamicBuffer.h
trunk/lzma/CPP/Common/IntToString.cpp
trunk/lzma/CPP/Common/IntToString.h
trunk/lzma/CPP/Common/ListFileUtils.cpp
trunk/lzma/CPP/Common/ListFileUtils.h
trunk/lzma/CPP/Common/MyCom.h
trunk/lzma/CPP/Common/MyException.h
trunk/lzma/CPP/Common/MyGuidDef.h
trunk/lzma/CPP/Common/MyInitGuid.h
trunk/lzma/CPP/Common/MyString.cpp
trunk/lzma/CPP/Common/MyString.h
trunk/lzma/CPP/Common/MyUnknown.h
trunk/lzma/CPP/Common/MyVector.cpp
trunk/lzma/CPP/Common/MyVector.h
trunk/lzma/CPP/Common/MyWindows.h
trunk/lzma/CPP/Common/NewHandler.cpp
trunk/lzma/CPP/Common/NewHandler.h
trunk/lzma/CPP/Common/StdAfx.h
trunk/lzma/CPP/Common/StdInStream.cpp
trunk/lzma/CPP/Common/StdInStream.h
trunk/lzma/CPP/Common/StdOutStream.cpp
trunk/lzma/CPP/Common/StdOutStream.h
trunk/lzma/CPP/Common/StringConvert.cpp
trunk/lzma/CPP/Common/StringConvert.h
trunk/lzma/CPP/Common/StringToInt.cpp
trunk/lzma/CPP/Common/StringToInt.h
trunk/lzma/CPP/Common/Types.h
trunk/lzma/CPP/Common/UTFConvert.cpp
trunk/lzma/CPP/Common/UTFConvert.h
trunk/lzma/CPP/Common/Wildcard.cpp
trunk/lzma/CPP/Common/Wildcard.h
trunk/lzma/CPP/Windows/
trunk/lzma/CPP/Windows/DLL.cpp
trunk/lzma/CPP/Windows/DLL.h
trunk/lzma/CPP/Windows/Defs.h
trunk/lzma/CPP/Windows/Error.cpp
trunk/lzma/CPP/Windows/Error.h
trunk/lzma/CPP/Windows/FileDir.cpp
trunk/lzma/CPP/Windows/FileDir.h
trunk/lzma/CPP/Windows/FileFind.cpp
trunk/lzma/CPP/Windows/FileFind.h
trunk/lzma/CPP/Windows/FileIO.cpp
trunk/lzma/CPP/Windows/FileIO.h
trunk/lzma/CPP/Windows/FileMapping.cpp
trunk/lzma/CPP/Windows/FileMapping.h
trunk/lzma/CPP/Windows/FileName.cpp
trunk/lzma/CPP/Windows/FileName.h
trunk/lzma/CPP/Windows/Handle.h
trunk/lzma/CPP/Windows/MemoryLock.cpp
trunk/lzma/CPP/Windows/MemoryLock.h
trunk/lzma/CPP/Windows/PropVariant.cpp
trunk/lzma/CPP/Windows/PropVariant.h
trunk/lzma/CPP/Windows/PropVariantConversions.cpp
trunk/lzma/CPP/Windows/PropVariantConversions.h
trunk/lzma/CPP/Windows/StdAfx.h
trunk/lzma/CPP/Windows/Synchronization.cpp
trunk/lzma/CPP/Windows/Synchronization.h
trunk/lzma/CPP/Windows/System.cpp
trunk/lzma/CPP/Windows/System.h
trunk/lzma/CPP/Windows/Thread.h
trunk/lzma/CPP/Windows/Time.h
trunk/lzma/CS/
trunk/lzma/CS/7zip/
trunk/lzma/CS/7zip/Common/
trunk/lzma/CS/7zip/Common/CRC.cs
trunk/lzma/CS/7zip/Common/CommandLineParser.cs
trunk/lzma/CS/7zip/Common/InBuffer.cs
trunk/lzma/CS/7zip/Common/OutBuffer.cs
trunk/lzma/CS/7zip/Compress/
trunk/lzma/CS/7zip/Compress/LZ/
trunk/lzma/CS/7zip/Compress/LZ/IMatchFinder.cs
trunk/lzma/CS/7zip/Compress/LZ/LzBinTree.cs
trunk/lzma/CS/7zip/Compress/LZ/LzInWindow.cs
trunk/lzma/CS/7zip/Compress/LZ/LzOutWindow.cs
trunk/lzma/CS/7zip/Compress/LZMA/
trunk/lzma/CS/7zip/Compress/LZMA/LzmaBase.cs
trunk/lzma/CS/7zip/Compress/LZMA/LzmaDecoder.cs
trunk/lzma/CS/7zip/Compress/LZMA/LzmaEncoder.cs
trunk/lzma/CS/7zip/Compress/LzmaAlone/
trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj
trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln
trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaBench.cs
trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/
trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs
trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs
trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs
trunk/lzma/CS/7zip/Compress/RangeCoder/
trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoder.cs
trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs
trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
trunk/lzma/CS/7zip/ICoder.cs
trunk/lzma/Java/
trunk/lzma/Java/SevenZip/
trunk/lzma/Java/SevenZip/CRC.java
trunk/lzma/Java/SevenZip/Compression/
trunk/lzma/Java/SevenZip/Compression/LZ/
trunk/lzma/Java/SevenZip/Compression/LZ/BinTree.java
trunk/lzma/Java/SevenZip/Compression/LZ/InWindow.java
trunk/lzma/Java/SevenZip/Compression/LZ/OutWindow.java
trunk/lzma/Java/SevenZip/Compression/LZMA/
trunk/lzma/Java/SevenZip/Compression/LZMA/Base.java
trunk/lzma/Java/SevenZip/Compression/LZMA/Decoder.java
trunk/lzma/Java/SevenZip/Compression/LZMA/Encoder.java
trunk/lzma/Java/SevenZip/Compression/RangeCoder/
trunk/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java
trunk/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java
trunk/lzma/Java/SevenZip/Compression/RangeCoder/Decoder.java
trunk/lzma/Java/SevenZip/Compression/RangeCoder/Encoder.java
trunk/lzma/Java/SevenZip/ICodeProgress.java
trunk/lzma/Java/SevenZip/LzmaAlone.java
trunk/lzma/Java/SevenZip/LzmaBench.java
trunk/lzma/LGPL.txt
trunk/lzma/Methods.txt
trunk/lzma/history.txt
trunk/lzma/lzma.exe
trunk/lzma/lzma.txt
Log:
Upgraded lzma sdk to 4.57.
Added: trunk/lzma/7zC.txt
===================================================================
--- trunk/lzma/7zC.txt (rev 0)
+++ trunk/lzma/7zC.txt 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,237 @@
+7z ANSI-C Decoder 4.48
+----------------------
+
+7z ANSI-C Decoder 4.48 Copyright (C) 1999-2006 Igor Pavlov
+
+7z ANSI-C provides 7z/LZMA decoding.
+7z ANSI-C version is simplified version ported from C++ code.
+
+LZMA is default and general compression method of 7z format
+in 7-Zip compression program (www.7-zip.org). LZMA provides high
+compression ratio and very fast decompression.
+
+
+LICENSE
+-------
+
+Read lzma.txt for information about license.
+
+
+Files
+---------------------
+
+7zAlloc.* - Allocate and Free
+7zBuffer.* - Buffer structure
+7zCrc.* - CRC32 code
+7zDecode.* - Low level memory->memory decoding
+7zExtract.* - High level stream->memory decoding
+7zHeader.* - .7z format constants
+7zIn.* - .7z archive opening
+7zItem.* - .7z structures
+7zMain.c - Test application
+7zMethodID.* - MethodID structure
+7zTypes.h - Base types and constants
+
+
+How To Use
+----------
+
+You must download 7-Zip program from www.7-zip.org.
+
+You can create .7z archive with 7z.exe or 7za.exe:
+
+ 7za.exe a archive.7z *.htm -r -mx -m0fb=255
+
+If you have big number of files in archive, and you need fast extracting,
+you can use partly-solid archives:
+
+ 7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K
+
+In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only
+512KB for extracting one file from such archive.
+
+
+Limitations of current version of 7z ANSI-C Decoder
+---------------------------------------------------
+
+ - It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive.
+ - It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters.
+ - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names.
+
+These limitations will be fixed in future versions.
+
+
+Using 7z ANSI-C Decoder Test application:
+-----------------------------------------
+
+Usage: 7zDec <command> <archive_name>
+
+<Command>:
+ e: Extract files from archive
+ l: List contents of archive
+ t: Test integrity of archive
+
+Example:
+
+ 7zDec l archive.7z
+
+lists contents of archive.7z
+
+ 7zDec e archive.7z
+
+extracts files from archive.7z to current folder.
+
+
+How to use .7z Decoder
+----------------------
+
+.7z Decoder can be compiled in one of two modes:
+
+1) Default mode. In that mode 7z Decoder will read full compressed
+ block to RAM before decompressing.
+
+2) Mode with defined _LZMA_IN_CB. In that mode 7z Decoder can read
+ compressed block by parts. And you can specify desired buffer size.
+ So memory requirements can be reduced. But decompressing speed will
+ be 5-10% lower and code size is slightly larger.
+
+
+Memory allocation
+~~~~~~~~~~~~~~~~~
+
+7z Decoder uses two memory pools:
+1) Temporary pool
+2) Main pool
+Such scheme can allow you to avoid fragmentation of allocated blocks.
+
+Steps for using 7z decoder
+--------------------------
+
+Use code at 7zMain.c as example.
+
+1) Declare variables:
+ inStream /* implements ISzInStream interface */
+ CArchiveDatabaseEx db; /* 7z archive database structure */
+ ISzAlloc allocImp; /* memory functions for main pool */
+ ISzAlloc allocTempImp; /* memory functions for temporary pool */
+
+2) call InitCrcTable(); function to initialize CRC structures.
+
+3) call SzArDbExInit(&db); function to initialize db structures.
+
+4) call SzArchiveOpen(inStream, &db, &allocMain, &allocTemp) to open archive
+
+This function opens archive "inStream" and reads headers to "db".
+All items in "db" will be allocated with "allocMain" functions.
+SzArchiveOpen function allocates and frees temporary structures by "allocTemp" functions.
+
+5) List items or Extract items
+
+ Listing code:
+ ~~~~~~~~~~~~~
+ {
+ UInt32 i;
+ for (i = 0; i < db.Database.NumFiles; i++)
+ {
+ CFileItem *f = db.Database.Files + i;
+ printf("%10d %s\n", (int)f->Size, f->Name);
+ }
+ }
+
+ Extracting code:
+ ~~~~~~~~~~~~~~~~
+
+ SZ_RESULT SzExtract(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ UInt32 fileIndex, /* index of file */
+ UInt32 *blockIndex, /* index of solid block */
+ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
+ size_t *outBufferSize, /* buffer size for output buffer */
+ size_t *offset, /* offset of stream for required file in *outBuffer */
+ size_t *outSizeProcessed, /* size of file in *outBuffer */
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp);
+
+ If you need to decompress more than one file, you can send these values from previous call:
+ blockIndex,
+ outBuffer,
+ outBufferSize,
+ You can consider "outBuffer" as cache of solid block. If your archive is solid,
+ it will increase decompression speed.
+
+ After decompressing you must free "outBuffer":
+ allocImp.Free(outBuffer);
+
+6) call SzArDbExFree(&db, allocImp.Free) to free allocated items in "db".
+
+
+
+
+Memory requirements for .7z decoding
+------------------------------------
+
+Memory usage for Archive opening:
+ - Temporary pool:
+ - Memory for compressed .7z headers (if _LZMA_IN_CB is not defined)
+ - Memory for uncompressed .7z headers
+ - some other temporary blocks
+ - Main pool:
+ - Memory for database:
+ Estimated size of one file structures in solid archive:
+ - Size (4 or 8 Bytes)
+ - CRC32 (4 bytes)
+ - LastWriteTime (8 bytes)
+ - Some file information (4 bytes)
+ - File Name (variable length) + pointer + allocation structures
+
+Memory usage for archive Decompressing:
+ - Temporary pool:
+ - Memory for compressed solid block (if _LZMA_IN_CB is not defined)
+ - Memory for LZMA decompressing structures
+ - Main pool:
+ - Memory for decompressed solid block
+ - Memory for temprorary buffers, if BCJ2 fileter is used. Usually these
+ temprorary buffers can be about 15% of solid block size.
+
+
+If _LZMA_IN_CB is defined, 7z Decoder will not allocate memory for
+compressed blocks. Instead of this, you must allocate buffer with desired
+size before calling 7z Decoder. Use 7zMain.c as example.
+
+
+
+EXIT codes
+-----------
+
+7z Decoder functions can return one of the following codes:
+
+#define SZ_OK (0)
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+#define SZE_CRC_ERROR (3)
+
+#define SZE_NOTIMPL (4)
+#define SZE_FAIL (5)
+
+#define SZE_ARCHIVE_ERROR (6)
+
+
+
+LZMA Defines
+------------
+
+_LZMA_IN_CB - Use special callback mode for input stream to reduce memory requirements
+
+_SZ_FILE_SIZE_32 - define it if you need only support for files smaller than 4 GB
+_SZ_NO_INT_64 - define it if your compiler doesn't support long long int or __int64.
+
+_LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs.
+
+_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr.
+
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/support.html
Added: trunk/lzma/7zFormat.txt
===================================================================
--- trunk/lzma/7zFormat.txt (rev 0)
+++ trunk/lzma/7zFormat.txt 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,471 @@
+7z Format description (2.30 Beta 25)
+-----------------------------------
+
+This file contains description of 7z archive format.
+7z archive can contain files compressed with any method.
+See "Methods.txt" for description for defined compressing methods.
+
+
+Format structure Overview
+-------------------------
+
+Some fields can be optional.
+
+Archive structure
+~~~~~~~~~~~~~~~~~
+SignatureHeader
+[PackedStreams]
+[PackedStreamsForHeaders]
+[
+ Header
+ or
+ {
+ Packed Header
+ HeaderInfo
+ }
+]
+
+
+
+Header structure
+~~~~~~~~~~~~~~~~
+{
+ ArchiveProperties
+ AdditionalStreams
+ {
+ PackInfo
+ {
+ PackPos
+ NumPackStreams
+ Sizes[NumPackStreams]
+ CRCs[NumPackStreams]
+ }
+ CodersInfo
+ {
+ NumFolders
+ Folders[NumFolders]
+ {
+ NumCoders
+ CodersInfo[NumCoders]
+ {
+ ID
+ NumInStreams;
+ NumOutStreams;
+ PropertiesSize
+ Properties[PropertiesSize]
+ }
+ NumBindPairs
+ BindPairsInfo[NumBindPairs]
+ {
+ InIndex;
+ OutIndex;
+ }
+ PackedIndices
+ }
+ UnPackSize[Folders][Folders.NumOutstreams]
+ CRCs[NumFolders]
+ }
+ SubStreamsInfo
+ {
+ NumUnPackStreamsInFolders[NumFolders];
+ UnPackSizes[]
+ CRCs[]
+ }
+ }
+ MainStreamsInfo
+ {
+ (Same as in AdditionalStreams)
+ }
+ FilesInfo
+ {
+ NumFiles
+ Properties[]
+ {
+ ID
+ Size
+ Data
+ }
+ }
+}
+
+HeaderInfo structure
+~~~~~~~~~~~~~~~~~~~~
+{
+ (Same as in AdditionalStreams)
+}
+
+
+
+Notes about Notation and encoding
+---------------------------------
+
+7z uses little endian encoding.
+
+7z archive format has optional headers that are marked as
+[]
+Header
+[]
+
+REAL_UINT64 means real UINT64.
+
+UINT64 means real UINT64 encoded with the following scheme:
+
+ Size of encoding sequence depends from first byte:
+ First_Byte Extra_Bytes Value
+ (binary)
+ 0xxxxxxx : ( xxxxxxx )
+ 10xxxxxx BYTE y[1] : ( xxxxxx << (8 * 1)) + y
+ 110xxxxx BYTE y[2] : ( xxxxx << (8 * 2)) + y
+ ...
+ 1111110x BYTE y[6] : ( x << (8 * 6)) + y
+ 11111110 BYTE y[7] : y
+ 11111111 BYTE y[8] : y
+
+
+
+Property IDs
+------------
+
+0x00 = kEnd,
+
+0x01 = kHeader,
+
+0x02 = kArchiveProperties,
+
+0x03 = kAdditionalStreamsInfo,
+0x04 = kMainStreamsInfo,
+0x05 = kFilesInfo,
+
+0x06 = kPackInfo,
+0x07 = kUnPackInfo,
+0x08 = kSubStreamsInfo,
+
+0x09 = kSize,
+0x0A = kCRC,
+
+0x0B = kFolder,
+
+0x0C = kCodersUnPackSize,
+0x0D = kNumUnPackStream,
+
+0x0E = kEmptyStream,
+0x0F = kEmptyFile,
+0x10 = kAnti,
+
+0x11 = kName,
+0x12 = kCreationTime,
+0x13 = kLastAccessTime,
+0x14 = kLastWriteTime,
+0x15 = kWinAttributes,
+0x16 = kComment,
+
+0x17 = kEncodedHeader,
+
+
+7z format headers
+-----------------
+
+SignatureHeader
+~~~~~~~~~~~~~~~
+ BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
+
+ ArchiveVersion
+ {
+ BYTE Major; // now = 0
+ BYTE Minor; // now = 2
+ };
+
+ UINT32 StartHeaderCRC;
+
+ StartHeader
+ {
+ REAL_UINT64 NextHeaderOffset
+ REAL_UINT64 NextHeaderSize
+ UINT32 NextHeaderCRC
+ }
+
+
+...........................
+
+
+ArchiveProperties
+~~~~~~~~~~~~~~~~~
+BYTE NID::kArchiveProperties (0x02)
+for (;;)
+{
+ BYTE PropertyType;
+ if (aType == 0)
+ break;
+ UINT64 PropertySize;
+ BYTE PropertyData[PropertySize];
+}
+
+
+Digests (NumStreams)
+~~~~~~~~~~~~~~~~~~~~~
+ BYTE AllAreDefined
+ if (AllAreDefined == 0)
+ {
+ for(NumStreams)
+ BIT Defined
+ }
+ UINT32 CRCs[NumDefined]
+
+
+PackInfo
+~~~~~~~~~~~~
+ BYTE NID::kPackInfo (0x06)
+ UINT64 PackPos
+ UINT64 NumPackStreams
+
+ []
+ BYTE NID::kSize (0x09)
+ UINT64 PackSizes[NumPackStreams]
+ []
+
+ []
+ BYTE NID::kCRC (0x0A)
+ PackStreamDigests[NumPackStreams]
+ []
+
+ BYTE NID::kEnd
+
+
+Folder
+~~~~~~
+ UINT64 NumCoders;
+ for (NumCoders)
+ {
+ BYTE
+ {
+ 0:3 DecompressionMethod.IDSize
+ 4:
+ 0 - IsSimple
+ 1 - Is not simple
+ 5:
+ 0 - No Attributes
+ 1 - There Are Attributes
+ 7:
+ 0 - Last Method in Alternative_Method_List
+ 1 - There are more alternative methods
+ }
+ BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]
+ if (!IsSimple)
+ {
+ UINT64 NumInStreams;
+ UINT64 NumOutStreams;
+ }
+ if (DecompressionMethod[0] != 0)
+ {
+ UINT64 PropertiesSize
+ BYTE Properties[PropertiesSize]
+ }
+ }
+
+ NumBindPairs = NumOutStreamsTotal - 1;
+
+ for (NumBindPairs)
+ {
+ UINT64 InIndex;
+ UINT64 OutIndex;
+ }
+
+ NumPackedStreams = NumInStreamsTotal - NumBindPairs;
+ if (NumPackedStreams > 1)
+ for(NumPackedStreams)
+ {
+ UINT64 Index;
+ };
+
+
+
+
+Coders Info
+~~~~~~~~~~~
+
+ BYTE NID::kUnPackInfo (0x07)
+
+
+ BYTE NID::kFolder (0x0B)
+ UINT64 NumFolders
+ BYTE External
+ switch(External)
+ {
+ case 0:
+ Folders[NumFolders]
+ case 1:
+ UINT64 DataStreamIndex
+ }
+
+
+ BYTE ID::kCodersUnPackSize (0x0C)
+ for(Folders)
+ for(Folder.NumOutStreams)
+ UINT64 UnPackSize;
+
+
+ []
+ BYTE NID::kCRC (0x0A)
+ UnPackDigests[NumFolders]
+ []
+
+
+
+ BYTE NID::kEnd
+
+
+
+SubStreams Info
+~~~~~~~~~~~~~~
+ BYTE NID::kSubStreamsInfo; (0x08)
+
+ []
+ BYTE NID::kNumUnPackStream; (0x0D)
+ UINT64 NumUnPackStreamsInFolders[NumFolders];
+ []
+
+
+ []
+ BYTE NID::kSize (0x09)
+ UINT64 UnPackSizes[]
+ []
+
+
+ []
+ BYTE NID::kCRC (0x0A)
+ Digests[Number of streams with unknown CRC]
+ []
+
+
+ BYTE NID::kEnd
+
+
+Streams Info
+~~~~~~~~~~~~
+
+ []
+ PackInfo
+ []
+
+
+ []
+ CodersInfo
+ []
+
+
+ []
+ SubStreamsInfo
+ []
+
+ BYTE NID::kEnd
+
+
+FilesInfo
+~~~~~~~~~
+ BYTE NID::kFilesInfo; (0x05)
+ UINT64 NumFiles
+
+ for (;;)
+ {
+ BYTE PropertyType;
+ if (aType == 0)
+ break;
+
+ UINT64 Size;
+
+ switch(PropertyType)
+ {
+ kEmptyStream: (0x0E)
+ for(NumFiles)
+ BIT IsEmptyStream
+
+ kEmptyFile: (0x0F)
+ for(EmptyStreams)
+ BIT IsEmptyFile
+
+ kAnti: (0x10)
+ for(EmptyStreams)
+ BIT IsAntiFile
+
+ case kCreationTime: (0x12)
+ case kLastAccessTime: (0x13)
+ case kLastWriteTime: (0x14)
+ BYTE AllAreDefined
+ if (AllAreDefined == 0)
+ {
+ for(NumFiles)
+ BIT TimeDefined
+ }
+ BYTE External;
+ if(External != 0)
+ UINT64 DataIndex
+ []
+ for(Definded Items)
+ UINT32 Time
+ []
+
+ kNames: (0x11)
+ BYTE External;
+ if(External != 0)
+ UINT64 DataIndex
+ []
+ for(Files)
+ {
+ wchar_t Names[NameSize];
+ wchar_t 0;
+ }
+ []
+
+ kAttributes: (0x15)
+ BYTE AllAreDefined
+ if (AllAreDefined == 0)
+ {
+ for(NumFiles)
+ BIT AttributesAreDefined
+ }
+ BYTE External;
+ if(External != 0)
+ UINT64 DataIndex
+ []
+ for(Definded Attributes)
+ UINT32 Attributes
+ []
+ }
+ }
+
+
+Header
+~~~~~~
+ BYTE NID::kHeader (0x01)
+
+ []
+ ArchiveProperties
+ []
+
+ []
+ BYTE NID::kAdditionalStreamsInfo; (0x03)
+ StreamsInfo
+ []
+
+ []
+ BYTE NID::kMainStreamsInfo; (0x04)
+ StreamsInfo
+ []
+
+ []
+ FilesInfo
+ []
+
+ BYTE NID::kEnd
+
+
+HeaderInfo
+~~~~~~~~~~
+ []
+ BYTE NID::kEncodedHeader; (0x17)
+ StreamsInfo for Encoded Header
+ []
+
+
+---
+End of document
Added: trunk/lzma/C/7zCrc.c
===================================================================
--- trunk/lzma/C/7zCrc.c (rev 0)
+++ trunk/lzma/C/7zCrc.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,32 @@
+/* 7zCrc.c */
+
+#include "7zCrc.h"
+
+#define kCrcPoly 0xEDB88320
+UInt32 g_CrcTable[256];
+
+void MY_FAST_CALL CrcGenerateTable(void)
+{
+ UInt32 i;
+ for (i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ int j;
+ for (j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ g_CrcTable[i] = r;
+ }
+}
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
+{
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 ; size--, p++)
+ v = CRC_UPDATE_BYTE(v, *p);
+ return v;
+}
+
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
+{
+ return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
+}
Added: trunk/lzma/C/7zCrc.h
===================================================================
--- trunk/lzma/C/7zCrc.h (rev 0)
+++ trunk/lzma/C/7zCrc.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,21 @@
+/* 7zCrc.h */
+
+#ifndef __7Z_CRC_H
+#define __7Z_CRC_H
+
+#include <stddef.h>
+
+#include "Types.h"
+
+extern UInt32 g_CrcTable[];
+
+void MY_FAST_CALL CrcGenerateTable(void);
+
+#define CRC_INIT_VAL 0xFFFFFFFF
+#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
+#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
+
+#endif
Added: trunk/lzma/C/7zCrcT8.c
===================================================================
--- trunk/lzma/C/7zCrcT8.c (rev 0)
+++ trunk/lzma/C/7zCrcT8.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,40 @@
+/* 7zCrcT8.c */
+
+#include "7zCrc.h"
+
+#define kCrcPoly 0xEDB88320
+#define CRC_NUM_TABLES 8
+
+UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
+
+void MY_FAST_CALL CrcGenerateTable()
+{
+ UInt32 i;
+ for (i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ int j;
+ for (j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ g_CrcTable[i] = r;
+ }
+ #if CRC_NUM_TABLES > 1
+ for (; i < 256 * CRC_NUM_TABLES; i++)
+ {
+ UInt32 r = g_CrcTable[i - 256];
+ g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
+ }
+ #endif
+}
+
+UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
+{
+ return CrcUpdateT8(v, data, size, g_CrcTable);
+}
+
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
+{
+ return CrcUpdateT8(CRC_INIT_VAL, data, size, g_CrcTable) ^ 0xFFFFFFFF;
+}
Added: trunk/lzma/C/Alloc.c
===================================================================
--- trunk/lzma/C/Alloc.c (rev 0)
+++ trunk/lzma/C/Alloc.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,119 @@
+/* Alloc.c */
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#include <stdlib.h>
+
+#include "Alloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+#ifdef _SZ_ALLOC_DEBUG
+#include <stdio.h>
+int g_allocCount = 0;
+int g_allocCountMid = 0;
+int g_allocCountBig = 0;
+#endif
+
+void *MyAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
+ #endif
+ return malloc(size);
+}
+
+void MyFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
+ #endif
+ free(address);
+}
+
+#ifdef _WIN32
+
+void *MidAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
+ #endif
+ return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void MidFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
+ #endif
+ if (address == 0)
+ return;
+ VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#ifndef MEM_LARGE_PAGES
+#undef _7ZIP_LARGE_PAGES
+#endif
+
+#ifdef _7ZIP_LARGE_PAGES
+SIZE_T g_LargePageSize = 0;
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
+#endif
+
+void SetLargePageSize()
+{
+ #ifdef _7ZIP_LARGE_PAGES
+ SIZE_T size = 0;
+ GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
+ GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
+ if (largePageMinimum == 0)
+ return;
+ size = largePageMinimum();
+ if (size == 0 || (size & (size - 1)) != 0)
+ return;
+ g_LargePageSize = size;
+ #endif
+}
+
+
+void *BigAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
+ #endif
+
+ #ifdef _7ZIP_LARGE_PAGES
+ if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
+ {
+ void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
+ MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
+ if (res != 0)
+ return res;
+ }
+ #endif
+ return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void BigFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
+ #endif
+
+ if (address == 0)
+ return;
+ VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#endif
Added: trunk/lzma/C/Alloc.h
===================================================================
--- trunk/lzma/C/Alloc.h (rev 0)
+++ trunk/lzma/C/Alloc.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,29 @@
+/* Alloc.h */
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include <stddef.h>
+
+void *MyAlloc(size_t size);
+void MyFree(void *address);
+
+#ifdef _WIN32
+
+void SetLargePageSize();
+
+void *MidAlloc(size_t size);
+void MidFree(void *address);
+void *BigAlloc(size_t size);
+void BigFree(void *address);
+
+#else
+
+#define MidAlloc(size) MyAlloc(size)
+#define MidFree(address) MyFree(address)
+#define BigAlloc(size) MyAlloc(size)
+#define BigFree(address) MyFree(address)
+
+#endif
+
+#endif
Added: trunk/lzma/C/Archive/7z/7zAlloc.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zAlloc.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zAlloc.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,70 @@
+/* 7zAlloc.c */
+
+#include <stdlib.h>
+#include "7zAlloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+
+#ifdef _SZ_ALLOC_DEBUG
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#include <stdio.h>
+int g_allocCount = 0;
+int g_allocCountTemp = 0;
+#endif
+
+void *SzAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
+ g_allocCount++;
+ #endif
+ return malloc(size);
+}
+
+void SzFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ {
+ g_allocCount--;
+ fprintf(stderr, "\nFree; count = %10d", g_allocCount);
+ }
+ #endif
+ free(address);
+}
+
+void *SzAllocTemp(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
+ g_allocCountTemp++;
+ #ifdef _WIN32
+ return HeapAlloc(GetProcessHeap(), 0, size);
+ #endif
+ #endif
+ return malloc(size);
+}
+
+void SzFreeTemp(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ {
+ g_allocCountTemp--;
+ fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
+ }
+ #ifdef _WIN32
+ HeapFree(GetProcessHeap(), 0, address);
+ return;
+ #endif
+ #endif
+ free(address);
+}
Added: trunk/lzma/C/Archive/7z/7zAlloc.h
===================================================================
--- trunk/lzma/C/Archive/7z/7zAlloc.h (rev 0)
+++ trunk/lzma/C/Archive/7z/7zAlloc.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,20 @@
+/* 7zAlloc.h */
+
+#ifndef __7Z_ALLOC_H
+#define __7Z_ALLOC_H
+
+#include <stddef.h>
+
+typedef struct _ISzAlloc
+{
+ void *(*Alloc)(size_t size);
+ void (*Free)(void *address); /* address can be 0 */
+} ISzAlloc;
+
+void *SzAlloc(size_t size);
+void SzFree(void *address);
+
+void *SzAllocTemp(size_t size);
+void SzFreeTemp(void *address);
+
+#endif
Added: trunk/lzma/C/Archive/7z/7zBuffer.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zBuffer.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zBuffer.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,29 @@
+/* 7zBuffer.c */
+
+#include "7zBuffer.h"
+#include "7zAlloc.h"
+
+void SzByteBufferInit(CSzByteBuffer *buffer)
+{
+ buffer->Capacity = 0;
+ buffer->Items = 0;
+}
+
+int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
+{
+ buffer->Capacity = newCapacity;
+ if (newCapacity == 0)
+ {
+ buffer->Items = 0;
+ return 1;
+ }
+ buffer->Items = (Byte *)allocFunc(newCapacity);
+ return (buffer->Items != 0);
+}
+
+void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
+{
+ freeFunc(buffer->Items);
+ buffer->Items = 0;
+ buffer->Capacity = 0;
+}
Added: trunk/lzma/C/Archive/7z/7zBuffer.h
===================================================================
--- trunk/lzma/C/Archive/7z/7zBuffer.h (rev 0)
+++ trunk/lzma/C/Archive/7z/7zBuffer.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,19 @@
+/* 7zBuffer.h */
+
+#ifndef __7Z_BUFFER_H
+#define __7Z_BUFFER_H
+
+#include <stddef.h>
+#include "../../Types.h"
+
+typedef struct _CSzByteBuffer
+{
+ size_t Capacity;
+ Byte *Items;
+}CSzByteBuffer;
+
+void SzByteBufferInit(CSzByteBuffer *buffer);
+int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
+void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
+
+#endif
Added: trunk/lzma/C/Archive/7z/7zDecode.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zDecode.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zDecode.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,341 @@
+/* 7zDecode.c */
+
+#include <memory.h>
+
+#include "7zDecode.h"
+#ifdef _SZ_ONE_DIRECTORY
+#include "LzmaDecode.h"
+#else
+#include "../../Compress/Lzma/LzmaDecode.h"
+#include "../../Compress/Branch/BranchX86.h"
+#include "../../Compress/Branch/BranchX86_2.h"
+#endif
+
+#define k_Copy 0
+#define k_LZMA 0x30101
+#define k_BCJ 0x03030103
+#define k_BCJ2 0x0303011B
+
+#ifdef _LZMA_IN_CB
+
+typedef struct _CLzmaInCallbackImp
+{
+ ILzmaInCallback InCallback;
+ ISzInStream *InStream;
+ CFileSize Size;
+} CLzmaInCallbackImp;
+
+int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
+{
+ CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
+ size_t processedSize;
+ SZ_RESULT res;
+ size_t curSize = (1 << 20);
+ if (curSize > cb->Size)
+ curSize = (size_t)cb->Size;
+ *size = 0;
+ res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, curSize, &processedSize);
+ *size = (SizeT)processedSize;
+ if (processedSize > curSize)
+ return (int)SZE_FAIL;
+ cb->Size -= processedSize;
+ if (res == SZ_OK)
+ return 0;
+ return (int)res;
+}
+
+#endif
+
+SZ_RESULT SzDecodeLzma(CCoderInfo *coder, CFileSize inSize,
+ #ifdef _LZMA_IN_CB
+ ISzInStream *inStream,
+ #else
+ const Byte *inBuffer,
+ #endif
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+{
+ #ifdef _LZMA_IN_CB
+ CLzmaInCallbackImp lzmaCallback;
+ #else
+ SizeT inProcessed;
+ #endif
+
+ CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
+ int result;
+ SizeT outSizeProcessedLoc;
+
+ #ifdef _LZMA_IN_CB
+ lzmaCallback.Size = inSize;
+ lzmaCallback.InStream = inStream;
+ lzmaCallback.InCallback.Read = LzmaReadImp;
+ #endif
+
+ if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
+ (unsigned)coder->Properties.Capacity) != LZMA_RESULT_OK)
+ return SZE_FAIL;
+
+ state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return SZE_OUTOFMEMORY;
+
+ #ifdef _LZMA_OUT_READ
+ if (state.Properties.DictionarySize == 0)
+ state.Dictionary = 0;
+ else
+ {
+ state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
+ if (state.Dictionary == 0)
+ {
+ allocMain->Free(state.Probs);
+ return SZE_OUTOFMEMORY;
+ }
+ }
+ LzmaDecoderInit(&state);
+ #endif
+
+ result = LzmaDecode(&state,
+ #ifdef _LZMA_IN_CB
+ &lzmaCallback.InCallback,
+ #else
+ inBuffer, (SizeT)inSize, &inProcessed,
+ #endif
+ outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
+ allocMain->Free(state.Probs);
+ #ifdef _LZMA_OUT_READ
+ allocMain->Free(state.Dictionary);
+ #endif
+ if (result == LZMA_RESULT_DATA_ERROR)
+ return SZE_DATA_ERROR;
+ if (result != LZMA_RESULT_OK)
+ return SZE_FAIL;
+ return (outSizeProcessedLoc == outSize) ? SZ_OK : SZE_DATA_ERROR;
+}
+
+#ifdef _LZMA_IN_CB
+SZ_RESULT SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer)
+{
+ while (inSize > 0)
+ {
+ void *inBuffer;
+ size_t processedSize, curSize = (1 << 18);
+ if (curSize > inSize)
+ curSize = (size_t)(inSize);
+ RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, curSize, &processedSize));
+ if (processedSize == 0)
+ return SZE_DATA_ERROR;
+ if (processedSize > curSize)
+ return SZE_FAIL;
+ memcpy(outBuffer, inBuffer, processedSize);
+ outBuffer += processedSize;
+ inSize -= processedSize;
+ }
+ return SZ_OK;
+}
+#endif
+
+#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
+#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
+
+SZ_RESULT CheckSupportedFolder(const CFolder *f)
+{
+ if (f->NumCoders < 1 || f->NumCoders > 4)
+ return SZE_NOTIMPL;
+ if (IS_UNSUPPORTED_CODER(f->Coders[0]))
+ return SZE_NOTIMPL;
+ if (f->NumCoders == 1)
+ {
+ if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
+ return SZE_NOTIMPL;
+ return SZ_OK;
+ }
+ if (f->NumCoders == 2)
+ {
+ if (IS_NO_BCJ(f->Coders[1]) ||
+ f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
+ f->NumBindPairs != 1 ||
+ f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
+ return SZE_NOTIMPL;
+ return SZ_OK;
+ }
+ if (f->NumCoders == 4)
+ {
+ if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
+ IS_UNSUPPORTED_CODER(f->Coders[2]) ||
+ IS_NO_BCJ2(f->Coders[3]))
+ return SZE_NOTIMPL;
+ if (f->NumPackStreams != 4 ||
+ f->PackStreams[0] != 2 ||
+ f->PackStreams[1] != 6 ||
+ f->PackStreams[2] != 1 ||
+ f->PackStreams[3] != 0 ||
+ f->NumBindPairs != 3 ||
+ f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
+ f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
+ f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
+ return SZE_NOTIMPL;
+ return SZ_OK;
+ }
+ return SZE_NOTIMPL;
+}
+
+CFileSize GetSum(const CFileSize *values, UInt32 index)
+{
+ CFileSize sum = 0;
+ UInt32 i;
+ for (i = 0; i < index; i++)
+ sum += values[i];
+ return sum;
+}
+
+SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
+ #ifdef _LZMA_IN_CB
+ ISzInStream *inStream, CFileSize startPos,
+ #else
+ const Byte *inBuffer,
+ #endif
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain,
+ Byte *tempBuf[])
+{
+ UInt32 ci;
+ size_t tempSizes[3] = { 0, 0, 0};
+ size_t tempSize3 = 0;
+ Byte *tempBuf3 = 0;
+
+ RINOK(CheckSupportedFolder(folder));
+
+ for (ci = 0; ci < folder->NumCoders; ci++)
+ {
+ CCoderInfo *coder = &folder->Coders[ci];
+
+ if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
+ {
+ UInt32 si = 0;
+ CFileSize offset;
+ CFileSize inSize;
+ Byte *outBufCur = outBuffer;
+ size_t outSizeCur = outSize;
+ if (folder->NumCoders == 4)
+ {
+ UInt32 indices[] = { 3, 2, 0 };
+ CFileSize unpackSize = folder->UnPackSizes[ci];
+ si = indices[ci];
+ if (ci < 2)
+ {
+ Byte *temp;
+ outSizeCur = (size_t)unpackSize;
+ if (outSizeCur != unpackSize)
+ return SZE_OUTOFMEMORY;
+ temp = (Byte *)allocMain->Alloc(outSizeCur);
+ if (temp == 0 && outSizeCur != 0)
+ return SZE_OUTOFMEMORY;
+ outBufCur = tempBuf[1 - ci] = temp;
+ tempSizes[1 - ci] = outSizeCur;
+ }
+ else if (ci == 2)
+ {
+ if (unpackSize > outSize)
+ return SZE_OUTOFMEMORY;
+ tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
+ tempSize3 = outSizeCur = (size_t)unpackSize;
+ }
+ else
+ return SZE_NOTIMPL;
+ }
+ offset = GetSum(packSizes, si);
+ inSize = packSizes[si];
+ #ifdef _LZMA_IN_CB
+ RINOK(inStream->Seek(inStream, startPos + offset));
+ #endif
+
+ if (coder->MethodID == k_Copy)
+ {
+ if (inSize != outSizeCur)
+ return SZE_DATA_ERROR;
+
+ #ifdef _LZMA_IN_CB
+ RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
+ #else
+ memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize);
+ #endif
+ }
+ else
+ {
+ SZ_RESULT res = SzDecodeLzma(coder, inSize,
+ #ifdef _LZMA_IN_CB
+ inStream,
+ #else
+ inBuffer + (size_t)offset,
+ #endif
+ outBufCur, outSizeCur, allocMain);
+ RINOK(res)
+ }
+ }
+ else if (coder->MethodID == k_BCJ)
+ {
+ UInt32 state;
+ if (ci != 1)
+ return SZE_NOTIMPL;
+ x86_Convert_Init(state);
+ x86_Convert(outBuffer, outSize, 0, &state, 0);
+ }
+ else if (coder->MethodID == k_BCJ2)
+ {
+ CFileSize offset = GetSum(packSizes, 1);
+ CFileSize s3Size = packSizes[1];
+ SZ_RESULT res;
+ if (ci != 3)
+ return SZE_NOTIMPL;
+
+ #ifdef _LZMA_IN_CB
+ RINOK(inStream->Seek(inStream, startPos + offset));
+ tempSizes[2] = (size_t)s3Size;
+ if (tempSizes[2] != s3Size)
+ return SZE_OUTOFMEMORY;
+ tempBuf[2] = (Byte *)allocMain->Alloc(tempSizes[2]);
+ if (tempBuf[2] == 0 && tempSizes[2] != 0)
+ return SZE_OUTOFMEMORY;
+ res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
+ RINOK(res)
+ #endif
+
+ res = x86_2_Decode(
+ tempBuf3, tempSize3,
+ tempBuf[0], tempSizes[0],
+ tempBuf[1], tempSizes[1],
+ #ifdef _LZMA_IN_CB
+ tempBuf[2], tempSizes[2],
+ #else
+ inBuffer + (size_t)offset, (size_t)s3Size,
+ #endif
+ outBuffer, outSize);
+ RINOK(res)
+ }
+ else
+ return SZE_NOTIMPL;
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
+ #ifdef _LZMA_IN_CB
+ ISzInStream *inStream, CFileSize startPos,
+ #else
+ const Byte *inBuffer,
+ #endif
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+{
+ Byte *tempBuf[3] = { 0, 0, 0};
+ int i;
+ SZ_RESULT res = SzDecode2(packSizes, folder,
+ #ifdef _LZMA_IN_CB
+ inStream, startPos,
+ #else
+ inBuffer,
+ #endif
+ outBuffer, outSize, allocMain, tempBuf);
+ for (i = 0; i < 3; i++)
+ allocMain->Free(tempBuf[i]);
+ return res;
+}
Added: trunk/lzma/C/Archive/7z/7zDecode.h
===================================================================
--- trunk/lzma/C/Archive/7z/7zDecode.h (rev 0)
+++ trunk/lzma/C/Archive/7z/7zDecode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,20 @@
+/* 7zDecode.h */
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "7zItem.h"
+#include "7zAlloc.h"
+#ifdef _LZMA_IN_CB
+#include "7zIn.h"
+#endif
+
+SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
+ #ifdef _LZMA_IN_CB
+ ISzInStream *stream, CFileSize startPos,
+ #else
+ const Byte *inBuffer,
+ #endif
+ Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
+
+#endif
Added: trunk/lzma/C/Archive/7z/7zExtract.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zExtract.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zExtract.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,119 @@
+/* 7zExtract.c */
+
+#include "7zExtract.h"
+#include "7zDecode.h"
+#include "../../7zCrc.h"
+
+SZ_RESULT SzExtract(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ UInt32 fileIndex,
+ UInt32 *blockIndex,
+ Byte **outBuffer,
+ size_t *outBufferSize,
+ size_t *offset,
+ size_t *outSizeProcessed,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
+ SZ_RESULT res = SZ_OK;
+ *offset = 0;
+ *outSizeProcessed = 0;
+ if (folderIndex == (UInt32)-1)
+ {
+ allocMain->Free(*outBuffer);
+ *blockIndex = folderIndex;
+ *outBuffer = 0;
+ *outBufferSize = 0;
+ return SZ_OK;
+ }
+
+ if (*outBuffer == 0 || *blockIndex != folderIndex)
+ {
+ CFolder *folder = db->Database.Folders + folderIndex;
+ CFileSize unPackSizeSpec = SzFolderGetUnPackSize(folder);
+ size_t unPackSize = (size_t)unPackSizeSpec;
+ CFileSize startOffset = SzArDbGetFolderStreamPos(db, folderIndex, 0);
+ #ifndef _LZMA_IN_CB
+ Byte *inBuffer = 0;
+ size_t processedSize;
+ CFileSize packSizeSpec;
+ size_t packSize;
+ RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec));
+ packSize = (size_t)packSizeSpec;
+ if (packSize != packSizeSpec)
+ return SZE_OUTOFMEMORY;
+ #endif
+ if (unPackSize != unPackSizeSpec)
+ return SZE_OUTOFMEMORY;
+ *blockIndex = folderIndex;
+ allocMain->Free(*outBuffer);
+ *outBuffer = 0;
+
+ RINOK(inStream->Seek(inStream, startOffset));
+
+ #ifndef _LZMA_IN_CB
+ if (packSize != 0)
+ {
+ inBuffer = (Byte *)allocTemp->Alloc(packSize);
+ if (inBuffer == 0)
+ return SZE_OUTOFMEMORY;
+ }
+ res = inStream->Read(inStream, inBuffer, packSize, &processedSize);
+ if (res == SZ_OK && processedSize != packSize)
+ res = SZE_FAIL;
+ #endif
+ if (res == SZ_OK)
+ {
+ *outBufferSize = unPackSize;
+ if (unPackSize != 0)
+ {
+ *outBuffer = (Byte *)allocMain->Alloc(unPackSize);
+ if (*outBuffer == 0)
+ res = SZE_OUTOFMEMORY;
+ }
+ if (res == SZ_OK)
+ {
+ res = SzDecode(db->Database.PackSizes +
+ db->FolderStartPackStreamIndex[folderIndex], folder,
+ #ifdef _LZMA_IN_CB
+ inStream, startOffset,
+ #else
+ inBuffer,
+ #endif
+ *outBuffer, unPackSize, allocTemp);
+ if (res == SZ_OK)
+ {
+ if (folder->UnPackCRCDefined)
+ {
+ if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC)
+ res = SZE_CRC_ERROR;
+ }
+ }
+ }
+ }
+ #ifndef _LZMA_IN_CB
+ allocTemp->Free(inBuffer);
+ #endif
+ }
+ if (res == SZ_OK)
+ {
+ UInt32 i;
+ CFileItem *fileItem = db->Database.Files + fileIndex;
+ *offset = 0;
+ for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
+ *offset += (UInt32)db->Database.Files[i].Size;
+ *outSizeProcessed = (size_t)fileItem->Size;
+ if (*offset + *outSizeProcessed > *outBufferSize)
+ return SZE_FAIL;
+ {
+ if (fileItem->IsFileCRCDefined)
+ {
+ if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
+ res = SZE_CRC_ERROR;
+ }
+ }
+ }
+ return res;
+}
Added: trunk/lzma/C/Archive/7z/7zExtract.h
===================================================================
--- trunk/lzma/C/Archive/7z/7zExtract.h (rev 0)
+++ trunk/lzma/C/Archive/7z/7zExtract.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,40 @@
+/* 7zExtract.h */
+
+#ifndef __7Z_EXTRACT_H
+#define __7Z_EXTRACT_H
+
+#include "7zIn.h"
+
+/*
+ SzExtract extracts file from archive
+
+ *outBuffer must be 0 before first call for each new archive.
+
+ Extracting cache:
+ If you need to decompress more than one file, you can send
+ these values from previous call:
+ *blockIndex,
+ *outBuffer,
+ *outBufferSize
+ You can consider "*outBuffer" as cache of solid block. If your archive is solid,
+ it will increase decompression speed.
+
+ If you use external function, you can declare these 3 cache variables
+ (blockIndex, outBuffer, outBufferSize) as static in that external function.
+
+ Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
+*/
+
+SZ_RESULT SzExtract(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ UInt32 fileIndex, /* index of file */
+ UInt32 *blockIndex, /* index of solid block */
+ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
+ size_t *outBufferSize, /* buffer size for output buffer */
+ size_t *offset, /* offset of stream for required file in *outBuffer */
+ size_t *outSizeProcessed, /* size of file in *outBuffer */
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp);
+
+#endif
Added: trunk/lzma/C/Archive/7z/7zHeader.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zHeader.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zHeader.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,5 @@
+/* 7zHeader.c */
+
+#include "7zHeader.h"
+
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
Added: trunk/lzma/C/Archive/7z/7zHeader.h
===================================================================
--- trunk/lzma/C/Archive/7z/7zHeader.h (rev 0)
+++ trunk/lzma/C/Archive/7z/7zHeader.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,55 @@
+/* 7zHeader.h */
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+#include "../../Types.h"
+
+#define k7zSignatureSize 6
+extern Byte k7zSignature[k7zSignatureSize];
+
+#define k7zMajorVersion 0
+
+#define k7zStartHeaderSize 0x20
+
+enum EIdEnum
+{
+ k7zIdEnd,
+
+ k7zIdHeader,
+
+ k7zIdArchiveProperties,
+
+ k7zIdAdditionalStreamsInfo,
+ k7zIdMainStreamsInfo,
+ k7zIdFilesInfo,
+
+ k7zIdPackInfo,
+ k7zIdUnPackInfo,
+ k7zIdSubStreamsInfo,
+
+ k7zIdSize,
+ k7zIdCRC,
+
+ k7zIdFolder,
+
+ k7zIdCodersUnPackSize,
+ k7zIdNumUnPackStream,
+
+ k7zIdEmptyStream,
+ k7zIdEmptyFile,
+ k7zIdAnti,
+
+ k7zIdName,
+ k7zIdCreationTime,
+ k7zIdLastAccessTime,
+ k7zIdLastWriteTime,
+ k7zIdWinAttributes,
+ k7zIdComment,
+
+ k7zIdEncodedHeader,
+
+ k7zIdStartPos
+};
+
+#endif
Added: trunk/lzma/C/Archive/7z/7zIn.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zIn.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zIn.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1314 @@
+/* 7zIn.c */
+
+#include "7zIn.h"
+#include "7zDecode.h"
+#include "../../7zCrc.h"
+
+#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; }
+
+void SzArDbExInit(CArchiveDatabaseEx *db)
+{
+ SzArchiveDatabaseInit(&db->Database);
+ db->FolderStartPackStreamIndex = 0;
+ db->PackStreamStartPositions = 0;
+ db->FolderStartFileIndex = 0;
+ db->FileIndexToFolderIndexMap = 0;
+}
+
+void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *))
+{
+ freeFunc(db->FolderStartPackStreamIndex);
+ freeFunc(db->PackStreamStartPositions);
+ freeFunc(db->FolderStartFileIndex);
+ freeFunc(db->FileIndexToFolderIndexMap);
+ SzArchiveDatabaseFree(&db->Database, freeFunc);
+ SzArDbExInit(db);
+}
+
+/*
+CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+{
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+}
+
+CFileSize GetFilePackSize(int fileIndex) const
+{
+ int folderIndex = FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex >= 0)
+ {
+ const CFolder &folderInfo = Folders[folderIndex];
+ if (FolderStartFileIndex[folderIndex] == fileIndex)
+ return GetFolderFullPackSize(folderIndex);
+ }
+ return 0;
+}
+*/
+
+#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \
+ if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; }
+
+SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
+{
+ UInt32 startPos = 0;
+ CFileSize startPosSize = 0;
+ UInt32 i;
+ UInt32 folderIndex = 0;
+ UInt32 indexInFolder = 0;
+ MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc);
+ for(i = 0; i < db->Database.NumFolders; i++)
+ {
+ db->FolderStartPackStreamIndex[i] = startPos;
+ startPos += db->Database.Folders[i].NumPackStreams;
+ }
+
+ MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc);
+
+ for(i = 0; i < db->Database.NumPackStreams; i++)
+ {
+ db->PackStreamStartPositions[i] = startPosSize;
+ startPosSize += db->Database.PackSizes[i];
+ }
+
+ MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc);
+ MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc);
+
+ for (i = 0; i < db->Database.NumFiles; i++)
+ {
+ CFileItem *file = db->Database.Files + i;
+ int emptyStream = !file->HasStream;
+ if (emptyStream && indexInFolder == 0)
+ {
+ db->FileIndexToFolderIndexMap[i] = (UInt32)-1;
+ continue;
+ }
+ if (indexInFolder == 0)
+ {
+ /*
+ v3.13 incorrectly worked with empty folders
+ v4.07: Loop for skipping empty folders
+ */
+ for (;;)
+ {
+ if (folderIndex >= db->Database.NumFolders)
+ return SZE_ARCHIVE_ERROR;
+ db->FolderStartFileIndex[folderIndex] = i;
+ if (db->Database.Folders[folderIndex].NumUnPackStreams != 0)
+ break;
+ folderIndex++;
+ }
+ }
+ db->FileIndexToFolderIndexMap[i] = folderIndex;
+ if (emptyStream)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams)
+ {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+ return SZ_OK;
+}
+
+
+CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder)
+{
+ return db->ArchiveInfo.DataStartPosition +
+ db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+}
+
+int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize)
+{
+ UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex];
+ CFolder *folder = db->Database.Folders + folderIndex;
+ CFileSize size = 0;
+ UInt32 i;
+ for (i = 0; i < folder->NumPackStreams; i++)
+ {
+ CFileSize t = size + db->Database.PackSizes[packStreamIndex + i];
+ if (t < size)
+ return SZE_FAIL;
+ size = t;
+ }
+ *resSize = size;
+ return SZ_OK;
+}
+
+
+/*
+SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt64 type)
+{
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+
+ for(int i = 0; i < files.Size(); i++)
+ {
+ CFileItem &file = files[i];
+ CArchiveFileTime fileTime;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ UInt32 low, high;
+ RINOK(SzReadUInt32(low));
+ RINOK(SzReadUInt32(high));
+ fileTime.dwLowDateTime = low;
+ fileTime.dwHighDateTime = high;
+ }
+ switch(type)
+ {
+ case k7zIdCreationTime:
+ file.IsCreationTimeDefined = defined;
+ if (defined)
+ file.CreationTime = fileTime;
+ break;
+ case k7zIdLastWriteTime:
+ file.IsLastWriteTimeDefined = defined;
+ if (defined)
+ file.LastWriteTime = fileTime;
+ break;
+ case k7zIdLastAccessTime:
+ file.IsLastAccessTimeDefined = defined;
+ if (defined)
+ file.LastAccessTime = fileTime;
+ break;
+ }
+ }
+ return SZ_OK;
+}
+*/
+
+SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
+{
+ #ifdef _LZMA_IN_CB
+ while (size > 0)
+ {
+ void *inBufferSpec;
+ size_t processedSize;
+ const Byte *inBuffer;
+ RINOK(inStream->Read(inStream, (void **)&inBufferSpec, size, &processedSize));
+ inBuffer = (const Byte *)inBufferSpec;
+ if (processedSize == 0 || processedSize > size)
+ return SZE_FAIL;
+ size -= processedSize;
+ do
+ {
+ *data++ = *inBuffer++;
+ }
+ while (--processedSize != 0);
+ }
+ #else
+ size_t processedSize;
+ RINOK(inStream->Read(inStream, data, size, &processedSize));
+ if (processedSize != size)
+ return SZE_FAIL;
+ #endif
+ return SZ_OK;
+}
+
+SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data)
+{
+ return SafeReadDirect(inStream, data, 1);
+}
+
+SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value, UInt32 *crc)
+{
+ int i;
+ *value = 0;
+ for (i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(inStream, &b));
+ *value |= ((UInt32)b << (8 * i));
+ *crc = CRC_UPDATE_BYTE(*crc, b);
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value, UInt32 *crc)
+{
+ int i;
+ *value = 0;
+ for (i = 0; i < 8; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(inStream, &b));
+ *value |= ((UInt64)b << (8 * i));
+ *crc = CRC_UPDATE_BYTE(*crc, b);
+ }
+ return SZ_OK;
+}
+
+int TestSignatureCandidate(Byte *testBytes)
+{
+ size_t i;
+ for (i = 0; i < k7zSignatureSize; i++)
+ if (testBytes[i] != k7zSignature[i])
+ return 0;
+ return 1;
+}
+
+typedef struct _CSzState
+{
+ Byte *Data;
+ size_t Size;
+}CSzData;
+
+SZ_RESULT SzReadByte(CSzData *sd, Byte *b)
+{
+ if (sd->Size == 0)
+ return SZE_ARCHIVE_ERROR;
+ sd->Size--;
+ *b = *sd->Data++;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size)
+{
+ size_t i;
+ for (i = 0; i < size; i++)
+ {
+ RINOK(SzReadByte(sd, data + i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value)
+{
+ int i;
+ *value = 0;
+ for (i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SzReadByte(sd, &b));
+ *value |= ((UInt32)(b) << (8 * i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value)
+{
+ Byte firstByte;
+ Byte mask = 0x80;
+ int i;
+ RINOK(SzReadByte(sd, &firstByte));
+ *value = 0;
+ for (i = 0; i < 8; i++)
+ {
+ Byte b;
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = firstByte & (mask - 1);
+ *value += (highPart << (8 * i));
+ return SZ_OK;
+ }
+ RINOK(SzReadByte(sd, &b));
+ *value |= ((UInt64)b << (8 * i));
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value)
+{
+ UInt64 value64;
+ RINOK(SzReadNumber(sd, &value64));
+ *value = (CFileSize)value64;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value)
+{
+ UInt64 value64;
+ RINOK(SzReadNumber(sd, &value64));
+ if (value64 >= 0x80000000)
+ return SZE_NOTIMPL;
+ if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
+ return SZE_NOTIMPL;
+ *value = (UInt32)value64;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadID(CSzData *sd, UInt64 *value)
+{
+ return SzReadNumber(sd, value);
+}
+
+SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size)
+{
+ if (size > sd->Size)
+ return SZE_ARCHIVE_ERROR;
+ sd->Size -= (size_t)size;
+ sd->Data += (size_t)size;
+ return SZ_OK;
+}
+
+SZ_RESULT SzSkeepData(CSzData *sd)
+{
+ UInt64 size;
+ RINOK(SzReadNumber(sd, &size));
+ return SzSkeepDataSize(sd, size);
+}
+
+SZ_RESULT SzReadArchiveProperties(CSzData *sd)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ SzSkeepData(sd);
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == attribute)
+ return SZ_OK;
+ if (type == k7zIdEnd)
+ return SZE_ARCHIVE_ERROR;
+ RINOK(SzSkeepData(sd));
+ }
+}
+
+SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
+{
+ Byte b = 0;
+ Byte mask = 0;
+ size_t i;
+ MY_ALLOC(Byte, *v, numItems, allocFunc);
+ for (i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ RINOK(SzReadByte(sd, &b));
+ mask = 0x80;
+ }
+ (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
+ mask >>= 1;
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
+{
+ Byte allAreDefined;
+ size_t i;
+ RINOK(SzReadByte(sd, &allAreDefined));
+ if (allAreDefined == 0)
+ return SzReadBoolVector(sd, numItems, v, allocFunc);
+ MY_ALLOC(Byte, *v, numItems, allocFunc);
+ for(i = 0; i < numItems; i++)
+ (*v)[i] = 1;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadHashDigests(
+ CSzData *sd,
+ size_t numItems,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ void * (*allocFunc)(size_t size))
+{
+ size_t i;
+ RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
+ MY_ALLOC(UInt32, *digests, numItems, allocFunc);
+ for(i = 0; i < numItems; i++)
+ if ((*digestsDefined)[i])
+ {
+ RINOK(SzReadUInt32(sd, (*digests) + i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadPackInfo(
+ CSzData *sd,
+ CFileSize *dataOffset,
+ UInt32 *numPackStreams,
+ CFileSize **packSizes,
+ Byte **packCRCsDefined,
+ UInt32 **packCRCs,
+ void * (*allocFunc)(size_t size))
+{
+ UInt32 i;
+ RINOK(SzReadSize(sd, dataOffset));
+ RINOK(SzReadNumber32(sd, numPackStreams));
+
+ RINOK(SzWaitAttribute(sd, k7zIdSize));
+
+ MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc);
+
+ for(i = 0; i < *numPackStreams; i++)
+ {
+ RINOK(SzReadSize(sd, (*packSizes) + i));
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ if (type == k7zIdCRC)
+ {
+ RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc));
+ continue;
+ }
+ RINOK(SzSkeepData(sd));
+ }
+ if (*packCRCsDefined == 0)
+ {
+ MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc);
+ MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc);
+ for(i = 0; i < *numPackStreams; i++)
+ {
+ (*packCRCsDefined)[i] = 0;
+ (*packCRCs)[i] = 0;
+ }
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadSwitch(CSzData *sd)
+{
+ Byte external;
+ RINOK(SzReadByte(sd, &external));
+ return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR;
+}
+
+SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size))
+{
+ UInt32 numCoders;
+ UInt32 numBindPairs;
+ UInt32 numPackedStreams;
+ UInt32 i;
+ UInt32 numInStreams = 0;
+ UInt32 numOutStreams = 0;
+ RINOK(SzReadNumber32(sd, &numCoders));
+ folder->NumCoders = numCoders;
+
+ MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc);
+
+ for (i = 0; i < numCoders; i++)
+ SzCoderInfoInit(folder->Coders + i);
+
+ for (i = 0; i < numCoders; i++)
+ {
+ Byte mainByte;
+ CCoderInfo *coder = folder->Coders + i;
+ {
+ unsigned idSize, j;
+ Byte longID[15];
+ RINOK(SzReadByte(sd, &mainByte));
+ idSize = (unsigned)(mainByte & 0xF);
+ RINOK(SzReadBytes(sd, longID, idSize));
+ if (idSize > sizeof(coder->MethodID))
+ return SZE_NOTIMPL;
+ coder->MethodID = 0;
+ for (j = 0; j < idSize; j++)
+ coder->MethodID |= (CMethodID)longID[idSize - 1 - j] << (8 * j);
+
+ if ((mainByte & 0x10) != 0)
+ {
+ RINOK(SzReadNumber32(sd, &coder->NumInStreams));
+ RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
+ }
+ else
+ {
+ coder->NumInStreams = 1;
+ coder->NumOutStreams = 1;
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt64 propertiesSize = 0;
+ RINOK(SzReadNumber(sd, &propertiesSize));
+ if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc))
+ return SZE_OUTOFMEMORY;
+ RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize));
+ }
+ }
+ while ((mainByte & 0x80) != 0)
+ {
+ RINOK(SzReadByte(sd, &mainByte));
+ RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
+ if ((mainByte & 0x10) != 0)
+ {
+ UInt32 n;
+ RINOK(SzReadNumber32(sd, &n));
+ RINOK(SzReadNumber32(sd, &n));
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ UInt64 propertiesSize = 0;
+ RINOK(SzReadNumber(sd, &propertiesSize));
+ RINOK(SzSkeepDataSize(sd, propertiesSize));
+ }
+ }
+ numInStreams += (UInt32)coder->NumInStreams;
+ numOutStreams += (UInt32)coder->NumOutStreams;
+ }
+
+ numBindPairs = numOutStreams - 1;
+ folder->NumBindPairs = numBindPairs;
+
+
+ MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc);
+
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CBindPair *bindPair = folder->BindPairs + i;;
+ RINOK(SzReadNumber32(sd, &bindPair->InIndex));
+ RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
+ }
+
+ numPackedStreams = numInStreams - (UInt32)numBindPairs;
+
+ folder->NumPackStreams = numPackedStreams;
+ MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc);
+
+ if (numPackedStreams == 1)
+ {
+ UInt32 j;
+ UInt32 pi = 0;
+ for (j = 0; j < numInStreams; j++)
+ if (SzFolderFindBindPairForInStream(folder, j) < 0)
+ {
+ folder->PackStreams[pi++] = j;
+ break;
+ }
+ }
+ else
+ for(i = 0; i < numPackedStreams; i++)
+ {
+ RINOK(SzReadNumber32(sd, folder->PackStreams + i));
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadUnPackInfo(
+ CSzData *sd,
+ UInt32 *numFolders,
+ CFolder **folders, /* for allocFunc */
+ void * (*allocFunc)(size_t size),
+ ISzAlloc *allocTemp)
+{
+ UInt32 i;
+ RINOK(SzWaitAttribute(sd, k7zIdFolder));
+ RINOK(SzReadNumber32(sd, numFolders));
+ {
+ RINOK(SzReadSwitch(sd));
+
+ MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc);
+
+ for(i = 0; i < *numFolders; i++)
+ SzFolderInit((*folders) + i);
+
+ for(i = 0; i < *numFolders; i++)
+ {
+ RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc));
+ }
+ }
+
+ RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize));
+
+ for(i = 0; i < *numFolders; i++)
+ {
+ UInt32 j;
+ CFolder *folder = (*folders) + i;
+ UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
+
+ MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc);
+
+ for(j = 0; j < numOutStreams; j++)
+ {
+ RINOK(SzReadSize(sd, folder->UnPackSizes + j));
+ }
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type == k7zIdCRC)
+ {
+ SZ_RESULT res;
+ Byte *crcsDefined = 0;
+ UInt32 *crcs = 0;
+ res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
+ if (res == SZ_OK)
+ {
+ for(i = 0; i < *numFolders; i++)
+ {
+ CFolder *folder = (*folders) + i;
+ folder->UnPackCRCDefined = crcsDefined[i];
+ folder->UnPackCRC = crcs[i];
+ }
+ }
+ allocTemp->Free(crcs);
+ allocTemp->Free(crcsDefined);
+ RINOK(res);
+ continue;
+ }
+ RINOK(SzSkeepData(sd));
+ }
+}
+
+SZ_RESULT SzReadSubStreamsInfo(
+ CSzData *sd,
+ UInt32 numFolders,
+ CFolder *folders,
+ UInt32 *numUnPackStreams,
+ CFileSize **unPackSizes,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ ISzAlloc *allocTemp)
+{
+ UInt64 type = 0;
+ UInt32 i;
+ UInt32 si = 0;
+ UInt32 numDigests = 0;
+
+ for(i = 0; i < numFolders; i++)
+ folders[i].NumUnPackStreams = 1;
+ *numUnPackStreams = numFolders;
+
+ for (;;)
+ {
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdNumUnPackStream)
+ {
+ *numUnPackStreams = 0;
+ for(i = 0; i < numFolders; i++)
+ {
+ UInt32 numStreams;
+ RINOK(SzReadNumber32(sd, &numStreams));
+ folders[i].NumUnPackStreams = numStreams;
+ *numUnPackStreams += numStreams;
+ }
+ continue;
+ }
+ if (type == k7zIdCRC || type == k7zIdSize)
+ break;
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SzSkeepData(sd));
+ }
+
+ if (*numUnPackStreams == 0)
+ {
+ *unPackSizes = 0;
+ *digestsDefined = 0;
+ *digests = 0;
+ }
+ else
+ {
+ *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize));
+ RINOM(*unPackSizes);
+ *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte));
+ RINOM(*digestsDefined);
+ *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32));
+ RINOM(*digests);
+ }
+
+ for(i = 0; i < numFolders; i++)
+ {
+ /*
+ v3.13 incorrectly worked with empty folders
+ v4.07: we check that folder is empty
+ */
+ CFileSize sum = 0;
+ UInt32 j;
+ UInt32 numSubstreams = folders[i].NumUnPackStreams;
+ if (numSubstreams == 0)
+ continue;
+ if (type == k7zIdSize)
+ for (j = 1; j < numSubstreams; j++)
+ {
+ CFileSize size;
+ RINOK(SzReadSize(sd, &size));
+ (*unPackSizes)[si++] = size;
+ sum += size;
+ }
+ (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum;
+ }
+ if (type == k7zIdSize)
+ {
+ RINOK(SzReadID(sd, &type));
+ }
+
+ for(i = 0; i < *numUnPackStreams; i++)
+ {
+ (*digestsDefined)[i] = 0;
+ (*digests)[i] = 0;
+ }
+
+
+ for(i = 0; i < numFolders; i++)
+ {
+ UInt32 numSubstreams = folders[i].NumUnPackStreams;
+ if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
+ numDigests += numSubstreams;
+ }
+
+
+ si = 0;
+ for (;;)
+ {
+ if (type == k7zIdCRC)
+ {
+ int digestIndex = 0;
+ Byte *digestsDefined2 = 0;
+ UInt32 *digests2 = 0;
+ SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
+ if (res == SZ_OK)
+ {
+ for (i = 0; i < numFolders; i++)
+ {
+ CFolder *folder = folders + i;
+ UInt32 numSubstreams = folder->NumUnPackStreams;
+ if (numSubstreams == 1 && folder->UnPackCRCDefined)
+ {
+ (*digestsDefined)[si] = 1;
+ (*digests)[si] = folder->UnPackCRC;
+ si++;
+ }
+ else
+ {
+ UInt32 j;
+ for (j = 0; j < numSubstreams; j++, digestIndex++)
+ {
+ (*digestsDefined)[si] = digestsDefined2[digestIndex];
+ (*digests)[si] = digests2[digestIndex];
+ si++;
+ }
+ }
+ }
+ }
+ allocTemp->Free(digestsDefined2);
+ allocTemp->Free(digests2);
+ RINOK(res);
+ }
+ else if (type == k7zIdEnd)
+ return SZ_OK;
+ else
+ {
+ RINOK(SzSkeepData(sd));
+ }
+ RINOK(SzReadID(sd, &type));
+ }
+}
+
+
+SZ_RESULT SzReadStreamsInfo(
+ CSzData *sd,
+ CFileSize *dataOffset,
+ CArchiveDatabase *db,
+ UInt32 *numUnPackStreams,
+ CFileSize **unPackSizes, /* allocTemp */
+ Byte **digestsDefined, /* allocTemp */
+ UInt32 **digests, /* allocTemp */
+ void * (*allocFunc)(size_t size),
+ ISzAlloc *allocTemp)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(SzReadID(sd, &type));
+ if ((UInt64)(int)type != type)
+ return SZE_FAIL;
+ switch((int)type)
+ {
+ case k7zIdEnd:
+ return SZ_OK;
+ case k7zIdPackInfo:
+ {
+ RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams,
+ &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc));
+ break;
+ }
+ case k7zIdUnPackInfo:
+ {
+ RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp));
+ break;
+ }
+ case k7zIdSubStreamsInfo:
+ {
+ RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
+ numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
+ break;
+ }
+ default:
+ return SZE_FAIL;
+ }
+ }
+}
+
+Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
+ void * (*allocFunc)(size_t size))
+{
+ UInt32 i;
+ for(i = 0; i < numFiles; i++)
+ {
+ UInt32 len = 0;
+ UInt32 pos = 0;
+ CFileItem *file = files + i;
+ while(pos + 2 <= sd->Size)
+ {
+ int numAdds;
+ UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+ pos += 2;
+ len++;
+ if (value == 0)
+ break;
+ if (value < 0x80)
+ continue;
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ UInt32 c2;
+ if (value >= 0xDC00)
+ return SZE_ARCHIVE_ERROR;
+ if (pos + 2 > sd->Size)
+ return SZE_ARCHIVE_ERROR;
+ c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+ pos += 2;
+ if (c2 < 0xDC00 || c2 >= 0xE000)
+ return SZE_ARCHIVE_ERROR;
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ len += numAdds;
+ }
+
+ MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
+
+ len = 0;
+ while(2 <= sd->Size)
+ {
+ int numAdds;
+ UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+ SzSkeepDataSize(sd, 2);
+ if (value < 0x80)
+ {
+ file->Name[len++] = (char)value;
+ if (value == 0)
+ break;
+ continue;
+ }
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+ SzSkeepDataSize(sd, 2);
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+ do
+ {
+ numAdds--;
+ file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+ }
+ while(numAdds > 0);
+
+ len += numAdds;
+ }
+ }
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadHeader2(
+ CSzData *sd,
+ CArchiveDatabaseEx *db, /* allocMain */
+ CFileSize **unPackSizes, /* allocTemp */
+ Byte **digestsDefined, /* allocTemp */
+ UInt32 **digests, /* allocTemp */
+ Byte **emptyStreamVector, /* allocTemp */
+ Byte **emptyFileVector, /* allocTemp */
+ Byte **lwtVector, /* allocTemp */
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ UInt64 type;
+ UInt32 numUnPackStreams = 0;
+ UInt32 numFiles = 0;
+ CFileItem *files = 0;
+ UInt32 numEmptyStreams = 0;
+ UInt32 i;
+
+ RINOK(SzReadID(sd, &type));
+
+ if (type == k7zIdArchiveProperties)
+ {
+ RINOK(SzReadArchiveProperties(sd));
+ RINOK(SzReadID(sd, &type));
+ }
+
+
+ if (type == k7zIdMainStreamsInfo)
+ {
+ RINOK(SzReadStreamsInfo(sd,
+ &db->ArchiveInfo.DataStartPosition,
+ &db->Database,
+ &numUnPackStreams,
+ unPackSizes,
+ digestsDefined,
+ digests, allocMain->Alloc, allocTemp));
+ db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
+ RINOK(SzReadID(sd, &type));
+ }
+
+ if (type == k7zIdEnd)
+ return SZ_OK;
+ if (type != k7zIdFilesInfo)
+ return SZE_ARCHIVE_ERROR;
+
+ RINOK(SzReadNumber32(sd, &numFiles));
+ db->Database.NumFiles = numFiles;
+
+ MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
+
+ db->Database.Files = files;
+ for(i = 0; i < numFiles; i++)
+ SzFileInit(files + i);
+
+ for (;;)
+ {
+ UInt64 type;
+ UInt64 size;
+ RINOK(SzReadID(sd, &type));
+ if (type == k7zIdEnd)
+ break;
+ RINOK(SzReadNumber(sd, &size));
+
+ if ((UInt64)(int)type != type)
+ {
+ RINOK(SzSkeepDataSize(sd, size));
+ }
+ else
+ switch((int)type)
+ {
+ case k7zIdName:
+ {
+ RINOK(SzReadSwitch(sd));
+ RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc))
+ break;
+ }
+ case k7zIdEmptyStream:
+ {
+ RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
+ numEmptyStreams = 0;
+ for (i = 0; i < numFiles; i++)
+ if ((*emptyStreamVector)[i])
+ numEmptyStreams++;
+ break;
+ }
+ case k7zIdEmptyFile:
+ {
+ RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
+ break;
+ }
+ case k7zIdLastWriteTime:
+ {
+ RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp->Alloc));
+ RINOK(SzReadSwitch(sd));
+ for (i = 0; i < numFiles; i++)
+ {
+ CFileItem *f = &files[i];
+ Byte defined = (*lwtVector)[i];
+ f->IsLastWriteTimeDefined = defined;
+ f->LastWriteTime.Low = f->LastWriteTime.High = 0;
+ if (defined)
+ {
+ RINOK(SzReadUInt32(sd, &f->LastWriteTime.Low));
+ RINOK(SzReadUInt32(sd, &f->LastWriteTime.High));
+ }
+ }
+ break;
+ }
+ default:
+ {
+ RINOK(SzSkeepDataSize(sd, size));
+ }
+ }
+ }
+
+ {
+ UInt32 emptyFileIndex = 0;
+ UInt32 sizeIndex = 0;
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem *file = files + i;
+ file->IsAnti = 0;
+ if (*emptyStreamVector == 0)
+ file->HasStream = 1;
+ else
+ file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
+ if(file->HasStream)
+ {
+ file->IsDirectory = 0;
+ file->Size = (*unPackSizes)[sizeIndex];
+ file->FileCRC = (*digests)[sizeIndex];
+ file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
+ sizeIndex++;
+ }
+ else
+ {
+ if (*emptyFileVector == 0)
+ file->IsDirectory = 1;
+ else
+ file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
+ emptyFileIndex++;
+ file->Size = 0;
+ file->IsFileCRCDefined = 0;
+ }
+ }
+ }
+ return SzArDbExFill(db, allocMain->Alloc);
+}
+
+SZ_RESULT SzReadHeader(
+ CSzData *sd,
+ CArchiveDatabaseEx *db,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ CFileSize *unPackSizes = 0;
+ Byte *digestsDefined = 0;
+ UInt32 *digests = 0;
+ Byte *emptyStreamVector = 0;
+ Byte *emptyFileVector = 0;
+ Byte *lwtVector = 0;
+ SZ_RESULT res = SzReadHeader2(sd, db,
+ &unPackSizes, &digestsDefined, &digests,
+ &emptyStreamVector, &emptyFileVector, &lwtVector,
+ allocMain, allocTemp);
+ allocTemp->Free(unPackSizes);
+ allocTemp->Free(digestsDefined);
+ allocTemp->Free(digests);
+ allocTemp->Free(emptyStreamVector);
+ allocTemp->Free(emptyFileVector);
+ allocTemp->Free(lwtVector);
+ return res;
+}
+
+SZ_RESULT SzReadAndDecodePackedStreams2(
+ ISzInStream *inStream,
+ CSzData *sd,
+ CSzByteBuffer *outBuffer,
+ CFileSize baseOffset,
+ CArchiveDatabase *db,
+ CFileSize **unPackSizes,
+ Byte **digestsDefined,
+ UInt32 **digests,
+ #ifndef _LZMA_IN_CB
+ Byte **inBuffer,
+ #endif
+ ISzAlloc *allocTemp)
+{
+
+ UInt32 numUnPackStreams = 0;
+ CFileSize dataStartPos;
+ CFolder *folder;
+ #ifndef _LZMA_IN_CB
+ CFileSize packSize = 0;
+ UInt32 i = 0;
+ #endif
+ CFileSize unPackSize;
+ SZ_RESULT res;
+
+ RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
+ &numUnPackStreams, unPackSizes, digestsDefined, digests,
+ allocTemp->Alloc, allocTemp));
+
+ dataStartPos += baseOffset;
+ if (db->NumFolders != 1)
+ return SZE_ARCHIVE_ERROR;
+
+ folder = db->Folders;
+ unPackSize = SzFolderGetUnPackSize(folder);
+
+ RINOK(inStream->Seek(inStream, dataStartPos));
+
+ #ifndef _LZMA_IN_CB
+ for (i = 0; i < db->NumPackStreams; i++)
+ packSize += db->PackSizes[i];
+
+ MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
+
+ RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
+ #endif
+
+ if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
+ return SZE_OUTOFMEMORY;
+
+ res = SzDecode(db->PackSizes, folder,
+ #ifdef _LZMA_IN_CB
+ inStream, dataStartPos,
+ #else
+ *inBuffer,
+ #endif
+ outBuffer->Items, (size_t)unPackSize, allocTemp);
+ RINOK(res)
+ if (folder->UnPackCRCDefined)
+ if (CrcCalc(outBuffer->Items, (size_t)unPackSize) != folder->UnPackCRC)
+ return SZE_FAIL;
+ return SZ_OK;
+}
+
+SZ_RESULT SzReadAndDecodePackedStreams(
+ ISzInStream *inStream,
+ CSzData *sd,
+ CSzByteBuffer *outBuffer,
+ CFileSize baseOffset,
+ ISzAlloc *allocTemp)
+{
+ CArchiveDatabase db;
+ CFileSize *unPackSizes = 0;
+ Byte *digestsDefined = 0;
+ UInt32 *digests = 0;
+ #ifndef _LZMA_IN_CB
+ Byte *inBuffer = 0;
+ #endif
+ SZ_RESULT res;
+ SzArchiveDatabaseInit(&db);
+ res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
+ &db, &unPackSizes, &digestsDefined, &digests,
+ #ifndef _LZMA_IN_CB
+ &inBuffer,
+ #endif
+ allocTemp);
+ SzArchiveDatabaseFree(&db, allocTemp->Free);
+ allocTemp->Free(unPackSizes);
+ allocTemp->Free(digestsDefined);
+ allocTemp->Free(digests);
+ #ifndef _LZMA_IN_CB
+ allocTemp->Free(inBuffer);
+ #endif
+ return res;
+}
+
+SZ_RESULT SzArchiveOpen2(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ Byte signature[k7zSignatureSize];
+ Byte version;
+ UInt32 crcFromArchive;
+ UInt64 nextHeaderOffset;
+ UInt64 nextHeaderSize;
+ UInt32 nextHeaderCRC;
+ UInt32 crc = 0;
+ CFileSize pos = 0;
+ CSzByteBuffer buffer;
+ CSzData sd;
+ SZ_RESULT res;
+
+ RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize));
+
+ if (!TestSignatureCandidate(signature))
+ return SZE_ARCHIVE_ERROR;
+
+ /*
+ db.Clear();
+ db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+ */
+ RINOK(SafeReadDirectByte(inStream, &version));
+ if (version != k7zMajorVersion)
+ return SZE_ARCHIVE_ERROR;
+ RINOK(SafeReadDirectByte(inStream, &version));
+
+ RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive, &crc));
+
+ crc = CRC_INIT_VAL;
+ RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset, &crc));
+ RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize, &crc));
+ RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC, &crc));
+
+ pos = k7zStartHeaderSize;
+ db->ArchiveInfo.StartPositionAfterHeader = pos;
+
+ if (CRC_GET_DIGEST(crc) != crcFromArchive)
+ return SZE_ARCHIVE_ERROR;
+
+ if (nextHeaderSize == 0)
+ return SZ_OK;
+
+ RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset)));
+
+ if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc))
+ return SZE_OUTOFMEMORY;
+
+ res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
+ if (res == SZ_OK)
+ {
+ res = SZE_ARCHIVE_ERROR;
+ if (CrcCalc(buffer.Items, (UInt32)nextHeaderSize) == nextHeaderCRC)
+ {
+ for (;;)
+ {
+ UInt64 type;
+ sd.Data = buffer.Items;
+ sd.Size = buffer.Capacity;
+ res = SzReadID(&sd, &type);
+ if (res != SZ_OK)
+ break;
+ if (type == k7zIdHeader)
+ {
+ res = SzReadHeader(&sd, db, allocMain, allocTemp);
+ break;
+ }
+ if (type != k7zIdEncodedHeader)
+ {
+ res = SZE_ARCHIVE_ERROR;
+ break;
+ }
+ {
+ CSzByteBuffer outBuffer;
+ res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
+ db->ArchiveInfo.StartPositionAfterHeader,
+ allocTemp);
+ if (res != SZ_OK)
+ {
+ SzByteBufferFree(&outBuffer, allocTemp->Free);
+ break;
+ }
+ SzByteBufferFree(&buffer, allocTemp->Free);
+ buffer.Items = outBuffer.Items;
+ buffer.Capacity = outBuffer.Capacity;
+ }
+ }
+ }
+ }
+ SzByteBufferFree(&buffer, allocTemp->Free);
+ return res;
+}
+
+SZ_RESULT SzArchiveOpen(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
+{
+ SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);
+ if (res != SZ_OK)
+ SzArDbExFree(db, allocMain->Free);
+ return res;
+}
Added: trunk/lzma/C/Archive/7z/7zIn.h
===================================================================
--- trunk/lzma/C/Archive/7z/7zIn.h (rev 0)
+++ trunk/lzma/C/Archive/7z/7zIn.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,55 @@
+/* 7zIn.h */
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "7zHeader.h"
+#include "7zItem.h"
+#include "7zAlloc.h"
+
+typedef struct _CInArchiveInfo
+{
+ CFileSize StartPositionAfterHeader;
+ CFileSize DataStartPosition;
+}CInArchiveInfo;
+
+typedef struct _CArchiveDatabaseEx
+{
+ CArchiveDatabase Database;
+ CInArchiveInfo ArchiveInfo;
+ UInt32 *FolderStartPackStreamIndex;
+ CFileSize *PackStreamStartPositions;
+ UInt32 *FolderStartFileIndex;
+ UInt32 *FileIndexToFolderIndexMap;
+}CArchiveDatabaseEx;
+
+void SzArDbExInit(CArchiveDatabaseEx *db);
+void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
+CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
+int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize);
+
+typedef struct _ISzInStream
+{
+ #ifdef _LZMA_IN_CB
+ SZ_RESULT (*Read)(
+ void *object, /* pointer to ISzInStream itself */
+ void **buffer, /* out: pointer to buffer with data */
+ size_t maxRequiredSize, /* max required size to read */
+ size_t *processedSize); /* real processed size.
+ processedSize can be less than maxRequiredSize.
+ If processedSize == 0, then there are no more
+ bytes in stream. */
+ #else
+ SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
+ #endif
+ SZ_RESULT (*Seek)(void *object, CFileSize pos);
+} ISzInStream;
+
+
+int SzArchiveOpen(
+ ISzInStream *inStream,
+ CArchiveDatabaseEx *db,
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp);
+
+#endif
Added: trunk/lzma/C/Archive/7z/7zItem.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zItem.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zItem.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,134 @@
+/* 7zItem.c */
+
+#include "7zItem.h"
+#include "7zAlloc.h"
+
+void SzCoderInfoInit(CCoderInfo *coder)
+{
+ SzByteBufferInit(&coder->Properties);
+}
+
+void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
+{
+ SzByteBufferFree(&coder->Properties, freeFunc);
+ SzCoderInfoInit(coder);
+}
+
+void SzFolderInit(CFolder *folder)
+{
+ folder->NumCoders = 0;
+ folder->Coders = 0;
+ folder->NumBindPairs = 0;
+ folder->BindPairs = 0;
+ folder->NumPackStreams = 0;
+ folder->PackStreams = 0;
+ folder->UnPackSizes = 0;
+ folder->UnPackCRCDefined = 0;
+ folder->UnPackCRC = 0;
+ folder->NumUnPackStreams = 0;
+}
+
+void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
+{
+ UInt32 i;
+ for (i = 0; i < folder->NumCoders; i++)
+ SzCoderInfoFree(&folder->Coders[i], freeFunc);
+ freeFunc(folder->Coders);
+ freeFunc(folder->BindPairs);
+ freeFunc(folder->PackStreams);
+ freeFunc(folder->UnPackSizes);
+ SzFolderInit(folder);
+}
+
+UInt32 SzFolderGetNumOutStreams(CFolder *folder)
+{
+ UInt32 result = 0;
+ UInt32 i;
+ for (i = 0; i < folder->NumCoders; i++)
+ result += folder->Coders[i].NumOutStreams;
+ return result;
+}
+
+int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
+{
+ UInt32 i;
+ for(i = 0; i < folder->NumBindPairs; i++)
+ if (folder->BindPairs[i].InIndex == inStreamIndex)
+ return i;
+ return -1;
+}
+
+
+int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
+{
+ UInt32 i;
+ for(i = 0; i < folder->NumBindPairs; i++)
+ if (folder->BindPairs[i].OutIndex == outStreamIndex)
+ return i;
+ return -1;
+}
+
+CFileSize SzFolderGetUnPackSize(CFolder *folder)
+{
+ int i = (int)SzFolderGetNumOutStreams(folder);
+ if (i == 0)
+ return 0;
+ for (i--; i >= 0; i--)
+ if (SzFolderFindBindPairForOutStream(folder, i) < 0)
+ return folder->UnPackSizes[i];
+ /* throw 1; */
+ return 0;
+}
+
+/*
+int FindPackStreamArrayIndex(int inStreamIndex) const
+{
+ for(int i = 0; i < PackStreams.Size(); i++)
+ if (PackStreams[i] == inStreamIndex)
+ return i;
+ return -1;
+}
+*/
+
+void SzFileInit(CFileItem *fileItem)
+{
+ fileItem->IsFileCRCDefined = 0;
+ fileItem->HasStream = 1;
+ fileItem->IsDirectory = 0;
+ fileItem->IsAnti = 0;
+ fileItem->IsLastWriteTimeDefined = 0;
+ fileItem->Name = 0;
+}
+
+void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
+{
+ freeFunc(fileItem->Name);
+ SzFileInit(fileItem);
+}
+
+void SzArchiveDatabaseInit(CArchiveDatabase *db)
+{
+ db->NumPackStreams = 0;
+ db->PackSizes = 0;
+ db->PackCRCsDefined = 0;
+ db->PackCRCs = 0;
+ db->NumFolders = 0;
+ db->Folders = 0;
+ db->NumFiles = 0;
+ db->Files = 0;
+}
+
+void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
+{
+ UInt32 i;
+ for (i = 0; i < db->NumFolders; i++)
+ SzFolderFree(&db->Folders[i], freeFunc);
+ for (i = 0; i < db->NumFiles; i++)
+ SzFileFree(&db->Files[i], freeFunc);
+ freeFunc(db->PackSizes);
+ freeFunc(db->PackCRCsDefined);
+ freeFunc(db->PackCRCs);
+ freeFunc(db->Folders);
+ freeFunc(db->Files);
+ SzArchiveDatabaseInit(db);
+}
Added: trunk/lzma/C/Archive/7z/7zItem.h
===================================================================
--- trunk/lzma/C/Archive/7z/7zItem.h (rev 0)
+++ trunk/lzma/C/Archive/7z/7zItem.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,95 @@
+/* 7zItem.h */
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "7zMethodID.h"
+#include "7zHeader.h"
+#include "7zBuffer.h"
+
+typedef struct _CCoderInfo
+{
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ CMethodID MethodID;
+ CSzByteBuffer Properties;
+}CCoderInfo;
+
+void SzCoderInfoInit(CCoderInfo *coder);
+void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
+
+typedef struct _CBindPair
+{
+ UInt32 InIndex;
+ UInt32 OutIndex;
+}CBindPair;
+
+typedef struct _CFolder
+{
+ UInt32 NumCoders;
+ CCoderInfo *Coders;
+ UInt32 NumBindPairs;
+ CBindPair *BindPairs;
+ UInt32 NumPackStreams;
+ UInt32 *PackStreams;
+ CFileSize *UnPackSizes;
+ int UnPackCRCDefined;
+ UInt32 UnPackCRC;
+
+ UInt32 NumUnPackStreams;
+}CFolder;
+
+void SzFolderInit(CFolder *folder);
+CFileSize SzFolderGetUnPackSize(CFolder *folder);
+int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
+UInt32 SzFolderGetNumOutStreams(CFolder *folder);
+CFileSize SzFolderGetUnPackSize(CFolder *folder);
+
+typedef struct _CArchiveFileTime
+{
+ UInt32 Low;
+ UInt32 High;
+} CArchiveFileTime;
+
+typedef struct _CFileItem
+{
+ CArchiveFileTime LastWriteTime;
+ /*
+ CFileSize StartPos;
+ UInt32 Attributes;
+ */
+ CFileSize Size;
+ UInt32 FileCRC;
+ char *Name;
+
+ Byte IsFileCRCDefined;
+ Byte HasStream;
+ Byte IsDirectory;
+ Byte IsAnti;
+ Byte IsLastWriteTimeDefined;
+ /*
+ int AreAttributesDefined;
+ int IsLastWriteTimeDefined;
+ int IsStartPosDefined;
+ */
+}CFileItem;
+
+void SzFileInit(CFileItem *fileItem);
+
+typedef struct _CArchiveDatabase
+{
+ UInt32 NumPackStreams;
+ CFileSize *PackSizes;
+ Byte *PackCRCsDefined;
+ UInt32 *PackCRCs;
+ UInt32 NumFolders;
+ CFolder *Folders;
+ UInt32 NumFiles;
+ CFileItem *Files;
+}CArchiveDatabase;
+
+void SzArchiveDatabaseInit(CArchiveDatabase *db);
+void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
+
+
+#endif
Added: trunk/lzma/C/Archive/7z/7zMain.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zMain.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zMain.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,428 @@
+/*
+7zMain.c
+Test application for 7z Decoder
+LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+#define USE_WINDOWS_FUNCTIONS
+#endif
+
+#ifdef USE_WINDOWS_FUNCTIONS
+#include <windows.h>
+#endif
+
+#include "7zIn.h"
+#include "7zExtract.h"
+
+#include "../../7zCrc.h"
+
+
+#ifdef USE_WINDOWS_FUNCTIONS
+typedef HANDLE MY_FILE_HANDLE;
+#else
+typedef FILE *MY_FILE_HANDLE;
+#endif
+
+void ConvertNumberToString(CFileSize value, char *s)
+{
+ char temp[32];
+ int pos = 0;
+ do
+ {
+ temp[pos++] = (char)('0' + (int)(value % 10));
+ value /= 10;
+ }
+ while (value != 0);
+ do
+ *s++ = temp[--pos];
+ while(pos > 0);
+ *s = '\0';
+}
+
+#define PERIOD_4 (4 * 365 + 1)
+#define PERIOD_100 (PERIOD_4 * 25 - 1)
+#define PERIOD_400 (PERIOD_100 * 4 + 1)
+
+void ConvertFileTimeToString(CArchiveFileTime *ft, char *s)
+{
+ unsigned year, mon, day, hour, min, sec;
+ UInt64 v64 = ft->Low | ((UInt64)ft->High << 32);
+ Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ unsigned temp;
+ UInt32 v;
+ v64 /= 10000000;
+ sec = (unsigned)(v64 % 60);
+ v64 /= 60;
+ min = (unsigned)(v64 % 60);
+ v64 /= 60;
+ hour = (unsigned)(v64 % 24);
+ v64 /= 24;
+
+ v = (UInt32)v64;
+
+ year = (unsigned)(1601 + v / PERIOD_400 * 400);
+ v %= PERIOD_400;
+
+ temp = (unsigned)(v / PERIOD_100);
+ if (temp == 4)
+ temp = 3;
+ year += temp * 100;
+ v -= temp * PERIOD_100;
+
+ temp = v / PERIOD_4;
+ if (temp == 25)
+ temp = 24;
+ year += temp * 4;
+ v -= temp * PERIOD_4;
+
+ temp = v / 365;
+ if (temp == 4)
+ temp = 3;
+ year += temp;
+ v -= temp * 365;
+
+ if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
+ ms[1] = 29;
+ for (mon = 1; mon <= 12; mon++)
+ {
+ unsigned s = ms[mon - 1];
+ if (v < s)
+ break;
+ v -= s;
+ }
+ day = (unsigned)v + 1;
+ sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
+}
+
+
+#ifdef USE_WINDOWS_FUNCTIONS
+/*
+ ReadFile and WriteFile functions in Windows have BUG:
+ If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
+ from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+ (Insufficient system resources exist to complete the requested service).
+*/
+#define kChunkSizeMax (1 << 24)
+#endif
+
+size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef USE_WINDOWS_FUNCTIONS
+ {
+ size_t processedSize = 0;
+ do
+ {
+ DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
+ DWORD processedLoc = 0;
+ BOOL res = ReadFile(file, data, curSize, &processedLoc, NULL);
+ data = (void *)((unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ processedSize += processedLoc;
+ if (!res || processedLoc == 0)
+ break;
+ }
+ while (size > 0);
+ return processedSize;
+ }
+ #else
+ return fread(data, 1, size, file);
+ #endif
+}
+
+size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef USE_WINDOWS_FUNCTIONS
+ {
+ size_t processedSize = 0;
+ do
+ {
+ DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
+ DWORD processedLoc = 0;
+ BOOL res = WriteFile(file, data, curSize, &processedLoc, NULL);
+ data = (void *)((unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ processedSize += processedLoc;
+ if (!res)
+ break;
+ }
+ while (size > 0);
+ return processedSize;
+ }
+ #else
+ return fwrite(data, 1, size, file);
+ #endif
+}
+
+int MyCloseFile(MY_FILE_HANDLE file)
+{
+ #ifdef USE_WINDOWS_FUNCTIONS
+ return (CloseHandle(file) != FALSE) ? 0 : 1;
+ #else
+ return fclose(file);
+ #endif
+}
+
+typedef struct _CFileInStream
+{
+ ISzInStream InStream;
+ MY_FILE_HANDLE File;
+} CFileInStream;
+
+#ifdef _LZMA_IN_CB
+
+#define kBufferSize (1 << 12)
+Byte g_Buffer[kBufferSize];
+
+SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
+{
+ CFileInStream *s = (CFileInStream *)object;
+ size_t processedSizeLoc;
+ if (maxRequiredSize > kBufferSize)
+ maxRequiredSize = kBufferSize;
+ processedSizeLoc = MyReadFile(s->File, g_Buffer, maxRequiredSize);
+ *buffer = g_Buffer;
+ if (processedSize != 0)
+ *processedSize = processedSizeLoc;
+ return SZ_OK;
+}
+
+#else
+
+SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
+{
+ CFileInStream *s = (CFileInStream *)object;
+ size_t processedSizeLoc = MyReadFile(s->File, buffer, size);
+ if (processedSize != 0)
+ *processedSize = processedSizeLoc;
+ return SZ_OK;
+}
+
+#endif
+
+SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
+{
+ CFileInStream *s = (CFileInStream *)object;
+
+ #ifdef USE_WINDOWS_FUNCTIONS
+ {
+ LARGE_INTEGER value;
+ value.LowPart = (DWORD)pos;
+ value.HighPart = (LONG)((UInt64)pos >> 32);
+ #ifdef _SZ_FILE_SIZE_32
+ /* VC 6.0 has bug with >> 32 shifts. */
+ value.HighPart = 0;
+ #endif
+ value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, FILE_BEGIN);
+ if (value.LowPart == 0xFFFFFFFF)
+ if(GetLastError() != NO_ERROR)
+ return SZE_FAIL;
+ return SZ_OK;
+ }
+ #else
+ int res = fseek(s->File, (long)pos, SEEK_SET);
+ if (res == 0)
+ return SZ_OK;
+ return SZE_FAIL;
+ #endif
+}
+
+void PrintError(char *sz)
+{
+ printf("\nERROR: %s\n", sz);
+}
+
+int main(int numargs, char *args[])
+{
+ CFileInStream archiveStream;
+ CArchiveDatabaseEx db;
+ SZ_RESULT res;
+ ISzAlloc allocImp;
+ ISzAlloc allocTempImp;
+
+ printf("\n7z ANSI-C Decoder 4.48 Copyright (c) 1999-2007 Igor Pavlov 2007-06-21\n");
+ if (numargs == 1)
+ {
+ printf(
+ "\nUsage: 7zDec <command> <archive_name>\n\n"
+ "<Commands>\n"
+ " e: Extract files from archive\n"
+ " l: List contents of archive\n"
+ " t: Test integrity of archive\n");
+ return 0;
+ }
+ if (numargs < 3)
+ {
+ PrintError("incorrect command");
+ return 1;
+ }
+
+ archiveStream.File =
+ #ifdef USE_WINDOWS_FUNCTIONS
+ CreateFile(args[2], GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (archiveStream.File == INVALID_HANDLE_VALUE)
+ #else
+ archiveStream.File = fopen(args[2], "rb");
+ if (archiveStream.File == 0)
+ #endif
+ {
+ PrintError("can not open input file");
+ return 1;
+ }
+
+ archiveStream.InStream.Read = SzFileReadImp;
+ archiveStream.InStream.Seek = SzFileSeekImp;
+
+ allocImp.Alloc = SzAlloc;
+ allocImp.Free = SzFree;
+
+ allocTempImp.Alloc = SzAllocTemp;
+ allocTempImp.Free = SzFreeTemp;
+
+ CrcGenerateTable();
+
+ SzArDbExInit(&db);
+ res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
+ if (res == SZ_OK)
+ {
+ char *command = args[1];
+ int listCommand = 0;
+ int testCommand = 0;
+ int extractCommand = 0;
+ if (strcmp(command, "l") == 0)
+ listCommand = 1;
+ if (strcmp(command, "t") == 0)
+ testCommand = 1;
+ else if (strcmp(command, "e") == 0)
+ extractCommand = 1;
+
+ if (listCommand)
+ {
+ UInt32 i;
+ for (i = 0; i < db.Database.NumFiles; i++)
+ {
+ CFileItem *f = db.Database.Files + i;
+ char s[32], t[32];
+ ConvertNumberToString(f->Size, s);
+ if (f->IsLastWriteTimeDefined)
+ ConvertFileTimeToString(&f->LastWriteTime, t);
+ else
+ strcpy(t, " ");
+
+ printf("%10s %s %s\n", s, t, f->Name);
+ }
+ }
+ else if (testCommand || extractCommand)
+ {
+ UInt32 i;
+
+ /*
+ if you need cache, use these 3 variables.
+ if you use external function, you can make these variable as static.
+ */
+ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
+ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
+ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
+
+ printf("\n");
+ for (i = 0; i < db.Database.NumFiles; i++)
+ {
+ size_t offset;
+ size_t outSizeProcessed;
+ CFileItem *f = db.Database.Files + i;
+ if (f->IsDirectory)
+ printf("Directory ");
+ else
+ printf(testCommand ?
+ "Testing ":
+ "Extracting");
+ printf(" %s", f->Name);
+ if (f->IsDirectory)
+ {
+ printf("\n");
+ continue;
+ }
+ res = SzExtract(&archiveStream.InStream, &db, i,
+ &blockIndex, &outBuffer, &outBufferSize,
+ &offset, &outSizeProcessed,
+ &allocImp, &allocTempImp);
+ if (res != SZ_OK)
+ break;
+ if (!testCommand)
+ {
+ MY_FILE_HANDLE outputHandle;
+ size_t processedSize;
+ char *fileName = f->Name;
+ size_t nameLen = strlen(f->Name);
+ for (; nameLen > 0; nameLen--)
+ if (f->Name[nameLen - 1] == '/')
+ {
+ fileName = f->Name + nameLen;
+ break;
+ }
+
+ outputHandle =
+ #ifdef USE_WINDOWS_FUNCTIONS
+ CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (outputHandle == INVALID_HANDLE_VALUE)
+ #else
+ fopen(fileName, "wb+");
+ if (outputHandle == 0)
+ #endif
+ {
+ PrintError("can not open output file");
+ res = SZE_FAIL;
+ break;
+ }
+ processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed);
+ if (processedSize != outSizeProcessed)
+ {
+ PrintError("can not write output file");
+ res = SZE_FAIL;
+ break;
+ }
+ if (MyCloseFile(outputHandle))
+ {
+ PrintError("can not close output file");
+ res = SZE_FAIL;
+ break;
+ }
+ }
+ printf("\n");
+ }
+ allocImp.Free(outBuffer);
+ }
+ else
+ {
+ PrintError("incorrect command");
+ res = SZE_FAIL;
+ }
+ }
+ SzArDbExFree(&db, allocImp.Free);
+
+ MyCloseFile(archiveStream.File);
+ if (res == SZ_OK)
+ {
+ printf("\nEverything is Ok\n");
+ return 0;
+ }
+ if (res == (SZ_RESULT)SZE_NOTIMPL)
+ PrintError("decoder doesn't support this archive");
+ else if (res == (SZ_RESULT)SZE_OUTOFMEMORY)
+ PrintError("can not allocate memory");
+ else if (res == (SZ_RESULT)SZE_CRC_ERROR)
+ PrintError("CRC error");
+ else
+ printf("\nERROR #%d\n", res);
+ return 1;
+}
Added: trunk/lzma/C/Archive/7z/7zMethodID.c
===================================================================
--- trunk/lzma/C/Archive/7z/7zMethodID.c (rev 0)
+++ trunk/lzma/C/Archive/7z/7zMethodID.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+/* 7zMethodID.c */
+
+#include "7zMethodID.h"
+
+/*
+int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
+{
+ return (*a1 == *a2) ? 1 : 0;
+}
+*/
Added: trunk/lzma/C/Archive/7z/7zMethodID.h
===================================================================
--- trunk/lzma/C/Archive/7z/7zMethodID.h (rev 0)
+++ trunk/lzma/C/Archive/7z/7zMethodID.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+/* 7zMethodID.h */
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "../../Types.h"
+
+typedef UInt64 CMethodID;
+
+#endif
Added: trunk/lzma/C/Archive/7z/7z_C.dsp
===================================================================
--- trunk/lzma/C/Archive/7z/7z_C.dsp (rev 0)
+++ trunk/lzma/C/Archive/7z/7z_C.dsp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,211 @@
+# Microsoft Developer Studio Project File - Name="7z_C" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=7z_C - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "7z_C.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "7z_C.mak" CFG="7z_C - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "7z_C - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "7z_C - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "7z_C - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "7z_C - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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
+
+!ENDIF
+
+# Begin Target
+
+# Name "7z_C - Win32 Release"
+# Name "7z_C - Win32 Debug"
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma\LzmaDecode.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma\LzmaDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma\LzmaTypes.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\7zCrc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Types.h
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchX86.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchX86.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchX86_2.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchX86_2.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7zAlloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zBuffer.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMain.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethodID.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethodID.h
+# End Source File
+# End Target
+# End Project
Added: trunk/lzma/C/Archive/7z/7z_C.dsw
===================================================================
--- trunk/lzma/C/Archive/7z/7z_C.dsw (rev 0)
+++ trunk/lzma/C/Archive/7z/7z_C.dsw 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7z_C"=.\7z_C.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
Added: trunk/lzma/C/Archive/7z/makefile
===================================================================
--- trunk/lzma/C/Archive/7z/makefile (rev 0)
+++ trunk/lzma/C/Archive/7z/makefile 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,74 @@
+PROG = 7zDec.exe
+
+!IFDEF CPU
+LIBS = $(LIBS) bufferoverflowU.lib
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope -WX -GS- -Gy -W4
+!ENDIF
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -D_LZMA_IN_CB
+CFLAGS_O1 = $(CFLAGS) -O1
+CFLAGS_O2 = $(CFLAGS) -O2
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 -OPT:REF
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
+COMPL = $(CPP) $(CFLAGS_O1) $**
+
+C_OBJS = \
+ $O\7zCrc.obj \
+
+
+7Z_OBJS = \
+ $O\7zAlloc.obj \
+ $O\7zBuffer.obj \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zItem.obj \
+ $O\7zMain.obj \
+ $O\7zMethodID.obj \
+
+OBJS = \
+ $(7Z_OBJS) \
+ $O\LzmaDecode.obj \
+ $O\BranchX86.obj \
+ $O\BranchX86_2.obj \
+ $(C_OBJS) \
+
+all: $(PROGPATH)
+
+clean:
+ -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
+
+$O:
+ if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS)
+ link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+
+
+$(7Z_OBJS): $(*B).c
+ $(COMPL)
+$O\LzmaDecode.obj: ../../Compress/Lzma/$(*B).c
+ $(COMPL_O2)
+
+$O\BranchX86.obj: ../../Compress/Branch/$(*B).c
+ $(COMPL_O2)
+
+$O\BranchX86_2.obj: ../../Compress/Branch/$(*B).c
+ $(COMPL_O2)
+
+$(C_OBJS): ../../$(*B).c
+ $(COMPL_O2)
Added: trunk/lzma/C/Archive/7z/makefile.gcc
===================================================================
--- trunk/lzma/C/Archive/7z/makefile.gcc (rev 0)
+++ trunk/lzma/C/Archive/7z/makefile.gcc 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,55 @@
+PROG = 7zDec
+CXX = g++
+LIB =
+RM = rm -f
+CFLAGS = -c -O2 -Wall -D_LZMA_IN_CB
+
+OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o BranchX86.o BranchX86_2.o
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
+
+7zAlloc.o: 7zAlloc.c
+ $(CXX) $(CFLAGS) 7zAlloc.c
+
+7zBuffer.o: 7zBuffer.c
+ $(CXX) $(CFLAGS) 7zBuffer.c
+
+7zCrc.o: ../../7zCrc.c
+ $(CXX) $(CFLAGS) ../../7zCrc.c
+
+7zDecode.o: 7zDecode.c
+ $(CXX) $(CFLAGS) 7zDecode.c
+
+7zExtract.o: 7zExtract.c
+ $(CXX) $(CFLAGS) 7zExtract.c
+
+7zHeader.o: 7zHeader.c
+ $(CXX) $(CFLAGS) 7zHeader.c
+
+7zIn.o: 7zIn.c
+ $(CXX) $(CFLAGS) 7zIn.c
+
+7zItem.o: 7zItem.c
+ $(CXX) $(CFLAGS) 7zItem.c
+
+7zMain.o: 7zMain.c
+ $(CXX) $(CFLAGS) 7zMain.c
+
+7zMethodID.o: 7zMethodID.c
+ $(CXX) $(CFLAGS) 7zMethodID.c
+
+LzmaDecode.o: ../../Compress/Lzma/LzmaDecode.c
+ $(CXX) $(CFLAGS) ../../Compress/Lzma/LzmaDecode.c
+
+BranchX86.o: ../../Compress/Branch/BranchX86.c
+ $(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86.c
+
+BranchX86_2.o: ../../Compress/Branch/BranchX86_2.c
+ $(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86_2.c
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
Added: trunk/lzma/C/Compress/Branch/BranchARM.c
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchARM.c (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchARM.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,26 @@
+/* BranchARM.c */
+
+#include "BranchARM.h"
+
+UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 4 <= size; i += 4)
+ {
+ if (data[i + 3] == 0xEB)
+ {
+ UInt32 dest;
+ UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]);
+ src <<= 2;
+ if (encoding)
+ dest = nowPos + i + 8 + src;
+ else
+ dest = src - (nowPos + i + 8);
+ dest >>= 2;
+ data[i + 2] = (Byte)(dest >> 16);
+ data[i + 1] = (Byte)(dest >> 8);
+ data[i + 0] = (Byte)dest;
+ }
+ }
+ return i;
+}
Added: trunk/lzma/C/Compress/Branch/BranchARM.h
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchARM.h (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchARM.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+/* BranchARM.h */
+
+#ifndef __BRANCH_ARM_H
+#define __BRANCH_ARM_H
+
+#include "BranchTypes.h"
+
+UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
Added: trunk/lzma/C/Compress/Branch/BranchARMThumb.c
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchARMThumb.c (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchARMThumb.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,35 @@
+/* BranchARMThumb.c */
+
+#include "BranchARMThumb.h"
+
+UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 4 <= size; i += 2)
+ {
+ if ((data[i + 1] & 0xF8) == 0xF0 &&
+ (data[i + 3] & 0xF8) == 0xF8)
+ {
+ UInt32 dest;
+ UInt32 src =
+ ((data[i + 1] & 0x7) << 19) |
+ (data[i + 0] << 11) |
+ ((data[i + 3] & 0x7) << 8) |
+ (data[i + 2]);
+
+ src <<= 1;
+ if (encoding)
+ dest = nowPos + i + 4 + src;
+ else
+ dest = src - (nowPos + i + 4);
+ dest >>= 1;
+
+ data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
+ data[i + 0] = (Byte)(dest >> 11);
+ data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
+ data[i + 2] = (Byte)dest;
+ i += 2;
+ }
+ }
+ return i;
+}
Added: trunk/lzma/C/Compress/Branch/BranchARMThumb.h
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchARMThumb.h (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchARMThumb.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+/* BranchARMThumb.h */
+
+#ifndef __BRANCH_ARM_THUMB_H
+#define __BRANCH_ARM_THUMB_H
+
+#include "BranchTypes.h"
+
+UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
Added: trunk/lzma/C/Compress/Branch/BranchIA64.c
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchIA64.c (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchIA64.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,66 @@
+/* BranchIA64.c */
+
+#include "BranchIA64.h"
+
+const Byte kBranchTable[32] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 6, 6, 0, 0, 7, 7,
+ 4, 4, 0, 0, 4, 4, 0, 0
+};
+
+UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 16 <= size; i += 16)
+ {
+ UInt32 instrTemplate = data[i] & 0x1F;
+ UInt32 mask = kBranchTable[instrTemplate];
+ UInt32 bitPos = 5;
+ int slot;
+ for (slot = 0; slot < 3; slot++, bitPos += 41)
+ {
+ UInt32 bytePos, bitRes;
+ UInt64 instruction, instNorm;
+ int j;
+ if (((mask >> slot) & 1) == 0)
+ continue;
+ bytePos = (bitPos >> 3);
+ bitRes = bitPos & 0x7;
+ instruction = 0;
+ for (j = 0; j < 6; j++)
+ instruction += (UInt64)(data[i + j + bytePos]) << (8 * j);
+
+ instNorm = instruction >> bitRes;
+ if (((instNorm >> 37) & 0xF) == 0x5
+ && ((instNorm >> 9) & 0x7) == 0
+ /* && (instNorm & 0x3F)== 0 */
+ )
+ {
+ UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
+ UInt32 dest;
+ src |= ((UInt32)(instNorm >> 36) & 1) << 20;
+
+ src <<= 4;
+
+ if (encoding)
+ dest = nowPos + i + src;
+ else
+ dest = src - (nowPos + i);
+
+ dest >>= 4;
+
+ instNorm &= ~((UInt64)(0x8FFFFF) << 13);
+ instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
+ instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
+
+ instruction &= (1 << bitRes) - 1;
+ instruction |= (instNorm << bitRes);
+ for (j = 0; j < 6; j++)
+ data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
+ }
+ }
+ }
+ return i;
+}
Added: trunk/lzma/C/Compress/Branch/BranchIA64.h
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchIA64.h (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchIA64.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+/* BranchIA64.h */
+
+#ifndef __BRANCH_IA64_H
+#define __BRANCH_IA64_H
+
+#include "BranchTypes.h"
+
+UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
Added: trunk/lzma/C/Compress/Branch/BranchPPC.c
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchPPC.c (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchPPC.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,36 @@
+/* BranchPPC.c */
+
+#include "BranchPPC.h"
+
+UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 4 <= size; i += 4)
+ {
+ /* PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) */
+ if ((data[i] >> 2) == 0x12 &&
+ (
+ (data[i + 3] & 3) == 1
+ /* || (data[i+3] & 3) == 3 */
+ )
+ )
+ {
+ UInt32 src = ((data[i + 0] & 3) << 24) |
+ (data[i + 1] << 16) |
+ (data[i + 2] << 8) |
+ (data[i + 3] & (~3));
+
+ UInt32 dest;
+ if (encoding)
+ dest = nowPos + i + src;
+ else
+ dest = src - (nowPos + i);
+ data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
+ data[i + 1] = (Byte)(dest >> 16);
+ data[i + 2] = (Byte)(dest >> 8);
+ data[i + 3] &= 0x3;
+ data[i + 3] |= dest;
+ }
+ }
+ return i;
+}
Added: trunk/lzma/C/Compress/Branch/BranchPPC.h
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchPPC.h (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchPPC.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+/* BranchPPC.h */
+
+#ifndef __BRANCH_PPC_H
+#define __BRANCH_PPC_H
+
+#include "BranchTypes.h"
+
+UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
Added: trunk/lzma/C/Compress/Branch/BranchSPARC.c
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchSPARC.c (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchSPARC.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,36 @@
+/* BranchSPARC.c */
+
+#include "BranchSPARC.h"
+
+UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+ UInt32 i;
+ for (i = 0; i + 4 <= size; i += 4)
+ {
+ if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
+ data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
+ {
+ UInt32 src =
+ ((UInt32)data[i + 0] << 24) |
+ ((UInt32)data[i + 1] << 16) |
+ ((UInt32)data[i + 2] << 8) |
+ ((UInt32)data[i + 3]);
+ UInt32 dest;
+
+ src <<= 2;
+ if (encoding)
+ dest = nowPos + i + src;
+ else
+ dest = src - (nowPos + i);
+ dest >>= 2;
+
+ dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
+
+ data[i + 0] = (Byte)(dest >> 24);
+ data[i + 1] = (Byte)(dest >> 16);
+ data[i + 2] = (Byte)(dest >> 8);
+ data[i + 3] = (Byte)dest;
+ }
+ }
+ return i;
+}
Added: trunk/lzma/C/Compress/Branch/BranchSPARC.h
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchSPARC.h (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchSPARC.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+/* BranchSPARC.h */
+
+#ifndef __BRANCH_SPARC_H
+#define __BRANCH_SPARC_H
+
+#include "BranchTypes.h"
+
+UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
Added: trunk/lzma/C/Compress/Branch/BranchTypes.h
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchTypes.h (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchTypes.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,51 @@
+/* BranchTypes.h */
+
+#ifndef __BRANCHTYPES_H
+#define __BRANCHTYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+#ifdef _SZ_NO_INT_64
+typedef unsigned long UInt64;
+#else
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 UInt64;
+#else
+typedef unsigned long long int UInt64;
+#endif
+#endif
+#endif
+
+/* #define _LZMA_NO_SYSTEM_SIZE_T */
+/* You can use it, if you don't want <stddef.h> */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+#endif
+
+#endif
Added: trunk/lzma/C/Compress/Branch/BranchX86.c
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchX86.c (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchX86.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,84 @@
+/* BranchX86.c */
+
+#include "BranchX86.h"
+
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix, int encoding)
+{
+ SizeT bufferPos = 0, prevPosT;
+ UInt32 prevMask = *prevMaskMix & 0x7;
+ if (endPos < 5)
+ return 0;
+ nowPos += 5;
+ prevPosT = (SizeT)0 - 1;
+
+ for(;;)
+ {
+ Byte *p = buffer + bufferPos;
+ Byte *limit = buffer + endPos - 4;
+ for (; p < limit; p++)
+ if ((*p & 0xFE) == 0xE8)
+ break;
+ bufferPos = (SizeT)(p - buffer);
+ if (p >= limit)
+ break;
+ prevPosT = bufferPos - prevPosT;
+ if (prevPosT > 3)
+ prevMask = 0;
+ else
+ {
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
+ if (prevMask != 0)
+ {
+ Byte b = p[4 - kMaskToBitNumber[prevMask]];
+ if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
+ {
+ prevPosT = bufferPos;
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ continue;
+ }
+ }
+ }
+ prevPosT = bufferPos;
+
+ if (Test86MSByte(p[4]))
+ {
+ UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+ UInt32 dest;
+ for (;;)
+ {
+ Byte b;
+ int index;
+ if (encoding)
+ dest = (nowPos + (UInt32)bufferPos) + src;
+ else
+ dest = src - (nowPos + (UInt32)bufferPos);
+ if (prevMask == 0)
+ break;
+ index = kMaskToBitNumber[prevMask] * 8;
+ b = (Byte)(dest >> (24 - index));
+ if (!Test86MSByte(b))
+ break;
+ src = dest ^ ((1 << (32 - index)) - 1);
+ }
+ p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
+ p[3] = (Byte)(dest >> 16);
+ p[2] = (Byte)(dest >> 8);
+ p[1] = (Byte)dest;
+ bufferPos += 5;
+ }
+ else
+ {
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ }
+ }
+ prevPosT = bufferPos - prevPosT;
+ *prevMaskMix = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
+ return bufferPos;
+}
Added: trunk/lzma/C/Compress/Branch/BranchX86.h
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchX86.h (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchX86.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,12 @@
+/* BranchX86.h */
+
+#ifndef __BRANCHX86_H
+#define __BRANCHX86_H
+
+#include "BranchTypes.h"
+
+#define x86_Convert_Init(state) { state = 0; }
+
+SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *state, int encoding);
+
+#endif
Added: trunk/lzma/C/Compress/Branch/BranchX86_2.c
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchX86_2.c (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchX86_2.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,135 @@
+// BranchX86_2.c
+
+#include "BranchX86_2.h"
+
+#include "../../Alloc.h"
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#define RC_TEST { if (Buffer == BufferLim) return BCJ2_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+// #define UpdateBit0(p) Range = bound; *(p) = (CProb)(*(p) + ((kBitModelTotal - *(p)) >> kNumMoveBits));
+// #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) = (CProb)(*(p) - (*(p) >> kNumMoveBits));
+
+int x86_2_Decode(
+ const Byte *buf0, SizeT size0,
+ const Byte *buf1, SizeT size1,
+ const Byte *buf2, SizeT size2,
+ const Byte *buf3, SizeT size3,
+ Byte *outBuf, SizeT outSize)
+{
+ CProb p[256 + 2];
+ SizeT inPos = 0, outPos = 0;
+
+ const Byte *Buffer, *BufferLim;
+ UInt32 Range, Code;
+ Byte prevByte = 0;
+
+ unsigned int i;
+ for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
+ p[i] = kBitModelTotal >> 1;
+ RC_INIT(buf3, size3);
+
+ if (outSize == 0)
+ return BCJ2_RESULT_OK;
+
+ for (;;)
+ {
+ Byte b;
+ CProb *prob;
+ UInt32 bound;
+
+ SizeT limit = size0 - inPos;
+ if (outSize - outPos < limit)
+ limit = outSize - outPos;
+ while (limit != 0)
+ {
+ Byte b = buf0[inPos];
+ outBuf[outPos++] = b;
+ if (IsJ(prevByte, b))
+ break;
+ inPos++;
+ prevByte = b;
+ limit--;
+ }
+
+ if (limit == 0 || outPos == outSize)
+ break;
+
+ b = buf0[inPos++];
+
+ if (b == 0xE8)
+ prob = p + prevByte;
+ else if (b == 0xE9)
+ prob = p + 256;
+ else
+ prob = p + 257;
+
+ IfBit0(prob)
+ {
+ UpdateBit0(prob)
+ prevByte = b;
+ }
+ else
+ {
+ UInt32 dest;
+ const Byte *v;
+ UpdateBit1(prob)
+ if (b == 0xE8)
+ {
+ v = buf1;
+ if (size1 < 4)
+ return BCJ2_RESULT_DATA_ERROR;
+ buf1 += 4;
+ size1 -= 4;
+ }
+ else
+ {
+ v = buf2;
+ if (size2 < 4)
+ return BCJ2_RESULT_DATA_ERROR;
+ buf2 += 4;
+ size2 -= 4;
+ }
+ dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
+ ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
+ outBuf[outPos++] = (Byte)dest;
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = (Byte)(dest >> 8);
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = (Byte)(dest >> 16);
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
+ }
+ }
+ return (outPos == outSize) ? BCJ2_RESULT_OK : BCJ2_RESULT_DATA_ERROR;
+}
Added: trunk/lzma/C/Compress/Branch/BranchX86_2.h
===================================================================
--- trunk/lzma/C/Compress/Branch/BranchX86_2.h (rev 0)
+++ trunk/lzma/C/Compress/Branch/BranchX86_2.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,28 @@
+// BranchX86_2.h
+
+#ifndef __BRANCHX86_2_H
+#define __BRANCHX86_2_H
+
+#include "BranchTypes.h"
+
+#define BCJ2_RESULT_OK 0
+#define BCJ2_RESULT_DATA_ERROR 1
+
+/*
+Conditions:
+ outSize <= FullOutputSize,
+ where FullOutputSize is full size of output stream of x86_2 filter.
+
+If buf0 overlaps outBuf, there are two required conditions:
+ 1) (buf0 >= outBuf)
+ 2) (buf0 + size0 >= outBuf + FullOutputSize).
+*/
+
+int x86_2_Decode(
+ const Byte *buf0, SizeT size0,
+ const Byte *buf1, SizeT size1,
+ const Byte *buf2, SizeT size2,
+ const Byte *buf3, SizeT size3,
+ Byte *outBuf, SizeT outSize);
+
+#endif
Added: trunk/lzma/C/Compress/Huffman/HuffmanEncode.c
===================================================================
--- trunk/lzma/C/Compress/Huffman/HuffmanEncode.c (rev 0)
+++ trunk/lzma/C/Compress/Huffman/HuffmanEncode.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,146 @@
+/* Compress/HuffmanEncode.c */
+
+#include "HuffmanEncode.h"
+#include "../../Sort.h"
+
+#define kMaxLen 16
+#define NUM_BITS 10
+#define MASK ((1 << NUM_BITS) - 1)
+
+#define NUM_COUNTERS 64
+
+/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize > 1M */
+#define HUFFMAN_SPEED_OPT
+
+void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen)
+{
+ UInt32 num = 0;
+ /* if (maxLen > 10) maxLen = 10; */
+ {
+ UInt32 i;
+
+ #ifdef HUFFMAN_SPEED_OPT
+
+ UInt32 counters[NUM_COUNTERS];
+ for (i = 0; i < NUM_COUNTERS; i++)
+ counters[i] = 0;
+ for (i = 0; i < numSymbols; i++)
+ {
+ UInt32 freq = freqs[i];
+ counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++;
+ }
+
+ for (i = 1; i < NUM_COUNTERS; i++)
+ {
+ UInt32 temp = counters[i];
+ counters[i] = num;
+ num += temp;
+ }
+
+ for (i = 0; i < numSymbols; i++)
+ {
+ UInt32 freq = freqs[i];
+ if (freq == 0)
+ lens[i] = 0;
+ else
+ p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS);
+ }
+ counters[0] = 0;
+ HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]);
+
+ #else
+
+ for (i = 0; i < numSymbols; i++)
+ {
+ UInt32 freq = freqs[i];
+ if (freq == 0)
+ lens[i] = 0;
+ else
+ p[num++] = i | (freq << NUM_BITS);
+ }
+ HeapSort(p, num);
+
+ #endif
+ }
+
+ if (num < 2)
+ {
+ int minCode = 0;
+ int maxCode = 1;
+ if (num == 1)
+ {
+ maxCode = p[0] & MASK;
+ if (maxCode == 0)
+ maxCode++;
+ }
+ p[minCode] = 0;
+ p[maxCode] = 1;
+ lens[minCode] = lens[maxCode] = 1;
+ return;
+ }
+
+ {
+ UInt32 b, e, i;
+
+ i = b = e = 0;
+ do
+ {
+ UInt32 n, m, freq;
+ n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
+ freq = (p[n] & ~MASK);
+ p[n] = (p[n] & MASK) | (e << NUM_BITS);
+ m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
+ freq += (p[m] & ~MASK);
+ p[m] = (p[m] & MASK) | (e << NUM_BITS);
+ p[e] = (p[e] & MASK) | freq;
+ e++;
+ }
+ while (num - e > 1);
+
+ {
+ UInt32 lenCounters[kMaxLen + 1];
+ for (i = 0; i <= kMaxLen; i++)
+ lenCounters[i] = 0;
+
+ p[--e] &= MASK;
+ lenCounters[1] = 2;
+ while (e > 0)
+ {
+ UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
+ p[e] = (p[e] & MASK) | (len << NUM_BITS);
+ if (len >= maxLen)
+ for (len = maxLen - 1; lenCounters[len] == 0; len--);
+ lenCounters[len]--;
+ lenCounters[len + 1] += 2;
+ }
+
+ {
+ UInt32 len;
+ i = 0;
+ for (len = maxLen; len != 0; len--)
+ {
+ UInt32 num;
+ for (num = lenCounters[len]; num != 0; num--)
+ lens[p[i++] & MASK] = (Byte)len;
+ }
+ }
+
+ {
+ UInt32 nextCodes[kMaxLen + 1];
+ {
+ UInt32 code = 0;
+ UInt32 len;
+ for (len = 1; len <= kMaxLen; len++)
+ nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
+ }
+ /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
+
+ {
+ UInt32 i;
+ for (i = 0; i < numSymbols; i++)
+ p[i] = nextCodes[lens[i]]++;
+ }
+ }
+ }
+ }
+}
Added: trunk/lzma/C/Compress/Huffman/HuffmanEncode.h
===================================================================
--- trunk/lzma/C/Compress/Huffman/HuffmanEncode.h (rev 0)
+++ trunk/lzma/C/Compress/Huffman/HuffmanEncode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,18 @@
+/* Compress/HuffmanEncode.h */
+
+#ifndef __COMPRESS_HUFFMANENCODE_H
+#define __COMPRESS_HUFFMANENCODE_H
+
+#include "../../Types.h"
+
+/*
+Conditions:
+ num <= 1024 = 2 ^ NUM_BITS
+ Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS)
+ maxLen <= 16 = kMaxLen
+ Num_Items(p) >= HUFFMAN_TEMP_SIZE(num)
+*/
+
+void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen);
+
+#endif
Added: trunk/lzma/C/Compress/Lz/LzHash.h
===================================================================
--- trunk/lzma/C/Compress/Lz/LzHash.h (rev 0)
+++ trunk/lzma/C/Compress/Lz/LzHash.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,53 @@
+/* LzHash.h */
+
+#ifndef __C_LZHASH_H
+#define __C_LZHASH_H
+
+#define kHash2Size (1 << 10)
+#define kHash3Size (1 << 16)
+#define kHash4Size (1 << 20)
+
+#define kFix3HashSize (kHash2Size)
+#define kFix4HashSize (kHash2Size + kHash3Size)
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
+
+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
+
+#define HASH3_CALC { \
+ UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+
+#define HASH4_CALC { \
+ UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)) & p->hashMask; }
+
+#define HASH5_CALC { \
+ UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)); \
+ hashValue = (hash4Value ^ (g_CrcTable[cur[4]] << 3)) & p->hashMask; \
+ hash4Value &= (kHash4Size - 1); }
+
+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ g_CrcTable[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ g_CrcTable[cur[1]]) & 0xFFFF;
+
+
+#define MT_HASH2_CALC \
+ hash2Value = (g_CrcTable[cur[0]] ^ cur[1]) & (kHash2Size - 1);
+
+#define MT_HASH3_CALC { \
+ UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+
+#define MT_HASH4_CALC { \
+ UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)) & (kHash4Size - 1); }
+
+#endif
Added: trunk/lzma/C/Compress/Lz/MatchFinder.c
===================================================================
--- trunk/lzma/C/Compress/Lz/MatchFinder.c (rev 0)
+++ trunk/lzma/C/Compress/Lz/MatchFinder.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,742 @@
+/* MatchFinder.c */
+/* Please call InitCrcTable before */
+
+#include <string.h>
+
+#include "MatchFinder.h"
+#include "LzHash.h"
+
+#include "../../7zCrc.h"
+
+#define kEmptyHashValue 0
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
+#define kNormalizeMask (~(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)3 << 30)
+
+#define kStartMaxLen 3
+
+void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+ if (!p->directInput)
+ {
+ alloc->Free(p->bufferBase);
+ p->bufferBase = 0;
+ }
+}
+
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
+
+int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
+{
+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
+ if (p->directInput)
+ {
+ p->blockSize = blockSize;
+ return 1;
+ }
+ if (p->bufferBase == 0 || p->blockSize != blockSize)
+ {
+ LzInWindow_Free(p, alloc);
+ p->blockSize = blockSize;
+ p->bufferBase = (Byte *)alloc->Alloc(blockSize);
+ }
+ return (p->bufferBase != 0);
+}
+
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
+
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+{
+ p->posLimit -= subValue;
+ p->pos -= subValue;
+ p->streamPos -= subValue;
+}
+
+void MatchFinder_ReadBlock(CMatchFinder *p)
+{
+ if (p->streamEndWasReached || p->result != SZ_OK)
+ return;
+ for (;;)
+ {
+ Byte *dest = p->buffer + (p->streamPos - p->pos);
+ UInt32 numReadBytes;
+ UInt32 size = (UInt32)(p->bufferBase + p->blockSize - dest);
+ if (size == 0)
+ return;
+ p->result = p->stream->Read(p->stream, dest, size, &numReadBytes);
+ if (p->result != SZ_OK)
+ return;
+ if (numReadBytes == 0)
+ {
+ p->streamEndWasReached = 1;
+ return;
+ }
+ p->streamPos += numReadBytes;
+ if (p->streamPos - p->pos > p->keepSizeAfter)
+ return;
+ }
+}
+
+void MatchFinder_MoveBlock(CMatchFinder *p)
+{
+ memmove(p->bufferBase,
+ p->buffer - p->keepSizeBefore,
+ p->streamPos - p->pos + p->keepSizeBefore);
+ p->buffer = p->bufferBase + p->keepSizeBefore;
+}
+
+int MatchFinder_NeedMove(CMatchFinder *p)
+{
+ /* if (p->streamEndWasReached) return 0; */
+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
+}
+
+void MatchFinder_ReadIfRequired(CMatchFinder *p)
+{
+ if (p->streamEndWasReached)
+ return;
+ if (p->keepSizeAfter >= p->streamPos - p->pos)
+ MatchFinder_ReadBlock(p);
+}
+
+void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
+{
+ if (MatchFinder_NeedMove(p))
+ MatchFinder_MoveBlock(p);
+ MatchFinder_ReadBlock(p);
+}
+
+void MatchFinder_SetDefaultSettings(CMatchFinder *p)
+{
+ p->cutValue = 32;
+ p->btMode = 1;
+ p->numHashBytes = 4;
+ /* p->skipModeBits = 0; */
+ p->directInput = 0;
+ p->bigHash = 0;
+}
+
+void MatchFinder_Construct(CMatchFinder *p)
+{
+ p->bufferBase = 0;
+ p->directInput = 0;
+ p->hash = 0;
+ MatchFinder_SetDefaultSettings(p);
+}
+
+void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+{
+ alloc->Free(p->hash);
+ p->hash = 0;
+}
+
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+ MatchFinder_FreeThisClassMemory(p, alloc);
+ LzInWindow_Free(p, alloc);
+}
+
+CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
+{
+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
+ if (sizeInBytes / sizeof(CLzRef) != num)
+ return 0;
+ return (CLzRef *)alloc->Alloc(sizeInBytes);
+}
+
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+ ISzAlloc *alloc)
+{
+ UInt32 sizeReserv;
+ if (historySize > kMaxHistorySize)
+ {
+ MatchFinder_Free(p, alloc);
+ return 0;
+ }
+ sizeReserv = historySize >> 1;
+ if (historySize > ((UInt32)2 << 30))
+ sizeReserv = historySize >> 2;
+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
+
+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+ if (LzInWindow_Create(p, sizeReserv, alloc))
+ {
+ UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
+ UInt32 hs;
+ p->matchMaxLen = matchMaxLen;
+ {
+ p->fixedHashSize = 0;
+ if (p->numHashBytes == 2)
+ hs = (1 << 16) - 1;
+ else
+ {
+ hs = historySize - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ /* hs >>= p->skipModeBits; */
+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */
+ if (hs > (1 << 24))
+ {
+ if (p->numHashBytes == 3)
+ hs = (1 << 24) - 1;
+ else
+ hs >>= 1;
+ }
+ }
+ p->hashMask = hs;
+ hs++;
+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
+ hs += p->fixedHashSize;
+ }
+
+ {
+ UInt32 prevSize = p->hashSizeSum + p->numSons;
+ UInt32 newSize;
+ p->historySize = historySize;
+ p->hashSizeSum = hs;
+ p->cyclicBufferSize = newCyclicBufferSize;
+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
+ newSize = p->hashSizeSum + p->numSons;
+ if (p->hash != 0 && prevSize == newSize)
+ return 1;
+ MatchFinder_FreeThisClassMemory(p, alloc);
+ p->hash = AllocRefs(newSize, alloc);
+ if (p->hash != 0)
+ {
+ p->son = p->hash + p->hashSizeSum;
+ return 1;
+ }
+ }
+ }
+ MatchFinder_Free(p, alloc);
+ return 0;
+}
+
+void MatchFinder_SetLimits(CMatchFinder *p)
+{
+ UInt32 limit = kMaxValForNormalize - p->pos;
+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+ if (limit2 < limit)
+ limit = limit2;
+ limit2 = p->streamPos - p->pos;
+ if (limit2 <= p->keepSizeAfter)
+ {
+ if (limit2 > 0)
+ limit2 = 1;
+ }
+ else
+ limit2 -= p->keepSizeAfter;
+ if (limit2 < limit)
+ limit = limit2;
+ {
+ UInt32 lenLimit = p->streamPos - p->pos;
+ if (lenLimit > p->matchMaxLen)
+ lenLimit = p->matchMaxLen;
+ p->lenLimit = lenLimit;
+ }
+ p->posLimit = p->pos + limit;
+}
+
+void MatchFinder_Init(CMatchFinder *p)
+{
+ UInt32 i;
+ for(i = 0; i < p->hashSizeSum; i++)
+ p->hash[i] = kEmptyHashValue;
+ p->cyclicBufferPos = 0;
+ p->buffer = p->bufferBase;
+ p->pos = p->streamPos = p->cyclicBufferSize;
+ p->result = SZ_OK;
+ p->streamEndWasReached = 0;
+ MatchFinder_ReadBlock(p);
+ MatchFinder_SetLimits(p);
+}
+
+UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
+{
+ return (p->pos - p->historySize - 1) & kNormalizeMask;
+}
+
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+{
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ UInt32 value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+}
+
+void MatchFinder_Normalize(CMatchFinder *p)
+{
+ UInt32 subValue = MatchFinder_GetSubValue(p);
+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+ MatchFinder_ReduceOffsets(p, subValue);
+}
+
+void MatchFinder_CheckLimits(CMatchFinder *p)
+{
+ if (p->pos == kMaxValForNormalize)
+ MatchFinder_Normalize(p);
+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
+ MatchFinder_CheckAndMoveAndRead(p);
+ if (p->cyclicBufferPos == p->cyclicBufferSize)
+ p->cyclicBufferPos = 0;
+ MatchFinder_SetLimits(p);
+}
+
+UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+ UInt32 *distances, UInt32 maxLen)
+{
+ son[_cyclicBufferPos] = curMatch;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ return distances;
+ {
+ const Byte *pb = cur - delta;
+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
+ if (pb[maxLen] == cur[maxLen] && *pb == *cur)
+ {
+ UInt32 len = 0;
+ while(++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ *distances++ = maxLen = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ return distances;
+ }
+ }
+ }
+ }
+}
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+ UInt32 *distances, UInt32 maxLen)
+{
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+ UInt32 len0 = 0, len1 = 0;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ return distances;
+ }
+ {
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ UInt32 len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ if (++len != lenLimit && pb[len] == cur[len])
+ while(++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ *distances++ = maxLen = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return distances;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+}
+
+void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
+{
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+ UInt32 len0 = 0, len1 = 0;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ return;
+ }
+ {
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ UInt32 len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ while(++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ {
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+}
+
+#define MOVE_POS \
+ ++p->cyclicBufferPos; \
+ p->buffer++; \
+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
+
+#define MOVE_POS_RET MOVE_POS return offset;
+
+void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
+
+#define GET_MATCHES_HEADER2(minLen, ret_op) \
+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
+ cur = p->buffer;
+
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
+
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
+
+#define GET_MATCHES_FOOTER(offset, maxLen) \
+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
+ distances + offset, maxLen) - distances); MOVE_POS_RET;
+
+#define SKIP_FOOTER \
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+
+UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(2)
+ HASH2_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = 0;
+ GET_MATCHES_FOOTER(offset, 1)
+}
+
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = 0;
+ GET_MATCHES_FOOTER(offset, 2)
+}
+
+UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, delta2, maxLen, offset;
+ GET_MATCHES_HEADER(3)
+
+ HASH3_CALC;
+
+ delta2 = p->pos - p->hash[hash2Value];
+ curMatch = p->hash[kFix3HashSize + hashValue];
+
+ p->hash[hash2Value] =
+ p->hash[kFix3HashSize + hashValue] = p->pos;
+
+
+ maxLen = 2;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+ break;
+ distances[0] = maxLen;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ GET_MATCHES_HEADER(4)
+
+ HASH4_CALC;
+
+ delta2 = p->pos - p->hash[ hash2Value];
+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+ curMatch = p->hash[kFix4HashSize + hashValue];
+
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+
+ maxLen = 1;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ }
+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+ {
+ maxLen = 3;
+ distances[offset + 1] = delta3 - 1;
+ offset += 2;
+ delta2 = delta3;
+ }
+ if (offset != 0)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+ break;
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+ if (maxLen < 3)
+ maxLen = 3;
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ GET_MATCHES_HEADER(4)
+
+ HASH4_CALC;
+
+ delta2 = p->pos - p->hash[ hash2Value];
+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+ curMatch = p->hash[kFix4HashSize + hashValue];
+
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+
+ maxLen = 1;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ }
+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+ {
+ maxLen = 3;
+ distances[offset + 1] = delta3 - 1;
+ offset += 2;
+ delta2 = delta3;
+ }
+ if (offset != 0)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+ break;
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS_RET;
+ }
+ }
+ if (maxLen < 3)
+ maxLen = 3;
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances + offset, maxLen) - (distances));
+ MOVE_POS_RET
+}
+
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances, 2) - (distances));
+ MOVE_POS_RET
+}
+
+void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(2)
+ HASH2_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value;
+ SKIP_HEADER(3)
+ HASH3_CALC;
+ curMatch = p->hash[kFix3HashSize + hashValue];
+ p->hash[hash2Value] =
+ p->hash[kFix3HashSize + hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value, hash3Value;
+ SKIP_HEADER(4)
+ HASH4_CALC;
+ curMatch = p->hash[kFix4HashSize + hashValue];
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] = p->pos;
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value, hash3Value;
+ SKIP_HEADER(4)
+ HASH4_CALC;
+ curMatch = p->hash[kFix4HashSize + hashValue];
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
+{
+ vTable->Init = (Mf_Init_Func)MatchFinder_Init;
+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
+ if (!p->btMode)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ }
+ else if (p->numHashBytes == 2)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
+ }
+ else if (p->numHashBytes == 3)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
+ }
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
+ }
+}
Added: trunk/lzma/C/Compress/Lz/MatchFinder.h
===================================================================
--- trunk/lzma/C/Compress/Lz/MatchFinder.h (rev 0)
+++ trunk/lzma/C/Compress/Lz/MatchFinder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,106 @@
+/* MatchFinder.h */
+
+#ifndef __MATCHFINDER_H
+#define __MATCHFINDER_H
+
+#include "../../IStream.h"
+
+typedef UInt32 CLzRef;
+
+typedef struct _CMatchFinder
+{
+ Byte *buffer;
+ UInt32 pos;
+ UInt32 posLimit;
+ UInt32 streamPos;
+ UInt32 lenLimit;
+
+ UInt32 cyclicBufferPos;
+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+
+ UInt32 matchMaxLen;
+ CLzRef *hash;
+ CLzRef *son;
+ UInt32 hashMask;
+ UInt32 cutValue;
+
+ Byte *bufferBase;
+ ISeqInStream *stream;
+ int streamEndWasReached;
+
+ UInt32 blockSize;
+ UInt32 keepSizeBefore;
+ UInt32 keepSizeAfter;
+
+ UInt32 numHashBytes;
+ int directInput;
+ int btMode;
+ /* int skipModeBits; */
+ int bigHash;
+ UInt32 historySize;
+ UInt32 fixedHashSize;
+ UInt32 hashSizeSum;
+ UInt32 numSons;
+
+ HRes result;
+} CMatchFinder;
+
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
+
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
+
+int MatchFinder_NeedMove(CMatchFinder *p);
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
+void MatchFinder_MoveBlock(CMatchFinder *p);
+void MatchFinder_ReadIfRequired(CMatchFinder *p);
+
+void MatchFinder_Construct(CMatchFinder *p);
+
+/* Conditions:
+ historySize <= 3 GB
+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
+*/
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+ ISzAlloc *alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+ UInt32 *distances, UInt32 maxLen);
+
+/*
+Conditions:
+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
+*/
+
+typedef void (*Mf_Init_Func)(void *object);
+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
+typedef void (*Mf_Skip_Func)(void *object, UInt32);
+
+typedef struct _IMatchFinder
+{
+ Mf_Init_Func Init;
+ Mf_GetIndexByte_Func GetIndexByte;
+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
+ Mf_GetMatches_Func GetMatches;
+ Mf_Skip_Func Skip;
+} IMatchFinder;
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+
+void MatchFinder_Init(CMatchFinder *p);
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+
+#endif
Added: trunk/lzma/C/Compress/Lz/MatchFinderMt.c
===================================================================
--- trunk/lzma/C/Compress/Lz/MatchFinderMt.c (rev 0)
+++ trunk/lzma/C/Compress/Lz/MatchFinderMt.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,806 @@
+/* MatchFinderMt.c */
+
+#ifdef _WIN32
+#define USE_ALLOCA
+#endif
+
+#ifdef USE_ALLOCA
+#ifdef _WIN32
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#endif
+
+#include "../../7zCrc.h"
+#include "LzHash.h"
+
+#include "MatchFinderMt.h"
+
+void MtSync_Construct(CMtSync *p)
+{
+ p->wasCreated = False;
+ p->csWasInitialized = False;
+ p->csWasEntered = False;
+ Thread_Construct(&p->thread);
+ Event_Construct(&p->canStart);
+ Event_Construct(&p->wasStarted);
+ Event_Construct(&p->wasStopped);
+ Semaphore_Construct(&p->freeSemaphore);
+ Semaphore_Construct(&p->filledSemaphore);
+}
+
+void MtSync_GetNextBlock(CMtSync *p)
+{
+ if (p->needStart)
+ {
+ p->numProcessedBlocks = 1;
+ p->needStart = False;
+ p->stopWriting = False;
+ p->exit = False;
+ Event_Reset(&p->wasStarted);
+ Event_Reset(&p->wasStopped);
+
+ Event_Set(&p->canStart);
+ Event_Wait(&p->wasStarted);
+ }
+ else
+ {
+ CriticalSection_Leave(&p->cs);
+ p->csWasEntered = False;
+ p->numProcessedBlocks++;
+ Semaphore_Release1(&p->freeSemaphore);
+ }
+ Semaphore_Wait(&p->filledSemaphore);
+ CriticalSection_Enter(&p->cs);
+ p->csWasEntered = True;
+}
+
+/* MtSync_StopWriting must be called if Writing was started */
+
+void MtSync_StopWriting(CMtSync *p)
+{
+ UInt32 myNumBlocks = p->numProcessedBlocks;
+ if (!Thread_WasCreated(&p->thread) || p->needStart)
+ return;
+ p->stopWriting = True;
+ if (p->csWasEntered)
+ {
+ CriticalSection_Leave(&p->cs);
+ p->csWasEntered = False;
+ }
+ Semaphore_Release1(&p->freeSemaphore);
+
+ Event_Wait(&p->wasStopped);
+
+ while (myNumBlocks++ != p->numProcessedBlocks)
+ {
+ Semaphore_Wait(&p->filledSemaphore);
+ Semaphore_Release1(&p->freeSemaphore);
+ }
+ p->needStart = True;
+}
+
+void MtSync_Destruct(CMtSync *p)
+{
+ if (Thread_WasCreated(&p->thread))
+ {
+ MtSync_StopWriting(p);
+ p->exit = True;
+ if (p->needStart)
+ Event_Set(&p->canStart);
+ Thread_Wait(&p->thread);
+ Thread_Close(&p->thread);
+ }
+ if (p->csWasInitialized)
+ {
+ CriticalSection_Delete(&p->cs);
+ p->csWasInitialized = False;
+ }
+
+ Event_Close(&p->canStart);
+ Event_Close(&p->wasStarted);
+ Event_Close(&p->wasStopped);
+ Semaphore_Close(&p->freeSemaphore);
+ Semaphore_Close(&p->filledSemaphore);
+
+ p->wasCreated = False;
+}
+
+HRes MtSync_Create2(CMtSync *p, unsigned (StdCall *startAddress)(void *), void *obj, UInt32 numBlocks)
+{
+ if (p->wasCreated)
+ return SZ_OK;
+
+ RINOK(CriticalSection_Init(&p->cs));
+ p->csWasInitialized = True;
+
+ RINOK(AutoResetEvent_CreateNotSignaled(&p->canStart));
+ RINOK(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
+ RINOK(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
+
+ RINOK(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
+ RINOK(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
+
+ p->needStart = True;
+
+ RINOK(Thread_Create(&p->thread, startAddress, obj));
+ p->wasCreated = True;
+ return SZ_OK;
+}
+
+HRes MtSync_Create(CMtSync *p, unsigned (StdCall *startAddress)(void *), void *obj, UInt32 numBlocks)
+{
+ HRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
+ if (res != SZ_OK)
+ MtSync_Destruct(p);
+ return res;
+}
+
+
+void MtSync_Init(CMtSync *p) { p->needStart = True; }
+
+#define kMtMaxValForNormalize 0xFFFFFFFF
+
+#define DEF_GetHeads(name, v) \
+static void GetHeads ## name(const Byte *p, UInt32 pos, \
+UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads) { \
+for (; numHeads != 0; numHeads--) { \
+const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
+
+DEF_GetHeads(2, (p[0] | ((UInt32)p[1] << 8)) & hashMask)
+DEF_GetHeads(3, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
+DEF_GetHeads(4, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (g_CrcTable[p[3]] << 5)) & hashMask)
+DEF_GetHeads(4b, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
+DEF_GetHeads(5, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (g_CrcTable[p[3]] << 5) ^ (g_CrcTable[p[4]] << 3)) & hashMask)
+
+void HashThreadFunc(CMatchFinderMt *mt)
+{
+ CMtSync *p = &mt->hashSync;
+ for (;;)
+ {
+ UInt32 numProcessedBlocks = 0;
+ Event_Wait(&p->canStart);
+ Event_Set(&p->wasStarted);
+ for (;;)
+ {
+ if (p->exit)
+ return;
+ if (p->stopWriting)
+ {
+ p->numProcessedBlocks = numProcessedBlocks;
+ Event_Set(&p->wasStopped);
+ break;
+ }
+
+ {
+ CMatchFinder *mf = mt->MatchFinder;
+ if (MatchFinder_NeedMove(mf))
+ {
+ CriticalSection_Enter(&mt->btSync.cs);
+ CriticalSection_Enter(&mt->hashSync.cs);
+ {
+ const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
+ const Byte *afterPtr;
+ MatchFinder_MoveBlock(mf);
+ afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
+ mt->pointerToCurPos -= beforePtr - afterPtr;
+ mt->buffer -= beforePtr - afterPtr;
+ }
+ CriticalSection_Leave(&mt->btSync.cs);
+ CriticalSection_Leave(&mt->hashSync.cs);
+ continue;
+ }
+
+ Semaphore_Wait(&p->freeSemaphore);
+
+ MatchFinder_ReadIfRequired(mf);
+ if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
+ {
+ UInt32 subValue = (mf->pos - mf->historySize - 1);
+ MatchFinder_ReduceOffsets(mf, subValue);
+ MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
+ }
+ {
+ UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
+ UInt32 num = mf->streamPos - mf->pos;
+ heads[0] = 2;
+ heads[1] = num;
+ if (num >= mf->numHashBytes)
+ {
+ num = num - mf->numHashBytes + 1;
+ if (num > kMtHashBlockSize - 2)
+ num = kMtHashBlockSize - 2;
+ mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num);
+ heads[0] += num;
+ }
+ mf->pos += num;
+ mf->buffer += num;
+ }
+ }
+
+ Semaphore_Release1(&p->filledSemaphore);
+ }
+ }
+}
+
+void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
+{
+ MtSync_GetNextBlock(&p->hashSync);
+ p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
+ p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];
+ p->hashNumAvail = p->hashBuf[p->hashBufPos++];
+}
+
+#define kEmptyHashValue 0
+
+/* #define MFMT_GM_INLINE */
+
+#ifdef MFMT_GM_INLINE
+
+#if _MSC_VER >= 1300
+#define NO_INLINE __declspec(noinline) __fastcall
+#else
+#ifdef _MSC_VER
+#define NO_INLINE __fastcall
+#endif
+#endif
+
+Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+ UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
+{
+ do
+ {
+ UInt32 *distances = _distances + 1;
+ UInt32 curMatch = pos - *hash++;
+
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+ UInt32 len0 = 0, len1 = 0;
+ UInt32 cutValue = _cutValue;
+ UInt32 maxLen = _maxLen;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ break;
+ }
+ {
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ UInt32 len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ if (++len != lenLimit && pb[len] == cur[len])
+ while(++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ *distances++ = maxLen = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ break;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+ pos++;
+ _cyclicBufferPos++;
+ cur++;
+ {
+ UInt32 num = (UInt32)(distances - _distances);
+ *_distances = num - 1;
+ _distances += num;
+ limit -= num;
+ }
+ }
+ while (limit > 0 && --size != 0);
+ *posRes = pos;
+ return limit;
+}
+
+#endif
+
+void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ UInt32 numProcessed = 0;
+ UInt32 curPos = 2;
+ UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
+ distances[1] = p->hashNumAvail;
+ while (curPos < limit)
+ {
+ if (p->hashBufPos == p->hashBufPosLimit)
+ {
+ MatchFinderMt_GetNextBlock_Hash(p);
+ distances[1] = numProcessed + p->hashNumAvail;
+ if (p->hashNumAvail >= p->numHashBytes)
+ continue;
+ for (; p->hashNumAvail != 0; p->hashNumAvail--)
+ distances[curPos++] = 0;
+ break;
+ }
+ {
+ UInt32 size = p->hashBufPosLimit - p->hashBufPos;
+ UInt32 lenLimit = p->matchMaxLen;
+ UInt32 pos = p->pos;
+ UInt32 cyclicBufferPos = p->cyclicBufferPos;
+ if (lenLimit >= p->hashNumAvail)
+ lenLimit = p->hashNumAvail;
+ {
+ UInt32 size2 = p->hashNumAvail - lenLimit + 1;
+ if (size2 < size)
+ size = size2;
+ size2 = p->cyclicBufferSize - cyclicBufferPos;
+ if (size2 < size)
+ size = size2;
+ }
+ #ifndef MFMT_GM_INLINE
+ while (curPos < limit && size-- != 0)
+ {
+ UInt32 *startDistances = distances + curPos;
+ UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
+ pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
+ startDistances + 1, p->numHashBytes - 1) - startDistances);
+ *startDistances = num - 1;
+ curPos += num;
+ cyclicBufferPos++;
+ pos++;
+ p->buffer++;
+ }
+ #else
+ {
+ UInt32 posRes;
+ curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
+ distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
+ p->hashBufPos += posRes - pos;
+ cyclicBufferPos += posRes - pos;
+ p->buffer += posRes - pos;
+ pos = posRes;
+ }
+ #endif
+
+ numProcessed += pos - p->pos;
+ p->hashNumAvail -= pos - p->pos;
+ p->pos = pos;
+ if (cyclicBufferPos == p->cyclicBufferSize)
+ cyclicBufferPos = 0;
+ p->cyclicBufferPos = cyclicBufferPos;
+ }
+ }
+ distances[0] = curPos;
+}
+
+void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
+{
+ CMtSync *sync = &p->hashSync;
+ if (!sync->needStart)
+ {
+ CriticalSection_Enter(&sync->cs);
+ sync->csWasEntered = True;
+ }
+
+ BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
+
+ if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
+ {
+ UInt32 subValue = p->pos - p->cyclicBufferSize;
+ MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
+ p->pos -= subValue;
+ }
+
+ if (!sync->needStart)
+ {
+ CriticalSection_Leave(&sync->cs);
+ sync->csWasEntered = False;
+ }
+}
+
+void BtThreadFunc(CMatchFinderMt *mt)
+{
+ CMtSync *p = &mt->btSync;
+ for (;;)
+ {
+ UInt32 blockIndex = 0;
+ Event_Wait(&p->canStart);
+ Event_Set(&p->wasStarted);
+ for (;;)
+ {
+ if (p->exit)
+ return;
+ if (p->stopWriting)
+ {
+ p->numProcessedBlocks = blockIndex;
+ MtSync_StopWriting(&mt->hashSync);
+ Event_Set(&p->wasStopped);
+ break;
+ }
+ Semaphore_Wait(&p->freeSemaphore);
+ BtFillBlock(mt, blockIndex++);
+ Semaphore_Release1(&p->filledSemaphore);
+ }
+ }
+}
+
+void MatchFinderMt_Construct(CMatchFinderMt *p)
+{
+ p->hashBuf = 0;
+ MtSync_Construct(&p->hashSync);
+ MtSync_Construct(&p->btSync);
+}
+
+void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
+{
+ alloc->Free(p->hashBuf);
+ p->hashBuf = 0;
+}
+
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
+{
+ MtSync_Destruct(&p->hashSync);
+ MtSync_Destruct(&p->btSync);
+ MatchFinderMt_FreeMem(p, alloc);
+}
+
+#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
+#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
+
+static unsigned StdCall HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
+static unsigned StdCall BtThreadFunc2(void *p)
+{
+ #ifdef USE_ALLOCA
+ alloca(0x180);
+ #endif
+ BtThreadFunc((CMatchFinderMt *)p);
+ return 0;
+}
+
+HRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
+{
+ CMatchFinder *mf = p->MatchFinder;
+ p->historySize = historySize;
+ if (kMtBtBlockSize <= matchMaxLen * 4)
+ return E_INVALIDARG;
+ if (p->hashBuf == 0)
+ {
+ p->hashBuf = (UInt32 *)alloc->Alloc((kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
+ if (p->hashBuf == 0)
+ return SZE_OUTOFMEMORY;
+ p->btBuf = p->hashBuf + kHashBufferSize;
+ }
+ keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
+ keepAddBufferAfter += kMtHashBlockSize;
+ if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
+ return SZE_OUTOFMEMORY;
+
+ RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));
+ RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));
+ return SZ_OK;
+}
+
+/* Call it after ReleaseStream / SetStream */
+void MatchFinderMt_Init(CMatchFinderMt *p)
+{
+ CMatchFinder *mf = p->MatchFinder;
+ p->btBufPos = p->btBufPosLimit = 0;
+ p->hashBufPos = p->hashBufPosLimit = 0;
+ MatchFinder_Init(mf);
+ p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
+ p->btNumAvailBytes = 0;
+ p->lzPos = p->historySize + 1;
+
+ p->hash = mf->hash;
+ p->fixedHashSize = mf->fixedHashSize;
+
+ p->son = mf->son;
+ p->matchMaxLen = mf->matchMaxLen;
+ p->numHashBytes = mf->numHashBytes;
+ p->pos = mf->pos;
+ p->buffer = mf->buffer;
+ p->cyclicBufferPos = mf->cyclicBufferPos;
+ p->cyclicBufferSize = mf->cyclicBufferSize;
+ p->cutValue = mf->cutValue;
+}
+
+/* ReleaseStream is required to finish multithreading */
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
+{
+ MtSync_StopWriting(&p->btSync);
+ /* p->MatchFinder->ReleaseStream(); */
+}
+
+void MatchFinderMt_Normalize(CMatchFinderMt *p)
+{
+ MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
+ p->lzPos = p->historySize + 1;
+}
+
+void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
+{
+ UInt32 blockIndex;
+ MtSync_GetNextBlock(&p->btSync);
+ blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);
+ p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
+ p->btBufPosLimit += p->btBuf[p->btBufPos++];
+ p->btNumAvailBytes = p->btBuf[p->btBufPos++];
+ if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
+ MatchFinderMt_Normalize(p);
+}
+
+const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
+{
+ return p->pointerToCurPos;
+}
+
+#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
+
+UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
+{
+ GET_NEXT_BLOCK_IF_REQUIRED;
+ return p->btNumAvailBytes;
+}
+
+Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
+{
+ return p->pointerToCurPos[index];
+}
+
+UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 hash2Value, curMatch2;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH2_CALC
+
+ curMatch2 = hash[hash2Value];
+ hash[hash2Value] = lzPos;
+
+ if (curMatch2 >= matchMinPos)
+ if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ *distances++ = 2;
+ *distances++ = lzPos - curMatch2 - 1;
+ }
+ return distances;
+}
+
+UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH3_CALC
+
+ curMatch2 = hash[ hash2Value];
+ curMatch3 = hash[kFix3HashSize + hash3Value];
+
+ hash[ hash2Value] =
+ hash[kFix3HashSize + hash3Value] =
+ lzPos;
+
+ if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch2 - 1;
+ if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
+ {
+ distances[0] = 3;
+ return distances + 2;
+ }
+ distances[0] = 2;
+ distances += 2;
+ }
+ if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
+ {
+ *distances++ = 3;
+ *distances++ = lzPos - curMatch3 - 1;
+ }
+ return distances;
+}
+
+/*
+UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH4_CALC
+
+ curMatch2 = hash[ hash2Value];
+ curMatch3 = hash[kFix3HashSize + hash3Value];
+ curMatch4 = hash[kFix4HashSize + hash4Value];
+
+ hash[ hash2Value] =
+ hash[kFix3HashSize + hash3Value] =
+ hash[kFix4HashSize + hash4Value] =
+ lzPos;
+
+ if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch2 - 1;
+ if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
+ {
+ distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
+ return distances + 2;
+ }
+ distances[0] = 2;
+ distances += 2;
+ }
+ if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch3 - 1;
+ if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])
+ {
+ distances[0] = 4;
+ return distances + 2;
+ }
+ distances[0] = 3;
+ distances += 2;
+ }
+
+ if (curMatch4 >= matchMinPos)
+ if (
+ cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&
+ cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]
+ )
+ {
+ *distances++ = 4;
+ *distances++ = lzPos - curMatch4 - 1;
+ }
+ return distances;
+}
+*/
+
+#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
+
+UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ const UInt32 *btBuf = p->btBuf + p->btBufPos;
+ UInt32 len = *btBuf++;
+ p->btBufPos += 1 + len;
+ p->btNumAvailBytes--;
+ {
+ UInt32 i;
+ for (i = 0; i < len; i += 2)
+ {
+ *distances++ = *btBuf++;
+ *distances++ = *btBuf++;
+ }
+ }
+ INCREASE_LZ_POS
+ return len;
+}
+
+UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ const UInt32 *btBuf = p->btBuf + p->btBufPos;
+ UInt32 len = *btBuf++;
+ p->btBufPos += 1 + len;
+
+ if (len == 0)
+ {
+ if (p->btNumAvailBytes-- >= 4)
+ len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
+ }
+ else
+ {
+ /* Condition: there are matches in btBuf with length < p->numHashBytes */
+ UInt32 *distances2;
+ p->btNumAvailBytes--;
+ distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
+ do
+ {
+ *distances2++ = *btBuf++;
+ *distances2++ = *btBuf++;
+ }
+ while ((len -= 2) != 0);
+ len = (UInt32)(distances2 - (distances));
+ }
+ INCREASE_LZ_POS
+ return len;
+}
+
+#define SKIP_HEADER2 do { GET_NEXT_BLOCK_IF_REQUIRED
+#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
+#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while(--num != 0);
+
+void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER2 { p->btNumAvailBytes--;
+ SKIP_FOOTER
+}
+
+void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(2)
+ UInt32 hash2Value;
+ MT_HASH2_CALC
+ hash[hash2Value] = p->lzPos;
+ SKIP_FOOTER
+}
+
+void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(3)
+ UInt32 hash2Value, hash3Value;
+ MT_HASH3_CALC
+ hash[kFix3HashSize + hash3Value] =
+ hash[ hash2Value] =
+ p->lzPos;
+ SKIP_FOOTER
+}
+
+/*
+void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(4)
+ UInt32 hash2Value, hash3Value, hash4Value;
+ MT_HASH4_CALC
+ hash[kFix4HashSize + hash4Value] =
+ hash[kFix3HashSize + hash3Value] =
+ hash[ hash2Value] =
+ p->lzPos;
+ SKIP_FOOTER
+}
+*/
+
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
+{
+ vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
+ vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
+ switch(p->MatchFinder->numHashBytes)
+ {
+ case 2:
+ p->GetHeadsFunc = GetHeads2;
+ p->MixMatchesFunc = (Mf_Mix_Matches)0;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
+ vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
+ break;
+ case 3:
+ p->GetHeadsFunc = GetHeads3;
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
+ break;
+ default:
+ /* case 4: */
+ p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
+ /* p->GetHeadsFunc = GetHeads4; */
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
+ break;
+ /*
+ default:
+ p->GetHeadsFunc = GetHeads5;
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;
+ break;
+ */
+ }
+}
Added: trunk/lzma/C/Compress/Lz/MatchFinderMt.h
===================================================================
--- trunk/lzma/C/Compress/Lz/MatchFinderMt.h (rev 0)
+++ trunk/lzma/C/Compress/Lz/MatchFinderMt.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,95 @@
+/* MatchFinderMt.h */
+
+#ifndef __MATCHFINDERMT_H
+#define __MATCHFINDERMT_H
+
+#include "../../Threads.h"
+#include "MatchFinder.h"
+
+#define kMtHashBlockSize (1 << 13)
+#define kMtHashNumBlocks (1 << 3)
+#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
+
+#define kMtBtBlockSize (1 << 14)
+#define kMtBtNumBlocks (1 << 6)
+#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
+
+typedef struct _CMtSync
+{
+ Bool wasCreated;
+ Bool needStart;
+ Bool exit;
+ Bool stopWriting;
+
+ CThread thread;
+ CAutoResetEvent canStart;
+ CAutoResetEvent wasStarted;
+ CAutoResetEvent wasStopped;
+ CSemaphore freeSemaphore;
+ CSemaphore filledSemaphore;
+ Bool csWasInitialized;
+ Bool csWasEntered;
+ CCriticalSection cs;
+ UInt32 numProcessedBlocks;
+} CMtSync;
+
+typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
+
+/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
+#define kMtCacheLineDummy 128
+
+typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
+ UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads);
+
+typedef struct _CMatchFinderMt
+{
+ /* LZ */
+ const Byte *pointerToCurPos;
+ UInt32 *btBuf;
+ UInt32 btBufPos;
+ UInt32 btBufPosLimit;
+ UInt32 lzPos;
+ UInt32 btNumAvailBytes;
+
+ UInt32 *hash;
+ UInt32 fixedHashSize;
+ UInt32 historySize;
+
+ Mf_Mix_Matches MixMatchesFunc;
+
+ /* LZ + BT */
+ CMtSync btSync;
+ Byte btDummy[kMtCacheLineDummy];
+
+ /* BT */
+ UInt32 *hashBuf;
+ UInt32 hashBufPos;
+ UInt32 hashBufPosLimit;
+ UInt32 hashNumAvail;
+
+ CLzRef *son;
+ UInt32 matchMaxLen;
+ UInt32 numHashBytes;
+ UInt32 pos;
+ Byte *buffer;
+ UInt32 cyclicBufferPos;
+ UInt32 cyclicBufferSize; /* it must be historySize + 1 */
+ UInt32 cutValue;
+
+ /* BT + Hash */
+ CMtSync hashSync;
+ /* Byte hashDummy[kMtCacheLineDummy]; */
+
+ /* Hash */
+ Mf_GetHeads GetHeadsFunc;
+ CMatchFinder *MatchFinder;
+} CMatchFinderMt;
+
+void MatchFinderMt_Construct(CMatchFinderMt *p);
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
+HRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
+
+#endif
Added: trunk/lzma/C/Compress/Lzma/LzmaDecode.c
===================================================================
--- trunk/lzma/C/Compress/Lzma/LzmaDecode.c (rev 0)
+++ trunk/lzma/C/Compress/Lzma/LzmaDecode.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,584 @@
+/*
+ LzmaDecode.c
+ LZMA Decoder (optimized for Speed version)
+
+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this Code, expressly permits you to
+ statically or dynamically link your Code (or bind by name) to the
+ interfaces of this file without subjecting your linked Code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+ { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
+ BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+ { UpdateBit0(p); mi <<= 1; A0; } else \
+ { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
+
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+ { int i = numLevels; res = 1; \
+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+ res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+ #ifdef _LZMA_OUT_READ
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ }
+ #endif
+ return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+ CProb *p = vs->Probs;
+ SizeT nowPos = 0;
+ Byte previousByte = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+
+ #ifdef _LZMA_OUT_READ
+
+ UInt32 Range = vs->Range;
+ UInt32 Code = vs->Code;
+ #ifdef _LZMA_IN_CB
+ const Byte *Buffer = vs->Buffer;
+ const Byte *BufferLim = vs->BufferLim;
+ #else
+ const Byte *Buffer = inStream;
+ const Byte *BufferLim = inStream + inSize;
+ #endif
+ int state = vs->State;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ Byte *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ Byte tempDictionary[4];
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+ #ifdef _LZMA_IN_CB
+ RC_INIT;
+ #else
+ RC_INIT(inStream, inSize);
+ #endif
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+ #else /* if !_LZMA_OUT_READ */
+
+ int state = 0;
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+ int len = 0;
+ const Byte *Buffer;
+ const Byte *BufferLim;
+ UInt32 Range;
+ UInt32 Code;
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+
+ {
+ UInt32 i;
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ }
+
+ #ifdef _LZMA_IN_CB
+ RC_INIT;
+ #else
+ RC_INIT(inStream, inSize);
+ #endif
+
+ #endif /* _LZMA_OUT_READ */
+
+ while(nowPos < outSize)
+ {
+ CProb *prob;
+ UInt32 bound;
+ int posState = (int)(
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & posStateMask);
+
+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ int symbol = 1;
+ UpdateBit0(prob)
+ prob = p + Literal + (LZMA_LIT_SIZE *
+ (((
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ int matchByte;
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ #else
+ matchByte = outStream[nowPos - rep0];
+ #endif
+ do
+ {
+ int bit;
+ CProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & 0x100);
+ probLit = prob + 0x100 + bit + symbol;
+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ {
+ CProb *probLit = prob + symbol;
+ RC_GET_BIT(probLit, symbol)
+ }
+ previousByte = (Byte)symbol;
+
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #endif
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRep + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < kNumLitStates ? 0 : 3;
+ prob = p + LenCoder;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG0 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos;
+ #endif
+ UpdateBit0(prob);
+
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit == 0)
+ #else
+ if (nowPos == 0)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ state = state < kNumLitStates ? 9 : 11;
+ #ifdef _LZMA_OUT_READ
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+ #endif
+
+ continue;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ UpdateBit1(prob);
+ prob = p + IsRepG1 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG2 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = p + RepLenCoder;
+ }
+ {
+ int numBits, offset;
+ CProb *probLen = prob + LenChoice;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ numBits = kLenNumLowBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenChoice2;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ numBits = kLenNumMidBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ numBits = kLenNumHighBits;
+ }
+ }
+ RangeDecoderBitTreeDecode(probLen, numBits, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ int posSlot;
+ state += kNumLitStates;
+ prob = p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = (2 | ((UInt32)posSlot & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 <<= numDirectBits;
+ prob = p + SpecPos + rep0 - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ RC_NORMALIZE
+ Range >>= 1;
+ rep0 <<= 1;
+ if (Code >= Range)
+ {
+ Code -= Range;
+ rep0 |= 1;
+ }
+ }
+ while (--numDirectBits != 0);
+ prob = p + Align;
+ rep0 <<= kNumAlignBits;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ int i = 1;
+ int mi = 1;
+ do
+ {
+ CProb *prob3 = prob + mi;
+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+ i <<= 1;
+ }
+ while(--numDirectBits != 0);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+ #ifdef _LZMA_OUT_READ
+ if (rep0 > distanceLimit)
+ #else
+ if (rep0 > nowPos)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ #ifdef _LZMA_OUT_READ
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+ #endif
+
+ do
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+ }
+ }
+ RC_NORMALIZE;
+
+ #ifdef _LZMA_OUT_READ
+ vs->Range = Range;
+ vs->Code = Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = globalPos + (UInt32)nowPos;
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+ #endif
+
+ #ifdef _LZMA_IN_CB
+ vs->Buffer = Buffer;
+ vs->BufferLim = BufferLim;
+ #else
+ *inSizeProcessed = (SizeT)(Buffer - inStream);
+ #endif
+ *outSizeProcessed = nowPos;
+ return LZMA_RESULT_OK;
+}
Added: trunk/lzma/C/Compress/Lzma/LzmaDecode.h
===================================================================
--- trunk/lzma/C/Compress/Lzma/LzmaDecode.h (rev 0)
+++ trunk/lzma/C/Compress/Lzma/LzmaDecode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,113 @@
+/*
+ LzmaDecode.h
+ LZMA Decoder interface
+
+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this code, expressly permits you to
+ statically or dynamically link your code (or bind by name) to the
+ interfaces of this file without subjecting your linked code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+ int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+ int lc;
+ int lp;
+ int pb;
+ #ifdef _LZMA_OUT_READ
+ UInt32 DictionarySize;
+ #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+ CLzmaProperties Properties;
+ CProb *Probs;
+
+ #ifdef _LZMA_IN_CB
+ const unsigned char *Buffer;
+ const unsigned char *BufferLim;
+ #endif
+
+ #ifdef _LZMA_OUT_READ
+ unsigned char *Dictionary;
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 DictionaryPos;
+ UInt32 GlobalPos;
+ UInt32 DistanceLimit;
+ UInt32 Reps[4];
+ int State;
+ int RemainLen;
+ unsigned char TempDictionary[4];
+ #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *inCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
Added: trunk/lzma/C/Compress/Lzma/LzmaDecodeSize.c
===================================================================
--- trunk/lzma/C/Compress/Lzma/LzmaDecodeSize.c (rev 0)
+++ trunk/lzma/C/Compress/Lzma/LzmaDecodeSize.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,712 @@
+/*
+ LzmaDecodeSize.c
+ LZMA Decoder (optimized for Size version)
+
+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this code, expressly permits you to
+ statically or dynamically link your code (or bind by name) to the
+ interfaces of this file without subjecting your linked code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+typedef struct _CRangeDecoder
+{
+ const Byte *Buffer;
+ const Byte *BufferLim;
+ UInt32 Range;
+ UInt32 Code;
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback;
+ int Result;
+ #endif
+ int ExtraBytes;
+} CRangeDecoder;
+
+Byte RangeDecoderReadByte(CRangeDecoder *rd)
+{
+ if (rd->Buffer == rd->BufferLim)
+ {
+ #ifdef _LZMA_IN_CB
+ SizeT size;
+ rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
+ rd->BufferLim = rd->Buffer + size;
+ if (size == 0)
+ #endif
+ {
+ rd->ExtraBytes = 1;
+ return 0xFF;
+ }
+ }
+ return (*rd->Buffer++);
+}
+
+/* #define ReadByte (*rd->Buffer++) */
+#define ReadByte (RangeDecoderReadByte(rd))
+
+void RangeDecoderInit(CRangeDecoder *rd
+ #ifndef _LZMA_IN_CB
+ , const Byte *stream, SizeT bufferSize
+ #endif
+ )
+{
+ int i;
+ #ifdef _LZMA_IN_CB
+ rd->Buffer = rd->BufferLim = 0;
+ #else
+ rd->Buffer = stream;
+ rd->BufferLim = stream + bufferSize;
+ #endif
+ rd->ExtraBytes = 0;
+ rd->Code = 0;
+ rd->Range = (0xFFFFFFFF);
+ for(i = 0; i < 5; i++)
+ rd->Code = (rd->Code << 8) | ReadByte;
+}
+
+#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
+#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
+#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
+
+UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
+{
+ RC_INIT_VAR
+ UInt32 result = 0;
+ int i;
+ for (i = numTotalBits; i != 0; i--)
+ {
+ /* UInt32 t; */
+ range >>= 1;
+
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ /*
+ t = (code - range) >> 31;
+ t &= 1;
+ code -= range & (t - 1);
+ result = (result + result) | (1 - t);
+ */
+ RC_NORMALIZE
+ }
+ RC_FLUSH_VAR
+ return result;
+}
+
+int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
+{
+ UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
+ if (rd->Code < bound)
+ {
+ rd->Range = bound;
+ *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
+ if (rd->Range < kTopValue)
+ {
+ rd->Code = (rd->Code << 8) | ReadByte;
+ rd->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ rd->Range -= bound;
+ rd->Code -= bound;
+ *prob -= (*prob) >> kNumMoveBits;
+ if (rd->Range < kTopValue)
+ {
+ rd->Code = (rd->Code << 8) | ReadByte;
+ rd->Range <<= 8;
+ }
+ return 1;
+ }
+}
+
+#define RC_GET_BIT2(prob, mi, A0, A1) \
+ UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
+ if (code < bound) \
+ { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
+ else \
+ { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
+ RC_NORMALIZE
+
+#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
+
+int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
+{
+ int mi = 1;
+ int i;
+ #ifdef _LZMA_LOC_OPT
+ RC_INIT_VAR
+ #endif
+ for(i = numLevels; i != 0; i--)
+ {
+ #ifdef _LZMA_LOC_OPT
+ CProb *prob = probs + mi;
+ RC_GET_BIT(prob, mi)
+ #else
+ mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
+ #endif
+ }
+ #ifdef _LZMA_LOC_OPT
+ RC_FLUSH_VAR
+ #endif
+ return mi - (1 << numLevels);
+}
+
+int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
+{
+ int mi = 1;
+ int i;
+ int symbol = 0;
+ #ifdef _LZMA_LOC_OPT
+ RC_INIT_VAR
+ #endif
+ for(i = 0; i < numLevels; i++)
+ {
+ #ifdef _LZMA_LOC_OPT
+ CProb *prob = probs + mi;
+ RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
+ #else
+ int bit = RangeDecoderBitDecode(probs + mi, rd);
+ mi = mi + mi + bit;
+ symbol |= (bit << i);
+ #endif
+ }
+ #ifdef _LZMA_LOC_OPT
+ RC_FLUSH_VAR
+ #endif
+ return symbol;
+}
+
+Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
+{
+ int symbol = 1;
+ #ifdef _LZMA_LOC_OPT
+ RC_INIT_VAR
+ #endif
+ do
+ {
+ #ifdef _LZMA_LOC_OPT
+ CProb *prob = probs + symbol;
+ RC_GET_BIT(prob, symbol)
+ #else
+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
+ #endif
+ }
+ while (symbol < 0x100);
+ #ifdef _LZMA_LOC_OPT
+ RC_FLUSH_VAR
+ #endif
+ return symbol;
+}
+
+Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
+{
+ int symbol = 1;
+ #ifdef _LZMA_LOC_OPT
+ RC_INIT_VAR
+ #endif
+ do
+ {
+ int bit;
+ int matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ #ifdef _LZMA_LOC_OPT
+ {
+ CProb *prob = probs + 0x100 + (matchBit << 8) + symbol;
+ RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
+ }
+ #else
+ bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd);
+ symbol = (symbol << 1) | bit;
+ #endif
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ #ifdef _LZMA_LOC_OPT
+ CProb *prob = probs + symbol;
+ RC_GET_BIT(prob, symbol)
+ #else
+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
+ #endif
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ #ifdef _LZMA_LOC_OPT
+ RC_FLUSH_VAR
+ #endif
+ return symbol;
+}
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
+{
+ if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
+ return RangeDecoderBitTreeDecode(p + LenLow +
+ (posState << kLenNumLowBits), kLenNumLowBits, rd);
+ if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
+ return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
+ (posState << kLenNumMidBits), kLenNumMidBits, rd);
+ return kLenNumLowSymbols + kLenNumMidSymbols +
+ RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
+}
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+ #ifdef _LZMA_OUT_READ
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ }
+ #endif
+ return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ #ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback,
+ #else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ #endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+ CProb *p = vs->Probs;
+ SizeT nowPos = 0;
+ Byte previousByte = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+ CRangeDecoder rd;
+
+ #ifdef _LZMA_OUT_READ
+
+ int state = vs->State;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ Byte *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ Byte tempDictionary[4];
+
+ rd.Range = vs->Range;
+ rd.Code = vs->Code;
+ #ifdef _LZMA_IN_CB
+ rd.InCallback = InCallback;
+ rd.Buffer = vs->Buffer;
+ rd.BufferLim = vs->BufferLim;
+ #else
+ rd.Buffer = inStream;
+ rd.BufferLim = inStream + inSize;
+ #endif
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+ RangeDecoderInit(&rd
+ #ifndef _LZMA_IN_CB
+ , inStream, inSize
+ #endif
+ );
+ #ifdef _LZMA_IN_CB
+ if (rd.Result != LZMA_RESULT_OK)
+ return rd.Result;
+ #endif
+ if (rd.ExtraBytes != 0)
+ return LZMA_RESULT_DATA_ERROR;
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+ #ifdef _LZMA_IN_CB
+ rd.Result = LZMA_RESULT_OK;
+ #endif
+ rd.ExtraBytes = 0;
+
+ #else /* if !_LZMA_OUT_READ */
+
+ int state = 0;
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+ int len = 0;
+
+ #ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+ #endif
+ *outSizeProcessed = 0;
+
+ {
+ UInt32 i;
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ }
+
+ #ifdef _LZMA_IN_CB
+ rd.InCallback = InCallback;
+ #endif
+ RangeDecoderInit(&rd
+ #ifndef _LZMA_IN_CB
+ , inStream, inSize
+ #endif
+ );
+
+ #ifdef _LZMA_IN_CB
+ if (rd.Result != LZMA_RESULT_OK)
+ return rd.Result;
+ #endif
+ if (rd.ExtraBytes != 0)
+ return LZMA_RESULT_DATA_ERROR;
+
+ #endif /* _LZMA_OUT_READ */
+
+
+ while(nowPos < outSize)
+ {
+ int posState = (int)(
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & posStateMask);
+ #ifdef _LZMA_IN_CB
+ if (rd.Result != LZMA_RESULT_OK)
+ return rd.Result;
+ #endif
+ if (rd.ExtraBytes != 0)
+ return LZMA_RESULT_DATA_ERROR;
+ if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
+ {
+ CProb *probs = p + Literal + (LZMA_LIT_SIZE *
+ (((
+ (nowPos
+ #ifdef _LZMA_OUT_READ
+ + globalPos
+ #endif
+ )
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ Byte matchByte;
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ #else
+ matchByte = outStream[nowPos - rep0];
+ #endif
+ previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
+ }
+ else
+ previousByte = LzmaLiteralDecode(probs, &rd);
+ outStream[nowPos++] = previousByte;
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #endif
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+ else
+ {
+ if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
+ {
+ if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
+ {
+ if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos;
+ #endif
+
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit == 0)
+ #else
+ if (nowPos == 0)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ state = state < 7 ? 9 : 11;
+ #ifdef _LZMA_OUT_READ
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ outStream[nowPos++] = previousByte;
+
+ #ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+ #endif
+ continue;
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
+ distance = rep1;
+ else
+ {
+ if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
+ state = state < 7 ? 8 : 11;
+ }
+ else
+ {
+ int posSlot;
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < 7 ? 7 : 10;
+ len = LzmaLenDecode(p + LenCoder, &rd, posState);
+ posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits), kNumPosSlotBits, &rd);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 += RangeDecoderReverseBitTreeDecode(
+ p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
+ }
+ else
+ {
+ rep0 += RangeDecoderDecodeDirectBits(&rd,
+ numDirectBits - kNumAlignBits) << kNumAlignBits;
+ rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+ #ifdef _LZMA_OUT_READ
+ if (rep0 > distanceLimit)
+ #else
+ if (rep0 > nowPos)
+ #endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ #ifdef _LZMA_OUT_READ
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+ #endif
+
+ do
+ {
+ #ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ #else
+ previousByte = outStream[nowPos - rep0];
+ #endif
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+ }
+ }
+
+
+ #ifdef _LZMA_OUT_READ
+ vs->Range = rd.Range;
+ vs->Code = rd.Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = globalPos + (UInt32)nowPos;
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+ #endif
+
+ #ifdef _LZMA_IN_CB
+ vs->Buffer = rd.Buffer;
+ vs->BufferLim = rd.BufferLim;
+ #else
+ *inSizeProcessed = (SizeT)(rd.Buffer - inStream);
+ #endif
+ *outSizeProcessed = nowPos;
+ return LZMA_RESULT_OK;
+}
Added: trunk/lzma/C/Compress/Lzma/LzmaStateDecode.c
===================================================================
--- trunk/lzma/C/Compress/Lzma/LzmaStateDecode.c (rev 0)
+++ trunk/lzma/C/Compress/Lzma/LzmaStateDecode.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,521 @@
+/*
+ LzmaStateDecode.c
+ LZMA Decoder (State version)
+
+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this Code, expressly permits you to
+ statically or dynamically link your Code (or bind by name) to the
+ interfaces of this file without subjecting your linked Code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaStateDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT Code = 0; Range = 0xFFFFFFFF; \
+ { int i; for(i = 0; i < 5; i++) { Code = (Code << 8) | RC_READ_BYTE; }}
+
+#define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+ { UpdateBit0(p); mi <<= 1; A0; } else \
+ { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
+
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+ { int i = numLevels; res = 1; \
+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+ res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+/* kRequiredInBufferSize = number of required input bytes for worst case:
+ longest match with longest distance.
+ kLzmaInBufferSize must be larger than kRequiredInBufferSize
+ 23 bits = 2 (match select) + 10 (len) + 6 (distance) + 4(align) + 1 (RC_NORMALIZE)
+*/
+
+#define kRequiredInBufferSize ((23 * (kNumBitModelTotalBits - kNumMoveBits + 1) + 26 + 9) / 8)
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ return LZMA_RESULT_OK;
+ }
+}
+
+int LzmaDecode(
+ CLzmaDecoderState *vs,
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
+ int finishDecoding)
+{
+ UInt32 Range = vs->Range;
+ UInt32 Code = vs->Code;
+
+ unsigned char *Buffer = vs->Buffer;
+ int BufferSize = vs->BufferSize; /* don't change it to unsigned int */
+ CProb *p = vs->Probs;
+
+ int state = vs->State;
+ unsigned char previousByte;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ SizeT nowPos = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ unsigned char *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ unsigned char tempDictionary[4];
+
+ (*inSizeProcessed) = 0;
+ (*outSizeProcessed) = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ while (inSize > 0 && BufferSize < kLzmaInBufferSize)
+ {
+ Buffer[BufferSize++] = *inStream++;
+ (*inSizeProcessed)++;
+ inSize--;
+ }
+ if (BufferSize < 5)
+ {
+ vs->BufferSize = BufferSize;
+ return finishDecoding ? LZMA_RESULT_DATA_ERROR : LZMA_RESULT_OK;
+ }
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+ RC_INIT;
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+ for (;;)
+ {
+ int bufferPos = (int)(Buffer - vs->Buffer);
+ if (BufferSize - bufferPos < kRequiredInBufferSize)
+ {
+ int i;
+ BufferSize -= bufferPos;
+ if (BufferSize < 0)
+ return LZMA_RESULT_DATA_ERROR;
+ for (i = 0; i < BufferSize; i++)
+ vs->Buffer[i] = Buffer[i];
+ Buffer = vs->Buffer;
+ while (inSize > 0 && BufferSize < kLzmaInBufferSize)
+ {
+ Buffer[BufferSize++] = *inStream++;
+ (*inSizeProcessed)++;
+ inSize--;
+ }
+ if (BufferSize < kRequiredInBufferSize && !finishDecoding)
+ break;
+ }
+ if (nowPos >= outSize)
+ break;
+ {
+ CProb *prob;
+ UInt32 bound;
+ int posState = (int)((nowPos + globalPos) & posStateMask);
+
+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ int symbol = 1;
+ UpdateBit0(prob)
+ prob = p + Literal + (LZMA_LIT_SIZE *
+ ((((nowPos + globalPos)& literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ int matchByte;
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ do
+ {
+ int bit;
+ CProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & 0x100);
+ probLit = prob + 0x100 + bit + symbol;
+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ {
+ CProb *probLit = prob + symbol;
+ RC_GET_BIT(probLit, symbol)
+ }
+ previousByte = (unsigned char)symbol;
+
+ outStream[nowPos++] = previousByte;
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRep + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < kNumLitStates ? 0 : 3;
+ prob = p + LenCoder;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG0 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ UInt32 pos;
+ UpdateBit0(prob);
+ if (distanceLimit == 0)
+ return LZMA_RESULT_DATA_ERROR;
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+ state = state < kNumLitStates ? 9 : 11;
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ outStream[nowPos++] = previousByte;
+ continue;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ UpdateBit1(prob);
+ prob = p + IsRepG1 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG2 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = p + RepLenCoder;
+ }
+ {
+ int numBits, offset;
+ CProb *probLen = prob + LenChoice;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ numBits = kLenNumLowBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenChoice2;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ numBits = kLenNumMidBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ numBits = kLenNumHighBits;
+ }
+ }
+ RangeDecoderBitTreeDecode(probLen, numBits, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ int posSlot;
+ state += kNumLitStates;
+ prob = p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = (2 | ((UInt32)posSlot & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 <<= numDirectBits;
+ prob = p + SpecPos + rep0 - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ RC_NORMALIZE
+ Range >>= 1;
+ rep0 <<= 1;
+ if (Code >= Range)
+ {
+ Code -= Range;
+ rep0 |= 1;
+ }
+ }
+ while (--numDirectBits != 0);
+ prob = p + Align;
+ rep0 <<= kNumAlignBits;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ int i = 1;
+ int mi = 1;
+ do
+ {
+ CProb *prob3 = prob + mi;
+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+ i <<= 1;
+ }
+ while(--numDirectBits != 0);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+ if (rep0 > distanceLimit)
+ return LZMA_RESULT_DATA_ERROR;
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+
+ do
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+ }
+ }
+ }
+ RC_NORMALIZE;
+
+ BufferSize -= (int)(Buffer - vs->Buffer);
+ if (BufferSize < 0)
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ int i;
+ for (i = 0; i < BufferSize; i++)
+ vs->Buffer[i] = Buffer[i];
+ }
+ vs->BufferSize = BufferSize;
+ vs->Range = Range;
+ vs->Code = Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = (UInt32)(globalPos + nowPos);
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+
+ (*outSizeProcessed) = nowPos;
+ return LZMA_RESULT_OK;
+}
Added: trunk/lzma/C/Compress/Lzma/LzmaStateDecode.h
===================================================================
--- trunk/lzma/C/Compress/Lzma/LzmaStateDecode.h (rev 0)
+++ trunk/lzma/C/Compress/Lzma/LzmaStateDecode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,96 @@
+/*
+ LzmaStateDecode.h
+ LZMA Decoder interface (State version)
+
+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+ http://www.7-zip.org/
+
+ LZMA SDK is licensed under two licenses:
+ 1) GNU Lesser General Public License (GNU LGPL)
+ 2) Common Public License (CPL)
+ It means that you can select one of these two licenses and
+ follow rules of that license.
+
+ SPECIAL EXCEPTION:
+ Igor Pavlov, as the author of this code, expressly permits you to
+ statically or dynamically link your code (or bind by name) to the
+ interfaces of this file without subjecting your linked code to the
+ terms of the CPL or GNU LGPL. Any modifications or additions
+ to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMASTATEDECODE_H
+#define __LZMASTATEDECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+ int lc;
+ int lp;
+ int pb;
+ UInt32 DictionarySize;
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(lzmaProps) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((lzmaProps)->lc + (lzmaProps)->lp)))
+
+#define kLzmaInBufferSize 64 /* don't change it. it must be larger than kRequiredInBufferSize */
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+ CLzmaProperties Properties;
+ CProb *Probs;
+ unsigned char *Dictionary;
+
+ unsigned char Buffer[kLzmaInBufferSize];
+ int BufferSize;
+
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 DictionaryPos;
+ UInt32 GlobalPos;
+ UInt32 DistanceLimit;
+ UInt32 Reps[4];
+ int State;
+ int RemainLen; /* -2: decoder needs internal initialization
+ -1: stream was finished,
+ 0: ok
+ > 0: need to write RemainLen bytes as match Reps[0],
+ */
+ unsigned char TempDictionary[4]; /* it's required when DictionarySize = 0 */
+} CLzmaDecoderState;
+
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; (vs)->BufferSize = 0; }
+
+/* LzmaDecode: decoding from input stream to output stream.
+ If finishDecoding != 0, then there are no more bytes in input stream
+ after inStream[inSize - 1]. */
+
+int LzmaDecode(CLzmaDecoderState *vs,
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
+ int finishDecoding);
+
+#endif
Added: trunk/lzma/C/Compress/Lzma/LzmaStateTest.c
===================================================================
--- trunk/lzma/C/Compress/Lzma/LzmaStateTest.c (rev 0)
+++ trunk/lzma/C/Compress/Lzma/LzmaStateTest.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,195 @@
+/*
+LzmaStateTest.c
+Test application for LZMA Decoder (State version)
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.26 (2005-08-02)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LzmaStateDecode.h"
+
+const char *kCantReadMessage = "Can not read input file";
+const char *kCantWriteMessage = "Can not write output file";
+const char *kCantAllocateMessage = "Can not allocate memory";
+
+#define kInBufferSize (1 << 15)
+#define kOutBufferSize (1 << 15)
+
+unsigned char g_InBuffer[kInBufferSize];
+unsigned char g_OutBuffer[kOutBufferSize];
+
+size_t MyReadFile(FILE *file, void *data, size_t size)
+ { return fread(data, 1, size, file); }
+
+int MyReadFileAndCheck(FILE *file, void *data, size_t size)
+ { return (MyReadFile(file, data, size) == size); }
+
+int PrintError(char *buffer, const char *message)
+{
+ sprintf(buffer + strlen(buffer), "\nError: ");
+ sprintf(buffer + strlen(buffer), message);
+ return 1;
+}
+
+int main3(FILE *inFile, FILE *outFile, char *rs)
+{
+ /* We use two 32-bit integers to construct 64-bit integer for file size.
+ You can remove outSizeHigh, if you don't need >= 4GB supporting,
+ or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+ UInt32 outSize = 0;
+ UInt32 outSizeHigh = 0;
+
+ int waitEOS = 1;
+ /* waitEOS = 1, if there is no uncompressed size in headers,
+ so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+ int i;
+ int res = 0;
+ CLzmaDecoderState state; /* it's about 140 bytes structure, if int is 32-bit */
+ unsigned char properties[LZMA_PROPERTIES_SIZE];
+ SizeT inAvail = 0;
+ unsigned char *inBuffer = 0;
+
+ if (sizeof(UInt32) < 4)
+ return PrintError(rs, "LZMA decoder needs correct UInt32");
+
+ /* Read LZMA properties for compressed stream */
+
+ if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
+ return PrintError(rs, kCantReadMessage);
+
+ /* Read uncompressed size */
+
+ for (i = 0; i < 8; i++)
+ {
+ unsigned char b;
+ if (!MyReadFileAndCheck(inFile, &b, 1))
+ return PrintError(rs, kCantReadMessage);
+ if (b != 0xFF)
+ waitEOS = 0;
+ if (i < 4)
+ outSize += (UInt32)(b) << (i * 8);
+ else
+ outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+ }
+
+ /* Decode LZMA properties and allocate memory */
+
+ if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return PrintError(rs, "Incorrect stream properties");
+ state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return PrintError(rs, kCantAllocateMessage);
+
+ if (state.Properties.DictionarySize == 0)
+ state.Dictionary = 0;
+ else
+ {
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+ if (state.Dictionary == 0)
+ {
+ free(state.Probs);
+ return PrintError(rs, kCantAllocateMessage);
+ }
+ }
+
+ /* Decompress */
+
+ LzmaDecoderInit(&state);
+
+ do
+ {
+ SizeT inProcessed, outProcessed;
+ int finishDecoding;
+ UInt32 outAvail = kOutBufferSize;
+ if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
+ outAvail = outSize;
+ if (inAvail == 0)
+ {
+ inAvail = (SizeT)MyReadFile(inFile, g_InBuffer, kInBufferSize);
+ inBuffer = g_InBuffer;
+ }
+ finishDecoding = (inAvail == 0);
+ res = LzmaDecode(&state,
+ inBuffer, inAvail, &inProcessed,
+ g_OutBuffer, outAvail, &outProcessed,
+ finishDecoding);
+ if (res != 0)
+ {
+ sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+ res = 1;
+ break;
+ }
+ inAvail -= inProcessed;
+ inBuffer += inProcessed;
+
+ if (outFile != 0)
+ if (fwrite(g_OutBuffer, 1, outProcessed, outFile) != outProcessed)
+ {
+ PrintError(rs, kCantWriteMessage);
+ res = 1;
+ break;
+ }
+
+ if (outSize < outProcessed)
+ outSizeHigh--;
+ outSize -= (UInt32)outProcessed;
+ outSize &= 0xFFFFFFFF;
+
+ if (outProcessed == 0 && finishDecoding)
+ {
+ if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
+ res = 1;
+ break;
+ }
+ }
+ while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
+
+ free(state.Dictionary);
+ free(state.Probs);
+ return res;
+}
+
+int main2(int numArgs, const char *args[], char *rs)
+{
+ FILE *inFile = 0;
+ FILE *outFile = 0;
+ int res;
+
+ sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n");
+ if (numArgs < 2 || numArgs > 3)
+ {
+ sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
+ return 1;
+ }
+
+ inFile = fopen(args[1], "rb");
+ if (inFile == 0)
+ return PrintError(rs, "Can not open input file");
+
+ if (numArgs > 2)
+ {
+ outFile = fopen(args[2], "wb+");
+ if (outFile == 0)
+ return PrintError(rs, "Can not open output file");
+ }
+
+ res = main3(inFile, outFile, rs);
+
+ if (outFile != 0)
+ fclose(outFile);
+ fclose(inFile);
+ return res;
+}
+
+int main(int numArgs, const char *args[])
+{
+ char rs[800] = { 0 };
+ int res = main2(numArgs, args, rs);
+ printf(rs);
+ return res;
+}
Added: trunk/lzma/C/Compress/Lzma/LzmaTest.c
===================================================================
--- trunk/lzma/C/Compress/Lzma/LzmaTest.c (rev 0)
+++ trunk/lzma/C/Compress/Lzma/LzmaTest.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,342 @@
+/*
+LzmaTest.c
+Test application for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.26 (2005-08-05)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LzmaDecode.h"
+
+const char *kCantReadMessage = "Can not read input file";
+const char *kCantWriteMessage = "Can not write output file";
+const char *kCantAllocateMessage = "Can not allocate memory";
+
+size_t MyReadFile(FILE *file, void *data, size_t size)
+{
+ if (size == 0)
+ return 0;
+ return fread(data, 1, size, file);
+}
+
+int MyReadFileAndCheck(FILE *file, void *data, size_t size)
+ { return (MyReadFile(file, data, size) == size);}
+
+size_t MyWriteFile(FILE *file, const void *data, size_t size)
+{
+ if (size == 0)
+ return 0;
+ return fwrite(data, 1, size, file);
+}
+
+int MyWriteFileAndCheck(FILE *file, const void *data, size_t size)
+ { return (MyWriteFile(file, data, size) == size); }
+
+#ifdef _LZMA_IN_CB
+#define kInBufferSize (1 << 15)
+typedef struct _CBuffer
+{
+ ILzmaInCallback InCallback;
+ FILE *File;
+ unsigned char Buffer[kInBufferSize];
+} CBuffer;
+
+int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
+{
+ CBuffer *b = (CBuffer *)object;
+ *buffer = b->Buffer;
+ *size = (SizeT)MyReadFile(b->File, b->Buffer, kInBufferSize);
+ return LZMA_RESULT_OK;
+}
+CBuffer g_InBuffer;
+
+#endif
+
+#ifdef _LZMA_OUT_READ
+#define kOutBufferSize (1 << 15)
+unsigned char g_OutBuffer[kOutBufferSize];
+#endif
+
+int PrintError(char *buffer, const char *message)
+{
+ sprintf(buffer + strlen(buffer), "\nError: ");
+ sprintf(buffer + strlen(buffer), message);
+ return 1;
+}
+
+int main3(FILE *inFile, FILE *outFile, char *rs)
+{
+ /* We use two 32-bit integers to construct 64-bit integer for file size.
+ You can remove outSizeHigh, if you don't need >= 4GB supporting,
+ or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+ UInt32 outSize = 0;
+ UInt32 outSizeHigh = 0;
+ #ifndef _LZMA_OUT_READ
+ SizeT outSizeFull;
+ unsigned char *outStream;
+ #endif
+
+ int waitEOS = 1;
+ /* waitEOS = 1, if there is no uncompressed size in headers,
+ so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+ #ifndef _LZMA_IN_CB
+ SizeT compressedSize;
+ unsigned char *inStream;
+ #endif
+
+ CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
+ unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+ int res;
+
+ #ifdef _LZMA_IN_CB
+ g_InBuffer.File = inFile;
+ #endif
+
+ if (sizeof(UInt32) < 4)
+ return PrintError(rs, "LZMA decoder needs correct UInt32");
+
+ #ifndef _LZMA_IN_CB
+ {
+ long length;
+ fseek(inFile, 0, SEEK_END);
+ length = ftell(inFile);
+ fseek(inFile, 0, SEEK_SET);
+ if ((long)(SizeT)length != length)
+ return PrintError(rs, "Too big compressed stream");
+ compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
+ }
+ #endif
+
+ /* Read LZMA properties for compressed stream */
+
+ if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
+ return PrintError(rs, kCantReadMessage);
+
+ /* Read uncompressed size */
+
+ {
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ unsigned char b;
+ if (!MyReadFileAndCheck(inFile, &b, 1))
+ return PrintError(rs, kCantReadMessage);
+ if (b != 0xFF)
+ waitEOS = 0;
+ if (i < 4)
+ outSize += (UInt32)(b) << (i * 8);
+ else
+ outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+ }
+
+ #ifndef _LZMA_OUT_READ
+ if (waitEOS)
+ return PrintError(rs, "Stream with EOS marker is not supported");
+ outSizeFull = (SizeT)outSize;
+ if (sizeof(SizeT) >= 8)
+ outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
+ else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
+ return PrintError(rs, "Too big uncompressed stream");
+ #endif
+ }
+
+ /* Decode LZMA properties and allocate memory */
+
+ if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return PrintError(rs, "Incorrect stream properties");
+ state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+
+ #ifdef _LZMA_OUT_READ
+ if (state.Properties.DictionarySize == 0)
+ state.Dictionary = 0;
+ else
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+ #else
+ if (outSizeFull == 0)
+ outStream = 0;
+ else
+ outStream = (unsigned char *)malloc(outSizeFull);
+ #endif
+
+ #ifndef _LZMA_IN_CB
+ if (compressedSize == 0)
+ inStream = 0;
+ else
+ inStream = (unsigned char *)malloc(compressedSize);
+ #endif
+
+ if (state.Probs == 0
+ #ifdef _LZMA_OUT_READ
+ || (state.Dictionary == 0 && state.Properties.DictionarySize != 0)
+ #else
+ || (outStream == 0 && outSizeFull != 0)
+ #endif
+ #ifndef _LZMA_IN_CB
+ || (inStream == 0 && compressedSize != 0)
+ #endif
+ )
+ {
+ free(state.Probs);
+ #ifdef _LZMA_OUT_READ
+ free(state.Dictionary);
+ #else
+ free(outStream);
+ #endif
+ #ifndef _LZMA_IN_CB
+ free(inStream);
+ #endif
+ return PrintError(rs, kCantAllocateMessage);
+ }
+
+ /* Decompress */
+
+ #ifdef _LZMA_IN_CB
+ g_InBuffer.InCallback.Read = LzmaReadCompressed;
+ #else
+ if (!MyReadFileAndCheck(inFile, inStream, compressedSize))
+ return PrintError(rs, kCantReadMessage);
+ #endif
+
+ #ifdef _LZMA_OUT_READ
+ {
+ #ifndef _LZMA_IN_CB
+ SizeT inAvail = compressedSize;
+ const unsigned char *inBuffer = inStream;
+ #endif
+ LzmaDecoderInit(&state);
+ do
+ {
+ #ifndef _LZMA_IN_CB
+ SizeT inProcessed;
+ #endif
+ SizeT outProcessed;
+ SizeT outAvail = kOutBufferSize;
+ if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
+ outAvail = (SizeT)outSize;
+ res = LzmaDecode(&state,
+ #ifdef _LZMA_IN_CB
+ &g_InBuffer.InCallback,
+ #else
+ inBuffer, inAvail, &inProcessed,
+ #endif
+ g_OutBuffer, outAvail, &outProcessed);
+ if (res != 0)
+ {
+ sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+ res = 1;
+ break;
+ }
+ #ifndef _LZMA_IN_CB
+ inAvail -= inProcessed;
+ inBuffer += inProcessed;
+ #endif
+
+ if (outFile != 0)
+ if (!MyWriteFileAndCheck(outFile, g_OutBuffer, (size_t)outProcessed))
+ {
+ PrintError(rs, kCantWriteMessage);
+ res = 1;
+ break;
+ }
+
+ if (outSize < outProcessed)
+ outSizeHigh--;
+ outSize -= (UInt32)outProcessed;
+ outSize &= 0xFFFFFFFF;
+
+ if (outProcessed == 0)
+ {
+ if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
+ res = 1;
+ break;
+ }
+ }
+ while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
+ }
+
+ #else
+ {
+ #ifndef _LZMA_IN_CB
+ SizeT inProcessed;
+ #endif
+ SizeT outProcessed;
+ res = LzmaDecode(&state,
+ #ifdef _LZMA_IN_CB
+ &g_InBuffer.InCallback,
+ #else
+ inStream, compressedSize, &inProcessed,
+ #endif
+ outStream, outSizeFull, &outProcessed);
+ if (res != 0)
+ {
+ sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+ res = 1;
+ }
+ else if (outFile != 0)
+ {
+ if (!MyWriteFileAndCheck(outFile, outStream, (size_t)outProcessed))
+ {
+ PrintError(rs, kCantWriteMessage);
+ res = 1;
+ }
+ }
+ }
+ #endif
+
+ free(state.Probs);
+ #ifdef _LZMA_OUT_READ
+ free(state.Dictionary);
+ #else
+ free(outStream);
+ #endif
+ #ifndef _LZMA_IN_CB
+ free(inStream);
+ #endif
+ return res;
+}
+
+int main2(int numArgs, const char *args[], char *rs)
+{
+ FILE *inFile = 0;
+ FILE *outFile = 0;
+ int res;
+
+ sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-05\n");
+ if (numArgs < 2 || numArgs > 3)
+ {
+ sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
+ return 1;
+ }
+
+ inFile = fopen(args[1], "rb");
+ if (inFile == 0)
+ return PrintError(rs, "Can not open input file");
+
+ if (numArgs > 2)
+ {
+ outFile = fopen(args[2], "wb+");
+ if (outFile == 0)
+ return PrintError(rs, "Can not open output file");
+ }
+
+ res = main3(inFile, outFile, rs);
+
+ if (outFile != 0)
+ fclose(outFile);
+ fclose(inFile);
+ return res;
+}
+
+int main(int numArgs, const char *args[])
+{
+ char rs[800] = { 0 };
+ int res = main2(numArgs, args, rs);
+ printf(rs);
+ return res;
+}
Added: trunk/lzma/C/Compress/Lzma/LzmaTypes.h
===================================================================
--- trunk/lzma/C/Compress/Lzma/LzmaTypes.h (rev 0)
+++ trunk/lzma/C/Compress/Lzma/LzmaTypes.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,45 @@
+/*
+LzmaTypes.h
+
+Types for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.40 (2006-05-01)
+*/
+
+#ifndef __LZMATYPES_H
+#define __LZMATYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif
+
+/* #define _LZMA_NO_SYSTEM_SIZE_T */
+/* You can use it, if you don't want <stddef.h> */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+#endif
+
+#endif
Added: trunk/lzma/C/CpuArch.h
===================================================================
--- trunk/lzma/C/CpuArch.h (rev 0)
+++ trunk/lzma/C/CpuArch.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,18 @@
+/* CpuArch.h */
+
+#ifndef __CPUARCH_H
+#define __CPUARCH_H
+
+/*
+LITTLE_ENDIAN_UNALIGN means:
+ 1) CPU is LITTLE_ENDIAN
+ 2) it's allowed to make unaligned memory accesses
+if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
+about these properties of platform.
+*/
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
+#define LITTLE_ENDIAN_UNALIGN
+#endif
+
+#endif
Added: trunk/lzma/C/IStream.h
===================================================================
--- trunk/lzma/C/IStream.h (rev 0)
+++ trunk/lzma/C/IStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,19 @@
+/* IStream.h */
+
+#ifndef __C_ISTREAM_H
+#define __C_ISTREAM_H
+
+#include "Types.h"
+
+typedef struct _ISeqInStream
+{
+ HRes (*Read)(void *object, void *data, UInt32 size, UInt32 *processedSize);
+} ISeqInStream;
+
+typedef struct _ISzAlloc
+{
+ void *(*Alloc)(size_t size);
+ void (*Free)(void *address); /* address can be 0 */
+} ISzAlloc;
+
+#endif
Added: trunk/lzma/C/Sort.c
===================================================================
--- trunk/lzma/C/Sort.c (rev 0)
+++ trunk/lzma/C/Sort.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,92 @@
+/* Sort.c */
+
+#include "Sort.h"
+
+#define HeapSortDown(p, k, size, temp) \
+ { for (;;) { \
+ UInt32 s = (k << 1); \
+ if (s > size) break; \
+ if (s < size && p[s + 1] > p[s]) s++; \
+ if (temp >= p[s]) break; \
+ p[k] = p[s]; k = s; \
+ } p[k] = temp; }
+
+void HeapSort(UInt32 *p, UInt32 size)
+{
+ if (size <= 1)
+ return;
+ p--;
+ {
+ UInt32 i = size / 2;
+ do
+ {
+ UInt32 temp = p[i];
+ UInt32 k = i;
+ HeapSortDown(p, k, size, temp)
+ }
+ while(--i != 0);
+ }
+ /*
+ do
+ {
+ UInt32 k = 1;
+ UInt32 temp = p[size];
+ p[size--] = p[1];
+ HeapSortDown(p, k, size, temp)
+ }
+ while (size > 1);
+ */
+ while (size > 3)
+ {
+ UInt32 temp = p[size];
+ UInt32 k = (p[3] > p[2]) ? 3 : 2;
+ p[size--] = p[1];
+ p[1] = p[k];
+ HeapSortDown(p, k, size, temp)
+ }
+ {
+ UInt32 temp = p[size];
+ p[size] = p[1];
+ if (size > 2 && p[2] < temp)
+ {
+ p[1] = p[2];
+ p[2] = temp;
+ }
+ else
+ p[1] = temp;
+ }
+}
+
+/*
+#define HeapSortRefDown(p, vals, n, size, temp) \
+ { UInt32 k = n; UInt32 val = vals[temp]; for (;;) { \
+ UInt32 s = (k << 1); \
+ if (s > size) break; \
+ if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \
+ if (val >= vals[p[s]]) break; \
+ p[k] = p[s]; k = s; \
+ } p[k] = temp; }
+
+void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size)
+{
+ if (size <= 1)
+ return;
+ p--;
+ {
+ UInt32 i = size / 2;
+ do
+ {
+ UInt32 temp = p[i];
+ HeapSortRefDown(p, vals, i, size, temp);
+ }
+ while(--i != 0);
+ }
+ do
+ {
+ UInt32 temp = p[size];
+ p[size--] = p[1];
+ HeapSortRefDown(p, vals, 1, size, temp);
+ }
+ while (size > 1);
+}
+*/
\ No newline at end of file
Added: trunk/lzma/C/Sort.h
===================================================================
--- trunk/lzma/C/Sort.h (rev 0)
+++ trunk/lzma/C/Sort.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,11 @@
+/* Sort.h */
+
+#ifndef __7Z_Sort_H
+#define __7Z_Sort_H
+
+#include "Types.h"
+
+void HeapSort(UInt32 *p, UInt32 size);
+/* void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size); */
+
+#endif
Added: trunk/lzma/C/Threads.c
===================================================================
--- trunk/lzma/C/Threads.c (rev 0)
+++ trunk/lzma/C/Threads.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,106 @@
+/* Threads.c */
+
+#include "Threads.h"
+#include <process.h>
+
+HRes GetError()
+{
+ DWORD res = GetLastError();
+ return (res) ? (HRes)(res) : SZE_FAIL;
+}
+
+HRes BoolToHRes(int v) { return v ? SZ_OK : GetError(); }
+HRes BOOLToHRes(BOOL v) { return v ? SZ_OK : GetError(); }
+
+HRes MyCloseHandle(HANDLE *h)
+{
+ if (*h != NULL)
+ if (!CloseHandle(*h))
+ return GetError();
+ *h = NULL;
+ return SZ_OK;
+}
+
+HRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
+{
+ unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
+ thread->handle =
+ /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
+ (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
+ /* maybe we must use errno here, but probably GetLastError() is also OK. */
+ return BoolToHRes(thread->handle != 0);
+}
+
+HRes WaitObject(HANDLE h)
+{
+ return (HRes)WaitForSingleObject(h, INFINITE);
+}
+
+HRes Thread_Wait(CThread *thread)
+{
+ if (thread->handle == NULL)
+ return 1;
+ return WaitObject(thread->handle);
+}
+
+HRes Thread_Close(CThread *thread)
+{
+ return MyCloseHandle(&thread->handle);
+}
+
+HRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
+{
+ p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
+ return BoolToHRes(p->handle != 0);
+}
+
+HRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
+ { return Event_Create(p, TRUE, initialSignaled); }
+HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
+ { return ManualResetEvent_Create(p, 0); }
+
+HRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
+ { return Event_Create(p, FALSE, initialSignaled); }
+HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
+ { return AutoResetEvent_Create(p, 0); }
+
+HRes Event_Set(CEvent *p) { return BOOLToHRes(SetEvent(p->handle)); }
+HRes Event_Reset(CEvent *p) { return BOOLToHRes(ResetEvent(p->handle)); }
+HRes Event_Wait(CEvent *p) { return WaitObject(p->handle); }
+HRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); }
+
+
+HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
+{
+ p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
+ return BoolToHRes(p->handle != 0);
+}
+
+HRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
+{
+ return BOOLToHRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
+}
+HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
+{
+ return Semaphore_Release(p, (LONG)releaseCount, NULL);
+}
+HRes Semaphore_Release1(CSemaphore *p)
+{
+ return Semaphore_ReleaseN(p, 1);
+}
+
+HRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); }
+HRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
+
+HRes CriticalSection_Init(CCriticalSection *p)
+{
+ /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
+ __try
+ {
+ InitializeCriticalSection(p);
+ /* InitializeCriticalSectionAndSpinCount(p, 0); */
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) { return SZE_OUTOFMEMORY; }
+ return SZ_OK;
+}
+
Added: trunk/lzma/C/Threads.h
===================================================================
--- trunk/lzma/C/Threads.h (rev 0)
+++ trunk/lzma/C/Threads.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,69 @@
+/* Threads.h */
+
+#ifndef __7Z_THRESDS_H
+#define __7Z_THRESDS_H
+
+#include <windows.h>
+
+#include "Types.h"
+
+typedef struct _CThread
+{
+ HANDLE handle;
+} CThread;
+
+#define Thread_Construct(thread) (thread)->handle = NULL
+#define Thread_WasCreated(thread) ((thread)->handle != NULL)
+
+typedef unsigned THREAD_FUNC_RET_TYPE;
+#define THREAD_FUNC_CALL_TYPE StdCall
+#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
+
+HRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter);
+HRes Thread_Wait(CThread *thread);
+HRes Thread_Close(CThread *thread);
+
+typedef struct _CEvent
+{
+ HANDLE handle;
+} CEvent;
+
+typedef CEvent CAutoResetEvent;
+typedef CEvent CManualResetEvent;
+
+#define Event_Construct(event) (event)->handle = NULL
+#define Event_IsCreated(event) ((event)->handle != NULL)
+
+HRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
+HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
+HRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
+HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
+HRes Event_Set(CEvent *event);
+HRes Event_Reset(CEvent *event);
+HRes Event_Wait(CEvent *event);
+HRes Event_Close(CEvent *event);
+
+
+typedef struct _CSemaphore
+{
+ HANDLE handle;
+} CSemaphore;
+
+#define Semaphore_Construct(p) (p)->handle = NULL
+
+HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
+HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
+HRes Semaphore_Release1(CSemaphore *p);
+HRes Semaphore_Wait(CSemaphore *p);
+HRes Semaphore_Close(CSemaphore *p);
+
+
+typedef CRITICAL_SECTION CCriticalSection;
+
+HRes CriticalSection_Init(CCriticalSection *p);
+#define CriticalSection_Delete(p) DeleteCriticalSection(p)
+#define CriticalSection_Enter(p) EnterCriticalSection(p)
+#define CriticalSection_Leave(p) LeaveCriticalSection(p)
+
+#endif
+
Added: trunk/lzma/C/Types.h
===================================================================
--- trunk/lzma/C/Types.h (rev 0)
+++ trunk/lzma/C/Types.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,100 @@
+/* 7zTypes.h */
+
+#ifndef __C_TYPES_H
+#define __C_TYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif
+
+#ifndef _7ZIP_INT32_DEFINED
+#define _7ZIP_INT32_DEFINED
+#ifdef _LZMA_INT32_IS_ULONG
+typedef long Int32;
+#else
+typedef int Int32;
+#endif
+#endif
+
+/* #define _SZ_NO_INT_64 */
+/* define it your compiler doesn't support long long int */
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+#ifdef _SZ_NO_INT_64
+typedef unsigned long UInt64;
+#else
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 UInt64;
+#else
+typedef unsigned long long int UInt64;
+#endif
+#endif
+#endif
+
+
+/* #define _SZ_FILE_SIZE_32 */
+/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/
+
+#ifndef CFileSize
+#ifdef _SZ_FILE_SIZE_32
+typedef UInt32 CFileSize;
+#else
+typedef UInt64 CFileSize;
+#endif
+#endif
+
+#define SZ_RESULT int
+
+typedef int HRes;
+#define RES_OK (0)
+
+#define SZ_OK (0)
+#define SZE_DATA_ERROR (1)
+#define SZE_CRC_ERROR (3)
+#define SZE_ARCHIVE_ERROR (6)
+
+#define SZE_OUTOFMEMORY (0x8007000EL)
+#define SZE_NOTIMPL (0x80004001L)
+#define SZE_FAIL (0x80004005L)
+#define SZE_INVALIDARG (0x80070057L)
+
+
+#ifndef RINOK
+#define RINOK(x) { HRes __result_ = (x); if(__result_ != 0) return __result_; }
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+#ifdef _MSC_VER
+#define StdCall __stdcall
+#else
+#define StdCall
+#endif
+
+#if _MSC_VER >= 1300
+#define MY_FAST_CALL __declspec(noinline) __fastcall
+#elif defined( _MSC_VER)
+#define MY_FAST_CALL __fastcall
+#else
+#define MY_FAST_CALL
+#endif
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7z.ico
===================================================================
(Binary files differ)
Property changes on: trunk/lzma/CPP/7zip/Archive/7z/7z.ico
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/lzma/CPP/7zip/Archive/7z/7zCompressionMode.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zCompressionMode.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zCompressionMode.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// CompressionMethod.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,50 @@
+// 7zCompressionMode.h
+
+#ifndef __7Z_COMPRESSION_MODE_H
+#define __7Z_COMPRESSION_MODE_H
+
+#include "../../../Common/MyString.h"
+
+#include "../../../Windows/PropVariant.h"
+
+#include "../../Common/MethodProps.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CMethodFull: public CMethod
+{
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+};
+
+struct CBind
+{
+ UInt32 InCoder;
+ UInt32 InStream;
+ UInt32 OutCoder;
+ UInt32 OutStream;
+};
+
+struct CCompressionMethodMode
+{
+ CObjectVector<CMethodFull> Methods;
+ CRecordVector<CBind> Binds;
+ #ifdef COMPRESS_MT
+ UInt32 NumThreads;
+ #endif
+ bool PasswordIsDefined;
+ UString Password;
+
+ bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
+ CCompressionMethodMode(): PasswordIsDefined(false)
+ #ifdef COMPRESS_MT
+ , NumThreads(1)
+ #endif
+ {}
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zDecode.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zDecode.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,330 @@
+// 7zDecode.cpp
+
+#include "StdAfx.h"
+
+#include "7zDecode.h"
+
+#include "../../IPassword.h"
+#include "../../Common/LockedStream.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/CreateCoder.h"
+#include "../../Common/FilterCoder.h"
+
+namespace NArchive {
+namespace N7z {
+
+static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
+ CBindInfoEx &bindInfo)
+{
+ bindInfo.Clear();
+ int i;
+ for (i = 0; i < folder.BindPairs.Size(); i++)
+ {
+ NCoderMixer::CBindPair bindPair;
+ bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
+ bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
+ bindInfo.BindPairs.Add(bindPair);
+ }
+ UInt32 outStreamIndex = 0;
+ for (i = 0; i < folder.Coders.Size(); i++)
+ {
+ NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+ const CCoderInfo &coderInfo = folder.Coders[i];
+ coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
+ coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
+ bindInfo.Coders.Add(coderStreamsInfo);
+ bindInfo.CoderMethodIDs.Add(coderInfo.MethodID);
+ for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
+ if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
+ bindInfo.OutStreams.Add(outStreamIndex);
+ }
+ for (i = 0; i < folder.PackStreams.Size(); i++)
+ bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
+}
+
+static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
+ const NCoderMixer::CCoderStreamsInfo &a2)
+{
+ return (a1.NumInStreams == a2.NumInStreams) &&
+ (a1.NumOutStreams == a2.NumOutStreams);
+}
+
+static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2)
+{
+ return (a1.InIndex == a2.InIndex) &&
+ (a1.OutIndex == a2.OutIndex);
+}
+
+static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
+{
+ if (a1.Coders.Size() != a2.Coders.Size())
+ return false;
+ int i;
+ for (i = 0; i < a1.Coders.Size(); i++)
+ if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
+ return false;
+ if (a1.BindPairs.Size() != a2.BindPairs.Size())
+ return false;
+ for (i = 0; i < a1.BindPairs.Size(); i++)
+ if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
+ return false;
+ for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
+ if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
+ return false;
+ if (a1.InStreams.Size() != a2.InStreams.Size())
+ return false;
+ if (a1.OutStreams.Size() != a2.OutStreams.Size())
+ return false;
+ return true;
+}
+
+CDecoder::CDecoder(bool multiThread)
+{
+ #ifndef _ST_MODE
+ multiThread = true;
+ #endif
+ _multiThread = multiThread;
+ _bindInfoExPrevIsDefined = false;
+}
+
+HRESULT CDecoder::Decode(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ IInStream *inStream,
+ UInt64 startPos,
+ const UInt64 *packSizes,
+ const CFolder &folderInfo,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
+ )
+{
+ CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
+
+ CLockedInStream lockedInStream;
+ lockedInStream.Init(inStream);
+
+ for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
+ {
+ CLockedSequentialInStreamImp *lockedStreamImpSpec = new
+ CLockedSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
+ lockedStreamImpSpec->Init(&lockedInStream, startPos);
+ startPos += packSizes[j];
+
+ CLimitedSequentialInStream *streamSpec = new
+ CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream = streamSpec;
+ streamSpec->SetStream(lockedStreamImp);
+ streamSpec->Init(packSizes[j]);
+ inStreams.Add(inStream);
+ }
+
+ int numCoders = folderInfo.Coders.Size();
+
+ CBindInfoEx bindInfo;
+ ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
+ bool createNewCoders;
+ if (!_bindInfoExPrevIsDefined)
+ createNewCoders = true;
+ else
+ createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
+ if (createNewCoders)
+ {
+ int i;
+ _decoders.Clear();
+ // _decoders2.Clear();
+
+ _mixerCoder.Release();
+
+ if (_multiThread)
+ {
+ _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT;
+ _mixerCoder = _mixerCoderMTSpec;
+ _mixerCoderCommon = _mixerCoderMTSpec;
+ }
+ else
+ {
+ #ifdef _ST_MODE
+ _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST;
+ _mixerCoder = _mixerCoderSTSpec;
+ _mixerCoderCommon = _mixerCoderSTSpec;
+ #endif
+ }
+ RINOK(_mixerCoderCommon->SetBindInfo(bindInfo));
+
+ for (i = 0; i < numCoders; i++)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+
+
+ CMyComPtr<ICompressCoder> decoder;
+ CMyComPtr<ICompressCoder2> decoder2;
+ RINOK(CreateCoder(
+ EXTERNAL_CODECS_LOC_VARS
+ coderInfo.MethodID, decoder, decoder2, false));
+ CMyComPtr<IUnknown> decoderUnknown;
+ if (coderInfo.IsSimpleCoder())
+ {
+ if (decoder == 0)
+ return E_NOTIMPL;
+
+ decoderUnknown = (IUnknown *)decoder;
+
+ if (_multiThread)
+ _mixerCoderMTSpec->AddCoder(decoder);
+ #ifdef _ST_MODE
+ else
+ _mixerCoderSTSpec->AddCoder(decoder, false);
+ #endif
+ }
+ else
+ {
+ if (decoder2 == 0)
+ return E_NOTIMPL;
+ decoderUnknown = (IUnknown *)decoder2;
+ if (_multiThread)
+ _mixerCoderMTSpec->AddCoder2(decoder2);
+ #ifdef _ST_MODE
+ else
+ _mixerCoderSTSpec->AddCoder2(decoder2, false);
+ #endif
+ }
+ _decoders.Add(decoderUnknown);
+ #ifdef EXTERNAL_CODECS
+ CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+ decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+ if (setCompressCodecsInfo)
+ {
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
+ }
+ #endif
+ }
+ _bindInfoExPrev = bindInfo;
+ _bindInfoExPrevIsDefined = true;
+ }
+ int i;
+ _mixerCoderCommon->ReInit();
+
+ UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
+ UInt32 coderIndex = 0;
+ // UInt32 coder2Index = 0;
+
+ for (i = 0; i < numCoders; i++)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
+
+ {
+ CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
+ decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
+ if (setDecoderProperties)
+ {
+ const CByteBuffer &properties = coderInfo.Properties;
+ size_t size = properties.GetCapacity();
+ if (size > 0xFFFFFFFF)
+ return E_NOTIMPL;
+ if (size > 0)
+ {
+ RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
+ }
+ }
+ }
+
+ #ifdef COMPRESS_MT
+ if (mtMode)
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+ }
+ }
+ #endif
+
+ #ifndef _NO_CRYPTO
+ {
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+ if (cryptoSetPassword)
+ {
+ if (getTextPassword == 0)
+ return E_FAIL;
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ CByteBuffer buffer;
+ UString unicodePassword(password);
+ const UInt32 sizeInBytes = unicodePassword.Length() * 2;
+ buffer.SetCapacity(sizeInBytes);
+ for (int i = 0; i < unicodePassword.Length(); i++)
+ {
+ wchar_t c = unicodePassword[i];
+ ((Byte *)buffer)[i * 2] = (Byte)c;
+ ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+ }
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const Byte *)buffer, sizeInBytes));
+ }
+ }
+ #endif
+
+ coderIndex++;
+
+ UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
+ UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
+ CRecordVector<const UInt64 *> packSizesPointers;
+ CRecordVector<const UInt64 *> unPackSizesPointers;
+ packSizesPointers.Reserve(numInStreams);
+ unPackSizesPointers.Reserve(numOutStreams);
+ UInt32 j;
+ for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
+ unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
+
+ for (j = 0; j < numInStreams; j++, packStreamIndex++)
+ {
+ int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
+ if (bindPairIndex >= 0)
+ packSizesPointers.Add(
+ &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
+ else
+ {
+ int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
+ if (index < 0)
+ return E_FAIL;
+ packSizesPointers.Add(&packSizes[index]);
+ }
+ }
+
+ _mixerCoderCommon->SetCoderInfo(i,
+ &packSizesPointers.Front(),
+ &unPackSizesPointers.Front());
+ }
+ UInt32 mainCoder, temp;
+ bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
+
+ if (_multiThread)
+ _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
+ /*
+ else
+ _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
+ */
+
+ if (numCoders == 0)
+ return 0;
+ CRecordVector<ISequentialInStream *> inStreamPointers;
+ inStreamPointers.Reserve(inStreams.Size());
+ for (i = 0; i < inStreams.Size(); i++)
+ inStreamPointers.Add(inStreams[i]);
+ ISequentialOutStream *outStreamPointer = outStream;
+ return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
+ inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zDecode.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zDecode.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zDecode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,68 @@
+// 7zDecode.h
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+
+#include "../Common/CoderMixer2.h"
+#include "../Common/CoderMixer2MT.h"
+#ifdef _ST_MODE
+#include "../Common/CoderMixer2ST.h"
+#endif
+
+#include "../../Common/CreateCoder.h"
+
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CBindInfoEx: public NCoderMixer::CBindInfo
+{
+ CRecordVector<CMethodId> CoderMethodIDs;
+ void Clear()
+ {
+ CBindInfo::Clear();
+ CoderMethodIDs.Clear();
+ }
+};
+
+class CDecoder
+{
+ bool _bindInfoExPrevIsDefined;
+ CBindInfoEx _bindInfoExPrev;
+
+ bool _multiThread;
+ #ifdef _ST_MODE
+ NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec;
+ #endif
+ NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec;
+ NCoderMixer::CCoderMixer2 *_mixerCoderCommon;
+
+ CMyComPtr<ICompressCoder2> _mixerCoder;
+ CObjectVector<CMyComPtr<IUnknown> > _decoders;
+ // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
+public:
+ CDecoder(bool multiThread);
+ HRESULT Decode(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ IInStream *inStream,
+ UInt64 startPos,
+ const UInt64 *packSizes,
+ const CFolder &folder,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPasswordSpec
+ #endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
+ );
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zEncode.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zEncode.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,453 @@
+// Encode.cpp
+
+#include "StdAfx.h"
+
+#include "7zEncode.h"
+#include "7zSpecStream.h"
+
+#include "../../IPassword.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/InOutTempBuffer.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/CreateCoder.h"
+#include "../../Common/FilterCoder.h"
+
+static const UInt64 k_AES = 0x06F10701;
+static const UInt64 k_BCJ = 0x03030103;
+static const UInt64 k_BCJ2 = 0x0303011B;
+
+namespace NArchive {
+namespace N7z {
+
+static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo,
+ const CRecordVector<CMethodId> decompressionMethods,
+ CFolder &folder)
+{
+ folder.Coders.Clear();
+ // bindInfo.CoderMethodIDs.Clear();
+ // folder.OutStreams.Clear();
+ folder.PackStreams.Clear();
+ folder.BindPairs.Clear();
+ int i;
+ for (i = 0; i < bindInfo.BindPairs.Size(); i++)
+ {
+ CBindPair bindPair;
+ bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
+ bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
+ folder.BindPairs.Add(bindPair);
+ }
+ for (i = 0; i < bindInfo.Coders.Size(); i++)
+ {
+ CCoderInfo coderInfo;
+ const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
+ coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
+ coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
+ coderInfo.MethodID = decompressionMethods[i];
+ folder.Coders.Add(coderInfo);
+ }
+ for (i = 0; i < bindInfo.InStreams.Size(); i++)
+ folder.PackStreams.Add(bindInfo.InStreams[i]);
+}
+
+HRESULT CEncoder::CreateMixerCoder(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const UInt64 *inSizeForReduce)
+{
+ _mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
+ _mixerCoder = _mixerCoderSpec;
+ RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));
+ for (int i = 0; i < _options.Methods.Size(); i++)
+ {
+ const CMethodFull &methodFull = _options.Methods[i];
+ _codersInfo.Add(CCoderInfo());
+ CCoderInfo &encodingInfo = _codersInfo.Back();
+ encodingInfo.MethodID = methodFull.Id;
+ CMyComPtr<ICompressCoder> encoder;
+ CMyComPtr<ICompressCoder2> encoder2;
+
+
+ RINOK(CreateCoder(
+ EXTERNAL_CODECS_LOC_VARS
+ methodFull.Id, encoder, encoder2, true));
+
+ if (!encoder && !encoder2)
+ return E_FAIL;
+
+ CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;
+
+ #ifdef COMPRESS_MT
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
+ }
+ }
+ #endif
+
+
+ RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));
+
+ /*
+ CMyComPtr<ICryptoResetSalt> resetSalt;
+ encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);
+ if (resetSalt != NULL)
+ {
+ resetSalt->ResetSalt();
+ }
+ */
+
+ #ifdef EXTERNAL_CODECS
+ CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+ encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+ if (setCompressCodecsInfo)
+ {
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
+ }
+ #endif
+
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+
+ if (cryptoSetPassword)
+ {
+ CByteBuffer buffer;
+ const UInt32 sizeInBytes = _options.Password.Length() * 2;
+ buffer.SetCapacity(sizeInBytes);
+ for (int i = 0; i < _options.Password.Length(); i++)
+ {
+ wchar_t c = _options.Password[i];
+ ((Byte *)buffer)[i * 2] = (Byte)c;
+ ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+ }
+ RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
+ }
+
+ if (encoder)
+ _mixerCoderSpec->AddCoder(encoder);
+ else
+ _mixerCoderSpec->AddCoder2(encoder2);
+ }
+ return S_OK;
+}
+
+HRESULT CEncoder::Encode(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ ISequentialInStream *inStream,
+ const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
+ CFolder &folderItem,
+ ISequentialOutStream *outStream,
+ CRecordVector<UInt64> &packSizes,
+ ICompressProgressInfo *compressProgress)
+{
+ RINOK(EncoderConstr());
+
+ if (_mixerCoderSpec == NULL)
+ {
+ RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
+ }
+ _mixerCoderSpec->ReInit();
+ // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
+
+ CObjectVector<CInOutTempBuffer> inOutTempBuffers;
+ CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
+ CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
+ int numMethods = _bindInfo.Coders.Size();
+ int i;
+ for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ inOutTempBuffers.Add(CInOutTempBuffer());
+ inOutTempBuffers.Back().Create();
+ inOutTempBuffers.Back().InitWriting();
+ }
+ for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ CSequentialOutTempBufferImp *tempBufferSpec =
+ new CSequentialOutTempBufferImp;
+ CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
+ tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
+ tempBuffers.Add(tempBuffer);
+ tempBufferSpecs.Add(tempBufferSpec);
+ }
+
+ for (i = 0; i < numMethods; i++)
+ _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
+
+ if (_bindInfo.InStreams.IsEmpty())
+ return E_FAIL;
+ UInt32 mainCoderIndex, mainStreamIndex;
+ _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
+
+ if (inStreamSize != NULL)
+ {
+ CRecordVector<const UInt64 *> sizePointers;
+ for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
+ if (i == mainStreamIndex)
+ sizePointers.Add(inStreamSize);
+ else
+ sizePointers.Add(NULL);
+ _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
+ }
+
+
+ // UInt64 outStreamStartPos;
+ // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
+
+ CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
+ new CSequentialInStreamSizeCount2;
+ CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
+ CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
+ new CSequentialOutStreamSizeCount;
+ CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
+
+ inStreamSizeCountSpec->Init(inStream);
+ outStreamSizeCountSpec->SetStream(outStream);
+ outStreamSizeCountSpec->Init();
+
+ CRecordVector<ISequentialInStream *> inStreamPointers;
+ CRecordVector<ISequentialOutStream *> outStreamPointers;
+ inStreamPointers.Add(inStreamSizeCount);
+ outStreamPointers.Add(outStreamSizeCount);
+ for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ outStreamPointers.Add(tempBuffers[i - 1]);
+
+ for (i = 0; i < _codersInfo.Size(); i++)
+ {
+ CCoderInfo &encodingInfo = _codersInfo[i];
+
+ CMyComPtr<ICryptoResetInitVector> resetInitVector;
+ _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
+ if (resetInitVector != NULL)
+ {
+ resetInitVector->ResetInitVector();
+ }
+
+ CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+ _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
+ if (writeCoderProperties != NULL)
+ {
+ CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init();
+ writeCoderProperties->WriteCoderProperties(outStream);
+ size_t size = outStreamSpec->GetSize();
+ encodingInfo.Properties.SetCapacity(size);
+ memmove(encodingInfo.Properties, outStreamSpec->GetBuffer(), size);
+ }
+ }
+
+ UInt32 progressIndex = mainCoderIndex;
+
+ for (i = 0; i < _codersInfo.Size(); i++)
+ {
+ const CCoderInfo &e = _codersInfo[i];
+ if ((e.MethodID == k_BCJ || e.MethodID == k_BCJ2) && i + 1 < _codersInfo.Size())
+ progressIndex = i + 1;
+ }
+
+ _mixerCoderSpec->SetProgressCoderIndex(progressIndex);
+
+ RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
+ &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
+
+ ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
+ folderItem);
+
+ packSizes.Add(outStreamSizeCountSpec->GetSize());
+
+ for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
+ inOutTempBuffer.FlushWrite();
+ inOutTempBuffer.InitReading();
+ inOutTempBuffer.WriteToStream(outStream);
+ packSizes.Add(inOutTempBuffer.GetDataSize());
+ }
+
+ for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
+ {
+ int binder = _bindInfo.FindBinderForInStream(
+ _bindReverseConverter->DestOutToSrcInMap[i]);
+ UInt64 streamSize;
+ if (binder < 0)
+ streamSize = inStreamSizeCountSpec->GetSize();
+ else
+ streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
+ folderItem.UnPackSizes.Add(streamSize);
+ }
+ for (i = numMethods - 1; i >= 0; i--)
+ folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
+ return S_OK;
+}
+
+
+CEncoder::CEncoder(const CCompressionMethodMode &options):
+ _bindReverseConverter(0),
+ _constructed(false)
+{
+ if (options.IsEmpty())
+ throw 1;
+
+ _options = options;
+ _mixerCoderSpec = NULL;
+}
+
+HRESULT CEncoder::EncoderConstr()
+{
+ if (_constructed)
+ return S_OK;
+ if (_options.Methods.IsEmpty())
+ {
+ // it has only password method;
+ if (!_options.PasswordIsDefined)
+ throw 1;
+ if (!_options.Binds.IsEmpty())
+ throw 1;
+ NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+ CMethodFull method;
+
+ method.NumInStreams = 1;
+ method.NumOutStreams = 1;
+ coderStreamsInfo.NumInStreams = 1;
+ coderStreamsInfo.NumOutStreams = 1;
+ method.Id = k_AES;
+
+ _options.Methods.Add(method);
+ _bindInfo.Coders.Add(coderStreamsInfo);
+
+ _bindInfo.InStreams.Add(0);
+ _bindInfo.OutStreams.Add(0);
+ }
+ else
+ {
+
+ UInt32 numInStreams = 0, numOutStreams = 0;
+ int i;
+ for (i = 0; i < _options.Methods.Size(); i++)
+ {
+ const CMethodFull &methodFull = _options.Methods[i];
+ NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+ coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
+ coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
+ if (_options.Binds.IsEmpty())
+ {
+ if (i < _options.Methods.Size() - 1)
+ {
+ NCoderMixer::CBindPair bindPair;
+ bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
+ bindPair.OutIndex = numOutStreams;
+ _bindInfo.BindPairs.Add(bindPair);
+ }
+ else
+ _bindInfo.OutStreams.Insert(0, numOutStreams);
+ for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
+ _bindInfo.OutStreams.Add(numOutStreams + j);
+ }
+
+ numInStreams += coderStreamsInfo.NumInStreams;
+ numOutStreams += coderStreamsInfo.NumOutStreams;
+
+ _bindInfo.Coders.Add(coderStreamsInfo);
+ }
+
+ if (!_options.Binds.IsEmpty())
+ {
+ for (i = 0; i < _options.Binds.Size(); i++)
+ {
+ NCoderMixer::CBindPair bindPair;
+ const CBind &bind = _options.Binds[i];
+ bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
+ bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
+ _bindInfo.BindPairs.Add(bindPair);
+ }
+ for (i = 0; i < (int)numOutStreams; i++)
+ if (_bindInfo.FindBinderForOutStream(i) == -1)
+ _bindInfo.OutStreams.Add(i);
+ }
+
+ for (i = 0; i < (int)numInStreams; i++)
+ if (_bindInfo.FindBinderForInStream(i) == -1)
+ _bindInfo.InStreams.Add(i);
+
+ if (_bindInfo.InStreams.IsEmpty())
+ throw 1; // this is error
+
+ // Make main stream first in list
+ int inIndex = _bindInfo.InStreams[0];
+ for (;;)
+ {
+ UInt32 coderIndex, coderStreamIndex;
+ _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
+ UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
+ int binder = _bindInfo.FindBinderForOutStream(outIndex);
+ if (binder >= 0)
+ {
+ inIndex = _bindInfo.BindPairs[binder].InIndex;
+ continue;
+ }
+ for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ if (_bindInfo.OutStreams[i] == outIndex)
+ {
+ _bindInfo.OutStreams.Delete(i);
+ _bindInfo.OutStreams.Insert(0, outIndex);
+ break;
+ }
+ break;
+ }
+
+ if (_options.PasswordIsDefined)
+ {
+ int numCryptoStreams = _bindInfo.OutStreams.Size();
+
+ for (i = 0; i < numCryptoStreams; i++)
+ {
+ NCoderMixer::CBindPair bindPair;
+ bindPair.InIndex = numInStreams + i;
+ bindPair.OutIndex = _bindInfo.OutStreams[i];
+ _bindInfo.BindPairs.Add(bindPair);
+ }
+ _bindInfo.OutStreams.Clear();
+
+ /*
+ if (numCryptoStreams == 0)
+ numCryptoStreams = 1;
+ */
+
+ for (i = 0; i < numCryptoStreams; i++)
+ {
+ NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+ CMethodFull method;
+ method.NumInStreams = 1;
+ method.NumOutStreams = 1;
+ coderStreamsInfo.NumInStreams = method.NumOutStreams;
+ coderStreamsInfo.NumOutStreams = method.NumInStreams;
+ method.Id = k_AES;
+
+ _options.Methods.Add(method);
+ _bindInfo.Coders.Add(coderStreamsInfo);
+ _bindInfo.OutStreams.Add(numOutStreams + i);
+ }
+ }
+
+ }
+
+ for (int i = _options.Methods.Size() - 1; i >= 0; i--)
+ {
+ const CMethodFull &methodFull = _options.Methods[i];
+ _decompressionMethods.Add(methodFull.Id);
+ }
+
+ _bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo);
+ _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
+ _constructed = true;
+ return S_OK;
+}
+
+CEncoder::~CEncoder()
+{
+ delete _bindReverseConverter;
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zEncode.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zEncode.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zEncode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,55 @@
+// 7zEncode.h
+
+#ifndef __7Z_ENCODE_H
+#define __7Z_ENCODE_H
+
+// #include "../../Common/StreamObjects.h"
+
+#include "7zCompressionMode.h"
+
+#include "../Common/CoderMixer2.h"
+#include "../Common/CoderMixer2MT.h"
+#ifdef _ST_MODE
+#include "../Common/CoderMixer2ST.h"
+#endif
+#include "7zItem.h"
+
+#include "../../Common/CreateCoder.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CEncoder
+{
+ NCoderMixer::CCoderMixer2MT *_mixerCoderSpec;
+ CMyComPtr<ICompressCoder2> _mixerCoder;
+
+ CObjectVector<CCoderInfo> _codersInfo;
+
+ CCompressionMethodMode _options;
+ NCoderMixer::CBindInfo _bindInfo;
+ NCoderMixer::CBindInfo _decompressBindInfo;
+ NCoderMixer::CBindReverseConverter *_bindReverseConverter;
+ CRecordVector<CMethodId> _decompressionMethods;
+
+ HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS
+ const UInt64 *inSizeForReduce);
+
+ bool _constructed;
+public:
+ CEncoder(const CCompressionMethodMode &options);
+ ~CEncoder();
+ HRESULT EncoderConstr();
+ HRESULT Encode(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ ISequentialInStream *inStream,
+ const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
+ CFolder &folderItem,
+ ISequentialOutStream *outStream,
+ CRecordVector<UInt64> &packSizes,
+ ICompressProgressInfo *compressProgress);
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zExtract.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zExtract.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,269 @@
+// 7zExtract.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zFolderOutStream.h"
+#include "7zDecode.h"
+// #include "7z1Decode.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CExtractFolderInfo
+{
+ #ifdef _7Z_VOL
+ int VolumeIndex;
+ #endif
+ CNum FileIndex;
+ CNum FolderIndex;
+ CBoolVector ExtractStatuses;
+ UInt64 UnPackSize;
+ CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ int volumeIndex,
+ #endif
+ CNum fileIndex, CNum folderIndex):
+ #ifdef _7Z_VOL
+ VolumeIndex(volumeIndex),
+ #endif
+ FileIndex(fileIndex),
+ FolderIndex(folderIndex),
+ UnPackSize(0)
+ {
+ if (fileIndex != kNumNoIndex)
+ {
+ ExtractStatuses.Reserve(1);
+ ExtractStatuses.Add(true);
+ }
+ };
+};
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
+{
+ COM_TRY_BEGIN
+ bool testMode = (testModeSpec != 0);
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ UInt64 importantTotalUnPacked = 0;
+
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems =
+ #ifdef _7Z_VOL
+ _refs.Size();
+ #else
+ _database.Files.Size();
+ #endif
+
+ if(numItems == 0)
+ return S_OK;
+
+ /*
+ if(_volumes.Size() != 1)
+ return E_FAIL;
+ const CVolume &volume = _volumes.Front();
+ const CArchiveDatabaseEx &_database = volume.Database;
+ IInStream *_inStream = volume.Stream;
+ */
+
+ CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
+ for(UInt32 ii = 0; ii < numItems; ii++)
+ {
+ // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
+ UInt32 ref2Index = allFilesMode ? ii : indices[ii];
+ // const CRef2 &ref2 = _refs[ref2Index];
+
+ // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
+ {
+ #ifdef _7Z_VOL
+ // const CRef &ref = ref2.Refs[ri];
+ const CRef &ref = _refs[ref2Index];
+
+ int volumeIndex = ref.VolumeIndex;
+ const CVolume &volume = _volumes[volumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ UInt32 fileIndex = ref.ItemIndex;
+ #else
+ const CArchiveDatabaseEx &database = _database;
+ UInt32 fileIndex = ref2Index;
+ #endif
+
+ CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex == kNumNoIndex)
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ volumeIndex,
+ #endif
+ fileIndex, kNumNoIndex));
+ continue;
+ }
+ if (extractFolderInfoVector.IsEmpty() ||
+ folderIndex != extractFolderInfoVector.Back().FolderIndex
+ #ifdef _7Z_VOL
+ || volumeIndex != extractFolderInfoVector.Back().VolumeIndex
+ #endif
+ )
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ volumeIndex,
+ #endif
+ kNumNoIndex, folderIndex));
+ const CFolder &folderInfo = database.Folders[folderIndex];
+ UInt64 unPackSize = folderInfo.GetUnPackSize();
+ importantTotalUnPacked += unPackSize;
+ extractFolderInfoVector.Back().UnPackSize = unPackSize;
+ }
+
+ CExtractFolderInfo &efi = extractFolderInfoVector.Back();
+
+ // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
+ CNum startIndex = database.FolderStartFileIndex[folderIndex];
+ for (CNum index = efi.ExtractStatuses.Size();
+ index <= fileIndex - startIndex; index++)
+ {
+ // UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize;
+ // Count partial_folder_size
+ // efi.UnPackSize += unPackSize;
+ // importantTotalUnPacked += unPackSize;
+ efi.ExtractStatuses.Add(index == fileIndex - startIndex);
+ }
+ }
+ }
+
+ extractCallback->SetTotal(importantTotalUnPacked);
+
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
+ // CDecoder1 decoder;
+
+ UInt64 currentTotalPacked = 0;
+ UInt64 currentTotalUnPacked = 0;
+ UInt64 totalFolderUnPacked;
+ UInt64 totalFolderPacked;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ for(int i = 0; i < extractFolderInfoVector.Size(); i++,
+ currentTotalUnPacked += totalFolderUnPacked,
+ currentTotalPacked += totalFolderPacked)
+ {
+ lps->OutSize = currentTotalUnPacked;
+ lps->InSize = currentTotalPacked;
+ RINOK(lps->SetCur());
+
+ const CExtractFolderInfo &efi = extractFolderInfoVector[i];
+ totalFolderUnPacked = efi.UnPackSize;
+
+ totalFolderPacked = 0;
+
+ CFolderOutStream *folderOutStream = new CFolderOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+
+ #ifdef _7Z_VOL
+ const CVolume &volume = _volumes[efi.VolumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ #else
+ const CArchiveDatabaseEx &database = _database;
+ #endif
+
+ CNum startIndex;
+ if (efi.FileIndex != kNumNoIndex)
+ startIndex = efi.FileIndex;
+ else
+ startIndex = database.FolderStartFileIndex[efi.FolderIndex];
+
+
+ HRESULT result = folderOutStream->Init(&database,
+ #ifdef _7Z_VOL
+ volume.StartRef2Index,
+ #else
+ 0,
+ #endif
+ startIndex,
+ &efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
+
+ RINOK(result);
+
+ if (efi.FileIndex != kNumNoIndex)
+ continue;
+
+ CNum folderIndex = efi.FolderIndex;
+ const CFolder &folderInfo = database.Folders[folderIndex];
+
+ totalFolderPacked = _database.GetFolderFullPackSize(folderIndex);
+
+ CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
+ UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (extractCallback)
+ extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
+ #endif
+
+ try
+ {
+ HRESULT result = decoder.Decode(
+ EXTERNAL_CODECS_VARS
+ #ifdef _7Z_VOL
+ volume.Stream,
+ #else
+ _inStream,
+ #endif
+ folderStartPackPos,
+ &database.PackSizes[packStreamIndex],
+ folderInfo,
+ outStream,
+ progress
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , true, _numThreads
+ #endif
+ );
+
+ if (result == S_FALSE)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ if (result == E_NOTIMPL)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ if (result != S_OK)
+ return result;
+ if (folderOutStream->WasWritingFinished() != S_OK)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ catch(...)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,130 @@
+// 7zFolderInStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderInStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderInStream::CFolderInStream()
+{
+ _inStreamWithHashSpec = new CSequentialInStreamWithCRC;
+ _inStreamWithHash = _inStreamWithHashSpec;
+}
+
+void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
+ const UInt32 *fileIndices, UInt32 numFiles)
+{
+ _updateCallback = updateCallback;
+ _numFiles = numFiles;
+ _fileIndex = 0;
+ _fileIndices = fileIndices;
+ Processed.Clear();
+ CRCs.Clear();
+ Sizes.Clear();
+ _fileIsOpen = false;
+ _currentSizeIsDefined = false;
+}
+
+HRESULT CFolderInStream::OpenStream()
+{
+ _filePos = 0;
+ while (_fileIndex < _numFiles)
+ {
+ _currentSizeIsDefined = false;
+ CMyComPtr<ISequentialInStream> stream;
+ HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
+ if (result != S_OK && result != S_FALSE)
+ return result;
+ _fileIndex++;
+ _inStreamWithHashSpec->SetStream(stream);
+ _inStreamWithHashSpec->Init();
+ if (!stream)
+ {
+ RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ Sizes.Add(0);
+ Processed.Add(result == S_OK);
+ AddDigest();
+ continue;
+ }
+ CMyComPtr<IStreamGetSize> streamGetSize;
+ if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK)
+ {
+ if(streamGetSize)
+ {
+ _currentSizeIsDefined = true;
+ RINOK(streamGetSize->GetSize(&_currentSize));
+ }
+ }
+
+ _fileIsOpen = true;
+ return S_OK;
+ }
+ return S_OK;
+}
+
+void CFolderInStream::AddDigest()
+{
+ CRCs.Add(_inStreamWithHashSpec->GetCRC());
+}
+
+HRESULT CFolderInStream::CloseStream()
+{
+ RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ _inStreamWithHashSpec->ReleaseStream();
+ _fileIsOpen = false;
+ Processed.Add(true);
+ Sizes.Add(_filePos);
+ AddDigest();
+ return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
+ {
+ if (_fileIsOpen)
+ {
+ UInt32 localProcessedSize;
+ RINOK(_inStreamWithHash->Read(
+ ((Byte *)data) + realProcessedSize, size, &localProcessedSize));
+ if (localProcessedSize == 0)
+ {
+ RINOK(CloseStream());
+ continue;
+ }
+ realProcessedSize += localProcessedSize;
+ _filePos += localProcessedSize;
+ size -= localProcessedSize;
+ break;
+ }
+ else
+ {
+ RINOK(OpenStream());
+ }
+ }
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
+{
+ *value = 0;
+ int subStreamIndex = (int)subStream;
+ if (subStreamIndex < 0 || subStream > Sizes.Size())
+ return E_FAIL;
+ if (subStreamIndex < Sizes.Size())
+ {
+ *value= Sizes[subStreamIndex];
+ return S_OK;
+ }
+ if (!_currentSizeIsDefined)
+ return S_FALSE;
+ *value = _currentSize;
+ return S_OK;
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,66 @@
+// 7z/FolderInStream.h
+
+#ifndef __7Z_FOLDERINSTREAM_H
+#define __7Z_FOLDERINSTREAM_H
+
+#include "7zItem.h"
+#include "7zHeader.h"
+
+#include "../IArchive.h"
+#include "../Common/InStreamWithCRC.h"
+#include "../../IStream.h"
+#include "../../ICoder.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CFolderInStream:
+ public ISequentialInStream,
+ public ICompressGetSubStreamSize,
+ public CMyUnknownImp
+{
+public:
+
+ MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
+
+ CFolderInStream();
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+private:
+ CSequentialInStreamWithCRC *_inStreamWithHashSpec;
+ CMyComPtr<ISequentialInStream> _inStreamWithHash;
+ CMyComPtr<IArchiveUpdateCallback> _updateCallback;
+
+ bool _currentSizeIsDefined;
+ UInt64 _currentSize;
+
+ bool _fileIsOpen;
+ UInt64 _filePos;
+
+ const UInt32 *_fileIndices;
+ UInt32 _numFiles;
+ UInt32 _fileIndex;
+
+ HRESULT OpenStream();
+ HRESULT CloseStream();
+ void AddDigest();
+public:
+ void Init(IArchiveUpdateCallback *updateCallback,
+ const UInt32 *fileIndices, UInt32 numFiles);
+ CRecordVector<bool> Processed;
+ CRecordVector<UInt32> CRCs;
+ CRecordVector<UInt64> Sizes;
+ UInt64 GetFullSize() const
+ {
+ UInt64 size = 0;
+ for (int i = 0; i < Sizes.Size(); i++)
+ size += Sizes[i];
+ return size;
+ }
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,165 @@
+// 7zFolderOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderOutStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderOutStream::CFolderOutStream()
+{
+ _outStreamWithHashSpec = new COutStreamWithCRC;
+ _outStreamWithHash = _outStreamWithHashSpec;
+}
+
+HRESULT CFolderOutStream::Init(
+ const CArchiveDatabaseEx *archiveDatabase,
+ UInt32 ref2Offset,
+ UInt32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode,
+ bool checkCrc)
+{
+ _archiveDatabase = archiveDatabase;
+ _ref2Offset = ref2Offset;
+ _startIndex = startIndex;
+
+ _extractStatuses = extractStatuses;
+ _extractCallback = extractCallback;
+ _testMode = testMode;
+
+ _checkCrc = checkCrc;
+
+ _currentIndex = 0;
+ _fileIsOpen = false;
+ return WriteEmptyFiles();
+}
+
+HRESULT CFolderOutStream::OpenFile()
+{
+ Int32 askMode;
+ if((*_extractStatuses)[_currentIndex])
+ askMode = _testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ else
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ CMyComPtr<ISequentialOutStream> realOutStream;
+
+ UInt32 index = _startIndex + _currentIndex;
+ RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
+
+ _outStreamWithHashSpec->SetStream(realOutStream);
+ _outStreamWithHashSpec->Init(_checkCrc);
+ if (askMode == NArchive::NExtract::NAskMode::kExtract &&
+ (!realOutStream))
+ {
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ }
+ return _extractCallback->PrepareOperation(askMode);
+}
+
+HRESULT CFolderOutStream::WriteEmptyFiles()
+{
+ for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
+ {
+ UInt32 index = _startIndex + _currentIndex;
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
+ return S_OK;
+ RINOK(OpenFile());
+ RINOK(_extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kOK));
+ _outStreamWithHashSpec->ReleaseStream();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFolderOutStream::Write(const void *data,
+ UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ while(_currentIndex < _extractStatuses->Size())
+ {
+ if (_fileIsOpen)
+ {
+ UInt32 index = _startIndex + _currentIndex;
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ UInt64 fileSize = fileInfo.UnPackSize;
+
+ UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
+ UInt64(size - realProcessedSize));
+
+ UInt32 processedSizeLocal;
+ RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
+ numBytesToWrite, &processedSizeLocal));
+
+ _filePos += processedSizeLocal;
+ realProcessedSize += processedSizeLocal;
+ if (_filePos == fileSize)
+ {
+ bool digestsAreEqual;
+ if (fileInfo.IsFileCRCDefined && _checkCrc)
+ digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
+ else
+ digestsAreEqual = true;
+
+ RINOK(_extractCallback->SetOperationResult(
+ digestsAreEqual ?
+ NArchive::NExtract::NOperationResult::kOK :
+ NArchive::NExtract::NOperationResult::kCRCError));
+ _outStreamWithHashSpec->ReleaseStream();
+ _fileIsOpen = false;
+ _currentIndex++;
+ }
+ if (realProcessedSize == size)
+ {
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return WriteEmptyFiles();
+ }
+ }
+ else
+ {
+ RINOK(OpenFile());
+ _fileIsOpen = true;
+ _filePos = 0;
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
+{
+ while(_currentIndex < _extractStatuses->Size())
+ {
+ if (_fileIsOpen)
+ {
+ RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
+ _outStreamWithHashSpec->ReleaseStream();
+ _fileIsOpen = false;
+ _currentIndex++;
+ }
+ else
+ {
+ RINOK(OpenFile());
+ _fileIsOpen = true;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CFolderOutStream::WasWritingFinished()
+{
+ if (_currentIndex == _extractStatuses->Size())
+ return S_OK;
+ return E_FAIL;
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,60 @@
+// 7zFolderOutStream.h
+
+#ifndef __7Z_FOLDEROUTSTREAM_H
+#define __7Z_FOLDEROUTSTREAM_H
+
+#include "7zIn.h"
+
+#include "../../IStream.h"
+#include "../IArchive.h"
+#include "../Common/OutStreamWithCRC.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CFolderOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ CFolderOutStream();
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+
+ COutStreamWithCRC *_outStreamWithHashSpec;
+ CMyComPtr<ISequentialOutStream> _outStreamWithHash;
+ const CArchiveDatabaseEx *_archiveDatabase;
+ const CBoolVector *_extractStatuses;
+ UInt32 _startIndex;
+ UInt32 _ref2Offset;
+ int _currentIndex;
+ // UInt64 _currentDataPos;
+ CMyComPtr<IArchiveExtractCallback> _extractCallback;
+ bool _testMode;
+
+ bool _fileIsOpen;
+
+ bool _checkCrc;
+ UInt64 _filePos;
+
+ HRESULT OpenFile();
+ HRESULT WriteEmptyFiles();
+public:
+ HRESULT Init(
+ const CArchiveDatabaseEx *archiveDatabase,
+ UInt32 ref2Offset,
+ UInt32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode,
+ bool checkCrc);
+ HRESULT FlushCorrupted(Int32 resultEOperationResult);
+ HRESULT WasWritingFinished();
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zHandler.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zHandler.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,793 @@
+// 7zHandler.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zProperties.h"
+
+#include "../../../Common/IntToString.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Windows/Defs.h"
+
+#include "../Common/ItemNameUtils.h"
+#ifdef _7Z_VOL
+#include "../Common/MultiStream.h"
+#endif
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+#include "../Common/ParseProperties.h"
+#endif
+#endif
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+using namespace NWindows;
+
+extern UString ConvertMethodIdToString(UInt64 id);
+
+namespace NArchive {
+namespace N7z {
+
+CHandler::CHandler()
+{
+ _crcSize = 4;
+
+ #ifdef EXTRACT_ONLY
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ #endif
+ #else
+ Init();
+ #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems =
+ #ifdef _7Z_VOL
+ _refs.Size();
+ #else
+ *numItems = _database.Files.Size();
+ #endif
+ return S_OK;
+}
+
+#ifdef _SFX
+
+IMP_IInArchive_ArcProps_NO
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
+ BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
+{
+ return E_NOTIMPL;
+}
+
+
+#else
+
+STATPROPSTG kArcProps[] =
+{
+ { NULL, kpidMethod, VT_BSTR},
+ { NULL, kpidSolid, VT_BOOL},
+ { NULL, kpidNumBlocks, VT_UI4}
+};
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case kpidMethod:
+ {
+ UString resString;
+ CRecordVector<UInt64> ids;
+ int i;
+ for (i = 0; i < _database.Folders.Size(); i++)
+ {
+ const CFolder &f = _database.Folders[i];
+ for (int j = f.Coders.Size() - 1; j >= 0; j--)
+ ids.AddToUniqueSorted(f.Coders[j].MethodID);
+ }
+
+ for (i = 0; i < ids.Size(); i++)
+ {
+ UInt64 id = ids[i];
+ UString methodName;
+ /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
+ if (methodName.IsEmpty())
+ methodName = ConvertMethodIdToString(id);
+ if (!resString.IsEmpty())
+ resString += L' ';
+ resString += methodName;
+ }
+ prop = resString;
+ break;
+ }
+ case kpidSolid: prop = _database.IsSolid(); break;
+ case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+IMP_IInArchive_ArcProps
+
+#endif
+
+static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
+{
+ if (timeDefined)
+ prop = unixTime;
+}
+
+#ifndef _SFX
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static UString GetStringForSizeValue(UInt32 value)
+{
+ for (int i = 31; i >= 0; i--)
+ if ((UInt32(1) << i) == value)
+ return ConvertUInt32ToString(i);
+ UString result;
+ if (value % (1 << 20) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 20);
+ result += L"m";
+ }
+ else if (value % (1 << 10) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 10);
+ result += L"k";
+ }
+ else
+ {
+ result += ConvertUInt32ToString(value);
+ result += L"b";
+ }
+ return result;
+}
+
+static const UInt64 k_Copy = 0x0;
+static const UInt64 k_LZMA = 0x030101;
+static const UInt64 k_PPMD = 0x030401;
+
+static wchar_t GetHex(Byte value)
+{
+ return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
+}
+static inline UString GetHex2(Byte value)
+{
+ UString result;
+ result += GetHex((Byte)(value >> 4));
+ result += GetHex((Byte)(value & 0xF));
+ return result;
+}
+
+#endif
+
+static const UInt64 k_AES = 0x06F10701;
+
+#ifndef _SFX
+static inline UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+ return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+#endif
+
+bool CHandler::IsEncrypted(UInt32 index2) const
+{
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
+ if (folderInfo.Coders[i].MethodID == k_AES)
+ return true;
+ }
+ return false;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+
+ /*
+ const CRef2 &ref2 = _refs[index];
+ if (ref2.Refs.IsEmpty())
+ return E_FAIL;
+ const CRef &ref = ref2.Refs.Front();
+ */
+
+ #ifdef _7Z_VOL
+ const CRef &ref = _refs[index];
+ const CVolume &volume = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &_database = volume.Database;
+ UInt32 index2 = ref.ItemIndex;
+ const CFileItem &item = _database.Files[index2];
+ #else
+ const CFileItem &item = _database.Files[index];
+ UInt32 index2 = index;
+ #endif
+
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ if (!item.Name.IsEmpty())
+ prop = NItemName::GetOSName(item.Name);
+ break;
+ }
+ case kpidIsFolder:
+ prop = item.IsDirectory;
+ break;
+ case kpidSize:
+ {
+ prop = item.UnPackSize;
+ // prop = ref2.UnPackSize;
+ break;
+ }
+ case kpidPosition:
+ {
+ /*
+ if (ref2.Refs.Size() > 1)
+ prop = ref2.StartPos;
+ else
+ */
+ if (item.IsStartPosDefined)
+ prop = item.StartPos;
+ break;
+ }
+ case kpidPackedSize:
+ {
+ // prop = ref2.PackSize;
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
+ prop = _database.GetFolderFullPackSize(folderIndex);
+ /*
+ else
+ prop = (UInt64)0;
+ */
+ }
+ else
+ prop = (UInt64)0;
+ }
+ break;
+ }
+ case kpidLastAccessTime:
+ MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
+ break;
+ case kpidCreationTime:
+ MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
+ break;
+ case kpidLastWriteTime:
+ MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
+ break;
+ case kpidAttributes:
+ if (item.AreAttributesDefined)
+ prop = item.Attributes;
+ break;
+ case kpidCRC:
+ if (item.IsFileCRCDefined)
+ prop = item.FileCRC;
+ break;
+ case kpidEncrypted:
+ {
+ prop = IsEncrypted(index2);
+ break;
+ }
+ #ifndef _SFX
+ case kpidMethod:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ UString methodsString;
+ for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ if (!methodsString.IsEmpty())
+ methodsString += L' ';
+
+ {
+ UString methodName;
+ bool methodIsKnown = FindMethod(
+ EXTERNAL_CODECS_VARS
+ coderInfo.MethodID, methodName);
+
+ if (methodIsKnown)
+ {
+ methodsString += methodName;
+ if (coderInfo.MethodID == k_LZMA)
+ {
+ if (coderInfo.Properties.GetCapacity() >= 5)
+ {
+ methodsString += L":";
+ UInt32 dicSize = GetUInt32FromMemLE(
+ ((const Byte *)coderInfo.Properties + 1));
+ methodsString += GetStringForSizeValue(dicSize);
+ }
+ }
+ else if (coderInfo.MethodID == k_PPMD)
+ {
+ if (coderInfo.Properties.GetCapacity() >= 5)
+ {
+ Byte order = *(const Byte *)coderInfo.Properties;
+ methodsString += L":o";
+ methodsString += ConvertUInt32ToString(order);
+ methodsString += L":mem";
+ UInt32 dicSize = GetUInt32FromMemLE(
+ ((const Byte *)coderInfo.Properties + 1));
+ methodsString += GetStringForSizeValue(dicSize);
+ }
+ }
+ else if (coderInfo.MethodID == k_AES)
+ {
+ if (coderInfo.Properties.GetCapacity() >= 1)
+ {
+ methodsString += L":";
+ const Byte *data = (const Byte *)coderInfo.Properties;
+ Byte firstByte = *data++;
+ UInt32 numCyclesPower = firstByte & 0x3F;
+ methodsString += ConvertUInt32ToString(numCyclesPower);
+ /*
+ if ((firstByte & 0xC0) != 0)
+ {
+ methodsString += L":";
+ return S_OK;
+ UInt32 saltSize = (firstByte >> 7) & 1;
+ UInt32 ivSize = (firstByte >> 6) & 1;
+ if (coderInfo.Properties.GetCapacity() >= 2)
+ {
+ Byte secondByte = *data++;
+ saltSize += (secondByte >> 4);
+ ivSize += (secondByte & 0x0F);
+ }
+ }
+ */
+ }
+ }
+ else
+ {
+ if (coderInfo.Properties.GetCapacity() > 0)
+ {
+ methodsString += L":[";
+ for (size_t bi = 0; bi < coderInfo.Properties.GetCapacity(); bi++)
+ {
+ if (bi > 5 && bi + 1 < coderInfo.Properties.GetCapacity())
+ {
+ methodsString += L"..";
+ break;
+ }
+ else
+ methodsString += GetHex2(coderInfo.Properties[bi]);
+ }
+ methodsString += L"]";
+ }
+ }
+ }
+ else
+ {
+ methodsString += ConvertMethodIdToString(coderInfo.MethodID);
+ }
+ }
+ }
+ prop = methodsString;
+ }
+ }
+ break;
+ case kpidBlock:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ prop = (UInt32)folderIndex;
+ }
+ break;
+ case kpidPackedSize0:
+ case kpidPackedSize1:
+ case kpidPackedSize2:
+ case kpidPackedSize3:
+ case kpidPackedSize4:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
+ folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
+ {
+ prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
+ }
+ else
+ prop = (UInt64)0;
+ }
+ else
+ prop = (UInt64)0;
+ }
+ break;
+ #endif
+ case kpidIsAnti:
+ prop = item.IsAnti;
+ break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+#ifdef _7Z_VOL
+
+static const wchar_t *kExt = L"7z";
+static const wchar_t *kAfterPart = L".7z";
+
+class CVolumeName
+{
+ bool _first;
+ UString _unchangedPart;
+ UString _changedPart;
+ UString _afterPart;
+public:
+ bool InitName(const UString &name)
+ {
+ _first = true;
+ int dotPos = name.ReverseFind('.');
+ UString basePart = name;
+ if (dotPos >= 0)
+ {
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.CompareNoCase(kExt)==0 ||
+ ext.CompareNoCase(L"EXE") == 0)
+ {
+ _afterPart = kAfterPart;
+ basePart = name.Left(dotPos);
+ }
+ }
+
+ int numLetters = 1;
+ bool splitStyle = false;
+ if (basePart.Right(numLetters) == L"1")
+ {
+ while (numLetters < basePart.Length())
+ {
+ if (basePart[basePart.Length() - numLetters - 1] != '0')
+ break;
+ numLetters++;
+ }
+ }
+ else
+ return false;
+ _unchangedPart = basePart.Left(basePart.Length() - numLetters);
+ _changedPart = basePart.Right(numLetters);
+ return true;
+ }
+
+ UString GetNextName()
+ {
+ UString newName;
+ // if (_newStyle || !_first)
+ {
+ int i;
+ int numLetters = _changedPart.Length();
+ for (i = numLetters - 1; i >= 0; i--)
+ {
+ wchar_t c = _changedPart[i];
+ if (c == L'9')
+ {
+ c = L'0';
+ newName = c + newName;
+ if (i == 0)
+ newName = UString(L'1') + newName;
+ continue;
+ }
+ c++;
+ newName = UString(c) + newName;
+ i--;
+ for (; i >= 0; i--)
+ newName = _changedPart[i] + newName;
+ break;
+ }
+ _changedPart = newName;
+ }
+ _first = false;
+ return _unchangedPart + _changedPart + _afterPart;
+ }
+};
+
+#endif
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ Close();
+ #ifndef _SFX
+ _fileInfoPopIDs.Clear();
+ #endif
+ try
+ {
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
+ #ifdef _7Z_VOL
+ CVolumeName seqName;
+
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ #endif
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (openArchiveCallback)
+ {
+ openArchiveCallbackTemp.QueryInterface(
+ IID_ICryptoGetTextPassword, &getTextPassword);
+ }
+ #endif
+ #ifdef _7Z_VOL
+ if (openArchiveCallback)
+ {
+ openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
+ }
+ for (;;)
+ {
+ CMyComPtr<IInStream> inStream;
+ if (!_volumes.IsEmpty())
+ {
+ if (!openVolumeCallback)
+ break;
+ if(_volumes.Size() == 1)
+ {
+ UString baseName;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
+ if (prop.vt != VT_BSTR)
+ break;
+ baseName = prop.bstrVal;
+ }
+ seqName.InitName(baseName);
+ }
+
+ UString fullName = seqName.GetNextName();
+ HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
+ if (result == S_FALSE)
+ break;
+ if (result != S_OK)
+ return result;
+ if (!stream)
+ break;
+ }
+ else
+ inStream = stream;
+
+ CInArchive archive;
+ RINOK(archive.Open(inStream, maxCheckStartPosition));
+
+ _volumes.Add(CVolume());
+ CVolume &volume = _volumes.Back();
+ CArchiveDatabaseEx &database = volume.Database;
+ volume.Stream = inStream;
+ volume.StartRef2Index = _refs.Size();
+
+ HRESULT result = archive.ReadDatabase(database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ if (result != S_OK)
+ {
+ _volumes.Clear();
+ return result;
+ }
+ database.Fill();
+ for(int i = 0; i < database.Files.Size(); i++)
+ {
+ CRef refNew;
+ refNew.VolumeIndex = _volumes.Size() - 1;
+ refNew.ItemIndex = i;
+ _refs.Add(refNew);
+ /*
+ const CFileItem &file = database.Files[i];
+ int j;
+ */
+ /*
+ for (j = _refs.Size() - 1; j >= 0; j--)
+ {
+ CRef2 &ref2 = _refs[j];
+ const CRef &ref = ref2.Refs.Back();
+ const CVolume &volume2 = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &database2 = volume2.Database;
+ const CFileItem &file2 = database2.Files[ref.ItemIndex];
+ if (file2.Name.CompareNoCase(file.Name) == 0)
+ {
+ if (!file.IsStartPosDefined)
+ continue;
+ if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
+ continue;
+ ref2.Refs.Add(refNew);
+ break;
+ }
+ }
+ */
+ /*
+ j = -1;
+ if (j < 0)
+ {
+ CRef2 ref2New;
+ ref2New.Refs.Add(refNew);
+ j = _refs.Add(ref2New);
+ }
+ CRef2 &ref2 = _refs[j];
+ ref2.UnPackSize += file.UnPackSize;
+ ref2.PackSize += database.GetFilePackSize(i);
+ if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
+ ref2.StartPos = file.StartPos;
+ */
+ }
+ if (database.Files.Size() != 1)
+ break;
+ const CFileItem &file = database.Files.Front();
+ if (!file.IsStartPosDefined)
+ break;
+ }
+ #else
+ CInArchive archive;
+ RINOK(archive.Open(stream, maxCheckStartPosition));
+ HRESULT result = archive.ReadDatabase(
+ EXTERNAL_CODECS_VARS
+ _database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ _database.Fill();
+ _inStream = stream;
+ #endif
+ }
+ catch(...)
+ {
+ Close();
+ return S_FALSE;
+ }
+ // _inStream = stream;
+ #ifndef _SFX
+ FillPopIDs();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ COM_TRY_BEGIN
+ #ifdef _7Z_VOL
+ _volumes.Clear();
+ _refs.Clear();
+ #else
+ _inStream.Release();
+ _database.Clear();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+#ifdef _7Z_VOL
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ if (index != 0)
+ return E_INVALIDARG;
+ *stream = 0;
+ CMultiStream *streamSpec = new CMultiStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+
+ UInt64 pos = 0;
+ const UString *fileName;
+ for (int i = 0; i < _refs.Size(); i++)
+ {
+ const CRef &ref = _refs[i];
+ const CVolume &volume = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ const CFileItem &file = database.Files[ref.ItemIndex];
+ if (i == 0)
+ fileName = &file.Name;
+ else
+ if (fileName->Compare(file.Name) != 0)
+ return S_FALSE;
+ if (!file.IsStartPosDefined)
+ return S_FALSE;
+ if (file.StartPos != pos)
+ return S_FALSE;
+ CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
+ if (folderIndex == kNumNoIndex)
+ {
+ if (file.UnPackSize != 0)
+ return E_FAIL;
+ continue;
+ }
+ if (database.NumUnPackStreamsVector[folderIndex] != 1)
+ return S_FALSE;
+ const CFolder &folder = database.Folders[folderIndex];
+ if (folder.Coders.Size() != 1)
+ return S_FALSE;
+ const CCoderInfo &coder = folder.Coders.Front();
+ if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
+ return S_FALSE;
+ if (coder.MethodID != k_Copy)
+ return S_FALSE;
+
+ pos += file.UnPackSize;
+ CMultiStream::CSubStreamInfo subStreamInfo;
+ subStreamInfo.Stream = volume.Stream;
+ subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
+ subStreamInfo.Size = file.UnPackSize;
+ streamSpec->Streams.Add(subStreamInfo);
+ }
+ streamSpec->Init();
+ *stream = streamTemp.Detach();
+ return S_OK;
+}
+#endif
+
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ COM_TRY_BEGIN
+ #ifdef COMPRESS_MT
+ const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
+ _numThreads = numProcessors;
+ #endif
+
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = names[i];
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+ const PROPVARIANT &value = values[i];
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ if (index == 0)
+ {
+ if(name.Left(2).CompareNoCase(L"MT") == 0)
+ {
+ #ifdef COMPRESS_MT
+ RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ #endif
+ continue;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+#endif
+#endif
+
+IMPL_ISetCompressCodecsInfo
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zHandler.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zHandler.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zHandler.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,146 @@
+// 7z/Handler.h
+
+#ifndef __7Z_HANDLER_H
+#define __7Z_HANDLER_H
+
+#include "../../ICoder.h"
+#include "../IArchive.h"
+#include "7zIn.h"
+
+#include "7zCompressionMode.h"
+
+#include "../../Common/CreateCoder.h"
+
+#ifndef EXTRACT_ONLY
+#include "../Common/HandlerOut.h"
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+#ifdef _7Z_VOL
+struct CRef
+{
+ int VolumeIndex;
+ int ItemIndex;
+};
+
+struct CVolume
+{
+ int StartRef2Index;
+ CMyComPtr<IInStream> Stream;
+ CArchiveDatabaseEx Database;
+};
+#endif
+
+#ifndef __7Z_SET_PROPERTIES
+
+#ifdef EXTRACT_ONLY
+#ifdef COMPRESS_MT
+#define __7Z_SET_PROPERTIES
+#endif
+#else
+#define __7Z_SET_PROPERTIES
+#endif
+
+#endif
+
+
+class CHandler:
+ #ifndef EXTRACT_ONLY
+ public NArchive::COutHandler,
+ #endif
+ public IInArchive,
+ #ifdef _7Z_VOL
+ public IInArchiveGetStream,
+ #endif
+ #ifdef __7Z_SET_PROPERTIES
+ public ISetProperties,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public IOutArchive,
+ #endif
+ PUBLIC_ISetCompressCodecsInfo
+ public CMyUnknownImp
+{
+public:
+ MY_QUERYINTERFACE_BEGIN2(IInArchive)
+ #ifdef _7Z_VOL
+ MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
+ #endif
+ #ifdef __7Z_SET_PROPERTIES
+ MY_QUERYINTERFACE_ENTRY(ISetProperties)
+ #endif
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY(IOutArchive)
+ #endif
+ QUERY_ENTRY_ISetCompressCodecsInfo
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ INTERFACE_IInArchive(;)
+
+ #ifdef _7Z_VOL
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+ #endif
+
+ #ifdef __7Z_SET_PROPERTIES
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ INTERFACE_IOutArchive(;)
+ #endif
+
+ DECL_ISetCompressCodecsInfo
+
+ CHandler();
+
+private:
+ #ifdef _7Z_VOL
+ CObjectVector<CVolume> _volumes;
+ CObjectVector<CRef> _refs;
+ #else
+ CMyComPtr<IInStream> _inStream;
+ NArchive::N7z::CArchiveDatabaseEx _database;
+ #endif
+
+ #ifdef EXTRACT_ONLY
+
+ #ifdef COMPRESS_MT
+ UInt32 _numThreads;
+ #endif
+
+ UInt32 _crcSize;
+
+ #else
+
+ CRecordVector<CBind> _binds;
+
+ HRESULT SetPassword(CCompressionMethodMode &methodMode, IArchiveUpdateCallback *updateCallback);
+
+ HRESULT SetCompressionMethod(CCompressionMethodMode &method,
+ CObjectVector<COneMethodInfo> &methodsInfo
+ #ifdef COMPRESS_MT
+ , UInt32 numThreads
+ #endif
+ );
+
+ HRESULT SetCompressionMethod(
+ CCompressionMethodMode &method,
+ CCompressionMethodMode &headerMethod);
+
+ #endif
+
+ bool IsEncrypted(UInt32 index2) const;
+ #ifndef _SFX
+
+ CRecordVector<UInt64> _fileInfoPopIDs;
+ void FillPopIDs();
+
+ #endif
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,464 @@
+// 7zHandlerOut.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zOut.h"
+#include "7zUpdate.h"
+
+#include "../../../Windows/PropVariant.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../../Common/StringToInt.h"
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+
+#include "../Common/ItemNameUtils.h"
+#include "../Common/ParseProperties.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+static const wchar_t *kLZMAMethodName = L"LZMA";
+static const wchar_t *kCopyMethod = L"Copy";
+static const wchar_t *kDefaultMethodName = kLZMAMethodName;
+
+static const UInt32 kLzmaAlgorithmX5 = 1;
+static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
+static const UInt32 kDictionaryForHeaders = 1 << 20;
+static const UInt32 kNumFastBytesForHeaders = 273;
+static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
+
+static inline bool IsCopyMethod(const UString &methodName)
+ { return (methodName.CompareNoCase(kCopyMethod) == 0); }
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+{
+ *type = NFileTimeType::kWindows;
+ return S_OK;
+}
+
+HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
+ IArchiveUpdateCallback *updateCallback)
+{
+ CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
+ if (!getTextPassword)
+ {
+ CMyComPtr<IArchiveUpdateCallback> udateCallback2(updateCallback);
+ udateCallback2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
+ }
+
+ if (getTextPassword)
+ {
+ CMyComBSTR password;
+ Int32 passwordIsDefined;
+ RINOK(getTextPassword->CryptoGetTextPassword2(
+ &passwordIsDefined, &password));
+ methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
+ if (methodMode.PasswordIsDefined)
+ methodMode.Password = password;
+ }
+ else
+ methodMode.PasswordIsDefined = false;
+ return S_OK;
+}
+
+HRESULT CHandler::SetCompressionMethod(
+ CCompressionMethodMode &methodMode,
+ CCompressionMethodMode &headerMethod)
+{
+ HRESULT res = SetCompressionMethod(methodMode, _methods
+ #ifdef COMPRESS_MT
+ , _numThreads
+ #endif
+ );
+ RINOK(res);
+ methodMode.Binds = _binds;
+
+ if (_compressHeaders)
+ {
+ // headerMethod.Methods.Add(methodMode.Methods.Back());
+
+ CObjectVector<COneMethodInfo> headerMethodInfoVector;
+ COneMethodInfo oneMethodInfo;
+ oneMethodInfo.MethodName = kLZMAMethodName;
+ {
+ CProp property;
+ property.Id = NCoderPropID::kMatchFinder;
+ property.Value = kLzmaMatchFinderForHeaders;
+ oneMethodInfo.Properties.Add(property);
+ }
+ {
+ CProp property;
+ property.Id = NCoderPropID::kAlgorithm;
+ property.Value = kAlgorithmForHeaders;
+ oneMethodInfo.Properties.Add(property);
+ }
+ {
+ CProp property;
+ property.Id = NCoderPropID::kNumFastBytes;
+ property.Value = UInt32(kNumFastBytesForHeaders);
+ oneMethodInfo.Properties.Add(property);
+ }
+ {
+ CProp property;
+ property.Id = NCoderPropID::kDictionarySize;
+ property.Value = UInt32(kDictionaryForHeaders);
+ oneMethodInfo.Properties.Add(property);
+ }
+ headerMethodInfoVector.Add(oneMethodInfo);
+ HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
+ #ifdef COMPRESS_MT
+ ,1
+ #endif
+ );
+ RINOK(res);
+ }
+ return S_OK;
+}
+
+HRESULT CHandler::SetCompressionMethod(
+ CCompressionMethodMode &methodMode,
+ CObjectVector<COneMethodInfo> &methodsInfo
+ #ifdef COMPRESS_MT
+ , UInt32 numThreads
+ #endif
+ )
+{
+ UInt32 level = _level;
+
+ if (methodsInfo.IsEmpty())
+ {
+ COneMethodInfo oneMethodInfo;
+ oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
+ methodsInfo.Add(oneMethodInfo);
+ }
+
+ bool needSolid = false;
+ for(int i = 0; i < methodsInfo.Size(); i++)
+ {
+ COneMethodInfo &oneMethodInfo = methodsInfo[i];
+ SetCompressionMethod2(oneMethodInfo
+ #ifdef COMPRESS_MT
+ , numThreads
+ #endif
+ );
+
+ if (!IsCopyMethod(oneMethodInfo.MethodName))
+ needSolid = true;
+
+ CMethodFull methodFull;
+
+ if (!FindMethod(
+ EXTERNAL_CODECS_VARS
+ oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams))
+ return E_INVALIDARG;
+ methodFull.Properties = oneMethodInfo.Properties;
+ methodMode.Methods.Add(methodFull);
+
+ if (!_numSolidBytesDefined)
+ {
+ for (int j = 0; j < methodFull.Properties.Size(); j++)
+ {
+ const CProp &prop = methodFull.Properties[j];
+ if ((prop.Id == NCoderPropID::kDictionarySize ||
+ prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
+ {
+ _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
+ const UInt64 kMinSize = (1 << 24);
+ if (_numSolidBytes < kMinSize)
+ _numSolidBytes = kMinSize;
+ _numSolidBytesDefined = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!needSolid && !_numSolidBytesDefined)
+ {
+ _numSolidBytesDefined = true;
+ _numSolidBytes = 0;
+ }
+ return S_OK;
+}
+
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined)
+{
+ filetimeIsDefined = false;
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(index, propID, &propVariant));
+ if (propVariant.vt == VT_FILETIME)
+ {
+ filetime = propVariant.filetime;
+ filetimeIsDefined = true;
+ }
+ else if (propVariant.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+
+ const CArchiveDatabaseEx *database = 0;
+ #ifdef _7Z_VOL
+ if(_volumes.Size() > 1)
+ return E_FAIL;
+ const CVolume *volume = 0;
+ if (_volumes.Size() == 1)
+ {
+ volume = &_volumes.Front();
+ database = &volume->Database;
+ }
+ #else
+ if (_inStream != 0)
+ database = &_database;
+ #endif
+
+ // CRecordVector<bool> compressStatuses;
+ CObjectVector<CUpdateItem> updateItems;
+ // CRecordVector<UInt32> copyIndices;
+
+ // CMyComPtr<IUpdateCallback2> updateCallback2;
+ // updateCallback->QueryInterface(&updateCallback2);
+
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ Int32 newData;
+ Int32 newProperties;
+ UInt32 indexInArchive;
+ if (!updateCallback)
+ return E_FAIL;
+ RINOK(updateCallback->GetUpdateItemInfo(i,
+ &newData, &newProperties, &indexInArchive));
+ CUpdateItem updateItem;
+ updateItem.NewProperties = IntToBool(newProperties);
+ updateItem.NewData = IntToBool(newData);
+ updateItem.IndexInArchive = indexInArchive;
+ updateItem.IndexInClient = i;
+ updateItem.IsAnti = false;
+ updateItem.Size = 0;
+
+ if (updateItem.IndexInArchive != -1)
+ {
+ const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
+ updateItem.Name = fileItem.Name;
+ updateItem.IsDirectory = fileItem.IsDirectory;
+ updateItem.Size = fileItem.UnPackSize;
+ updateItem.IsAnti = fileItem.IsAnti;
+
+ updateItem.CreationTime = fileItem.CreationTime;
+ updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined;
+ updateItem.LastWriteTime = fileItem.LastWriteTime;
+ updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
+ updateItem.LastAccessTime = fileItem.LastAccessTime;
+ updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
+ }
+
+ if (updateItem.NewProperties)
+ {
+ bool nameIsDefined;
+ bool folderStatusIsDefined;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ updateItem.AttributesAreDefined = false;
+ else if (propVariant.vt != VT_UI4)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.Attributes = propVariant.ulVal;
+ updateItem.AttributesAreDefined = true;
+ }
+ }
+
+ RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined));
+ RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined));
+ RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined));
+
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ nameIsDefined = false;
+ else if (propVariant.vt != VT_BSTR)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal);
+ nameIsDefined = true;
+ }
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ folderStatusIsDefined = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
+ folderStatusIsDefined = true;
+ }
+ }
+
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ updateItem.IsAnti = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
+ }
+
+ if (updateItem.IsAnti)
+ {
+ updateItem.AttributesAreDefined = false;
+
+ updateItem.IsCreationTimeDefined = false;
+ updateItem.IsLastWriteTimeDefined = false;
+ updateItem.IsLastAccessTimeDefined = false;
+
+ updateItem.Size = 0;
+ }
+
+ if (!folderStatusIsDefined && updateItem.AttributesAreDefined)
+ updateItem.SetDirectoryStatusFromAttributes();
+ }
+
+ if (updateItem.NewData)
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
+ if (updateItem.Size != 0 && updateItem.IsAnti)
+ return E_INVALIDARG;
+ }
+ updateItems.Add(updateItem);
+ }
+
+ CCompressionMethodMode methodMode, headerMethod;
+ RINOK(SetCompressionMethod(methodMode, headerMethod));
+ #ifdef COMPRESS_MT
+ methodMode.NumThreads = _numThreads;
+ headerMethod.NumThreads = 1;
+ #endif
+
+ RINOK(SetPassword(methodMode, updateCallback));
+
+ bool compressMainHeader = _compressHeaders; // check it
+
+ if (methodMode.PasswordIsDefined)
+ {
+ compressMainHeader = true;
+ if(_encryptHeaders)
+ RINOK(SetPassword(headerMethod, updateCallback));
+ }
+
+ if (numItems < 2)
+ compressMainHeader = false;
+
+ CUpdateOptions options;
+ options.Method = &methodMode;
+ options.HeaderMethod = (_compressHeaders ||
+ (methodMode.PasswordIsDefined && _encryptHeaders)) ?
+ &headerMethod : 0;
+ options.UseFilters = _level != 0 && _autoFilter;
+ options.MaxFilter = _level >= 8;
+
+ options.HeaderOptions.CompressMainHeader = compressMainHeader;
+ options.HeaderOptions.WriteModified = WriteModified;
+ options.HeaderOptions.WriteCreated = WriteCreated;
+ options.HeaderOptions.WriteAccessed = WriteAccessed;
+
+ options.NumSolidFiles = _numSolidFiles;
+ options.NumSolidBytes = _numSolidBytes;
+ options.SolidExtension = _solidExtension;
+ options.RemoveSfxBlock = _removeSfxBlock;
+ options.VolumeMode = _volumeMode;
+ return Update(
+ EXTERNAL_CODECS_VARS
+ #ifdef _7Z_VOL
+ volume ? volume->Stream: 0,
+ volume ? database: 0,
+ #else
+ _inStream,
+ database,
+ #endif
+ updateItems, outStream, updateCallback, options);
+ COM_TRY_END
+}
+
+static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
+{
+ stream = 0;
+ int index = ParseStringToUInt32(srcString, coder);
+ if (index == 0)
+ return E_INVALIDARG;
+ srcString.Delete(0, index);
+ if (srcString[0] == 'S')
+ {
+ srcString.Delete(0);
+ int index = ParseStringToUInt32(srcString, stream);
+ if (index == 0)
+ return E_INVALIDARG;
+ srcString.Delete(0, index);
+ }
+ return S_OK;
+}
+
+static HRESULT GetBindInfo(UString &srcString, CBind &bind)
+{
+ RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
+ if (srcString[0] != ':')
+ return E_INVALIDARG;
+ srcString.Delete(0);
+ RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
+ if (!srcString.IsEmpty())
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ COM_TRY_BEGIN
+ _binds.Clear();
+ BeforeSetProperty();
+
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = names[i];
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ const PROPVARIANT &value = values[i];
+
+ if (name[0] == 'B')
+ {
+ name.Delete(0);
+ CBind bind;
+ RINOK(GetBindInfo(name, bind));
+ _binds.Add(bind);
+ continue;
+ }
+
+ RINOK(SetProperty(name, value));
+ }
+
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zHeader.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zHeader.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,27 @@
+// 7z/Header.cpp
+
+#include "StdAfx.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
+#ifdef _7Z_VOL
+Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
+#endif
+
+class SignatureInitializer
+{
+public:
+ SignatureInitializer()
+ {
+ kSignature[0]--;
+ #ifdef _7Z_VOL
+ kFinishSignature[0]--;
+ #endif
+ };
+} g_SignatureInitializer;
+
+}}
+
Added: trunk/lzma/CPP/7zip/Archive/7z/7zHeader.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zHeader.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zHeader.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,96 @@
+// 7z/7zHeader.h
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+#include "../../../Common/Types.h"
+
+namespace NArchive {
+namespace N7z {
+
+const int kSignatureSize = 6;
+extern Byte kSignature[kSignatureSize];
+
+// #define _7Z_VOL
+// 7z-MultiVolume is not finished yet.
+// It can work already, but I still do not like some
+// things of that new multivolume format.
+// So please keep it commented.
+
+#ifdef _7Z_VOL
+extern Byte kFinishSignature[kSignatureSize];
+#endif
+
+struct CArchiveVersion
+{
+ Byte Major;
+ Byte Minor;
+};
+
+const Byte kMajorVersion = 0;
+
+struct CStartHeader
+{
+ UInt64 NextHeaderOffset;
+ UInt64 NextHeaderSize;
+ UInt32 NextHeaderCRC;
+};
+
+const UInt32 kStartHeaderSize = 20;
+
+#ifdef _7Z_VOL
+struct CFinishHeader: public CStartHeader
+{
+ UInt64 ArchiveStartOffset; // data offset from end if that struct
+ UInt64 AdditionalStartBlockSize; // start signature & start header size
+};
+
+const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;
+#endif
+
+namespace NID
+{
+ enum EEnum
+ {
+ kEnd,
+
+ kHeader,
+
+ kArchiveProperties,
+
+ kAdditionalStreamsInfo,
+ kMainStreamsInfo,
+ kFilesInfo,
+
+ kPackInfo,
+ kUnPackInfo,
+ kSubStreamsInfo,
+
+ kSize,
+ kCRC,
+
+ kFolder,
+
+ kCodersUnPackSize,
+ kNumUnPackStream,
+
+ kEmptyStream,
+ kEmptyFile,
+ kAnti,
+
+ kName,
+ kCreationTime,
+ kLastAccessTime,
+ kLastWriteTime,
+ kWinAttributes,
+ kComment,
+
+ kEncodedHeader,
+
+ kStartPos
+ };
+}
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zIn.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zIn.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zIn.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1206 @@
+// 7zIn.cpp
+
+#include "StdAfx.h"
+
+#include "7zIn.h"
+#include "7zDecode.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+extern "C"
+{
+#include "../../../../C/7zCrc.h"
+}
+
+// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
+#ifndef _SFX
+#define FORMAT_7Z_RECOVERY
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+class CInArchiveException {};
+
+static void ThrowException() { throw CInArchiveException(); }
+static inline void ThrowEndOfData() { ThrowException(); }
+static inline void ThrowUnsupported() { ThrowException(); }
+static inline void ThrowIncorrect() { ThrowException(); }
+static inline void ThrowUnsupportedVersion() { ThrowException(); }
+
+/*
+class CInArchiveException
+{
+public:
+ enum CCauseType
+ {
+ kUnsupportedVersion = 0,
+ kUnsupported,
+ kIncorrect,
+ kEndOfData,
+ } Cause;
+ CInArchiveException(CCauseType cause): Cause(cause) {};
+};
+
+static void ThrowException(CInArchiveException::CCauseType c) { throw CInArchiveException(c); }
+static void ThrowEndOfData() { ThrowException(CInArchiveException::kEndOfData); }
+static void ThrowUnsupported() { ThrowException(CInArchiveException::kUnsupported); }
+static void ThrowIncorrect() { ThrowException(CInArchiveException::kIncorrect); }
+static void ThrowUnsupportedVersion() { ThrowException(CInArchiveException::kUnsupportedVersion); }
+*/
+
+class CStreamSwitch
+{
+ CInArchive *_archive;
+ bool _needRemove;
+public:
+ CStreamSwitch(): _needRemove(false) {}
+ ~CStreamSwitch() { Remove(); }
+ void Remove();
+ void Set(CInArchive *archive, const Byte *data, size_t size);
+ void Set(CInArchive *archive, const CByteBuffer &byteBuffer);
+ void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);
+};
+
+void CStreamSwitch::Remove()
+{
+ if (_needRemove)
+ {
+ _archive->DeleteByteStream();
+ _needRemove = false;
+ }
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size)
+{
+ Remove();
+ _archive = archive;
+ _archive->AddByteStream(data, size);
+ _needRemove = true;
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
+{
+ Set(archive, byteBuffer, byteBuffer.GetCapacity());
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
+{
+ Remove();
+ Byte external = archive->ReadByte();
+ if (external != 0)
+ {
+ int dataIndex = (int)archive->ReadNum();
+ if (dataIndex < 0 || dataIndex >= dataVector->Size())
+ ThrowIncorrect();
+ Set(archive, (*dataVector)[dataIndex]);
+ }
+}
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
+#define SZ_LITTLE_ENDIAN_UNALIGN
+#endif
+
+#ifdef SZ_LITTLE_ENDIAN_UNALIGN
+static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; }
+static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; }
+static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; }
+#else
+static inline UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); }
+static inline UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); }
+static inline UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); }
+#endif
+
+Byte CInByte2::ReadByte()
+{
+ if (_pos >= _size)
+ ThrowEndOfData();
+ return _buffer[_pos++];
+}
+
+void CInByte2::ReadBytes(Byte *data, size_t size)
+{
+ if (size > _size - _pos)
+ ThrowEndOfData();
+ for (size_t i = 0; i < size; i++)
+ data[i] = _buffer[_pos++];
+}
+
+void CInByte2::SkeepData(UInt64 size)
+{
+ if (size > _size - _pos)
+ ThrowEndOfData();
+}
+
+void CInByte2::SkeepData()
+{
+ SkeepData(ReadNumber());
+}
+
+UInt64 CInByte2::ReadNumber()
+{
+ if (_pos >= _size)
+ ThrowEndOfData();
+ Byte firstByte = _buffer[_pos++];
+ Byte mask = 0x80;
+ UInt64 value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = firstByte & (mask - 1);
+ value += (highPart << (i * 8));
+ return value;
+ }
+ if (_pos >= _size)
+ ThrowEndOfData();
+ value |= ((UInt64)_buffer[_pos++] << (8 * i));
+ mask >>= 1;
+ }
+ return value;
+}
+
+CNum CInByte2::ReadNum()
+{
+ UInt64 value = ReadNumber();
+ if (value > kNumMax)
+ ThrowUnsupported();
+ return (CNum)value;
+}
+
+UInt32 CInByte2::ReadUInt32()
+{
+ if (_pos + 4 > _size)
+ ThrowEndOfData();
+ UInt32 res = GetUInt32FromMem(_buffer + _pos);
+ _pos += 4;
+ return res;
+}
+
+UInt64 CInByte2::ReadUInt64()
+{
+ if (_pos + 8 > _size)
+ ThrowEndOfData();
+ UInt64 res = GetUInt64FromMem(_buffer + _pos);
+ _pos += 8;
+ return res;
+}
+
+void CInByte2::ReadString(UString &s)
+{
+ const Byte *buf = _buffer + _pos;
+ size_t rem = (_size - _pos) / 2 * 2;
+ {
+ size_t i;
+ for (i = 0; i < rem; i += 2)
+ if (buf[i] == 0 && buf[i + 1] == 0)
+ break;
+ if (i == rem)
+ ThrowEndOfData();
+ rem = i;
+ }
+ int len = (int)(rem / 2);
+ if (len < 0 || (size_t)len * 2 != rem)
+ ThrowUnsupported();
+ wchar_t *p = s.GetBuffer(len);
+ int i;
+ for (i = 0; i < len; i++, buf += 2)
+ p[i] = (wchar_t)GetUInt16FromMem(buf);
+ p[i] = 0;
+ s.ReleaseBuffer(len);
+ _pos += rem + 2;
+}
+
+static inline bool TestSignatureCandidate(const Byte *p)
+{
+ for (int i = 0; i < kSignatureSize; i++)
+ if (p[i] != kSignature[i])
+ return false;
+ return (p[0x1A] == 0 && p[0x1B] == 0);
+}
+
+HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ UInt32 processedSize;
+ RINOK(ReadStream(stream, _header, kHeaderSize, &processedSize));
+ if (processedSize != kHeaderSize)
+ return S_FALSE;
+ if (TestSignatureCandidate(_header))
+ return S_OK;
+
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (1 << 16);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ UInt32 numPrevBytes = kHeaderSize - 1;
+ memcpy(buffer, _header + 1, numPrevBytes);
+ UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
+ for (;;)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
+ break;
+ UInt32 numReadBytes = kBufferSize - numPrevBytes;
+ RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
+ UInt32 numBytesInBuffer = numPrevBytes + processedSize;
+ if (numBytesInBuffer < kHeaderSize)
+ break;
+ UInt32 numTests = numBytesInBuffer - kHeaderSize + 1;
+ for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
+ {
+ if (TestSignatureCandidate(buffer + pos))
+ {
+ memcpy(_header, buffer + pos, kHeaderSize);
+ _arhiveBeginStreamPosition = curTestPos;
+ return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
+ }
+ }
+ numPrevBytes = numBytesInBuffer - numTests;
+ memmove(buffer, buffer + numTests, numPrevBytes);
+ }
+ return S_FALSE;
+}
+
+// S_FALSE means that file is not archive
+HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ Close();
+ RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
+ RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
+ _stream = stream;
+ return S_OK;
+}
+
+void CInArchive::Close()
+{
+ _stream.Release();
+}
+
+void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
+{
+ for (;;)
+ {
+ if (ReadID() == NID::kEnd)
+ break;
+ SkeepData();
+ }
+}
+
+void CInArchive::GetNextFolderItem(CFolder &folder)
+{
+ CNum numCoders = ReadNum();
+
+ folder.Coders.Clear();
+ folder.Coders.Reserve((int)numCoders);
+ CNum numInStreams = 0;
+ CNum numOutStreams = 0;
+ CNum i;
+ for (i = 0; i < numCoders; i++)
+ {
+ folder.Coders.Add(CCoderInfo());
+ CCoderInfo &coder = folder.Coders.Back();
+
+ {
+ Byte mainByte = ReadByte();
+ int idSize = (mainByte & 0xF);
+ Byte longID[15];
+ ReadBytes(longID, idSize);
+ if (idSize > 8)
+ ThrowUnsupported();
+ UInt64 id = 0;
+ for (int j = 0; j < idSize; j++)
+ id |= (UInt64)longID[idSize - 1 - j] << (8 * j);
+ coder.MethodID = id;
+
+ if ((mainByte & 0x10) != 0)
+ {
+ coder.NumInStreams = ReadNum();
+ coder.NumOutStreams = ReadNum();
+ }
+ else
+ {
+ coder.NumInStreams = 1;
+ coder.NumOutStreams = 1;
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ CNum propertiesSize = ReadNum();
+ coder.Properties.SetCapacity((size_t)propertiesSize);
+ ReadBytes((Byte *)coder.Properties, (size_t)propertiesSize);
+ }
+ if ((mainByte & 0x80) != 0)
+ ThrowUnsupported();
+ }
+ numInStreams += coder.NumInStreams;
+ numOutStreams += coder.NumOutStreams;
+ }
+
+ CNum numBindPairs;
+ numBindPairs = numOutStreams - 1;
+ folder.BindPairs.Clear();
+ folder.BindPairs.Reserve(numBindPairs);
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CBindPair bindPair;
+ bindPair.InIndex = ReadNum();
+ bindPair.OutIndex = ReadNum();
+ folder.BindPairs.Add(bindPair);
+ }
+
+ CNum numPackedStreams = numInStreams - numBindPairs;
+ folder.PackStreams.Reserve(numPackedStreams);
+ if (numPackedStreams == 1)
+ {
+ for (CNum j = 0; j < numInStreams; j++)
+ if (folder.FindBindPairForInStream(j) < 0)
+ {
+ folder.PackStreams.Add(j);
+ break;
+ }
+ }
+ else
+ for(i = 0; i < numPackedStreams; i++)
+ folder.PackStreams.Add(ReadNum());
+}
+
+void CInArchive::WaitAttribute(UInt64 attribute)
+{
+ for (;;)
+ {
+ UInt64 type = ReadID();
+ if (type == attribute)
+ return;
+ if (type == NID::kEnd)
+ ThrowIncorrect();
+ SkeepData();
+ }
+}
+
+void CInArchive::ReadHashDigests(int numItems,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ ReadBoolVector2(numItems, digestsDefined);
+ digests.Clear();
+ digests.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ {
+ UInt32 crc = 0;
+ if (digestsDefined[i])
+ crc = ReadUInt32();
+ digests.Add(crc);
+ }
+}
+
+void CInArchive::ReadPackInfo(
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs)
+{
+ dataOffset = ReadNumber();
+ CNum numPackStreams = ReadNum();
+
+ WaitAttribute(NID::kSize);
+ packSizes.Clear();
+ packSizes.Reserve(numPackStreams);
+ for (CNum i = 0; i < numPackStreams; i++)
+ packSizes.Add(ReadNumber());
+
+ UInt64 type;
+ for (;;)
+ {
+ type = ReadID();
+ if (type == NID::kEnd)
+ break;
+ if (type == NID::kCRC)
+ {
+ ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
+ continue;
+ }
+ SkeepData();
+ }
+ if (packCRCsDefined.IsEmpty())
+ {
+ packCRCsDefined.Reserve(numPackStreams);
+ packCRCsDefined.Clear();
+ packCRCs.Reserve(numPackStreams);
+ packCRCs.Clear();
+ for(CNum i = 0; i < numPackStreams; i++)
+ {
+ packCRCsDefined.Add(false);
+ packCRCs.Add(0);
+ }
+ }
+}
+
+void CInArchive::ReadUnPackInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ CObjectVector<CFolder> &folders)
+{
+ WaitAttribute(NID::kFolder);
+ CNum numFolders = ReadNum();
+
+ {
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, dataVector);
+ folders.Clear();
+ folders.Reserve(numFolders);
+ for(CNum i = 0; i < numFolders; i++)
+ {
+ folders.Add(CFolder());
+ GetNextFolderItem(folders.Back());
+ }
+ }
+
+ WaitAttribute(NID::kCodersUnPackSize);
+
+ CNum i;
+ for (i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ CNum numOutStreams = folder.GetNumOutStreams();
+ folder.UnPackSizes.Reserve(numOutStreams);
+ for (CNum j = 0; j < numOutStreams; j++)
+ folder.UnPackSizes.Add(ReadNumber());
+ }
+
+ for (;;)
+ {
+ UInt64 type = ReadID();
+ if (type == NID::kEnd)
+ return;
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> crcsDefined;
+ CRecordVector<UInt32> crcs;
+ ReadHashDigests(numFolders, crcsDefined, crcs);
+ for(i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ folder.UnPackCRCDefined = crcsDefined[i];
+ folder.UnPackCRC = crcs[i];
+ }
+ continue;
+ }
+ SkeepData();
+ }
+}
+
+void CInArchive::ReadSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ numUnPackStreamsInFolders.Clear();
+ numUnPackStreamsInFolders.Reserve(folders.Size());
+ UInt64 type;
+ for (;;)
+ {
+ type = ReadID();
+ if (type == NID::kNumUnPackStream)
+ {
+ for(int i = 0; i < folders.Size(); i++)
+ numUnPackStreamsInFolders.Add(ReadNum());
+ continue;
+ }
+ if (type == NID::kCRC || type == NID::kSize)
+ break;
+ if (type == NID::kEnd)
+ break;
+ SkeepData();
+ }
+
+ if (numUnPackStreamsInFolders.IsEmpty())
+ for(int i = 0; i < folders.Size(); i++)
+ numUnPackStreamsInFolders.Add(1);
+
+ int i;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ {
+ // v3.13 incorrectly worked with empty folders
+ // v4.07: we check that folder is empty
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ if (numSubstreams == 0)
+ continue;
+ UInt64 sum = 0;
+ for (CNum j = 1; j < numSubstreams; j++)
+ if (type == NID::kSize)
+ {
+ UInt64 size = ReadNumber();
+ unPackSizes.Add(size);
+ sum += size;
+ }
+ unPackSizes.Add(folders[i].GetUnPackSize() - sum);
+ }
+ if (type == NID::kSize)
+ type = ReadID();
+
+ int numDigests = 0;
+ int numDigestsTotal = 0;
+ for(i = 0; i < folders.Size(); i++)
+ {
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
+ numDigests += numSubstreams;
+ numDigestsTotal += numSubstreams;
+ }
+
+ for (;;)
+ {
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> digestsDefined2;
+ CRecordVector<UInt32> digests2;
+ ReadHashDigests(numDigests, digestsDefined2, digests2);
+ int digestIndex = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ const CFolder &folder = folders[i];
+ if (numSubstreams == 1 && folder.UnPackCRCDefined)
+ {
+ digestsDefined.Add(true);
+ digests.Add(folder.UnPackCRC);
+ }
+ else
+ for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
+ {
+ digestsDefined.Add(digestsDefined2[digestIndex]);
+ digests.Add(digests2[digestIndex]);
+ }
+ }
+ }
+ else if (type == NID::kEnd)
+ {
+ if (digestsDefined.IsEmpty())
+ {
+ digestsDefined.Clear();
+ digests.Clear();
+ for (int i = 0; i < numDigestsTotal; i++)
+ {
+ digestsDefined.Add(false);
+ digests.Add(0);
+ }
+ }
+ return;
+ }
+ else
+ SkeepData();
+ type = ReadID();
+ }
+}
+
+void CInArchive::ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ for (;;)
+ {
+ UInt64 type = ReadID();
+ if (type > ((UInt32)1 << 30))
+ ThrowIncorrect();
+ switch((UInt32)type)
+ {
+ case NID::kEnd:
+ return;
+ case NID::kPackInfo:
+ {
+ ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
+ break;
+ }
+ case NID::kUnPackInfo:
+ {
+ ReadUnPackInfo(dataVector, folders);
+ break;
+ }
+ case NID::kSubStreamsInfo:
+ {
+ ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
+ unPackSizes, digestsDefined, digests);
+ break;
+ }
+ default:
+ ThrowIncorrect();
+ }
+ }
+}
+
+void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
+{
+ v.Clear();
+ v.Reserve(numItems);
+ Byte b = 0;
+ Byte mask = 0;
+ for(int i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ b = ReadByte();
+ mask = 0x80;
+ }
+ v.Add((b & mask) != 0);
+ mask >>= 1;
+ }
+}
+
+void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
+{
+ Byte allAreDefined = ReadByte();
+ if (allAreDefined == 0)
+ {
+ ReadBoolVector(numItems, v);
+ return;
+ }
+ v.Clear();
+ v.Reserve(numItems);
+ for (int i = 0; i < numItems; i++)
+ v.Add(true);
+}
+
+void CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt32 type)
+{
+ CBoolVector boolVector;
+ ReadBoolVector2(files.Size(), boolVector);
+
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, &dataVector);
+
+ for(int i = 0; i < files.Size(); i++)
+ {
+ CFileItem &file = files[i];
+ CArchiveFileTime fileTime;
+ fileTime.dwLowDateTime = 0;
+ fileTime.dwHighDateTime = 0;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ fileTime.dwLowDateTime = ReadUInt32();
+ fileTime.dwHighDateTime = ReadUInt32();
+ }
+ switch(type)
+ {
+ case NID::kCreationTime:
+ file.IsCreationTimeDefined = defined;
+ if (defined)
+ file.CreationTime = fileTime;
+ break;
+ case NID::kLastWriteTime:
+ file.IsLastWriteTimeDefined = defined;
+ if (defined)
+ file.LastWriteTime = fileTime;
+ break;
+ case NID::kLastAccessTime:
+ file.IsLastAccessTimeDefined = defined;
+ if (defined)
+ file.LastAccessTime = fileTime;
+ break;
+ }
+ }
+}
+
+HRESULT CInArchive::ReadAndDecodePackedStreams(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ UInt64 baseOffset,
+ UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ CRecordVector<UInt64> packSizes;
+ CRecordVector<bool> packCRCsDefined;
+ CRecordVector<UInt32> packCRCs;
+ CObjectVector<CFolder> folders;
+
+ CRecordVector<CNum> numUnPackStreamsInFolders;
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+
+ ReadStreamsInfo(NULL,
+ dataOffset,
+ packSizes,
+ packCRCsDefined,
+ packCRCs,
+ folders,
+ numUnPackStreamsInFolders,
+ unPackSizes,
+ digestsDefined,
+ digests);
+
+ // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+
+ CNum packIndex = 0;
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
+ UInt64 dataStartPos = baseOffset + dataOffset;
+ for(int i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ dataVector.Add(CByteBuffer());
+ CByteBuffer &data = dataVector.Back();
+ UInt64 unPackSize64 = folder.GetUnPackSize();
+ size_t unPackSize = (size_t)unPackSize64;
+ if (unPackSize != unPackSize64)
+ ThrowUnsupported();
+ data.SetCapacity(unPackSize);
+
+ CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ outStreamSpec->Init(data, unPackSize);
+
+ HRESULT result = decoder.Decode(
+ EXTERNAL_CODECS_LOC_VARS
+ _stream, dataStartPos,
+ &packSizes[packIndex], folder, outStream, NULL
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , false, 1
+ #endif
+ );
+ RINOK(result);
+
+ if (folder.UnPackCRCDefined)
+ if (CrcCalc(data, unPackSize) != folder.UnPackCRC)
+ ThrowIncorrect();
+ for (int j = 0; j < folder.PackStreams.Size(); j++)
+ dataStartPos += packSizes[packIndex++];
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadHeader(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ UInt64 type = ReadID();
+
+ if (type == NID::kArchiveProperties)
+ {
+ ReadArchiveProperties(database.ArchiveInfo);
+ type = ReadID();
+ }
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ if (type == NID::kAdditionalStreamsInfo)
+ {
+ HRESULT result = ReadAndDecodePackedStreams(
+ EXTERNAL_CODECS_LOC_VARS
+ database.ArchiveInfo.StartPositionAfterHeader,
+ database.ArchiveInfo.DataStartPosition2,
+ dataVector
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+ type = ReadID();
+ }
+
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+
+ if (type == NID::kMainStreamsInfo)
+ {
+ ReadStreamsInfo(&dataVector,
+ database.ArchiveInfo.DataStartPosition,
+ database.PackSizes,
+ database.PackCRCsDefined,
+ database.PackCRCs,
+ database.Folders,
+ database.NumUnPackStreamsVector,
+ unPackSizes,
+ digestsDefined,
+ digests);
+ database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader;
+ type = ReadID();
+ }
+ else
+ {
+ for(int i = 0; i < database.Folders.Size(); i++)
+ {
+ database.NumUnPackStreamsVector.Add(1);
+ CFolder &folder = database.Folders[i];
+ unPackSizes.Add(folder.GetUnPackSize());
+ digestsDefined.Add(folder.UnPackCRCDefined);
+ digests.Add(folder.UnPackCRC);
+ }
+ }
+
+ database.Files.Clear();
+
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type != NID::kFilesInfo)
+ ThrowIncorrect();
+
+ CNum numFiles = ReadNum();
+ database.Files.Reserve(numFiles);
+ CNum i;
+ for(i = 0; i < numFiles; i++)
+ database.Files.Add(CFileItem());
+
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
+ if (!database.PackSizes.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+ if (numFiles > 0 && !digests.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.Reserve((int)numFiles);
+ for(i = 0; i < numFiles; i++)
+ emptyStreamVector.Add(false);
+ CBoolVector emptyFileVector;
+ CBoolVector antiFileVector;
+ CNum numEmptyStreams = 0;
+
+ for (;;)
+ {
+ UInt64 type = ReadID();
+ if (type == NID::kEnd)
+ break;
+ UInt64 size = ReadNumber();
+ bool isKnownType = true;
+ if (type > ((UInt32)1 << 30))
+ isKnownType = false;
+ else switch((UInt32)type)
+ {
+ case NID::kName:
+ {
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, &dataVector);
+ for(int i = 0; i < database.Files.Size(); i++)
+ _inByteBack->ReadString(database.Files[i].Name);
+ break;
+ }
+ case NID::kWinAttributes:
+ {
+ CBoolVector boolVector;
+ ReadBoolVector2(database.Files.Size(), boolVector);
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, &dataVector);
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ file.AreAttributesDefined = boolVector[i];
+ if (file.AreAttributesDefined)
+ file.Attributes = ReadUInt32();
+ }
+ break;
+ }
+ case NID::kStartPos:
+ {
+ CBoolVector boolVector;
+ ReadBoolVector2(database.Files.Size(), boolVector);
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, &dataVector);
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ file.IsStartPosDefined = boolVector[i];
+ if (file.IsStartPosDefined)
+ file.StartPos = ReadUInt64();
+ }
+ break;
+ }
+ case NID::kEmptyStream:
+ {
+ ReadBoolVector(numFiles, emptyStreamVector);
+ for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
+ if (emptyStreamVector[i])
+ numEmptyStreams++;
+ emptyFileVector.Reserve(numEmptyStreams);
+ antiFileVector.Reserve(numEmptyStreams);
+ for (i = 0; i < numEmptyStreams; i++)
+ {
+ emptyFileVector.Add(false);
+ antiFileVector.Add(false);
+ }
+ break;
+ }
+ case NID::kEmptyFile:
+ {
+ ReadBoolVector(numEmptyStreams, emptyFileVector);
+ break;
+ }
+ case NID::kAnti:
+ {
+ ReadBoolVector(numEmptyStreams, antiFileVector);
+ break;
+ }
+ case NID::kCreationTime:
+ case NID::kLastWriteTime:
+ case NID::kLastAccessTime:
+ {
+ ReadTime(dataVector, database.Files, (UInt32)type);
+ break;
+ }
+ default:
+ isKnownType = false;
+ }
+ if (isKnownType)
+ database.ArchiveInfo.FileInfoPopIDs.Add(type);
+ else
+ SkeepData(size);
+ }
+
+ CNum emptyFileIndex = 0;
+ CNum sizeIndex = 0;
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ file.HasStream = !emptyStreamVector[i];
+ if(file.HasStream)
+ {
+ file.IsDirectory = false;
+ file.IsAnti = false;
+ file.UnPackSize = unPackSizes[sizeIndex];
+ file.FileCRC = digests[sizeIndex];
+ file.IsFileCRCDefined = digestsDefined[sizeIndex];
+ sizeIndex++;
+ }
+ else
+ {
+ file.IsDirectory = !emptyFileVector[emptyFileIndex];
+ file.IsAnti = antiFileVector[emptyFileIndex];
+ emptyFileIndex++;
+ file.UnPackSize = 0;
+ file.IsFileCRCDefined = false;
+ }
+ }
+ return S_OK;
+}
+
+
+void CArchiveDatabaseEx::FillFolderStartPackStream()
+{
+ FolderStartPackStreamIndex.Clear();
+ FolderStartPackStreamIndex.Reserve(Folders.Size());
+ CNum startPos = 0;
+ for(int i = 0; i < Folders.Size(); i++)
+ {
+ FolderStartPackStreamIndex.Add(startPos);
+ startPos += (CNum)Folders[i].PackStreams.Size();
+ }
+}
+
+void CArchiveDatabaseEx::FillStartPos()
+{
+ PackStreamStartPositions.Clear();
+ PackStreamStartPositions.Reserve(PackSizes.Size());
+ UInt64 startPos = 0;
+ for(int i = 0; i < PackSizes.Size(); i++)
+ {
+ PackStreamStartPositions.Add(startPos);
+ startPos += PackSizes[i];
+ }
+}
+
+void CArchiveDatabaseEx::FillFolderStartFileIndex()
+{
+ FolderStartFileIndex.Clear();
+ FolderStartFileIndex.Reserve(Folders.Size());
+ FileIndexToFolderIndexMap.Clear();
+ FileIndexToFolderIndexMap.Reserve(Files.Size());
+
+ int folderIndex = 0;
+ CNum indexInFolder = 0;
+ for (int i = 0; i < Files.Size(); i++)
+ {
+ const CFileItem &file = Files[i];
+ bool emptyStream = !file.HasStream;
+ if (emptyStream && indexInFolder == 0)
+ {
+ FileIndexToFolderIndexMap.Add(kNumNoIndex);
+ continue;
+ }
+ if (indexInFolder == 0)
+ {
+ // v3.13 incorrectly worked with empty folders
+ // v4.07: Loop for skipping empty folders
+ for (;;)
+ {
+ if (folderIndex >= Folders.Size())
+ ThrowIncorrect();
+ FolderStartFileIndex.Add(i); // check it
+ if (NumUnPackStreamsVector[folderIndex] != 0)
+ break;
+ folderIndex++;
+ }
+ }
+ FileIndexToFolderIndexMap.Add(folderIndex);
+ if (emptyStream)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= NumUnPackStreamsVector[folderIndex])
+ {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+}
+
+HRESULT CInArchive::ReadDatabase2(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ database.Clear();
+ database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+
+ database.ArchiveInfo.Version.Major = _header[6];
+ database.ArchiveInfo.Version.Minor = _header[7];
+
+ if (database.ArchiveInfo.Version.Major != kMajorVersion)
+ ThrowUnsupportedVersion();
+
+ UInt32 crcFromArchive = GetUInt32FromMem(_header + 8);
+ UInt64 nextHeaderOffset = GetUInt64FromMem(_header + 0xC);
+ UInt64 nextHeaderSize = GetUInt64FromMem(_header + 0x14);
+ UInt32 nextHeaderCRC = GetUInt32FromMem(_header + 0x1C);
+ UInt32 crc = CrcCalc(_header + 0xC, 20);
+
+ #ifdef FORMAT_7Z_RECOVERY
+ if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
+ {
+ UInt64 cur, cur2;
+ RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));
+ const int kCheckSize = 500;
+ Byte buf[kCheckSize];
+ RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2));
+ int checkSize = kCheckSize;
+ if (cur2 - cur < kCheckSize)
+ checkSize = (int)(cur2 - cur);
+ RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
+
+ UInt32 realProcessedSize;
+ RINOK(_stream->Read(buf, (UInt32)kCheckSize, &realProcessedSize));
+
+ int i;
+ for (i = (int)realProcessedSize - 2; i >= 0; i--)
+ if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
+ break;
+ if (i < 0)
+ return S_FALSE;
+ nextHeaderSize = realProcessedSize - i;
+ nextHeaderOffset = cur2 - cur + i;
+ nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
+ RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
+ }
+ #endif
+
+ #ifdef FORMAT_7Z_RECOVERY
+ crcFromArchive = crc;
+ #endif
+
+ database.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
+
+ if (crc != crcFromArchive)
+ ThrowIncorrect();
+
+ if (nextHeaderSize == 0)
+ return S_OK;
+
+ if (nextHeaderSize > (UInt64)0xFFFFFFFF)
+ return S_FALSE;
+
+ RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
+
+ CByteBuffer buffer2;
+ buffer2.SetCapacity((size_t)nextHeaderSize);
+
+ UInt32 realProcessedSize;
+ RINOK(_stream->Read(buffer2, (UInt32)nextHeaderSize, &realProcessedSize));
+ if (realProcessedSize != (UInt32)nextHeaderSize)
+ return S_FALSE;
+ if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
+ ThrowIncorrect();
+
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, buffer2);
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ for (;;)
+ {
+ UInt64 type = ReadID();
+ if (type == NID::kHeader)
+ break;
+ if (type != NID::kEncodedHeader)
+ ThrowIncorrect();
+ HRESULT result = ReadAndDecodePackedStreams(
+ EXTERNAL_CODECS_LOC_VARS
+ database.ArchiveInfo.StartPositionAfterHeader,
+ database.ArchiveInfo.DataStartPosition2,
+ dataVector
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ if (dataVector.Size() == 0)
+ return S_OK;
+ if (dataVector.Size() > 1)
+ ThrowIncorrect();
+ streamSwitch.Remove();
+ streamSwitch.Set(this, dataVector.Front());
+ }
+
+ return ReadHeader(
+ EXTERNAL_CODECS_LOC_VARS
+ database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+}
+
+HRESULT CInArchive::ReadDatabase(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ try
+ {
+ return ReadDatabase2(
+ EXTERNAL_CODECS_LOC_VARS database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ }
+ catch(CInArchiveException &) { return S_FALSE; }
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zIn.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zIn.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zIn.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,235 @@
+// 7zIn.h
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+#include "../../IPassword.h"
+#include "../../Common/CreateCoder.h"
+#include "../../Common/InBuffer.h"
+
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CInArchiveInfo
+{
+ CArchiveVersion Version;
+ UInt64 StartPosition;
+ UInt64 StartPositionAfterHeader;
+ UInt64 DataStartPosition;
+ UInt64 DataStartPosition2;
+ CRecordVector<UInt64> FileInfoPopIDs;
+ void Clear()
+ {
+ FileInfoPopIDs.Clear();
+ }
+};
+
+struct CArchiveDatabaseEx: public CArchiveDatabase
+{
+ CInArchiveInfo ArchiveInfo;
+ CRecordVector<UInt64> PackStreamStartPositions;
+ CRecordVector<CNum> FolderStartPackStreamIndex;
+ CRecordVector<CNum> FolderStartFileIndex;
+ CRecordVector<CNum> FileIndexToFolderIndexMap;
+
+ void Clear()
+ {
+ CArchiveDatabase::Clear();
+ ArchiveInfo.Clear();
+ PackStreamStartPositions.Clear();
+ FolderStartPackStreamIndex.Clear();
+ FolderStartFileIndex.Clear();
+ FileIndexToFolderIndexMap.Clear();
+ }
+
+ void FillFolderStartPackStream();
+ void FillStartPos();
+ void FillFolderStartFileIndex();
+
+ void Fill()
+ {
+ FillFolderStartPackStream();
+ FillStartPos();
+ FillFolderStartFileIndex();
+ }
+
+ UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
+ {
+ return ArchiveInfo.DataStartPosition +
+ PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+ }
+
+ UInt64 GetFolderFullPackSize(int folderIndex) const
+ {
+ CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
+ const CFolder &folder = Folders[folderIndex];
+ UInt64 size = 0;
+ for (int i = 0; i < folder.PackStreams.Size(); i++)
+ size += PackSizes[packStreamIndex + i];
+ return size;
+ }
+
+ UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+ {
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+ }
+
+ UInt64 GetFilePackSize(CNum fileIndex) const
+ {
+ CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex != kNumNoIndex)
+ if (FolderStartFileIndex[folderIndex] == fileIndex)
+ return GetFolderFullPackSize(folderIndex);
+ return 0;
+ }
+};
+
+class CInByte2
+{
+ const Byte *_buffer;
+ size_t _size;
+ size_t _pos;
+public:
+ void Init(const Byte *buffer, size_t size)
+ {
+ _buffer = buffer;
+ _size = size;
+ _pos = 0;
+ }
+ Byte ReadByte();
+ void ReadBytes(Byte *data, size_t size);
+ void SkeepData(UInt64 size);
+ void SkeepData();
+ UInt64 ReadNumber();
+ CNum ReadNum();
+ UInt32 ReadUInt32();
+ UInt64 ReadUInt64();
+ void ReadString(UString &s);
+};
+
+class CStreamSwitch;
+
+const UInt32 kHeaderSize = 32;
+
+class CInArchive
+{
+ friend class CStreamSwitch;
+
+ CMyComPtr<IInStream> _stream;
+
+ CObjectVector<CInByte2> _inByteVector;
+ CInByte2 *_inByteBack;
+
+ UInt64 _arhiveBeginStreamPosition;
+
+ Byte _header[kHeaderSize];
+
+ void AddByteStream(const Byte *buffer, size_t size)
+ {
+ _inByteVector.Add(CInByte2());
+ _inByteBack = &_inByteVector.Back();
+ _inByteBack->Init(buffer, size);
+ }
+
+ void DeleteByteStream()
+ {
+ _inByteVector.DeleteBack();
+ if (!_inByteVector.IsEmpty())
+ _inByteBack = &_inByteVector.Back();
+ }
+
+private:
+ HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
+
+ void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
+ Byte ReadByte() { return _inByteBack->ReadByte(); }
+ UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
+ CNum ReadNum() { return _inByteBack->ReadNum(); }
+ UInt64 ReadID() { return _inByteBack->ReadNumber(); }
+ UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }
+ UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
+ void SkeepData(UInt64 size) { _inByteBack->SkeepData(size); }
+ void SkeepData() { _inByteBack->SkeepData(); }
+ void WaitAttribute(UInt64 attribute);
+
+ void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
+ void GetNextFolderItem(CFolder &itemInfo);
+ void ReadHashDigests(int numItems,
+ CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
+
+ void ReadPackInfo(
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs);
+
+ void ReadUnPackInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ CObjectVector<CFolder> &folders);
+
+ void ReadSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests);
+
+ void ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests);
+
+
+ void ReadBoolVector(int numItems, CBoolVector &v);
+ void ReadBoolVector2(int numItems, CBoolVector &v);
+ void ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt32 type);
+ HRESULT ReadAndDecodePackedStreams(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ UInt64 baseOffset, UInt64 &dataOffset,
+ CObjectVector<CByteBuffer> &dataVector
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+ HRESULT ReadHeader(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+ HRESULT ReadDatabase2(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+public:
+ HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ void Close();
+
+ HRESULT ReadDatabase(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zItem.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zItem.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zItem.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,184 @@
+// 7zItem.h
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "../../../Common/Buffer.h"
+#include "../../../Common/MyString.h"
+#include "../../Common/MethodId.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+typedef UInt32 CNum;
+const CNum kNumMax = 0x7FFFFFFF;
+const CNum kNumNoIndex = 0xFFFFFFFF;
+
+struct CCoderInfo
+{
+ CMethodId MethodID;
+ CByteBuffer Properties;
+ CNum NumInStreams;
+ CNum NumOutStreams;
+ bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+};
+
+struct CBindPair
+{
+ CNum InIndex;
+ CNum OutIndex;
+};
+
+struct CFolder
+{
+ CObjectVector<CCoderInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<CNum> PackStreams;
+ CRecordVector<UInt64> UnPackSizes;
+ UInt32 UnPackCRC;
+ bool UnPackCRCDefined;
+
+ CFolder(): UnPackCRCDefined(false) {}
+
+ UInt64 GetUnPackSize() const // test it
+ {
+ if (UnPackSizes.IsEmpty())
+ return 0;
+ for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
+ if (FindBindPairForOutStream(i) < 0)
+ return UnPackSizes[i];
+ throw 1;
+ }
+
+ CNum GetNumOutStreams() const
+ {
+ CNum result = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ result += Coders[i].NumOutStreams;
+ return result;
+ }
+
+ int FindBindPairForInStream(CNum inStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindBindPairForOutStream(CNum outStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindPackStreamArrayIndex(CNum inStreamIndex) const
+ {
+ for(int i = 0; i < PackStreams.Size(); i++)
+ if (PackStreams[i] == inStreamIndex)
+ return i;
+ return -1;
+ }
+};
+
+typedef FILETIME CArchiveFileTime;
+
+class CFileItem
+{
+public:
+ CArchiveFileTime CreationTime;
+ CArchiveFileTime LastWriteTime;
+ CArchiveFileTime LastAccessTime;
+ UInt64 UnPackSize;
+ UInt64 StartPos;
+ UInt32 Attributes;
+ UInt32 FileCRC;
+ UString Name;
+
+ bool HasStream; // Test it !!! it means that there is
+ // stream in some folder. It can be empty stream
+ bool IsDirectory;
+ bool IsAnti;
+ bool IsFileCRCDefined;
+ bool AreAttributesDefined;
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+ bool IsStartPosDefined;
+
+ /*
+ const bool HasStream() const {
+ return !IsDirectory && !IsAnti && UnPackSize != 0; }
+ */
+ CFileItem():
+ HasStream(true),
+ IsDirectory(false),
+ IsAnti(false),
+ IsFileCRCDefined(false),
+ AreAttributesDefined(false),
+ IsCreationTimeDefined(false),
+ IsLastWriteTimeDefined(false),
+ IsLastAccessTimeDefined(false),
+ IsStartPosDefined(false)
+ {}
+ void SetAttributes(UInt32 attributes)
+ {
+ AreAttributesDefined = true;
+ Attributes = attributes;
+ }
+ void SetCreationTime(const CArchiveFileTime &creationTime)
+ {
+ IsCreationTimeDefined = true;
+ CreationTime = creationTime;
+ }
+ void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
+ {
+ IsLastWriteTimeDefined = true;
+ LastWriteTime = lastWriteTime;
+ }
+ void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
+ {
+ IsLastAccessTimeDefined = true;
+ LastAccessTime = lastAccessTime;
+ }
+};
+
+struct CArchiveDatabase
+{
+ CRecordVector<UInt64> PackSizes;
+ CRecordVector<bool> PackCRCsDefined;
+ CRecordVector<UInt32> PackCRCs;
+ CObjectVector<CFolder> Folders;
+ CRecordVector<CNum> NumUnPackStreamsVector;
+ CObjectVector<CFileItem> Files;
+ void Clear()
+ {
+ PackSizes.Clear();
+ PackCRCsDefined.Clear();
+ PackCRCs.Clear();
+ Folders.Clear();
+ NumUnPackStreamsVector.Clear();
+ Files.Clear();
+ }
+ bool IsEmpty() const
+ {
+ return (PackSizes.IsEmpty() &&
+ PackCRCsDefined.IsEmpty() &&
+ PackCRCs.IsEmpty() &&
+ Folders.IsEmpty() &&
+ NumUnPackStreamsVector.IsEmpty() &&
+ Files.IsEmpty());
+ }
+ bool IsSolid() const
+ {
+ for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
+ if (NumUnPackStreamsVector[i] > 1)
+ return true;
+ return false;
+ }
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zOut.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zOut.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zOut.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1026 @@
+// 7zOut.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/AutoPtr.h"
+#include "../../Common/StreamObjects.h"
+
+#include "7zOut.h"
+
+extern "C"
+{
+#include "../../../../C/7zCrc.h"
+}
+
+static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size)
+{
+ while (size > 0)
+ {
+ UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);
+ UInt32 processedSize;
+ RINOK(stream->Write(data, curSize, &processedSize));
+ if(processedSize == 0)
+ return E_FAIL;
+ data = (const void *)((const Byte *)data + processedSize);
+ size -= processedSize;
+ }
+ return S_OK;
+}
+
+namespace NArchive {
+namespace N7z {
+
+HRESULT COutArchive::WriteDirect(const void *data, UInt32 size)
+{
+ return ::WriteBytes(SeqStream, data, size);
+}
+
+UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 value)
+{
+ for (int i = 0; i < 4; i++, value >>= 8)
+ crc = CRC_UPDATE_BYTE(crc, (Byte)value);
+ return crc;
+}
+
+UInt32 CrcUpdateUInt64(UInt32 crc, UInt64 value)
+{
+ for (int i = 0; i < 8; i++, value >>= 8)
+ crc = CRC_UPDATE_BYTE(crc, (Byte)value);
+ return crc;
+}
+
+HRESULT COutArchive::WriteDirectUInt32(UInt32 value)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ RINOK(WriteDirectByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteDirectUInt64(UInt64 value)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ RINOK(WriteDirectByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteSignature()
+{
+ RINOK(WriteDirect(kSignature, kSignatureSize));
+ RINOK(WriteDirectByte(kMajorVersion));
+ return WriteDirectByte(2);
+}
+
+#ifdef _7Z_VOL
+HRESULT COutArchive::WriteFinishSignature()
+{
+ RINOK(WriteDirect(kFinishSignature, kSignatureSize));
+ CArchiveVersion av;
+ av.Major = kMajorVersion;
+ av.Minor = 2;
+ RINOK(WriteDirectByte(av.Major));
+ return WriteDirectByte(av.Minor);
+}
+#endif
+
+HRESULT COutArchive::WriteStartHeader(const CStartHeader &h)
+{
+ UInt32 crc = CRC_INIT_VAL;
+ crc = CrcUpdateUInt64(crc, h.NextHeaderOffset);
+ crc = CrcUpdateUInt64(crc, h.NextHeaderSize);
+ crc = CrcUpdateUInt32(crc, h.NextHeaderCRC);
+ RINOK(WriteDirectUInt32(CRC_GET_DIGEST(crc)));
+ RINOK(WriteDirectUInt64(h.NextHeaderOffset));
+ RINOK(WriteDirectUInt64(h.NextHeaderSize));
+ return WriteDirectUInt32(h.NextHeaderCRC);
+}
+
+#ifdef _7Z_VOL
+HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
+{
+ CCRC crc;
+ crc.UpdateUInt64(h.NextHeaderOffset);
+ crc.UpdateUInt64(h.NextHeaderSize);
+ crc.UpdateUInt32(h.NextHeaderCRC);
+ crc.UpdateUInt64(h.ArchiveStartOffset);
+ crc.UpdateUInt64(h.AdditionalStartBlockSize);
+ RINOK(WriteDirectUInt32(crc.GetDigest()));
+ RINOK(WriteDirectUInt64(h.NextHeaderOffset));
+ RINOK(WriteDirectUInt64(h.NextHeaderSize));
+ RINOK(WriteDirectUInt32(h.NextHeaderCRC));
+ RINOK(WriteDirectUInt64(h.ArchiveStartOffset));
+ return WriteDirectUInt64(h.AdditionalStartBlockSize);
+}
+#endif
+
+HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
+{
+ Close();
+ #ifdef _7Z_VOL
+ // endMarker = false;
+ _endMarker = endMarker;
+ #endif
+ SeqStream = stream;
+ if (!endMarker)
+ {
+ SeqStream.QueryInterface(IID_IOutStream, &Stream);
+ if (!Stream)
+ {
+ return E_NOTIMPL;
+ // endMarker = true;
+ }
+ }
+ #ifdef _7Z_VOL
+ if (endMarker)
+ {
+ /*
+ CStartHeader sh;
+ sh.NextHeaderOffset = (UInt32)(Int32)-1;
+ sh.NextHeaderSize = (UInt32)(Int32)-1;
+ sh.NextHeaderCRC = 0;
+ WriteStartHeader(sh);
+ */
+ }
+ else
+ #endif
+ {
+ if (!Stream)
+ return E_FAIL;
+ RINOK(WriteSignature());
+ RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
+ }
+ return S_OK;
+}
+
+void COutArchive::Close()
+{
+ SeqStream.Release();
+ Stream.Release();
+}
+
+HRESULT COutArchive::SkeepPrefixArchiveHeader()
+{
+ #ifdef _7Z_VOL
+ if (_endMarker)
+ return S_OK;
+ #endif
+ return Stream->Seek(24, STREAM_SEEK_CUR, NULL);
+}
+
+HRESULT COutArchive::WriteBytes(const void *data, size_t size)
+{
+ if (_mainMode)
+ {
+ if (_dynamicMode)
+ _dynamicBuffer.Write(data, size);
+ else
+ _outByte.WriteBytes(data, size);
+ _crc = CrcUpdate(_crc, data, size);
+ }
+ else
+ {
+ if (_countMode)
+ _countSize += size;
+ else
+ RINOK(_outByte2.Write(data, size));
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteBytes(const CByteBuffer &data)
+{
+ return WriteBytes(data, data.GetCapacity());
+}
+
+HRESULT COutArchive::WriteByte(Byte b)
+{
+ return WriteBytes(&b, 1);
+}
+
+HRESULT COutArchive::WriteUInt32(UInt32 value)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ RINOK(WriteByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteNumber(UInt64 value)
+{
+ Byte firstByte = 0;
+ Byte mask = 0x80;
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ if (value < ((UInt64(1) << ( 7 * (i + 1)))))
+ {
+ firstByte |= Byte(value >> (8 * i));
+ break;
+ }
+ firstByte |= mask;
+ mask >>= 1;
+ }
+ RINOK(WriteByte(firstByte));
+ for (;i > 0; i--)
+ {
+ RINOK(WriteByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+#ifdef _7Z_VOL
+static UInt32 GetBigNumberSize(UInt64 value)
+{
+ int i;
+ for (i = 0; i < 8; i++)
+ if (value < ((UInt64(1) << ( 7 * (i + 1)))))
+ break;
+ return 1 + i;
+}
+
+UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props)
+{
+ UInt32 result = GetBigNumberSize(dataSize) * 2 + 41;
+ if (nameLength != 0)
+ {
+ nameLength = (nameLength + 1) * 2;
+ result += nameLength + GetBigNumberSize(nameLength) + 2;
+ }
+ if (props)
+ {
+ result += 20;
+ }
+ if (result >= 128)
+ result++;
+ result += kSignatureSize + 2 + kFinishHeaderSize;
+ return result;
+}
+
+UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props)
+{
+ UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props);
+ int testSize;
+ if (volSize > headersSizeBase)
+ testSize = volSize - headersSizeBase;
+ else
+ testSize = 1;
+ UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props);
+ UInt64 pureSize = 1;
+ if (volSize > headersSize)
+ pureSize = volSize - headersSize;
+ return pureSize;
+}
+#endif
+
+HRESULT COutArchive::WriteFolder(const CFolder &folder)
+{
+ RINOK(WriteNumber(folder.Coders.Size()));
+ int i;
+ for (i = 0; i < folder.Coders.Size(); i++)
+ {
+ const CCoderInfo &coder = folder.Coders[i];
+ {
+ size_t propertiesSize = coder.Properties.GetCapacity();
+
+ UInt64 id = coder.MethodID;
+ int idSize;
+ for (idSize = 1; idSize < sizeof(id); idSize++)
+ if ((id >> (8 * idSize)) == 0)
+ break;
+ BYTE longID[15];
+ for (int t = idSize - 1; t >= 0 ; t--, id >>= 8)
+ longID[t] = (Byte)(id & 0xFF);
+ Byte b;
+ b = (Byte)(idSize & 0xF);
+ bool isComplex = !coder.IsSimpleCoder();
+ b |= (isComplex ? 0x10 : 0);
+ b |= ((propertiesSize != 0) ? 0x20 : 0 );
+ RINOK(WriteByte(b));
+ RINOK(WriteBytes(longID, idSize));
+ if (isComplex)
+ {
+ RINOK(WriteNumber(coder.NumInStreams));
+ RINOK(WriteNumber(coder.NumOutStreams));
+ }
+ if (propertiesSize == 0)
+ continue;
+ RINOK(WriteNumber(propertiesSize));
+ RINOK(WriteBytes(coder.Properties, propertiesSize));
+ }
+ }
+ for (i = 0; i < folder.BindPairs.Size(); i++)
+ {
+ const CBindPair &bindPair = folder.BindPairs[i];
+ RINOK(WriteNumber(bindPair.InIndex));
+ RINOK(WriteNumber(bindPair.OutIndex));
+ }
+ if (folder.PackStreams.Size() > 1)
+ for (i = 0; i < folder.PackStreams.Size(); i++)
+ {
+ RINOK(WriteNumber(folder.PackStreams[i]));
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector)
+{
+ Byte b = 0;
+ Byte mask = 0x80;
+ for(int i = 0; i < boolVector.Size(); i++)
+ {
+ if (boolVector[i])
+ b |= mask;
+ mask >>= 1;
+ if (mask == 0)
+ {
+ RINOK(WriteByte(b));
+ mask = 0x80;
+ b = 0;
+ }
+ }
+ if (mask != 0x80)
+ {
+ RINOK(WriteByte(b));
+ }
+ return S_OK;
+}
+
+
+HRESULT COutArchive::WriteHashDigests(
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &digests)
+{
+ int numDefined = 0;
+ int i;
+ for(i = 0; i < digestsDefined.Size(); i++)
+ if (digestsDefined[i])
+ numDefined++;
+ if (numDefined == 0)
+ return S_OK;
+
+ RINOK(WriteByte(NID::kCRC));
+ if (numDefined == digestsDefined.Size())
+ {
+ RINOK(WriteByte(1));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBoolVector(digestsDefined));
+ }
+ for(i = 0; i < digests.Size(); i++)
+ {
+ if(digestsDefined[i])
+ RINOK(WriteUInt32(digests[i]));
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WritePackInfo(
+ UInt64 dataOffset,
+ const CRecordVector<UInt64> &packSizes,
+ const CRecordVector<bool> &packCRCsDefined,
+ const CRecordVector<UInt32> &packCRCs)
+{
+ if (packSizes.IsEmpty())
+ return S_OK;
+ RINOK(WriteByte(NID::kPackInfo));
+ RINOK(WriteNumber(dataOffset));
+ RINOK(WriteNumber(packSizes.Size()));
+ RINOK(WriteByte(NID::kSize));
+ for(int i = 0; i < packSizes.Size(); i++)
+ RINOK(WriteNumber(packSizes[i]));
+
+ RINOK(WriteHashDigests(packCRCsDefined, packCRCs));
+
+ return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteUnPackInfo(const CObjectVector<CFolder> &folders)
+{
+ if (folders.IsEmpty())
+ return S_OK;
+
+ RINOK(WriteByte(NID::kUnPackInfo));
+
+ RINOK(WriteByte(NID::kFolder));
+ RINOK(WriteNumber(folders.Size()));
+ {
+ RINOK(WriteByte(0));
+ for(int i = 0; i < folders.Size(); i++)
+ RINOK(WriteFolder(folders[i]));
+ }
+
+ RINOK(WriteByte(NID::kCodersUnPackSize));
+ int i;
+ for(i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ for (int j = 0; j < folder.UnPackSizes.Size(); j++)
+ RINOK(WriteNumber(folder.UnPackSizes[j]));
+ }
+
+ CRecordVector<bool> unPackCRCsDefined;
+ CRecordVector<UInt32> unPackCRCs;
+ for(i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ unPackCRCsDefined.Add(folder.UnPackCRCDefined);
+ unPackCRCs.Add(folder.UnPackCRC);
+ }
+ RINOK(WriteHashDigests(unPackCRCsDefined, unPackCRCs));
+
+ return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ const CRecordVector<CNum> &numUnPackStreamsInFolders,
+ const CRecordVector<UInt64> &unPackSizes,
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &digests)
+{
+ RINOK(WriteByte(NID::kSubStreamsInfo));
+
+ int i;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ {
+ if (numUnPackStreamsInFolders[i] != 1)
+ {
+ RINOK(WriteByte(NID::kNumUnPackStream));
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ RINOK(WriteNumber(numUnPackStreamsInFolders[i]));
+ break;
+ }
+ }
+
+
+ bool needFlag = true;
+ CNum index = 0;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ for (CNum j = 0; j < numUnPackStreamsInFolders[i]; j++)
+ {
+ if (j + 1 != numUnPackStreamsInFolders[i])
+ {
+ if (needFlag)
+ RINOK(WriteByte(NID::kSize));
+ needFlag = false;
+ RINOK(WriteNumber(unPackSizes[index]));
+ }
+ index++;
+ }
+
+ CRecordVector<bool> digestsDefined2;
+ CRecordVector<UInt32> digests2;
+
+ int digestIndex = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ int numSubStreams = (int)numUnPackStreamsInFolders[i];
+ if (numSubStreams == 1 && folders[i].UnPackCRCDefined)
+ digestIndex++;
+ else
+ for (int j = 0; j < numSubStreams; j++, digestIndex++)
+ {
+ digestsDefined2.Add(digestsDefined[digestIndex]);
+ digests2.Add(digests[digestIndex]);
+ }
+ }
+ RINOK(WriteHashDigests(digestsDefined2, digests2));
+ return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteTime(
+ const CObjectVector<CFileItem> &files, Byte type)
+{
+ /////////////////////////////////////////////////
+ // CreationTime
+ CBoolVector boolVector;
+ boolVector.Reserve(files.Size());
+ bool thereAreDefined = false;
+ bool allDefined = true;
+ int i;
+ for(i = 0; i < files.Size(); i++)
+ {
+ const CFileItem &item = files[i];
+ bool defined;
+ switch(type)
+ {
+ case NID::kCreationTime:
+ defined = item.IsCreationTimeDefined;
+ break;
+ case NID::kLastWriteTime:
+ defined = item.IsLastWriteTimeDefined;
+ break;
+ case NID::kLastAccessTime:
+ defined = item.IsLastAccessTimeDefined;
+ break;
+ default:
+ throw 1;
+ }
+ boolVector.Add(defined);
+ thereAreDefined = (thereAreDefined || defined);
+ allDefined = (allDefined && defined);
+ }
+ if (!thereAreDefined)
+ return S_OK;
+ RINOK(WriteByte(type));
+ size_t dataSize = 1 + 1;
+ dataSize += files.Size() * 8;
+ if (allDefined)
+ {
+ RINOK(WriteNumber(dataSize));
+ WriteByte(1);
+ }
+ else
+ {
+ RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize));
+ WriteByte(0);
+ RINOK(WriteBoolVector(boolVector));
+ }
+ RINOK(WriteByte(0));
+ for(i = 0; i < files.Size(); i++)
+ {
+ if (boolVector[i])
+ {
+ const CFileItem &item = files[i];
+ CArchiveFileTime timeValue;
+ timeValue.dwLowDateTime = 0;
+ timeValue.dwHighDateTime = 0;
+ switch(type)
+ {
+ case NID::kCreationTime:
+ timeValue = item.CreationTime;
+ break;
+ case NID::kLastWriteTime:
+ timeValue = item.LastWriteTime;
+ break;
+ case NID::kLastAccessTime:
+ timeValue = item.LastAccessTime;
+ break;
+ }
+ RINOK(WriteUInt32(timeValue.dwLowDateTime));
+ RINOK(WriteUInt32(timeValue.dwHighDateTime));
+ }
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::EncodeStream(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CEncoder &encoder, const Byte *data, size_t dataSize,
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
+{
+ CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> stream = streamSpec;
+ streamSpec->Init(data, dataSize);
+ CFolder folderItem;
+ folderItem.UnPackCRCDefined = true;
+ folderItem.UnPackCRC = CrcCalc(data, dataSize);
+ UInt64 dataSize64 = dataSize;
+ RINOK(encoder.Encode(
+ EXTERNAL_CODECS_LOC_VARS
+ stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))
+ folders.Add(folderItem);
+ return S_OK;
+}
+
+HRESULT COutArchive::EncodeStream(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CEncoder &encoder, const CByteBuffer &data,
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
+{
+ return EncodeStream(
+ EXTERNAL_CODECS_LOC_VARS
+ encoder, data, data.GetCapacity(), packSizes, folders);
+}
+
+static void WriteUInt32ToBuffer(Byte *data, UInt32 value)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ *data++ = (Byte)value;
+ value >>= 8;
+ }
+}
+
+static void WriteUInt64ToBuffer(Byte *data, UInt64 value)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ *data++ = (Byte)value;
+ value >>= 8;
+ }
+}
+
+
+HRESULT COutArchive::WriteHeader(
+ const CArchiveDatabase &database,
+ const CHeaderOptions &headerOptions,
+ UInt64 &headerOffset)
+{
+ int i;
+
+ /////////////////////////////////
+ // Names
+
+ CNum numDefinedNames = 0;
+ size_t namesDataSize = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const UString &name = database.Files[i].Name;
+ if (!name.IsEmpty())
+ numDefinedNames++;
+ namesDataSize += (name.Length() + 1) * 2;
+ }
+
+ CByteBuffer namesData;
+ if (numDefinedNames > 0)
+ {
+ namesData.SetCapacity((size_t)namesDataSize);
+ size_t pos = 0;
+ for(int i = 0; i < database.Files.Size(); i++)
+ {
+ const UString &name = database.Files[i].Name;
+ for (int t = 0; t < name.Length(); t++)
+ {
+ wchar_t c = name[t];
+ namesData[pos++] = Byte(c);
+ namesData[pos++] = Byte(c >> 8);
+ }
+ namesData[pos++] = 0;
+ namesData[pos++] = 0;
+ }
+ }
+
+ /////////////////////////////////
+ // Write Attributes
+ CBoolVector attributesBoolVector;
+ attributesBoolVector.Reserve(database.Files.Size());
+ int numDefinedAttributes = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ bool defined = database.Files[i].AreAttributesDefined;
+ attributesBoolVector.Add(defined);
+ if (defined)
+ numDefinedAttributes++;
+ }
+
+ CByteBuffer attributesData;
+ if (numDefinedAttributes > 0)
+ {
+ attributesData.SetCapacity(numDefinedAttributes * 4);
+ size_t pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (file.AreAttributesDefined)
+ {
+ WriteUInt32ToBuffer(attributesData + pos, file.Attributes);
+ pos += 4;
+ }
+ }
+ }
+
+ /////////////////////////////////
+ // Write StartPos
+ CBoolVector startsBoolVector;
+ startsBoolVector.Reserve(database.Files.Size());
+ int numDefinedStarts = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ bool defined = database.Files[i].IsStartPosDefined;
+ startsBoolVector.Add(defined);
+ if (defined)
+ numDefinedStarts++;
+ }
+
+ CByteBuffer startsData;
+ if (numDefinedStarts > 0)
+ {
+ startsData.SetCapacity(numDefinedStarts * 8);
+ size_t pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (file.IsStartPosDefined)
+ {
+ WriteUInt64ToBuffer(startsData + pos, file.StartPos);
+ pos += 8;
+ }
+ }
+ }
+
+ /////////////////////////////////
+ // Write Last Write Time
+ // /*
+ CNum numDefinedLastWriteTimes = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ if (database.Files[i].IsLastWriteTimeDefined)
+ numDefinedLastWriteTimes++;
+
+ if (numDefinedLastWriteTimes > 0)
+ {
+ CByteBuffer lastWriteTimeData;
+ lastWriteTimeData.SetCapacity(numDefinedLastWriteTimes * 8);
+ size_t pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (file.IsLastWriteTimeDefined)
+ {
+ WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwLowDateTime);
+ pos += 4;
+ WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwHighDateTime);
+ pos += 4;
+ }
+ }
+ }
+ // */
+
+
+ UInt64 packedSize = 0;
+ for(i = 0; i < database.PackSizes.Size(); i++)
+ packedSize += database.PackSizes[i];
+
+ headerOffset = packedSize;
+
+ _mainMode = true;
+
+ _outByte.SetStream(SeqStream);
+ _outByte.Init();
+ _crc = CRC_INIT_VAL;
+
+
+ RINOK(WriteByte(NID::kHeader));
+
+ // Archive Properties
+
+ if (database.Folders.Size() > 0)
+ {
+ RINOK(WriteByte(NID::kMainStreamsInfo));
+ RINOK(WritePackInfo(0, database.PackSizes,
+ database.PackCRCsDefined,
+ database.PackCRCs));
+
+ RINOK(WriteUnPackInfo(database.Folders));
+
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+ for (i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (!file.HasStream)
+ continue;
+ unPackSizes.Add(file.UnPackSize);
+ digestsDefined.Add(file.IsFileCRCDefined);
+ digests.Add(file.FileCRC);
+ }
+
+ RINOK(WriteSubStreamsInfo(
+ database.Folders,
+ database.NumUnPackStreamsVector,
+ unPackSizes,
+ digestsDefined,
+ digests));
+ RINOK(WriteByte(NID::kEnd));
+ }
+
+ if (database.Files.IsEmpty())
+ {
+ RINOK(WriteByte(NID::kEnd));
+ return _outByte.Flush();
+ }
+
+ RINOK(WriteByte(NID::kFilesInfo));
+ RINOK(WriteNumber(database.Files.Size()));
+
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.Reserve(database.Files.Size());
+ int numEmptyStreams = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ if (database.Files[i].HasStream)
+ emptyStreamVector.Add(false);
+ else
+ {
+ emptyStreamVector.Add(true);
+ numEmptyStreams++;
+ }
+ if (numEmptyStreams > 0)
+ {
+ RINOK(WriteByte(NID::kEmptyStream));
+ RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(emptyStreamVector));
+
+ CBoolVector emptyFileVector, antiVector;
+ emptyFileVector.Reserve(numEmptyStreams);
+ antiVector.Reserve(numEmptyStreams);
+ CNum numEmptyFiles = 0, numAntiItems = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (!file.HasStream)
+ {
+ emptyFileVector.Add(!file.IsDirectory);
+ if (!file.IsDirectory)
+ numEmptyFiles++;
+ antiVector.Add(file.IsAnti);
+ if (file.IsAnti)
+ numAntiItems++;
+ }
+ }
+
+ if (numEmptyFiles > 0)
+ {
+ RINOK(WriteByte(NID::kEmptyFile));
+ RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(emptyFileVector));
+ }
+
+ if (numAntiItems > 0)
+ {
+ RINOK(WriteByte(NID::kAnti));
+ RINOK(WriteNumber((antiVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(antiVector));
+ }
+ }
+
+ if (numDefinedNames > 0)
+ {
+ /////////////////////////////////////////////////
+ RINOK(WriteByte(NID::kName));
+ {
+ RINOK(WriteNumber(1 + namesData.GetCapacity()));
+ RINOK(WriteByte(0));
+ RINOK(WriteBytes(namesData));
+ }
+
+ }
+
+ if (headerOptions.WriteCreated)
+ {
+ RINOK(WriteTime(database.Files, NID::kCreationTime));
+ }
+ if (headerOptions.WriteModified)
+ {
+ RINOK(WriteTime(database.Files, NID::kLastWriteTime));
+ }
+ if (headerOptions.WriteAccessed)
+ {
+ RINOK(WriteTime(database.Files, NID::kLastAccessTime));
+ }
+
+ if (numDefinedAttributes > 0)
+ {
+ RINOK(WriteByte(NID::kWinAttributes));
+ size_t size = 2;
+ if (numDefinedAttributes != database.Files.Size())
+ size += (attributesBoolVector.Size() + 7) / 8 + 1;
+ size += attributesData.GetCapacity();
+
+ RINOK(WriteNumber(size));
+ if (numDefinedAttributes == database.Files.Size())
+ {
+ RINOK(WriteByte(1));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBoolVector(attributesBoolVector));
+ }
+
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBytes(attributesData));
+ }
+ }
+
+ if (numDefinedStarts > 0)
+ {
+ RINOK(WriteByte(NID::kStartPos));
+ size_t size = 2;
+ if (numDefinedStarts != database.Files.Size())
+ size += (startsBoolVector.Size() + 7) / 8 + 1;
+ size += startsData.GetCapacity();
+
+ RINOK(WriteNumber(size));
+ if (numDefinedStarts == database.Files.Size())
+ {
+ RINOK(WriteByte(1));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBoolVector(startsBoolVector));
+ }
+
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBytes(startsData));
+ }
+ }
+
+ RINOK(WriteByte(NID::kEnd)); // for files
+ RINOK(WriteByte(NID::kEnd)); // for headers
+
+ return _outByte.Flush();
+}
+
+HRESULT COutArchive::WriteDatabase(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const CArchiveDatabase &database,
+ const CCompressionMethodMode *options,
+ const CHeaderOptions &headerOptions)
+{
+ UInt64 headerOffset;
+ UInt32 headerCRC;
+ UInt64 headerSize;
+ if (database.IsEmpty())
+ {
+ headerSize = 0;
+ headerOffset = 0;
+ headerCRC = CrcCalc(0, 0);
+ }
+ else
+ {
+ _dynamicBuffer.Init();
+ _dynamicMode = false;
+
+ if (options != 0)
+ if (options->IsEmpty())
+ options = 0;
+ if (options != 0)
+ if (options->PasswordIsDefined || headerOptions.CompressMainHeader)
+ _dynamicMode = true;
+ RINOK(WriteHeader(database, headerOptions, headerOffset));
+
+ if (_dynamicMode)
+ {
+ CCompressionMethodMode encryptOptions;
+ encryptOptions.PasswordIsDefined = options->PasswordIsDefined;
+ encryptOptions.Password = options->Password;
+ CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);
+ CRecordVector<UInt64> packSizes;
+ CObjectVector<CFolder> folders;
+ RINOK(EncodeStream(
+ EXTERNAL_CODECS_LOC_VARS
+ encoder, _dynamicBuffer,
+ _dynamicBuffer.GetSize(), packSizes, folders));
+ _dynamicMode = false;
+ _mainMode = true;
+
+ _outByte.SetStream(SeqStream);
+ _outByte.Init();
+ _crc = CRC_INIT_VAL;
+
+ if (folders.Size() == 0)
+ throw 1;
+
+ RINOK(WriteID(NID::kEncodedHeader));
+ RINOK(WritePackInfo(headerOffset, packSizes,
+ CRecordVector<bool>(), CRecordVector<UInt32>()));
+ RINOK(WriteUnPackInfo(folders));
+ RINOK(WriteByte(NID::kEnd));
+ for (int i = 0; i < packSizes.Size(); i++)
+ headerOffset += packSizes[i];
+ RINOK(_outByte.Flush());
+ }
+ headerCRC = CRC_GET_DIGEST(_crc);
+ headerSize = _outByte.GetProcessedSize();
+ }
+ #ifdef _7Z_VOL
+ if (_endMarker)
+ {
+ CFinishHeader h;
+ h.NextHeaderSize = headerSize;
+ h.NextHeaderCRC = headerCRC;
+ h.NextHeaderOffset =
+ UInt64(0) - (headerSize +
+ 4 + kFinishHeaderSize);
+ h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset;
+ h.AdditionalStartBlockSize = 0;
+ RINOK(WriteFinishHeader(h));
+ return WriteFinishSignature();
+ }
+ else
+ #endif
+ {
+ CStartHeader h;
+ h.NextHeaderSize = headerSize;
+ h.NextHeaderCRC = headerCRC;
+ h.NextHeaderOffset = headerOffset;
+ RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
+ return WriteStartHeader(h);
+ }
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zOut.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zOut.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zOut.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,193 @@
+// 7z/Out.h
+
+#ifndef __7Z_OUT_H
+#define __7Z_OUT_H
+
+#include "7zHeader.h"
+#include "7zItem.h"
+#include "7zCompressionMode.h"
+#include "7zEncode.h"
+
+#include "../../Common/OutBuffer.h"
+#include "../../../Common/DynamicBuffer.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CWriteBufferLoc
+{
+ Byte *_data;
+ size_t _size;
+ size_t _pos;
+public:
+ CWriteBufferLoc(): _size(0), _pos(0) {}
+ void Init(Byte *data, size_t size)
+ {
+ _pos = 0;
+ _data = data;
+ _size = size;
+ }
+ HRESULT Write(const void *data, size_t size)
+ {
+ if (_pos + size > _size)
+ return E_FAIL;
+ memmove(_data + _pos, data, size);
+ _pos += size;
+ return S_OK;
+ }
+};
+
+class CWriteDynamicBuffer
+{
+ CByteDynamicBuffer _buffer;
+ size_t _pos;
+public:
+ CWriteDynamicBuffer(): _pos(0) {}
+ void Init()
+ {
+ _pos = 0;
+ }
+ void Write(const void *data, size_t size)
+ {
+ if (_pos + size > _buffer.GetCapacity())
+ _buffer.EnsureCapacity(_pos + size);
+ memmove(((Byte *)_buffer) +_pos, data, size);
+ _pos += size;
+ }
+ operator Byte *() { return (Byte *)_buffer; };
+ operator const Byte *() const { return (const Byte *)_buffer; };
+ size_t GetSize() const { return _pos; }
+};
+
+struct CHeaderOptions
+{
+ // bool UseAdditionalHeaderStreams;
+ bool CompressMainHeader;
+ bool WriteModified;
+ bool WriteCreated;
+ bool WriteAccessed;
+
+ CHeaderOptions():
+ // UseAdditionalHeaderStreams(false),
+ CompressMainHeader(true),
+ WriteModified(true),
+ WriteCreated(false),
+ WriteAccessed(false) {}
+};
+
+class COutArchive
+{
+ UInt64 _prefixHeaderPos;
+
+ HRESULT WriteDirect(const void *data, UInt32 size);
+ HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
+ HRESULT WriteDirectUInt32(UInt32 value);
+ HRESULT WriteDirectUInt64(UInt64 value);
+
+ HRESULT WriteBytes(const void *data, size_t size);
+ HRESULT WriteBytes(const CByteBuffer &data);
+ HRESULT WriteByte(Byte b);
+ HRESULT WriteUInt32(UInt32 value);
+ HRESULT WriteNumber(UInt64 value);
+ HRESULT WriteID(UInt64 value) { return WriteNumber(value); }
+
+ HRESULT WriteFolder(const CFolder &folder);
+ HRESULT WriteFileHeader(const CFileItem &itemInfo);
+ HRESULT WriteBoolVector(const CBoolVector &boolVector);
+ HRESULT WriteHashDigests(
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &hashDigests);
+
+ HRESULT WritePackInfo(
+ UInt64 dataOffset,
+ const CRecordVector<UInt64> &packSizes,
+ const CRecordVector<bool> &packCRCsDefined,
+ const CRecordVector<UInt32> &packCRCs);
+
+ HRESULT WriteUnPackInfo(const CObjectVector<CFolder> &folders);
+
+ HRESULT WriteSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ const CRecordVector<CNum> &numUnPackStreamsInFolders,
+ const CRecordVector<UInt64> &unPackSizes,
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &hashDigests);
+
+ /*
+ HRESULT WriteStreamsInfo(
+ UInt64 dataOffset,
+ const CRecordVector<UInt64> &packSizes,
+ const CRecordVector<bool> &packCRCsDefined,
+ const CRecordVector<UInt32> &packCRCs,
+ bool externalFolders,
+ UInt64 externalFoldersStreamIndex,
+ const CObjectVector<CFolder> &folders,
+ const CRecordVector<CNum> &numUnPackStreamsInFolders,
+ const CRecordVector<UInt64> &unPackSizes,
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &hashDigests);
+ */
+
+
+ HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type);
+
+ HRESULT EncodeStream(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CEncoder &encoder, const Byte *data, size_t dataSize,
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
+ HRESULT EncodeStream(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CEncoder &encoder, const CByteBuffer &data,
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
+ HRESULT WriteHeader(
+ const CArchiveDatabase &database,
+ const CHeaderOptions &headerOptions,
+ UInt64 &headerOffset);
+
+ bool _mainMode;
+
+ bool _dynamicMode;
+
+ bool _countMode;
+ size_t _countSize;
+ COutBuffer _outByte;
+ CWriteBufferLoc _outByte2;
+ CWriteDynamicBuffer _dynamicBuffer;
+ UInt32 _crc;
+
+ #ifdef _7Z_VOL
+ bool _endMarker;
+ #endif
+
+ HRESULT WriteSignature();
+ #ifdef _7Z_VOL
+ HRESULT WriteFinishSignature();
+ #endif
+ HRESULT WriteStartHeader(const CStartHeader &h);
+ #ifdef _7Z_VOL
+ HRESULT WriteFinishHeader(const CFinishHeader &h);
+ #endif
+ CMyComPtr<IOutStream> Stream;
+public:
+
+ COutArchive() { _outByte.Create(1 << 16); }
+ CMyComPtr<ISequentialOutStream> SeqStream;
+ HRESULT Create(ISequentialOutStream *stream, bool endMarker);
+ void Close();
+ HRESULT SkeepPrefixArchiveHeader();
+ HRESULT WriteDatabase(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const CArchiveDatabase &database,
+ const CCompressionMethodMode *options,
+ const CHeaderOptions &headerOptions);
+
+ #ifdef _7Z_VOL
+ static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
+ static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
+ #endif
+
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zProperties.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zProperties.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,162 @@
+// 7zProperties.cpp
+
+#include "StdAfx.h"
+
+#include "7zProperties.h"
+#include "7zHeader.h"
+#include "7zHandler.h"
+
+// #define _MULTI_PACK
+
+namespace NArchive {
+namespace N7z {
+
+struct CPropMap
+{
+ UInt64 FilePropID;
+ STATPROPSTG StatPROPSTG;
+};
+
+CPropMap kPropMap[] =
+{
+ { NID::kName, NULL, kpidPath, VT_BSTR},
+ { NID::kSize, NULL, kpidSize, VT_UI8},
+ { NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
+
+ #ifdef _MULTI_PACK
+ { 100, L"Pack0", kpidPackedSize0, VT_UI8},
+ { 101, L"Pack1", kpidPackedSize1, VT_UI8},
+ { 102, L"Pack2", kpidPackedSize2, VT_UI8},
+ { 103, L"Pack3", kpidPackedSize3, VT_UI8},
+ { 104, L"Pack4", kpidPackedSize4, VT_UI8},
+ #endif
+
+ { NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
+ { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
+ { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
+ { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
+ { NID::kStartPos, NULL, kpidPosition, VT_UI4},
+
+ { NID::kCRC, NULL, kpidCRC, VT_UI4},
+
+ { NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
+ // { 97, NULL, kpidSolid, VT_BOOL},
+ #ifndef _SFX
+ { 98, NULL, kpidMethod, VT_BSTR},
+ { 99, NULL, kpidBlock, VT_UI4}
+ #endif
+};
+
+static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
+
+static int FindPropInMap(UInt64 filePropID)
+{
+ for (int i = 0; i < kPropMapSize; i++)
+ if (kPropMap[i].FilePropID == filePropID)
+ return i;
+ return -1;
+}
+
+static void CopyOneItem(CRecordVector<UInt64> &src,
+ CRecordVector<UInt64> &dest, UInt32 item)
+{
+ for (int i = 0; i < src.Size(); i++)
+ if (src[i] == item)
+ {
+ dest.Add(item);
+ src.Delete(i);
+ return;
+ }
+}
+
+static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
+{
+ for (int i = 0; i < src.Size(); i++)
+ if (src[i] == item)
+ {
+ src.Delete(i);
+ return;
+ }
+}
+
+static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
+{
+ for (int i = 0; i < dest.Size(); i++)
+ if (dest[i] == item)
+ {
+ dest.Delete(i);
+ break;
+ }
+ dest.Insert(0, item);
+}
+
+void CHandler::FillPopIDs()
+{
+ _fileInfoPopIDs.Clear();
+
+ #ifdef _7Z_VOL
+ if(_volumes.Size() < 1)
+ return;
+ const CVolume &volume = _volumes.Front();
+ const CArchiveDatabaseEx &_database = volume.Database;
+ #endif
+
+ CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
+
+ RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
+ RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
+
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
+ _fileInfoPopIDs += fileInfoPopIDs;
+
+ #ifndef _SFX
+ _fileInfoPopIDs.Add(98);
+ _fileInfoPopIDs.Add(99);
+ #endif
+ #ifdef _MULTI_PACK
+ _fileInfoPopIDs.Add(100);
+ _fileInfoPopIDs.Add(101);
+ _fileInfoPopIDs.Add(102);
+ _fileInfoPopIDs.Add(103);
+ _fileInfoPopIDs.Add(104);
+ #endif
+
+ #ifndef _SFX
+ InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
+ InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
+ InsertToHead(_fileInfoPopIDs, NID::kSize);
+ InsertToHead(_fileInfoPopIDs, NID::kName);
+ #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = _fileInfoPopIDs.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if((int)index >= _fileInfoPopIDs.Size())
+ return E_INVALIDARG;
+ int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
+ if (indexInMap == -1)
+ return E_INVALIDARG;
+ const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
+ *propID = srcItem.propid;
+ *varType = srcItem.vt;
+ *name = 0;
+ return S_OK;
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zProperties.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zProperties.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zProperties.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,22 @@
+// 7zProperties.h
+
+#ifndef __7Z_PROPERTIES_H
+#define __7Z_PROPERTIES_H
+
+#include "../../PropID.h"
+
+namespace NArchive {
+namespace N7z {
+
+enum
+{
+ kpidPackedSize0 = kpidUserDefined,
+ kpidPackedSize1,
+ kpidPackedSize2,
+ kpidPackedSize3,
+ kpidPackedSize4
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zRegister.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zRegister.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,18 @@
+// 7zRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterArc.h"
+
+#include "7zHandler.h"
+static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; }
+#ifndef EXTRACT_ONLY
+static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; }
+#else
+#define CreateArcOut 0
+#endif
+
+static CArcInfo g_ArcInfo =
+ { L"7z", L"7z", 0, 7, {'7' + 1 , 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };
+
+REGISTER_ARC_DEC_SIG(7z)
Added: trunk/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// 7zSpecStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zSpecStream.h"
+
+STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
+ UInt64 subStream, UInt64 *value)
+{
+ if (_getSubStreamSize == NULL)
+ return E_NOTIMPL;
+ return _getSubStreamSize->GetSubStreamSize(subStream, value);
+}
+
Added: trunk/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zSpecStream.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zSpecStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,35 @@
+// 7zSpecStream.h
+
+#ifndef __7Z_SPEC_STREAM_H
+#define __7Z_SPEC_STREAM_H
+
+#include "../../IStream.h"
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+class CSequentialInStreamSizeCount2:
+ public ISequentialInStream,
+ public ICompressGetSubStreamSize,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
+ UInt64 _size;
+public:
+ void Init(ISequentialInStream *stream)
+ {
+ _stream = stream;
+ _getSubStreamSize = 0;
+ _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
+ _size = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1029 @@
+// UpdateMain.cpp
+
+#include "StdAfx.h"
+
+#include "7zUpdate.h"
+#include "7zFolderInStream.h"
+#include "7zEncode.h"
+#include "7zHandler.h"
+#include "7zOut.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/LimitedStreams.h"
+#include "../Common/ItemNameUtils.h"
+
+namespace NArchive {
+namespace N7z {
+
+static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
+static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
+static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
+static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
+
+static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
+ UInt64 position, UInt64 size, ICompressProgressInfo *progress)
+{
+ RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+ streamSpec->SetStream(inStream);
+ streamSpec->Init(size);
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+ RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
+ return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);
+}
+
+static int GetReverseSlashPos(const UString &name)
+{
+ int slashPos = name.ReverseFind(L'/');
+ #ifdef _WIN32
+ int slash1Pos = name.ReverseFind(L'\\');
+ slashPos = MyMax(slashPos, slash1Pos);
+ #endif
+ return slashPos;
+}
+
+int CUpdateItem::GetExtensionPos() const
+{
+ int slashPos = GetReverseSlashPos(Name);
+ int dotPos = Name.ReverseFind(L'.');
+ if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
+ return Name.Length();
+ return dotPos + 1;
+}
+
+UString CUpdateItem::GetExtension() const
+{
+ return Name.Mid(GetExtensionPos());
+}
+
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
+
+static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
+{
+ size_t c1 = a1.GetCapacity();
+ size_t c2 = a2.GetCapacity();
+ RINOZ(MyCompare(c1, c2));
+ for (size_t i = 0; i < c1; i++)
+ RINOZ(MyCompare(a1[i], a2[i]));
+ return 0;
+}
+
+static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2)
+{
+ RINOZ(MyCompare(c1.NumInStreams, c2.NumInStreams));
+ RINOZ(MyCompare(c1.NumOutStreams, c2.NumOutStreams));
+ RINOZ(MyCompare(c1.MethodID, c2.MethodID));
+ return CompareBuffers(c1.Properties, c2.Properties);
+}
+
+static int CompareBindPairs(const CBindPair &b1, const CBindPair &b2)
+{
+ RINOZ(MyCompare(b1.InIndex, b2.InIndex));
+ return MyCompare(b1.OutIndex, b2.OutIndex);
+}
+
+static int CompareFolders(const CFolder &f1, const CFolder &f2)
+{
+ int s1 = f1.Coders.Size();
+ int s2 = f2.Coders.Size();
+ RINOZ(MyCompare(s1, s2));
+ int i;
+ for (i = 0; i < s1; i++)
+ RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i]));
+ s1 = f1.BindPairs.Size();
+ s2 = f2.BindPairs.Size();
+ RINOZ(MyCompare(s1, s2));
+ for (i = 0; i < s1; i++)
+ RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i]));
+ return 0;
+}
+
+static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
+{
+ return MyStringCompareNoCase(f1.Name, f2.Name);
+}
+
+static int CompareFolderRefs(const int *p1, const int *p2, void *param)
+{
+ int i1 = *p1;
+ int i2 = *p2;
+ const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
+ RINOZ(CompareFolders(
+ db.Folders[i1],
+ db.Folders[i2]));
+ RINOZ(MyCompare(
+ db.NumUnPackStreamsVector[i1],
+ db.NumUnPackStreamsVector[i2]));
+ if (db.NumUnPackStreamsVector[i1] == 0)
+ return 0;
+ return CompareFiles(
+ db.Files[db.FolderStartFileIndex[i1]],
+ db.Files[db.FolderStartFileIndex[i2]]);
+}
+
+////////////////////////////////////////////////////////////
+
+static int CompareEmptyItems(const int *p1, const int *p2, void *param)
+{
+ const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
+ const CUpdateItem &u1 = updateItems[*p1];
+ const CUpdateItem &u2 = updateItems[*p2];
+ if (u1.IsDirectory != u2.IsDirectory)
+ return (u1.IsDirectory) ? 1 : -1;
+ if (u1.IsDirectory)
+ {
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ int n = MyStringCompareNoCase(u1.Name, u2.Name);
+ return -n;
+ }
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ return MyStringCompareNoCase(u1.Name, u2.Name);
+}
+
+static const char *g_Exts =
+ " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
+ " zip jar ear war msi"
+ " 3gp avi mov mpeg mpg mpe wmv"
+ " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
+ " swf "
+ " chm hxi hxs"
+ " gif jpeg jpg jp2 png tiff bmp ico psd psp"
+ " awg ps eps cgm dxf svg vrml wmf emf ai md"
+ " cad dwg pps key sxi"
+ " max 3ds"
+ " iso bin nrg mdf img pdi tar cpio xpi"
+ " vfd vhd vud vmc vsv"
+ " vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
+ " inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
+ " f77 f f90 f95"
+ " asm sql manifest dep "
+ " mak clw csproj vcproj sln dsp dsw "
+ " class "
+ " bat cmd"
+ " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
+ " awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"
+ " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
+ " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
+ " abw afp cwk lwp wpd wps wpt wrf wri"
+ " abf afm bdf fon mgf otf pcf pfa snf ttf"
+ " dbf mdb nsf ntf wdb db fdb gdb"
+ " exe dll ocx vbx sfx sys tlb awx com obj lib out o so "
+ " pdb pch idb ncb opt";
+
+int GetExtIndex(const char *ext)
+{
+ int extIndex = 1;
+ const char *p = g_Exts;
+ for (;;)
+ {
+ char c = *p++;
+ if (c == 0)
+ return extIndex;
+ if (c == ' ')
+ continue;
+ int pos = 0;
+ for (;;)
+ {
+ char c2 = ext[pos++];
+ if (c2 == 0 && (c == 0 || c == ' '))
+ return extIndex;
+ if (c != c2)
+ break;
+ c = *p++;
+ }
+ extIndex++;
+ for (;;)
+ {
+ if (c == 0)
+ return extIndex;
+ if (c == ' ')
+ break;
+ c = *p++;
+ }
+ }
+}
+
+struct CRefItem
+{
+ UInt32 Index;
+ const CUpdateItem *UpdateItem;
+ UInt32 ExtensionPos;
+ UInt32 NamePos;
+ int ExtensionIndex;
+ CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
+ Index(index),
+ UpdateItem(&updateItem),
+ ExtensionPos(0),
+ NamePos(0),
+ ExtensionIndex(0)
+ {
+ if (sortByType)
+ {
+ int slashPos = GetReverseSlashPos(updateItem.Name);
+ NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
+ int dotPos = updateItem.Name.ReverseFind(L'.');
+ if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
+ ExtensionPos = updateItem.Name.Length();
+ else
+ {
+ ExtensionPos = dotPos + 1;
+ UString us = updateItem.Name.Mid(ExtensionPos);
+ if (!us.IsEmpty())
+ {
+ us.MakeLower();
+ int i;
+ AString s;
+ for (i = 0; i < us.Length(); i++)
+ {
+ wchar_t c = us[i];
+ if (c >= 0x80)
+ break;
+ s += (char)c;
+ }
+ if (i == us.Length())
+ ExtensionIndex = GetExtIndex(s);
+ else
+ ExtensionIndex = 0;
+ }
+ }
+ }
+ }
+};
+
+static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
+{
+ const CRefItem &a1 = *p1;
+ const CRefItem &a2 = *p2;
+ const CUpdateItem &u1 = *a1.UpdateItem;
+ const CUpdateItem &u2 = *a2.UpdateItem;
+ int n;
+ if (u1.IsDirectory != u2.IsDirectory)
+ return (u1.IsDirectory) ? 1 : -1;
+ if (u1.IsDirectory)
+ {
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ n = MyStringCompareNoCase(u1.Name, u2.Name);
+ return -n;
+ }
+ bool sortByType = *(bool *)param;
+ if (sortByType)
+ {
+ RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex))
+ RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
+ RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
+ if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined)
+ RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
+ RINOZ(MyCompare(u1.Size, u2.Size))
+ }
+ return MyStringCompareNoCase(u1.Name, u2.Name);
+}
+
+struct CSolidGroup
+{
+ CCompressionMethodMode Method;
+ CRecordVector<UInt32> Indices;
+};
+
+static wchar_t *g_ExeExts[] =
+{
+ L"dll",
+ L"exe",
+ L"ocx",
+ L"sfx",
+ L"sys"
+};
+
+static bool IsExeFile(const UString &ext)
+{
+ for (int i = 0; i < sizeof(g_ExeExts) / sizeof(g_ExeExts[0]); i++)
+ if (ext.CompareNoCase(g_ExeExts[i]) == 0)
+ return true;
+ return false;
+}
+
+static const UInt64 k_LZMA = 0x030101;
+static const UInt64 k_BCJ = 0x03030103;
+static const UInt64 k_BCJ2 = 0x0303011B;
+
+static bool GetMethodFull(UInt64 methodID,
+ UInt32 numInStreams, CMethodFull &methodResult)
+{
+ methodResult.Id = methodID;
+ methodResult.NumInStreams = numInStreams;
+ methodResult.NumOutStreams = 1;
+ return true;
+}
+
+static bool MakeExeMethod(const CCompressionMethodMode &method,
+ bool bcj2Filter, CCompressionMethodMode &exeMethod)
+{
+ exeMethod = method;
+ if (bcj2Filter)
+ {
+ CMethodFull methodFull;
+ if (!GetMethodFull(k_BCJ2, 4, methodFull))
+ return false;
+ exeMethod.Methods.Insert(0, methodFull);
+ if (!GetMethodFull(k_LZMA, 1, methodFull))
+ return false;
+ {
+ CProp property;
+ property.Id = NCoderPropID::kAlgorithm;
+ property.Value = kAlgorithmForBCJ2_LZMA;
+ methodFull.Properties.Add(property);
+ }
+ {
+ CProp property;
+ property.Id = NCoderPropID::kMatchFinder;
+ property.Value = kMatchFinderForBCJ2_LZMA;
+ methodFull.Properties.Add(property);
+ }
+ {
+ CProp property;
+ property.Id = NCoderPropID::kDictionarySize;
+ property.Value = kDictionaryForBCJ2_LZMA;
+ methodFull.Properties.Add(property);
+ }
+ {
+ CProp property;
+ property.Id = NCoderPropID::kNumFastBytes;
+ property.Value = kNumFastBytesForBCJ2_LZMA;
+ methodFull.Properties.Add(property);
+ }
+
+ exeMethod.Methods.Add(methodFull);
+ exeMethod.Methods.Add(methodFull);
+ CBind bind;
+
+ bind.OutCoder = 0;
+ bind.InStream = 0;
+
+ bind.InCoder = 1;
+ bind.OutStream = 0;
+ exeMethod.Binds.Add(bind);
+
+ bind.InCoder = 2;
+ bind.OutStream = 1;
+ exeMethod.Binds.Add(bind);
+
+ bind.InCoder = 3;
+ bind.OutStream = 2;
+ exeMethod.Binds.Add(bind);
+ }
+ else
+ {
+ CMethodFull methodFull;
+ if (!GetMethodFull(k_BCJ, 1, methodFull))
+ return false;
+ exeMethod.Methods.Insert(0, methodFull);
+ CBind bind;
+ bind.OutCoder = 0;
+ bind.InStream = 0;
+ bind.InCoder = 1;
+ bind.OutStream = 0;
+ exeMethod.Binds.Add(bind);
+ }
+ return true;
+}
+
+static void SplitFilesToGroups(
+ const CCompressionMethodMode &method,
+ bool useFilters, bool maxFilter,
+ const CObjectVector<CUpdateItem> &updateItems,
+ CObjectVector<CSolidGroup> &groups)
+{
+ if (method.Methods.Size() != 1 || method.Binds.Size() != 0)
+ useFilters = false;
+ groups.Clear();
+ groups.Add(CSolidGroup());
+ groups.Add(CSolidGroup());
+ CSolidGroup &generalGroup = groups[0];
+ CSolidGroup &exeGroup = groups[1];
+ generalGroup.Method = method;
+ int i;
+ for (i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (!updateItem.NewData)
+ continue;
+ if (!updateItem.HasStream())
+ continue;
+ if (useFilters)
+ {
+ const UString name = updateItem.Name;
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos >= 0)
+ {
+ UString ext = name.Mid(dotPos + 1);
+ if (IsExeFile(ext))
+ {
+ exeGroup.Indices.Add(i);
+ continue;
+ }
+ }
+ }
+ generalGroup.Indices.Add(i);
+ }
+ if (exeGroup.Indices.Size() > 0)
+ if (!MakeExeMethod(method, maxFilter, exeGroup.Method))
+ exeGroup.Method = method;
+ for (i = 0; i < groups.Size();)
+ if (groups[i].Indices.Size() == 0)
+ groups.Delete(i);
+ else
+ i++;
+}
+
+static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
+ CFileItem &file)
+{
+ file.Name = NItemName::MakeLegalName(updateItem.Name);
+ if (updateItem.AttributesAreDefined)
+ file.SetAttributes(updateItem.Attributes);
+
+ if (updateItem.IsCreationTimeDefined)
+ file.SetCreationTime(updateItem.CreationTime);
+ if (updateItem.IsLastWriteTimeDefined)
+ file.SetLastWriteTime(updateItem.LastWriteTime);
+ if (updateItem.IsLastAccessTimeDefined)
+ file.SetLastAccessTime(updateItem.LastAccessTime);
+
+ file.UnPackSize = updateItem.Size;
+ file.IsDirectory = updateItem.IsDirectory;
+ file.IsAnti = updateItem.IsAnti;
+ file.HasStream = updateItem.HasStream();
+}
+
+static HRESULT Update2(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ IInStream *inStream,
+ const CArchiveDatabaseEx *database,
+ const CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ IArchiveUpdateCallback *updateCallback,
+ const CUpdateOptions &options)
+{
+ UInt64 numSolidFiles = options.NumSolidFiles;
+ if (numSolidFiles == 0)
+ numSolidFiles = 1;
+ /*
+ CMyComPtr<IOutStream> outStream;
+ RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
+ if (!outStream)
+ return E_NOTIMPL;
+ */
+
+ UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0;
+ if (startBlockSize > 0 && !options.RemoveSfxBlock)
+ {
+ RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
+ }
+
+ CRecordVector<int> fileIndexToUpdateIndexMap;
+ if (database != 0)
+ {
+ fileIndexToUpdateIndexMap.Reserve(database->Files.Size());
+ for (int i = 0; i < database->Files.Size(); i++)
+ fileIndexToUpdateIndexMap.Add(-1);
+ }
+ int i;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ int index = updateItems[i].IndexInArchive;
+ if (index != -1)
+ fileIndexToUpdateIndexMap[index] = i;
+ }
+
+ CRecordVector<int> folderRefs;
+ if (database != 0)
+ {
+ for(i = 0; i < database->Folders.Size(); i++)
+ {
+ CNum indexInFolder = 0;
+ CNum numCopyItems = 0;
+ CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
+ for (CNum fileIndex = database->FolderStartFileIndex[i];
+ indexInFolder < numUnPackStreams; fileIndex++)
+ {
+ if (database->Files[fileIndex].HasStream)
+ {
+ indexInFolder++;
+ int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
+ if (updateIndex >= 0)
+ if (!updateItems[updateIndex].NewData)
+ numCopyItems++;
+ }
+ }
+ if (numCopyItems != numUnPackStreams && numCopyItems != 0)
+ return E_NOTIMPL; // It needs repacking !!!
+ if (numCopyItems > 0)
+ folderRefs.Add(i);
+ }
+ folderRefs.Sort(CompareFolderRefs, (void *)database);
+ }
+
+ CArchiveDatabase newDatabase;
+
+ ////////////////////////////
+
+ COutArchive archive;
+ RINOK(archive.Create(seqOutStream, false));
+ RINOK(archive.SkeepPrefixArchiveHeader());
+ UInt64 complexity = 0;
+ for(i = 0; i < folderRefs.Size(); i++)
+ complexity += database->GetFolderFullPackSize(folderRefs[i]);
+ UInt64 inSizeForReduce = 0;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (updateItem.NewData)
+ {
+ complexity += updateItem.Size;
+ if (numSolidFiles == 1)
+ {
+ if (updateItem.Size > inSizeForReduce)
+ inSizeForReduce = updateItem.Size;
+ }
+ else
+ inSizeForReduce += updateItem.Size;
+ }
+ }
+ RINOK(updateCallback->SetTotal(complexity));
+ complexity = 0;
+ RINOK(updateCallback->SetCompleted(&complexity));
+
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(updateCallback, true);
+
+ /////////////////////////////////////////
+ // Write Copy Items
+
+ for(i = 0; i < folderRefs.Size(); i++)
+ {
+ int folderIndex = folderRefs[i];
+
+ lps->ProgressOffset = complexity;
+ UInt64 packSize = database->GetFolderFullPackSize(folderIndex);
+ RINOK(WriteRange(inStream, archive.SeqStream,
+ database->GetFolderStreamPos(folderIndex, 0), packSize, progress));
+ complexity += packSize;
+
+ const CFolder &folder = database->Folders[folderIndex];
+ CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
+ for (int j = 0; j < folder.PackStreams.Size(); j++)
+ {
+ newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]);
+ // newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
+ // newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
+ }
+ newDatabase.Folders.Add(folder);
+
+ CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex];
+ newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+
+ CNum indexInFolder = 0;
+ for (CNum fi = database->FolderStartFileIndex[folderIndex];
+ indexInFolder < numUnPackStreams; fi++)
+ {
+ CFileItem file = database->Files[fi];
+ if (file.HasStream)
+ {
+ indexInFolder++;
+ int updateIndex = fileIndexToUpdateIndexMap[fi];
+ if (updateIndex >= 0)
+ {
+ const CUpdateItem &updateItem = updateItems[updateIndex];
+ if (updateItem.NewProperties)
+ {
+ CFileItem file2;
+ FromUpdateItemToFileItem(updateItem, file2);
+ file2.UnPackSize = file.UnPackSize;
+ file2.FileCRC = file.FileCRC;
+ file2.IsFileCRCDefined = file.IsFileCRCDefined;
+ file2.HasStream = file.HasStream;
+ file = file2;
+ }
+ }
+ newDatabase.Files.Add(file);
+ }
+ }
+ }
+
+ /////////////////////////////////////////
+ // Compress New Files
+
+ CObjectVector<CSolidGroup> groups;
+ SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
+ updateItems, groups);
+
+ const UInt32 kMinReduceSize = (1 << 16);
+ if (inSizeForReduce < kMinReduceSize)
+ inSizeForReduce = kMinReduceSize;
+
+ for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++)
+ {
+ const CSolidGroup &group = groups[groupIndex];
+ int numFiles = group.Indices.Size();
+ if (numFiles == 0)
+ continue;
+ CRecordVector<CRefItem> refItems;
+ refItems.Reserve(numFiles);
+ bool sortByType = (numSolidFiles > 1);
+ for (i = 0; i < numFiles; i++)
+ refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType));
+ refItems.Sort(CompareUpdateItems, (void *)&sortByType);
+
+ CRecordVector<UInt32> indices;
+ indices.Reserve(numFiles);
+
+ for (i = 0; i < numFiles; i++)
+ {
+ UInt32 index = refItems[i].Index;
+ indices.Add(index);
+ /*
+ const CUpdateItem &updateItem = updateItems[index];
+ CFileItem file;
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database.Files[updateItem.IndexInArchive];
+ if (file.IsAnti || file.IsDirectory)
+ return E_FAIL;
+ newDatabase.Files.Add(file);
+ */
+ }
+
+ CEncoder encoder(group.Method);
+
+ for (i = 0; i < numFiles;)
+ {
+ UInt64 totalSize = 0;
+ int numSubFiles;
+ UString prevExtension;
+ for (numSubFiles = 0; i + numSubFiles < numFiles &&
+ numSubFiles < numSolidFiles; numSubFiles++)
+ {
+ const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
+ totalSize += updateItem.Size;
+ if (totalSize > options.NumSolidBytes)
+ break;
+ if (options.SolidExtension)
+ {
+ UString ext = updateItem.GetExtension();
+ if (numSubFiles == 0)
+ prevExtension = ext;
+ else
+ if (ext.CompareNoCase(prevExtension) != 0)
+ break;
+ }
+ }
+ if (numSubFiles < 1)
+ numSubFiles = 1;
+
+ CFolderInStream *inStreamSpec = new CFolderInStream;
+ CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec);
+ inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
+
+ CFolder folderItem;
+
+ int startPackIndex = newDatabase.PackSizes.Size();
+ RINOK(encoder.Encode(
+ EXTERNAL_CODECS_LOC_VARS
+ solidInStream, NULL, &inSizeForReduce, folderItem,
+ archive.SeqStream, newDatabase.PackSizes, progress));
+
+ for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
+ lps->OutSize += newDatabase.PackSizes[startPackIndex];
+
+ lps->InSize += folderItem.GetUnPackSize();
+ // for()
+ // newDatabase.PackCRCsDefined.Add(false);
+ // newDatabase.PackCRCs.Add(0);
+
+ newDatabase.Folders.Add(folderItem);
+
+ CNum numUnPackStreams = 0;
+ for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
+ {
+ const CUpdateItem &updateItem = updateItems[indices[i + subIndex]];
+ CFileItem file;
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database->Files[updateItem.IndexInArchive];
+ if (file.IsAnti || file.IsDirectory)
+ return E_FAIL;
+
+ /*
+ CFileItem &file = newDatabase.Files[
+ startFileIndexInDatabase + i + subIndex];
+ */
+ if (!inStreamSpec->Processed[subIndex])
+ {
+ continue;
+ // file.Name += L".locked";
+ }
+
+ file.FileCRC = inStreamSpec->CRCs[subIndex];
+ file.UnPackSize = inStreamSpec->Sizes[subIndex];
+ if (file.UnPackSize != 0)
+ {
+ file.IsFileCRCDefined = true;
+ file.HasStream = true;
+ numUnPackStreams++;
+ }
+ else
+ {
+ file.IsFileCRCDefined = false;
+ file.HasStream = false;
+ }
+ newDatabase.Files.Add(file);
+ }
+ // numUnPackStreams = 0 is very bad case for locked files
+ // v3.13 doesn't understand it.
+ newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+ i += numSubFiles;
+ }
+ }
+
+ {
+ /////////////////////////////////////////
+ // Write Empty Files & Folders
+
+ CRecordVector<int> emptyRefs;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (updateItem.NewData)
+ {
+ if (updateItem.HasStream())
+ continue;
+ }
+ else
+ if (updateItem.IndexInArchive != -1)
+ if (database->Files[updateItem.IndexInArchive].HasStream)
+ continue;
+ emptyRefs.Add(i);
+ }
+ emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
+ for(i = 0; i < emptyRefs.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
+ CFileItem file;
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database->Files[updateItem.IndexInArchive];
+ newDatabase.Files.Add(file);
+ }
+ }
+
+ /*
+ if (newDatabase.Files.Size() != updateItems.Size())
+ return E_FAIL;
+ */
+
+ return archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS
+ newDatabase, options.HeaderMethod, options.HeaderOptions);
+}
+
+#ifdef _7Z_VOL
+
+static const UInt64 k_Copy = 0x0;
+
+static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options)
+{
+ CCoderInfo coder;
+ coder.NumInStreams = coder.NumOutStreams = 1;
+ coder.MethodID = k_Copy;
+
+ CFolder folder;
+ folder.Coders.Add(coder);
+ folder.PackStreams.Add(0);
+
+ CNum numUnPackStreams = 0;
+ if (file.UnPackSize != 0)
+ {
+ file.IsFileCRCDefined = true;
+ file.HasStream = true;
+ numUnPackStreams++;
+ }
+ else
+ {
+ throw 1;
+ file.IsFileCRCDefined = false;
+ file.HasStream = false;
+ }
+ folder.UnPackSizes.Add(file.UnPackSize);
+
+ CArchiveDatabase newDatabase;
+ newDatabase.Files.Add(file);
+ newDatabase.Folders.Add(folder);
+ newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+ newDatabase.PackSizes.Add(file.UnPackSize);
+ newDatabase.PackCRCsDefined.Add(false);
+ newDatabase.PackCRCs.Add(file.FileCRC);
+
+ return archive.WriteDatabase(newDatabase,
+ options.HeaderMethod,
+ false,
+ false);
+}
+
+HRESULT UpdateVolume(
+ IInStream *inStream,
+ const CArchiveDatabaseEx *database,
+ CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ IArchiveUpdateCallback *updateCallback,
+ const CUpdateOptions &options)
+{
+ if (updateItems.Size() != 1)
+ return E_NOTIMPL;
+
+ CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
+ RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
+ if (!volumeCallback)
+ return E_NOTIMPL;
+
+ CMyComPtr<ISequentialInStream> fileStream;
+ HRESULT result = updateCallback->GetStream(0, &fileStream);
+ if (result != S_OK && result != S_FALSE)
+ return result;
+ if (result == S_FALSE)
+ return E_FAIL;
+
+ CFileItem file;
+
+ const CUpdateItem &updateItem = updateItems[0];
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database->Files[updateItem.IndexInArchive];
+ if (file.IsAnti || file.IsDirectory)
+ return E_FAIL;
+
+ UInt64 complexity = 0;
+ file.IsStartPosDefined = true;
+ file.StartPos = 0;
+ for (UInt64 volumeIndex = 0; true; volumeIndex++)
+ {
+ UInt64 volSize;
+ RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize));
+ UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true);
+ CMyComPtr<ISequentialOutStream> volumeStream;
+ RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
+
+ COutArchive archive;
+ RINOK(archive.Create(volumeStream, true));
+ RINOK(archive.SkeepPrefixArchiveHeader());
+
+ CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
+ CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
+ inCrcStreamSpec->Init(fileStream);
+
+ RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity));
+ file.UnPackSize = inCrcStreamSpec->GetSize();
+ if (file.UnPackSize == 0)
+ break;
+ file.FileCRC = inCrcStreamSpec->GetCRC();
+ RINOK(WriteVolumeHeader(archive, file, options));
+ file.StartPos += file.UnPackSize;
+ if (file.UnPackSize < pureSize)
+ break;
+ }
+ return S_OK;
+}
+
+class COutVolumeStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ int _volIndex;
+ UInt64 _volSize;
+ UInt64 _curPos;
+ CMyComPtr<ISequentialOutStream> _volumeStream;
+ COutArchive _archive;
+ CCRC _crc;
+
+public:
+ MY_UNKNOWN_IMP
+
+ CFileItem _file;
+ CUpdateOptions _options;
+ CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+ void Init(IArchiveUpdateCallback2 *volumeCallback,
+ const UString &name)
+ {
+ _file.Name = name;
+ _file.IsStartPosDefined = true;
+ _file.StartPos = 0;
+
+ VolumeCallback = volumeCallback;
+ _volIndex = 0;
+ _volSize = 0;
+ }
+
+ HRESULT Flush();
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+HRESULT COutVolumeStream::Flush()
+{
+ if (_volumeStream)
+ {
+ _file.UnPackSize = _curPos;
+ _file.FileCRC = _crc.GetDigest();
+ RINOK(WriteVolumeHeader(_archive, _file, _options));
+ _archive.Close();
+ _volumeStream.Release();
+ _file.StartPos += _file.UnPackSize;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+ while(size > 0)
+ {
+ if (!_volumeStream)
+ {
+ RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
+ RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
+ _volIndex++;
+ _curPos = 0;
+ RINOK(_archive.Create(_volumeStream, true));
+ RINOK(_archive.SkeepPrefixArchiveHeader());
+ _crc.Init();
+ continue;
+ }
+ UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
+ UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);
+
+ _crc.Update(data, curSize);
+ UInt32 realProcessed;
+ RINOK(_volumeStream->Write(data, curSize, &realProcessed))
+ data = (void *)((Byte *)data + realProcessed);
+ size -= realProcessed;
+ if(processedSize != NULL)
+ *processedSize += realProcessed;
+ _curPos += realProcessed;
+ if (realProcessed != curSize && realProcessed == 0)
+ return E_FAIL;
+ if (_curPos == pureSize)
+ {
+ RINOK(Flush());
+ }
+ }
+ return S_OK;
+}
+
+#endif
+
+HRESULT Update(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ IInStream *inStream,
+ const CArchiveDatabaseEx *database,
+ const CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ IArchiveUpdateCallback *updateCallback,
+ const CUpdateOptions &options)
+{
+ #ifdef _7Z_VOL
+ if (seqOutStream)
+ #endif
+ return Update2(
+ EXTERNAL_CODECS_LOC_VARS
+ inStream, database, updateItems,
+ seqOutStream, updateCallback, options);
+ #ifdef _7Z_VOL
+ if (options.VolumeMode)
+ return UpdateVolume(inStream, database, updateItems,
+ seqOutStream, updateCallback, options);
+ COutVolumeStream *volStreamSpec = new COutVolumeStream;
+ CMyComPtr<ISequentialOutStream> volStream = volStreamSpec;
+ CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
+ RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
+ if (!volumeCallback)
+ return E_NOTIMPL;
+ volStreamSpec->Init(volumeCallback, L"a.7z");
+ volStreamSpec->_options = options;
+ RINOK(Update2(inStream, database, updateItems,
+ volStream, updateCallback, options));
+ return volStreamSpec->Flush();
+ #endif
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/7z/7zUpdate.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/7zUpdate.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/7zUpdate.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,80 @@
+// 7zUpdate.h
+
+#ifndef __7Z_UPDATE_H
+#define __7Z_UPDATE_H
+
+#include "7zIn.h"
+#include "7zOut.h"
+#include "7zCompressionMode.h"
+
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CUpdateItem
+{
+ bool NewData;
+ bool NewProperties;
+ int IndexInArchive;
+ int IndexInClient;
+
+ UInt32 Attributes;
+ FILETIME CreationTime;
+ FILETIME LastWriteTime;
+ FILETIME LastAccessTime;
+
+ UInt64 Size;
+ UString Name;
+
+ bool IsAnti;
+ bool IsDirectory;
+
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+ bool AttributesAreDefined;
+
+ bool HasStream() const
+ { return !IsDirectory && !IsAnti && Size != 0; }
+ CUpdateItem():
+ IsAnti(false),
+ AttributesAreDefined(false),
+ IsCreationTimeDefined(false),
+ IsLastWriteTimeDefined(false),
+ IsLastAccessTimeDefined(false)
+ {}
+ void SetDirectoryStatusFromAttributes()
+ { IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
+
+ int GetExtensionPos() const;
+ UString GetExtension() const;
+};
+
+struct CUpdateOptions
+{
+ const CCompressionMethodMode *Method;
+ const CCompressionMethodMode *HeaderMethod;
+ bool UseFilters;
+ bool MaxFilter;
+
+ CHeaderOptions HeaderOptions;
+
+ UInt64 NumSolidFiles;
+ UInt64 NumSolidBytes;
+ bool SolidExtension;
+ bool RemoveSfxBlock;
+ bool VolumeMode;
+};
+
+HRESULT Update(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ IInStream *inStream,
+ const CArchiveDatabaseEx *database,
+ const CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ IArchiveUpdateCallback *updateCallback,
+ const CUpdateOptions &options);
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/7z/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Archive/7z/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/7z/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/7z/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Archive.def
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Archive.def (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Archive.def 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,6 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
+ GetNumberOfFormats PRIVATE
+ GetHandlerProperty2 PRIVATE
+ CreateObject PRIVATE
Added: trunk/lzma/CPP/7zip/Archive/Archive2.def
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Archive2.def (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Archive2.def 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
+ GetNumberOfFormats PRIVATE
+ GetHandlerProperty2 PRIVATE
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
+ SetLargePageMode PRIVATE
Added: trunk/lzma/CPP/7zip/Archive/ArchiveExports.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/ArchiveExports.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/ArchiveExports.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,130 @@
+// ArchiveExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/ComTry.h"
+#include "../../Common/Types.h"
+#include "../../Windows/PropVariant.h"
+#include "../Common/RegisterArc.h"
+
+#include "IArchive.h"
+#include "../ICoder.h"
+#include "../IPassword.h"
+
+static const unsigned int kNumArcsMax = 32;
+static unsigned int g_NumArcs = 0;
+static const CArcInfo *g_Arcs[kNumArcsMax];
+void RegisterArc(const CArcInfo *arcInfo)
+{
+ if (g_NumArcs < kNumArcsMax)
+ g_Arcs[g_NumArcs++] = arcInfo;
+}
+
+DEFINE_GUID(CLSID_CArchiveHandler,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
+
+#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
+
+static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
+{
+ if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+}
+
+static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
+{
+ return SetPropString((const char *)&guid, sizeof(GUID), value);
+}
+
+int FindFormatCalssId(const GUID *clsID)
+{
+ GUID cls = *clsID;
+ CLS_ARC_ID_ITEM(cls) = 0;
+ if (cls != CLSID_CArchiveHandler)
+ return -1;
+ Byte id = CLS_ARC_ID_ITEM(*clsID);
+ for (UInt32 i = 0; i < g_NumArcs; i++)
+ if (g_Arcs[i]->ClassId == id)
+ return i;
+ return -1;
+}
+
+STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
+{
+ COM_TRY_BEGIN
+ {
+ int needIn = (*iid == IID_IInArchive);
+ int needOut = (*iid == IID_IOutArchive);
+ if (!needIn && !needOut)
+ return E_NOINTERFACE;
+ int formatIndex = FindFormatCalssId(clsid);
+ if (formatIndex < 0)
+ return CLASS_E_CLASSNOTAVAILABLE;
+
+ const CArcInfo &arc = *g_Arcs[formatIndex];
+ if (needIn)
+ {
+ *outObject = arc.CreateInArchive();
+ ((IInArchive *)*outObject)->AddRef();
+ }
+ else
+ {
+ if (!arc.CreateOutArchive)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = arc.CreateOutArchive();
+ ((IOutArchive *)*outObject)->AddRef();
+ }
+ }
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
+{
+ if (formatIndex >= g_NumArcs)
+ return E_INVALIDARG;
+ const CArcInfo &arc = *g_Arcs[formatIndex];
+ NWindows::NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case NArchive::kName:
+ prop = arc.Name;
+ break;
+ case NArchive::kClassID:
+ {
+ GUID clsId = CLSID_CArchiveHandler;
+ CLS_ARC_ID_ITEM(clsId) = arc.ClassId;
+ return SetPropGUID(clsId, value);
+ }
+ case NArchive::kExtension:
+ if (arc.Ext != 0)
+ prop = arc.Ext;
+ break;
+ case NArchive::kAddExtension:
+ if (arc.AddExt != 0)
+ prop = arc.AddExt;
+ break;
+ case NArchive::kUpdate:
+ prop = (bool)(arc.CreateOutArchive != 0);
+ break;
+ case NArchive::kKeepName:
+ prop = arc.KeepName;
+ break;
+ case NArchive::kStartSignature:
+ return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
+ }
+ prop.Detach(value);
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ return GetHandlerProperty2(0, propID, value);
+}
+
+STDAPI GetNumberOfFormats(UINT32 *numFormats)
+{
+ *numFormats = g_NumArcs;
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,121 @@
+// CoderMixer2.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2.h"
+
+namespace NCoderMixer {
+
+CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
+ _srcBindInfo(srcBindInfo)
+{
+ srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
+
+ UInt32 j;
+ for (j = 0; j < NumSrcInStreams; j++)
+ {
+ _srcInToDestOutMap.Add(0);
+ DestOutToSrcInMap.Add(0);
+ }
+ for (j = 0; j < _numSrcOutStreams; j++)
+ {
+ _srcOutToDestInMap.Add(0);
+ _destInToSrcOutMap.Add(0);
+ }
+
+ UInt32 destInOffset = 0;
+ UInt32 destOutOffset = 0;
+ UInt32 srcInOffset = NumSrcInStreams;
+ UInt32 srcOutOffset = _numSrcOutStreams;
+
+ for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];
+
+ srcInOffset -= srcCoderInfo.NumInStreams;
+ srcOutOffset -= srcCoderInfo.NumOutStreams;
+
+ UInt32 j;
+ for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
+ {
+ UInt32 index = srcInOffset + j;
+ _srcInToDestOutMap[index] = destOutOffset;
+ DestOutToSrcInMap[destOutOffset] = index;
+ }
+ for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)
+ {
+ UInt32 index = srcOutOffset + j;
+ _srcOutToDestInMap[index] = destInOffset;
+ _destInToSrcOutMap[destInOffset] = index;
+ }
+ }
+}
+
+void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
+{
+ destBindInfo.Coders.Clear();
+ destBindInfo.BindPairs.Clear();
+ destBindInfo.InStreams.Clear();
+ destBindInfo.OutStreams.Clear();
+
+ int i;
+ for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
+ CCoderStreamsInfo destCoderInfo;
+ destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
+ destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
+ destBindInfo.Coders.Add(destCoderInfo);
+ }
+ for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
+ {
+ const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
+ CBindPair destBindPair;
+ destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
+ destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
+ destBindInfo.BindPairs.Add(destBindPair);
+ }
+ for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
+ destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
+ for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
+ destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
+}
+
+CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
+ NumInStreams(numInStreams),
+ NumOutStreams(numOutStreams)
+{
+ InSizes.Reserve(NumInStreams);
+ InSizePointers.Reserve(NumInStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+ sizes.Clear();
+ sizePointers.Clear();
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (srcSizes == 0 || srcSizes[i] == NULL)
+ {
+ sizes.Add(0);
+ sizePointers.Add(NULL);
+ }
+ else
+ {
+ sizes.Add(*srcSizes[i]);
+ sizePointers.Add(&sizes.Back());
+ }
+ }
+}
+
+void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes)
+{
+ SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+ SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+}
Added: trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,174 @@
+// CoderMixer2.h
+
+#ifndef __CODER_MIXER2_H
+#define __CODER_MIXER2_H
+
+#include "../../../Common/MyVector.h"
+#include "../../../Common/Types.h"
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+namespace NCoderMixer {
+
+struct CBindPair
+{
+ UInt32 InIndex;
+ UInt32 OutIndex;
+};
+
+struct CCoderStreamsInfo
+{
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+};
+
+struct CBindInfo
+{
+ CRecordVector<CCoderStreamsInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<UInt32> InStreams;
+ CRecordVector<UInt32> OutStreams;
+
+ void Clear()
+ {
+ Coders.Clear();
+ BindPairs.Clear();
+ InStreams.Clear();
+ OutStreams.Clear();
+ }
+
+ /*
+ UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
+ {
+ UInt32 numOutStreams = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ numOutStreams += Coders[i].NumOutStreams;
+ return numOutStreams;
+ }
+ */
+
+
+ void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
+ {
+ numInStreams = 0;
+ numOutStreams = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ {
+ const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
+ numInStreams += coderStreamsInfo.NumInStreams;
+ numOutStreams += coderStreamsInfo.NumOutStreams;
+ }
+ }
+
+ int FindBinderForInStream(UInt32 inStream) const
+ {
+ for (int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStream)
+ return i;
+ return -1;
+ }
+ int FindBinderForOutStream(UInt32 outStream) const
+ {
+ for (int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStream)
+ return i;
+ return -1;
+ }
+
+ UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
+ {
+ UInt32 streamIndex = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ streamIndex += Coders[i].NumInStreams;
+ return streamIndex;
+ }
+
+ UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
+ {
+ UInt32 streamIndex = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ streamIndex += Coders[i].NumOutStreams;
+ return streamIndex;
+ }
+
+
+ void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
+ UInt32 &coderStreamIndex) const
+ {
+ for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+ {
+ UInt32 curSize = Coders[coderIndex].NumInStreams;
+ if (streamIndex < curSize)
+ {
+ coderStreamIndex = streamIndex;
+ return;
+ }
+ streamIndex -= curSize;
+ }
+ throw 1;
+ }
+ void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
+ UInt32 &coderStreamIndex) const
+ {
+ for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+ {
+ UInt32 curSize = Coders[coderIndex].NumOutStreams;
+ if (streamIndex < curSize)
+ {
+ coderStreamIndex = streamIndex;
+ return;
+ }
+ streamIndex -= curSize;
+ }
+ throw 1;
+ }
+};
+
+class CBindReverseConverter
+{
+ UInt32 _numSrcOutStreams;
+ NCoderMixer::CBindInfo _srcBindInfo;
+ CRecordVector<UInt32> _srcInToDestOutMap;
+ CRecordVector<UInt32> _srcOutToDestInMap;
+ CRecordVector<UInt32> _destInToSrcOutMap;
+public:
+ UInt32 NumSrcInStreams;
+ CRecordVector<UInt32> DestOutToSrcInMap;
+
+ CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo);
+ void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);
+};
+
+struct CCoderInfo2
+{
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ICompressCoder2> Coder2;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+
+ CRecordVector<UInt64> InSizes;
+ CRecordVector<UInt64> OutSizes;
+ CRecordVector<const UInt64 *> InSizePointers;
+ CRecordVector<const UInt64 *> OutSizePointers;
+
+ CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams);
+ void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+
+ HRESULT QueryInterface(REFGUID iid, void** pp) const
+ {
+ IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
+ return p->QueryInterface(iid, pp);
+ }
+};
+
+class CCoderMixer2
+{
+public:
+ virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0;
+ virtual void ReInit() = 0;
+ virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
+};
+
+}
+#endif
+
Added: trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,228 @@
+// CoderMixer2MT.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2MT.h"
+
+namespace NCoderMixer {
+
+CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
+ CCoderInfo2(numInStreams, numOutStreams)
+{
+ InStreams.Reserve(NumInStreams);
+ InStreamPointers.Reserve(NumInStreams);
+ OutStreams.Reserve(NumOutStreams);
+ OutStreamPointers.Reserve(NumOutStreams);
+}
+
+void CCoder2::Execute() { Code(NULL); }
+
+void CCoder2::Code(ICompressProgressInfo *progress)
+{
+ InStreamPointers.Clear();
+ OutStreamPointers.Clear();
+ UInt32 i;
+ for (i = 0; i < NumInStreams; i++)
+ {
+ if (InSizePointers[i] != NULL)
+ InSizePointers[i] = &InSizes[i];
+ InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
+ }
+ for (i = 0; i < NumOutStreams; i++)
+ {
+ if (OutSizePointers[i] != NULL)
+ OutSizePointers[i] = &OutSizes[i];
+ OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
+ }
+ if (Coder)
+ Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
+ InSizePointers[0], OutSizePointers[0], progress);
+ else
+ Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
+ &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
+ {
+ int i;
+ for (i = 0; i < InStreams.Size(); i++)
+ InStreams[i].Release();
+ for (i = 0; i < OutStreams.Size(); i++)
+ OutStreams[i].Release();
+ }
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+ sizes.Clear();
+ sizePointers.Clear();
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (srcSizes == 0 || srcSizes[i] == NULL)
+ {
+ sizes.Add(0);
+ sizePointers.Add(NULL);
+ }
+ else
+ {
+ sizes.Add(*srcSizes[i]);
+ sizePointers.Add(&sizes.Back());
+ }
+ }
+}
+
+
+void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
+{
+ SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+ SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+//////////////////////////////////////
+// CCoderMixer2MT
+
+HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
+{
+ _bindInfo = bindInfo;
+ _streamBinders.Clear();
+ for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ _streamBinders.Add(CStreamBinder());
+ RINOK(_streamBinders.Back().CreateEvents());
+ }
+ return S_OK;
+}
+
+void CCoderMixer2MT::AddCoderCommon()
+{
+ const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
+ CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
+ _coders.Add(threadCoderInfo);
+}
+
+void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
+{
+ AddCoderCommon();
+ _coders.Back().Coder = coder;
+}
+
+void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
+{
+ AddCoderCommon();
+ _coders.Back().Coder2 = coder;
+}
+
+
+void CCoderMixer2MT::ReInit()
+{
+ for(int i = 0; i < _streamBinders.Size(); i++)
+ _streamBinders[i].ReInit();
+}
+
+
+HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
+{
+ /*
+ if (_coders.Size() != _bindInfo.Coders.Size())
+ throw 0;
+ */
+ int i;
+ for(i = 0; i < _coders.Size(); i++)
+ {
+ CCoder2 &coderInfo = _coders[i];
+ const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
+ coderInfo.InStreams.Clear();
+ UInt32 j;
+ for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
+ coderInfo.InStreams.Add(NULL);
+ coderInfo.OutStreams.Clear();
+ for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
+ coderInfo.OutStreams.Add(NULL);
+ }
+
+ for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ const CBindPair &bindPair = _bindInfo.BindPairs[i];
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ UInt32 outCoderIndex, outCoderStreamIndex;
+ _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
+ _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
+
+ _streamBinders[i].CreateStreams(
+ &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
+ &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
+ }
+
+ for(i = 0; i < _bindInfo.InStreams.Size(); i++)
+ {
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
+ _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
+ }
+
+ for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ UInt32 outCoderIndex, outCoderStreamIndex;
+ _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
+ _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
+ }
+ return S_OK;
+}
+
+HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
+{
+ for (int i = 0; i < _coders.Size(); i++)
+ if (_coders[i].Result == code)
+ return code;
+ return S_OK;
+}
+
+STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
+ const UInt64 ** /* inSizes */,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 ** /* outSizes */,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
+ numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
+ return E_INVALIDARG;
+
+ Init(inStreams, outStreams);
+
+ int i;
+ for (i = 0; i < _coders.Size(); i++)
+ if (i != _progressCoderIndex)
+ {
+ RINOK(_coders[i].Create());
+ }
+
+ for (i = 0; i < _coders.Size(); i++)
+ if (i != _progressCoderIndex)
+ _coders[i].Start();
+
+ _coders[_progressCoderIndex].Code(progress);
+
+ for (i = 0; i < _coders.Size(); i++)
+ if (i != _progressCoderIndex)
+ _coders[i].WaitFinish();
+
+ RINOK(ReturnIfError(E_ABORT));
+ RINOK(ReturnIfError(E_OUTOFMEMORY));
+ RINOK(ReturnIfError(S_FALSE));
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ HRESULT result = _coders[i].Result;
+ if (result != S_OK && result != E_FAIL)
+ return result;
+ }
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ HRESULT result = _coders[i].Result;
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+}
Added: trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,80 @@
+// CoderMixer2MT.h
+
+#ifndef __CODER_MIXER2_MT_H
+#define __CODER_MIXER2_MT_H
+
+#include "CoderMixer2.h"
+#include "../../../Common/MyCom.h"
+#include "../../Common/StreamBinder.h"
+#include "../../Common/VirtThread.h"
+
+namespace NCoderMixer {
+
+struct CCoder2: public CCoderInfo2, public CVirtThread
+{
+ HRESULT Result;
+ CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
+ CRecordVector<ISequentialInStream*> InStreamPointers;
+ CRecordVector<ISequentialOutStream*> OutStreamPointers;
+
+ CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
+ void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+ virtual void Execute();
+ void Code(ICompressProgressInfo *progress);
+};
+
+
+/*
+ SetBindInfo()
+ for each coder
+ AddCoder[2]()
+ SetProgressIndex(UInt32 coderIndex);
+
+ for each file
+ {
+ ReInit()
+ for each coder
+ SetCoderInfo
+ Code
+ }
+*/
+
+class CCoderMixer2MT:
+ public ICompressCoder2,
+ public CCoderMixer2,
+ public CMyUnknownImp
+{
+ CBindInfo _bindInfo;
+ CObjectVector<CStreamBinder> _streamBinders;
+ int _progressCoderIndex;
+
+ void AddCoderCommon();
+ HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);
+ HRESULT ReturnIfError(HRESULT code);
+public:
+ CObjectVector<CCoder2> _coders;
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+
+ HRESULT SetBindInfo(const CBindInfo &bindInfo);
+ void AddCoder(ICompressCoder *coder);
+ void AddCoder2(ICompressCoder2 *coder);
+ void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; }
+
+ void ReInit();
+ void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
+ { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }
+ UInt64 GetWriteProcessedSize(UInt32 binderIndex) const
+ { return _streamBinders[binderIndex].ProcessedSize; }
+};
+
+}
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,15 @@
+// CrossThreadProgress.cpp
+
+#include "StdAfx.h"
+
+#include "CrossThreadProgress.h"
+
+STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ InSize = inSize;
+ OutSize = outSize;
+ ProgressEvent.Set();
+ WaitEvent.Lock();
+ return Result;
+}
+
Added: trunk/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,37 @@
+// CrossThreadProgress.h
+
+#ifndef __CROSSTHREADPROGRESS_H
+#define __CROSSTHREADPROGRESS_H
+
+#include "../../ICoder.h"
+#include "../../../Windows/Synchronization.h"
+#include "../../../Common/MyCom.h"
+
+class CCrossThreadProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ const UInt64 *InSize;
+ const UInt64 *OutSize;
+ HRESULT Result;
+ NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
+ NWindows::NSynchronization::CAutoResetEvent WaitEvent;
+
+ HRes Create()
+ {
+ RINOK(ProgressEvent.CreateIfNotCreated());
+ return WaitEvent.CreateIfNotCreated();
+ }
+ void Init()
+ {
+ ProgressEvent.Reset();
+ WaitEvent.Reset();
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,22 @@
+// DummyOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "DummyOutStream.h"
+
+STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result;
+ if(!_stream)
+ {
+ realProcessedSize = size;
+ result = S_OK;
+ }
+ else
+ result = _stream->Write(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
Added: trunk/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/DummyOutStream.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/DummyOutStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,23 @@
+// DummyOutStream.h
+
+#ifndef __DUMMYOUTSTREAM_H
+#define __DUMMYOUTSTREAM_H
+
+#include "../../IStream.h"
+#include "Common/MyCom.h"
+
+class CDummyOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+public:
+ void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
+ void Init() { _size = 0; }
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ UInt64 GetSize() const { return _size; }
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,618 @@
+// HandlerOutCommon.cpp
+
+#include "StdAfx.h"
+
+#include "HandlerOut.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Common/StringToInt.h"
+#include "../../ICoder.h"
+#include "../Common/ParseProperties.h"
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+using namespace NWindows;
+
+namespace NArchive {
+
+static const wchar_t *kCopyMethod = L"Copy";
+static const wchar_t *kLZMAMethodName = L"LZMA";
+static const wchar_t *kLZMA2MethodName = L"LZMA2";
+static const wchar_t *kBZip2MethodName = L"BZip2";
+static const wchar_t *kPpmdMethodName = L"PPMd";
+static const wchar_t *kDeflateMethodName = L"Deflate";
+static const wchar_t *kDeflate64MethodName = L"Deflate64";
+
+static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
+static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
+
+static const UInt32 kLzmaAlgoX1 = 0;
+static const UInt32 kLzmaAlgoX5 = 1;
+
+static const UInt32 kLzmaDicSizeX1 = 1 << 16;
+static const UInt32 kLzmaDicSizeX3 = 1 << 20;
+static const UInt32 kLzmaDicSizeX5 = 1 << 24;
+static const UInt32 kLzmaDicSizeX7 = 1 << 25;
+static const UInt32 kLzmaDicSizeX9 = 1 << 26;
+
+static const UInt32 kLzmaFastBytesX1 = 32;
+static const UInt32 kLzmaFastBytesX7 = 64;
+
+static const UInt32 kPpmdMemSizeX1 = (1 << 22);
+static const UInt32 kPpmdMemSizeX5 = (1 << 24);
+static const UInt32 kPpmdMemSizeX7 = (1 << 26);
+static const UInt32 kPpmdMemSizeX9 = (192 << 20);
+
+static const UInt32 kPpmdOrderX1 = 4;
+static const UInt32 kPpmdOrderX5 = 6;
+static const UInt32 kPpmdOrderX7 = 16;
+static const UInt32 kPpmdOrderX9 = 32;
+
+static const UInt32 kDeflateAlgoX1 = 0;
+static const UInt32 kDeflateAlgoX5 = 1;
+
+static const UInt32 kDeflateFastBytesX1 = 32;
+static const UInt32 kDeflateFastBytesX7 = 64;
+static const UInt32 kDeflateFastBytesX9 = 128;
+
+static const UInt32 kDeflatePassesX1 = 1;
+static const UInt32 kDeflatePassesX7 = 3;
+static const UInt32 kDeflatePassesX9 = 10;
+
+static const UInt32 kBZip2NumPassesX1 = 1;
+static const UInt32 kBZip2NumPassesX7 = 2;
+static const UInt32 kBZip2NumPassesX9 = 7;
+
+static const UInt32 kBZip2DicSizeX1 = 100000;
+static const UInt32 kBZip2DicSizeX3 = 500000;
+static const UInt32 kBZip2DicSizeX5 = 900000;
+
+static const wchar_t *kDefaultMethodName = kLZMAMethodName;
+
+static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
+static const UInt32 kDictionaryForHeaders = 1 << 20;
+static const UInt32 kNumFastBytesForHeaders = 273;
+static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;
+
+static bool AreEqual(const UString &methodName, const wchar_t *s)
+ { return (methodName.CompareNoCase(s) == 0); }
+
+static inline bool IsLZMAMethod(const UString &methodName)
+{
+ return
+ AreEqual(methodName, kLZMAMethodName) ||
+ AreEqual(methodName, kLZMA2MethodName);
+}
+
+static inline bool IsBZip2Method(const UString &methodName)
+ { return AreEqual(methodName, kBZip2MethodName); }
+
+static inline bool IsPpmdMethod(const UString &methodName)
+ { return AreEqual(methodName, kPpmdMethodName); }
+
+static inline bool IsDeflateMethod(const UString &methodName)
+{
+ return
+ AreEqual(methodName, kDeflateMethodName) ||
+ AreEqual(methodName, kDeflate64MethodName);
+}
+
+struct CNameToPropID
+{
+ PROPID PropID;
+ VARTYPE VarType;
+ const wchar_t *Name;
+};
+
+CNameToPropID g_NameToPropID[] =
+{
+ { NCoderPropID::kOrder, VT_UI4, L"O" },
+ { NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
+ { NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
+ { NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
+ { NCoderPropID::kEndMarker, VT_BOOL, L"eos" },
+
+ { NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
+ { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
+ { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
+ { NCoderPropID::kAlgorithm, VT_UI4, L"a" },
+ { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
+ { NCoderPropID::kNumThreads, VT_UI4, L"mt" }
+};
+
+static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
+{
+ if (varType == srcProp.vt)
+ {
+ destProp = srcProp;
+ return true;
+ }
+ if (varType == VT_UI1)
+ {
+ if (srcProp.vt == VT_UI4)
+ {
+ UInt32 value = srcProp.ulVal;
+ if (value > 0xFF)
+ return false;
+ destProp = (Byte)value;
+ return true;
+ }
+ }
+ else if (varType == VT_BOOL)
+ {
+ bool res;
+ if (SetBoolProperty(res, srcProp) != S_OK)
+ return false;
+ destProp = res;
+ return true;
+ }
+ return false;
+}
+
+static int FindPropIdFromStringName(const UString &name)
+{
+ for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
+ if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
+ return i;
+ return -1;
+}
+
+static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
+ const NWindows::NCOM::CPropVariant &value)
+{
+ for (int j = 0; j < oneMethodInfo.Properties.Size(); j++)
+ if (oneMethodInfo.Properties[j].Id == propID)
+ return;
+ CProp property;
+ property.Id = propID;
+ property.Value = value;
+ oneMethodInfo.Properties.Add(property);
+}
+
+void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
+ #ifdef COMPRESS_MT
+ , UInt32 numThreads
+ #endif
+ )
+{
+ UInt32 level = _level;
+ if (oneMethodInfo.MethodName.IsEmpty())
+ oneMethodInfo.MethodName = kDefaultMethodName;
+
+ if (IsLZMAMethod(oneMethodInfo.MethodName))
+ {
+ UInt32 dicSize =
+ (level >= 9 ? kLzmaDicSizeX9 :
+ (level >= 7 ? kLzmaDicSizeX7 :
+ (level >= 5 ? kLzmaDicSizeX5 :
+ (level >= 3 ? kLzmaDicSizeX3 :
+ kLzmaDicSizeX1))));
+
+ UInt32 algo =
+ (level >= 5 ? kLzmaAlgoX5 :
+ kLzmaAlgoX1);
+
+ UInt32 fastBytes =
+ (level >= 7 ? kLzmaFastBytesX7 :
+ kLzmaFastBytesX1);
+
+ const wchar_t *matchFinder =
+ (level >= 5 ? kLzmaMatchFinderX5 :
+ kLzmaMatchFinderX1);
+
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
+ #ifdef COMPRESS_MT
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
+ #endif
+ }
+ else if (IsDeflateMethod(oneMethodInfo.MethodName))
+ {
+ UInt32 fastBytes =
+ (level >= 9 ? kDeflateFastBytesX9 :
+ (level >= 7 ? kDeflateFastBytesX7 :
+ kDeflateFastBytesX1));
+
+ UInt32 numPasses =
+ (level >= 9 ? kDeflatePassesX9 :
+ (level >= 7 ? kDeflatePassesX7 :
+ kDeflatePassesX1));
+
+ UInt32 algo =
+ (level >= 5 ? kDeflateAlgoX5 :
+ kDeflateAlgoX1);
+
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
+ }
+ else if (IsBZip2Method(oneMethodInfo.MethodName))
+ {
+ UInt32 numPasses =
+ (level >= 9 ? kBZip2NumPassesX9 :
+ (level >= 7 ? kBZip2NumPassesX7 :
+ kBZip2NumPassesX1));
+
+ UInt32 dicSize =
+ (level >= 5 ? kBZip2DicSizeX5 :
+ (level >= 3 ? kBZip2DicSizeX3 :
+ kBZip2DicSizeX1));
+
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
+ #ifdef COMPRESS_MT
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
+ #endif
+ }
+ else if (IsPpmdMethod(oneMethodInfo.MethodName))
+ {
+ UInt32 useMemSize =
+ (level >= 9 ? kPpmdMemSizeX9 :
+ (level >= 7 ? kPpmdMemSizeX7 :
+ (level >= 5 ? kPpmdMemSizeX5 :
+ kPpmdMemSizeX1)));
+
+ UInt32 order =
+ (level >= 9 ? kPpmdOrderX9 :
+ (level >= 7 ? kPpmdOrderX7 :
+ (level >= 5 ? kPpmdOrderX5 :
+ kPpmdOrderX1)));
+
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
+ }
+}
+
+static void SplitParams(const UString &srcString, UStringVector &subStrings)
+{
+ subStrings.Clear();
+ UString name;
+ int len = srcString.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L':')
+ {
+ subStrings.Add(name);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ subStrings.Add(name);
+}
+
+static void SplitParam(const UString ¶m, UString &name, UString &value)
+{
+ int eqPos = param.Find(L'=');
+ if (eqPos >= 0)
+ {
+ name = param.Left(eqPos);
+ value = param.Mid(eqPos + 1);
+ return;
+ }
+ for(int i = 0; i < param.Length(); i++)
+ {
+ wchar_t c = param[i];
+ if (c >= L'0' && c <= L'9')
+ {
+ name = param.Left(i);
+ value = param.Mid(i);
+ return;
+ }
+ }
+ name = param;
+}
+
+HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
+{
+ CProp property;
+ if (
+ name.CompareNoCase(L"D") == 0 ||
+ name.CompareNoCase(L"MEM") == 0)
+ {
+ UInt32 dicSize;
+ RINOK(ParsePropDictionaryValue(value, dicSize));
+ if (name.CompareNoCase(L"D") == 0)
+ property.Id = NCoderPropID::kDictionarySize;
+ else
+ property.Id = NCoderPropID::kUsedMemorySize;
+ property.Value = dicSize;
+ oneMethodInfo.Properties.Add(property);
+ }
+ else
+ {
+ int index = FindPropIdFromStringName(name);
+ if (index < 0)
+ return E_INVALIDARG;
+
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ property.Id = nameToPropID.PropID;
+
+ NCOM::CPropVariant propValue;
+
+ if (nameToPropID.VarType == VT_BSTR)
+ propValue = value;
+ else if (nameToPropID.VarType == VT_BOOL)
+ {
+ bool res;
+ if (!StringToBool(value, res))
+ return E_INVALIDARG;
+ propValue = res;
+ }
+ else
+ {
+ UInt32 number;
+ if (ParseStringToUInt32(value, number) == value.Length())
+ propValue = number;
+ else
+ propValue = value;
+ }
+
+ if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value))
+ return E_INVALIDARG;
+
+ oneMethodInfo.Properties.Add(property);
+ }
+ return S_OK;
+}
+
+HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
+{
+ UStringVector params;
+ SplitParams(srcString, params);
+ if (params.Size() > 0)
+ oneMethodInfo.MethodName = params[0];
+ for (int i = 1; i < params.Size(); i++)
+ {
+ const UString ¶m = params[i];
+ UString name, value;
+ SplitParam(param, name, value);
+ RINOK(SetParam(oneMethodInfo, name, value));
+ }
+ return S_OK;
+}
+
+HRESULT COutHandler::SetSolidSettings(const UString &s)
+{
+ bool res;
+ if (StringToBool(s, res))
+ {
+ if (res)
+ InitSolid();
+ else
+ _numSolidFiles = 1;
+ return S_OK;
+ }
+ UString s2 = s;
+ s2.MakeUpper();
+ for (int i = 0; i < s2.Length();)
+ {
+ const wchar_t *start = ((const wchar_t *)s2) + i;
+ const wchar_t *end;
+ UInt64 v = ConvertStringToUInt64(start, &end);
+ if (start == end)
+ {
+ if (s2[i++] != 'E')
+ return E_INVALIDARG;
+ _solidExtension = true;
+ continue;
+ }
+ i += (int)(end - start);
+ if (i == s2.Length())
+ return E_INVALIDARG;
+ wchar_t c = s2[i++];
+ switch(c)
+ {
+ case 'F':
+ if (v < 1)
+ v = 1;
+ _numSolidFiles = v;
+ break;
+ case 'B':
+ _numSolidBytes = v;
+ _numSolidBytesDefined = true;
+ break;
+ case 'K':
+ _numSolidBytes = (v << 10);
+ _numSolidBytesDefined = true;
+ break;
+ case 'M':
+ _numSolidBytes = (v << 20);
+ _numSolidBytesDefined = true;
+ break;
+ case 'G':
+ _numSolidBytes = (v << 30);
+ _numSolidBytesDefined = true;
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)
+{
+ switch(value.vt)
+ {
+ case VT_EMPTY:
+ InitSolid();
+ return S_OK;
+ case VT_BSTR:
+ return SetSolidSettings(value.bstrVal);
+ default:
+ return E_INVALIDARG;
+ }
+}
+
+void COutHandler::Init()
+{
+ _removeSfxBlock = false;
+ _compressHeaders = true;
+ _encryptHeaders = false;
+
+ WriteModified = true;
+ WriteCreated = false;
+ WriteAccessed = false;
+
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ #endif
+
+ _level = 5;
+ _autoFilter = true;
+ _volumeMode = false;
+ _crcSize = 4;
+ InitSolid();
+}
+
+void COutHandler::BeforeSetProperty()
+{
+ Init();
+ #ifdef COMPRESS_MT
+ numProcessors = NSystem::GetNumberOfProcessors();
+ #endif
+
+ mainDicSize = 0xFFFFFFFF;
+ mainDicMethodIndex = 0xFFFFFFFF;
+ minNumber = 0;
+ _crcSize = 4;
+}
+
+HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
+{
+ UString name = nameSpec;
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ if (name[0] == 'X')
+ {
+ name.Delete(0);
+ _level = 9;
+ return ParsePropValue(name, value, _level);
+ }
+
+ if (name[0] == L'S')
+ {
+ name.Delete(0);
+ if (name.IsEmpty())
+ return SetSolidSettings(value);
+ if (value.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return SetSolidSettings(name);
+ }
+
+ if (name == L"CRC")
+ {
+ _crcSize = 4;
+ name.Delete(0, 3);
+ return ParsePropValue(name, value, _crcSize);
+ }
+
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ UString realName = name.Mid(index);
+ if (index == 0)
+ {
+ if(name.Left(2).CompareNoCase(L"MT") == 0)
+ {
+ #ifdef COMPRESS_MT
+ RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ #endif
+ return S_OK;
+ }
+ if (name.CompareNoCase(L"RSFX") == 0)
+ return SetBoolProperty(_removeSfxBlock, value);
+ if (name.CompareNoCase(L"F") == 0)
+ return SetBoolProperty(_autoFilter, value);
+ if (name.CompareNoCase(L"HC") == 0)
+ return SetBoolProperty(_compressHeaders, value);
+ if (name.CompareNoCase(L"HCF") == 0)
+ {
+ bool compressHeadersFull = true;
+ RINOK(SetBoolProperty(compressHeadersFull, value));
+ if (!compressHeadersFull)
+ return E_INVALIDARG;
+ return S_OK;
+ }
+ if (name.CompareNoCase(L"HE") == 0)
+ return SetBoolProperty(_encryptHeaders, value);
+ if (name.CompareNoCase(L"TM") == 0)
+ return SetBoolProperty(WriteModified, value);
+ if (name.CompareNoCase(L"TC") == 0)
+ return SetBoolProperty(WriteCreated, value);
+ if (name.CompareNoCase(L"TA") == 0)
+ return SetBoolProperty(WriteAccessed, value);
+ if (name.CompareNoCase(L"V") == 0)
+ return SetBoolProperty(_volumeMode, value);
+ number = 0;
+ }
+ if (number > 10000)
+ return E_FAIL;
+ if (number < minNumber)
+ return E_INVALIDARG;
+ number -= minNumber;
+ for(int j = _methods.Size(); j <= (int)number; j++)
+ {
+ COneMethodInfo oneMethodInfo;
+ _methods.Add(oneMethodInfo);
+ }
+
+ COneMethodInfo &oneMethodInfo = _methods[number];
+
+ if (realName.Length() == 0)
+ {
+ if (value.vt != VT_BSTR)
+ return E_INVALIDARG;
+
+ RINOK(SetParams(oneMethodInfo, value.bstrVal));
+ }
+ else
+ {
+ CProp property;
+ if (realName.Left(1).CompareNoCase(L"D") == 0)
+ {
+ UInt32 dicSize;
+ RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
+ property.Id = NCoderPropID::kDictionarySize;
+ property.Value = dicSize;
+ oneMethodInfo.Properties.Add(property);
+ if (number <= mainDicMethodIndex)
+ mainDicSize = dicSize;
+ }
+ else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
+ {
+ UInt32 dicSize;
+ RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
+ property.Id = NCoderPropID::kUsedMemorySize;
+ property.Value = dicSize;
+ oneMethodInfo.Properties.Add(property);
+ if (number <= mainDicMethodIndex)
+ mainDicSize = dicSize;
+ }
+ else
+ {
+ int index = FindPropIdFromStringName(realName);
+ if (index < 0)
+ return E_INVALIDARG;
+
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ property.Id = nameToPropID.PropID;
+
+ if (!ConvertProperty(value, nameToPropID.VarType, property.Value))
+ return E_INVALIDARG;
+
+ oneMethodInfo.Properties.Add(property);
+ }
+ }
+ return S_OK;
+}
+
+}
Added: trunk/lzma/CPP/7zip/Archive/Common/HandlerOut.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/HandlerOut.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/HandlerOut.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,86 @@
+// HandlerOut.h
+
+#ifndef __HANDLER_OUT_H
+#define __HANDLER_OUT_H
+
+#include "../../Common/MethodProps.h"
+#include "../../Common/CreateCoder.h"
+
+namespace NArchive {
+
+struct COneMethodInfo
+{
+ CObjectVector<CProp> Properties;
+ UString MethodName;
+};
+
+class COutHandler
+{
+public:
+ HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
+
+ HRESULT SetSolidSettings(const UString &s);
+ HRESULT SetSolidSettings(const PROPVARIANT &value);
+
+ #ifdef COMPRESS_MT
+ UInt32 _numThreads;
+ #endif
+
+ UInt32 _crcSize;
+
+ CObjectVector<COneMethodInfo> _methods;
+ bool _removeSfxBlock;
+
+ UInt64 _numSolidFiles;
+ UInt64 _numSolidBytes;
+ bool _numSolidBytesDefined;
+ bool _solidExtension;
+
+ bool _compressHeaders;
+ bool _encryptHeaders;
+
+ bool WriteModified;
+ bool WriteCreated;
+ bool WriteAccessed;
+
+ bool _autoFilter;
+ UInt32 _level;
+
+ bool _volumeMode;
+
+ HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
+ HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
+
+ void SetCompressionMethod2(COneMethodInfo &oneMethodInfo
+ #ifdef COMPRESS_MT
+ , UInt32 numThreads
+ #endif
+ );
+
+ void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
+ void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
+ void InitSolid()
+ {
+ InitSolidFiles();
+ InitSolidSize();
+ _solidExtension = false;
+ _numSolidBytesDefined = false;
+ }
+
+ void Init();
+
+ COutHandler() { Init(); }
+
+ void BeforeSetProperty();
+
+ UInt32 minNumber;
+ UInt32 numProcessors;
+ UInt32 mainDicSize;
+ UInt32 mainDicMethodIndex;
+
+ DECL_EXTERNAL_CODECS_VARS
+};
+
+}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,40 @@
+// InStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "InStreamWithCRC.h"
+
+STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (size > 0 && realProcessedSize == 0)
+ _wasFinished = true;
+ _crc = CrcUpdate(_crc, data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ if (size > 0 && realProcessedSize == 0)
+ _wasFinished = true;
+ _size += realProcessedSize;
+ _crc = CrcUpdate(_crc, data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ if (seekOrigin != STREAM_SEEK_SET || offset != 0)
+ return E_FAIL;
+ _size = 0;
+ _crc = CRC_INIT_VAL;
+ return _stream->Seek(offset, seekOrigin, newPosition);
+}
Added: trunk/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,69 @@
+// InStreamWithCRC.h
+
+#ifndef __INSTREAMWITHCRC_H
+#define __INSTREAMWITHCRC_H
+
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+extern "C"
+{
+#include "../../../../C/7zCrc.h"
+}
+
+class CSequentialInStreamWithCRC:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+ UInt32 _crc;
+ bool _wasFinished;
+public:
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+ void Init()
+ {
+ _size = 0;
+ _wasFinished = false;
+ _crc = CRC_INIT_VAL;
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
+ UInt64 GetSize() const { return _size; }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+class CInStreamWithCRC:
+ public IInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+private:
+ CMyComPtr<IInStream> _stream;
+ UInt64 _size;
+ UInt32 _crc;
+ bool _wasFinished;
+public:
+ void SetStream(IInStream *stream) { _stream = stream; }
+ void Init()
+ {
+ _size = 0;
+ _wasFinished = false;
+ _crc = CRC_INIT_VAL;
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
+ UInt64 GetSize() const { return _size; }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,59 @@
+// Archive/Common/ItemNameUtils.cpp
+
+#include "StdAfx.h"
+
+#include "ItemNameUtils.h"
+
+namespace NArchive {
+namespace NItemName {
+
+static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
+static const wchar_t kDirDelimiter = L'/';
+
+UString MakeLegalName(const UString &name)
+{
+ UString zipName = name;
+ zipName.Replace(kOSDirDelimiter, kDirDelimiter);
+ return zipName;
+}
+
+UString GetOSName(const UString &name)
+{
+ UString newName = name;
+ newName.Replace(kDirDelimiter, kOSDirDelimiter);
+ return newName;
+}
+
+UString GetOSName2(const UString &name)
+{
+ if (name.IsEmpty())
+ return UString();
+ UString newName = GetOSName(name);
+ if (newName[newName.Length() - 1] == kOSDirDelimiter)
+ newName.Delete(newName.Length() - 1);
+ return newName;
+}
+
+bool HasTailSlash(const AString &name, UINT codePage)
+{
+ if (name.IsEmpty())
+ return false;
+ LPCSTR prev =
+ #ifdef _WIN32
+ CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
+ #else
+ (LPCSTR)(name) + (name.Length() - 1);
+ #endif
+ return (*prev == '/');
+}
+
+#ifndef _WIN32
+UString WinNameToOSName(const UString &name)
+{
+ UString newName = name;
+ newName.Replace(L'\\', kOSDirDelimiter);
+ return newName;
+}
+#endif
+
+}}
Added: trunk/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// Archive/Common/ItemNameUtils.h
+
+#ifndef __ARCHIVE_ITEMNAMEUTILS_H
+#define __ARCHIVE_ITEMNAMEUTILS_H
+
+#include "../../../Common/MyString.h"
+
+namespace NArchive {
+namespace NItemName {
+
+ UString MakeLegalName(const UString &name);
+ UString GetOSName(const UString &name);
+ UString GetOSName2(const UString &name);
+ bool HasTailSlash(const AString &name, UINT codePage);
+
+ #ifdef _WIN32
+ inline UString WinNameToOSName(const UString &name) { return name; }
+ #else
+ UString WinNameToOSName(const UString &name);
+ #endif
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/MultiStream.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/MultiStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,201 @@
+// MultiStream.cpp
+
+#include "StdAfx.h"
+
+#include "MultiStream.h"
+
+STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+ while(_streamIndex < Streams.Size() && size > 0)
+ {
+ CSubStreamInfo &s = Streams[_streamIndex];
+ if (_pos == s.Size)
+ {
+ _streamIndex++;
+ _pos = 0;
+ continue;
+ }
+ RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
+ UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
+ UInt32 realProcessed;
+ HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
+ data = (void *)((Byte *)data + realProcessed);
+ size -= realProcessed;
+ if(processedSize != NULL)
+ *processedSize += realProcessed;
+ _pos += realProcessed;
+ _seekPos += realProcessed;
+ RINOK(result);
+ break;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ UInt64 newPos;
+ switch(seekOrigin)
+ {
+ case STREAM_SEEK_SET:
+ newPos = offset;
+ break;
+ case STREAM_SEEK_CUR:
+ newPos = _seekPos + offset;
+ break;
+ case STREAM_SEEK_END:
+ newPos = _totalLength + offset;
+ break;
+ default:
+ return STG_E_INVALIDFUNCTION;
+ }
+ _seekPos = 0;
+ for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
+ {
+ UInt64 size = Streams[_streamIndex].Size;
+ if (newPos < _seekPos + size)
+ {
+ _pos = newPos - _seekPos;
+ _seekPos += _pos;
+ if (newPosition != 0)
+ *newPosition = newPos;
+ return S_OK;
+ }
+ _seekPos += size;
+ }
+ if (newPos == _seekPos)
+ {
+ if (newPosition != 0)
+ *newPosition = newPos;
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+
+/*
+class COutVolumeStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ int _volIndex;
+ UInt64 _volSize;
+ UInt64 _curPos;
+ CMyComPtr<ISequentialOutStream> _volumeStream;
+ COutArchive _archive;
+ CCRC _crc;
+
+public:
+ MY_UNKNOWN_IMP
+
+ CFileItem _file;
+ CUpdateOptions _options;
+ CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+ void Init(IArchiveUpdateCallback2 *volumeCallback,
+ const UString &name)
+ {
+ _file.Name = name;
+ _file.IsStartPosDefined = true;
+ _file.StartPos = 0;
+
+ VolumeCallback = volumeCallback;
+ _volIndex = 0;
+ _volSize = 0;
+ }
+
+ HRESULT Flush();
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+HRESULT COutVolumeStream::Flush()
+{
+ if (_volumeStream)
+ {
+ _file.UnPackSize = _curPos;
+ _file.FileCRC = _crc.GetDigest();
+ RINOK(WriteVolumeHeader(_archive, _file, _options));
+ _archive.Close();
+ _volumeStream.Release();
+ _file.StartPos += _file.UnPackSize;
+ }
+ return S_OK;
+}
+*/
+
+/*
+STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+ while(size > 0)
+ {
+ if (_streamIndex >= Streams.Size())
+ {
+ CSubStreamInfo subStream;
+ RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
+ RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
+ subStream.Pos = 0;
+ Streams.Add(subStream);
+ continue;
+ }
+ CSubStreamInfo &subStream = Streams[_streamIndex];
+ if (_offsetPos >= subStream.Size)
+ {
+ _offsetPos -= subStream.Size;
+ _streamIndex++;
+ continue;
+ }
+ if (_offsetPos != subStream.Pos)
+ {
+ CMyComPtr<IOutStream> outStream;
+ RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
+ RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+ subStream.Pos = _offsetPos;
+ }
+
+ UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
+ UInt32 realProcessed;
+ RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
+ data = (void *)((Byte *)data + realProcessed);
+ size -= realProcessed;
+ subStream.Pos += realProcessed;
+ _offsetPos += realProcessed;
+ _absPos += realProcessed;
+ if (_absPos > _length)
+ _length = _absPos;
+ if(processedSize != NULL)
+ *processedSize += realProcessed;
+ if (subStream.Pos == subStream.Size)
+ {
+ _streamIndex++;
+ _offsetPos = 0;
+ }
+ if (realProcessed != curSize && realProcessed == 0)
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ switch(seekOrigin)
+ {
+ case STREAM_SEEK_SET:
+ _absPos = offset;
+ break;
+ case STREAM_SEEK_CUR:
+ _absPos += offset;
+ break;
+ case STREAM_SEEK_END:
+ _absPos = _length + offset;
+ break;
+ }
+ _offsetPos = _absPos;
+ _streamIndex = 0;
+ return S_OK;
+}
+*/
Added: trunk/lzma/CPP/7zip/Archive/Common/MultiStream.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/MultiStream.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/MultiStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,76 @@
+// MultiStream.h
+
+#ifndef __MULTISTREAM_H
+#define __MULTISTREAM_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/MyVector.h"
+#include "../../Archive/IArchive.h"
+
+class CMultiStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ int _streamIndex;
+ UInt64 _pos;
+ UInt64 _seekPos;
+ UInt64 _totalLength;
+public:
+ struct CSubStreamInfo
+ {
+ CMyComPtr<IInStream> Stream;
+ UInt64 Pos;
+ UInt64 Size;
+ };
+ CObjectVector<CSubStreamInfo> Streams;
+ void Init()
+ {
+ _streamIndex = 0;
+ _pos = 0;
+ _seekPos = 0;
+ _totalLength = 0;
+ for (int i = 0; i < Streams.Size(); i++)
+ _totalLength += Streams[i].Size;
+ }
+
+ MY_UNKNOWN_IMP1(IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+};
+
+/*
+class COutMultiStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ int _streamIndex; // required stream
+ UInt64 _offsetPos; // offset from start of _streamIndex index
+ UInt64 _absPos;
+ UInt64 _length;
+
+ struct CSubStreamInfo
+ {
+ CMyComPtr<ISequentialOutStream> Stream;
+ UInt64 Size;
+ UInt64 Pos;
+ };
+ CObjectVector<CSubStreamInfo> Streams;
+public:
+ CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+ void Init()
+ {
+ _streamIndex = 0;
+ _offsetPos = 0;
+ _absPos = 0;
+ _length = 0;
+ }
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+};
+*/
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// OutStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "OutStreamWithCRC.h"
+
+STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result;
+ if(!_stream)
+ {
+ realProcessedSize = size;
+ result = S_OK;
+ }
+ else
+ result = _stream->Write(data, size, &realProcessedSize);
+ if (_calculate)
+ _crc = CrcUpdate(_crc, data, realProcessedSize);
+ _size += realProcessedSize;
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
Added: trunk/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,38 @@
+// OutStreamWithCRC.h
+
+#ifndef __OUTSTREAMWITHCRC_H
+#define __OUTSTREAMWITHCRC_H
+
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+extern "C"
+{
+#include "../../../../C/7zCrc.h"
+}
+
+class COutStreamWithCRC:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+ UInt32 _crc;
+ bool _calculate;
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void ReleaseStream() { _stream.Release(); }
+ void Init(bool calculate = true)
+ {
+ _size = 0;
+ _calculate = calculate;
+ _crc = CRC_INIT_VAL;
+ }
+ void InitCRC() { _crc = CRC_INIT_VAL; }
+ UInt64 GetSize() const { return _size; }
+ UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/Common/ParseProperties.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/ParseProperties.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/ParseProperties.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,174 @@
+// ParseProperties.cpp
+
+#include "StdAfx.h"
+
+#include "ParseProperties.h"
+
+#include "Common/StringToInt.h"
+#include "Common/MyCom.h"
+
+HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+ if (prop.vt == VT_UI4)
+ {
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
+ resValue = prop.ulVal;
+ }
+ else if (prop.vt == VT_EMPTY)
+ {
+ if(!name.IsEmpty())
+ {
+ const wchar_t *start = name;
+ const wchar_t *end;
+ UInt64 v = ConvertStringToUInt64(start, &end);
+ if (end - start != name.Length())
+ return E_INVALIDARG;
+ resValue = (UInt32)v;
+ }
+ }
+ else
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+static const int kLogarithmicSizeLimit = 32;
+static const wchar_t kByteSymbol = L'B';
+static const wchar_t kKiloByteSymbol = L'K';
+static const wchar_t kMegaByteSymbol = L'M';
+
+HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
+{
+ UString srcString = srcStringSpec;
+ srcString.MakeUpper();
+
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ UInt64 number = ConvertStringToUInt64(start, &end);
+ int numDigits = (int)(end - start);
+ if (numDigits == 0 || srcString.Length() > numDigits + 1)
+ return E_INVALIDARG;
+ if (srcString.Length() == numDigits)
+ {
+ if (number >= kLogarithmicSizeLimit)
+ return E_INVALIDARG;
+ dicSize = (UInt32)1 << (int)number;
+ return S_OK;
+ }
+ switch (srcString[numDigits])
+ {
+ case kByteSymbol:
+ if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
+ return E_INVALIDARG;
+ dicSize = (UInt32)number;
+ break;
+ case kKiloByteSymbol:
+ if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
+ return E_INVALIDARG;
+ dicSize = (UInt32)(number << 10);
+ break;
+ case kMegaByteSymbol:
+ if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
+ return E_INVALIDARG;
+ dicSize = (UInt32)(number << 20);
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+ if (name.IsEmpty())
+ {
+ if (prop.vt == VT_UI4)
+ {
+ UInt32 logDicSize = prop.ulVal;
+ if (logDicSize >= 32)
+ return E_INVALIDARG;
+ resValue = (UInt32)1 << logDicSize;
+ return S_OK;
+ }
+ if (prop.vt == VT_BSTR)
+ return ParsePropDictionaryValue(prop.bstrVal, resValue);
+ return E_INVALIDARG;
+ }
+ return ParsePropDictionaryValue(name, resValue);
+}
+
+bool StringToBool(const UString &s, bool &res)
+{
+ if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0)
+ {
+ res = true;
+ return true;
+ }
+ if (s.CompareNoCase(L"OFF") == 0)
+ {
+ res = false;
+ return true;
+ }
+ return false;
+}
+
+HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
+{
+ switch(value.vt)
+ {
+ case VT_EMPTY:
+ dest = true;
+ return S_OK;
+ /*
+ case VT_UI4:
+ dest = (value.ulVal != 0);
+ break;
+ */
+ case VT_BSTR:
+ return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG;
+ }
+ return E_INVALIDARG;
+}
+
+int ParseStringToUInt32(const UString &srcString, UInt32 &number)
+{
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ UInt64 number64 = ConvertStringToUInt64(start, &end);
+ if (number64 > 0xFFFFFFFF)
+ {
+ number = 0;
+ return 0;
+ }
+ number = (UInt32)number64;
+ return (int)(end - start);
+}
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
+{
+ if (name.IsEmpty())
+ {
+ switch(prop.vt)
+ {
+ case VT_UI4:
+ numThreads = prop.ulVal;
+ break;
+ default:
+ {
+ bool val;
+ RINOK(SetBoolProperty(val, prop));
+ numThreads = (val ? defaultNumThreads : 1);
+ break;
+ }
+ }
+ }
+ else
+ {
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ if (index != name.Length())
+ return E_INVALIDARG;
+ numThreads = number;
+ }
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/Archive/Common/ParseProperties.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/Common/ParseProperties.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/Common/ParseProperties.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,18 @@
+// ParseProperties.h
+
+#ifndef __PARSEPROPERTIES_H
+#define __PARSEPROPERTIES_H
+
+#include "Common/MyString.h"
+#include "Common/Types.h"
+
+HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
+HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
+HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
+
+bool StringToBool(const UString &s, bool &res);
+HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
+int ParseStringToUInt32(const UString &srcString, UInt32 &number);
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
+
+#endif
Added: trunk/lzma/CPP/7zip/Archive/DllExports2.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Archive/DllExports2.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/DllExports2.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,82 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyInitGuid.h"
+#include "../../Common/ComTry.h"
+#include "../../Common/Types.h"
+#include "../../Windows/PropVariant.h"
+#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+extern "C"
+{
+#include "../../../C/Alloc.h"
+}
+#endif
+
+#include "IArchive.h"
+#include "../ICoder.h"
+#include "../IPassword.h"
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+#ifdef _WIN32
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+#endif
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ #ifdef _WIN32
+ g_IsNT = IsItWindowsNT();
+ #endif
+ #endif
+ }
+ return TRUE;
+}
+
+DEFINE_GUID(CLSID_CArchiveHandler,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
+
+static const UInt16 kDecodeId = 0x2790;
+
+DEFINE_GUID(CLSID_CCodec,
+0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
+STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);
+
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
+{
+ // COM_TRY_BEGIN
+ *outObject = 0;
+ if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter)
+ {
+ return CreateCoder(clsid, iid, outObject);
+ }
+ else
+ {
+ return CreateArchiver(clsid, iid, outObject);
+ }
+ // COM_TRY_END
+}
+
+STDAPI SetLargePageMode()
+{
+ #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+ SetLargePageSize();
+ #endif
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/Archive/IArchive.h
===================================================================
--- trunk/lzma/CPP/7zip/Archive/IArchive.h (rev 0)
+++ trunk/lzma/CPP/7zip/Archive/IArchive.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,207 @@
+// IArchive.h
+
+#ifndef __IARCHIVE_H
+#define __IARCHIVE_H
+
+#include "../IStream.h"
+#include "../IProgress.h"
+#include "../PropID.h"
+
+#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
+#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
+
+namespace NFileTimeType
+{
+ enum EEnum
+ {
+ kWindows,
+ kUnix,
+ kDOS
+ };
+}
+
+namespace NArchive
+{
+ enum
+ {
+ kName = 0,
+ kClassID,
+ kExtension,
+ kAddExtension,
+ kUpdate,
+ kKeepName,
+ kStartSignature,
+ kFinishSignature,
+ kAssociate
+ };
+
+ namespace NExtract
+ {
+ namespace NAskMode
+ {
+ enum
+ {
+ kExtract = 0,
+ kTest,
+ kSkip
+ };
+ }
+ namespace NOperationResult
+ {
+ enum
+ {
+ kOK = 0,
+ kUnSupportedMethod,
+ kDataError,
+ kCRCError
+ };
+ }
+ }
+ namespace NUpdate
+ {
+ namespace NOperationResult
+ {
+ enum
+ {
+ kOK = 0,
+ kError
+ };
+ }
+ }
+}
+
+ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
+{
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
+{
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,
+ Int32 askExtractMode) PURE;
+ // GetStream OUT: S_OK - OK, S_FALSE - skeep this file
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode) PURE;
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
+{
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
+{
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
+{
+ STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
+};
+
+
+/*
+IInArchive::Extract:
+ indices must be sorted
+ numItems = 0xFFFFFFFF means "all files"
+ testMode != 0 means "test files without writing to outStream"
+*/
+
+#define INTERFACE_IInArchive(x) \
+ STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \
+ STDMETHOD(Close)() x; \
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \
+ STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x;
+
+ARCHIVE_INTERFACE(IInArchive, 0x60)
+{
+ INTERFACE_IInArchive(PURE)
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
+{
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index,
+ Int32 *newData, // 1 - new data, 0 - old data
+ Int32 *newProperties, // 1 - new properties, 0 - old properties
+ UInt32 *indexInArchive // -1 if there is no in archive, or if doesn't matter
+ ) PURE;
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) PURE;
+ STDMETHOD(SetOperationResult)(Int32 operationResult) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
+{
+ STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE;
+ STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE;
+};
+
+
+#define INTERFACE_IOutArchive(x) \
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
+ STDMETHOD(GetFileTimeType)(UInt32 *type) x;
+
+ARCHIVE_INTERFACE(IOutArchive, 0xA0)
+{
+ INTERFACE_IOutArchive(PURE)
+};
+
+
+ARCHIVE_INTERFACE(ISetProperties, 0x03)
+{
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
+};
+
+
+#define IMP_IInArchive_GetProp(k) \
+ (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
+ { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
+ const STATPROPSTG &srcItem = k[index]; \
+ *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \
+
+#define IMP_IInArchive_GetProp_WITH_NAME(k) \
+ (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
+ { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
+ const STATPROPSTG &srcItem = k[index]; \
+ *propID = srcItem.propid; *varType = srcItem.vt; \
+ if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \
+
+#define IMP_IInArchive_Props \
+ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
+ { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
+
+#define IMP_IInArchive_Props_WITH_NAME \
+ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
+ { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
+
+
+#define IMP_IInArchive_ArcProps \
+ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
+ { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
+ STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
+
+#define IMP_IInArchive_ArcProps_NO \
+ STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
+ { *numProperties = 0; return S_OK; } \
+ STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
+ { return E_NOTIMPL; } \
+ STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
+ { value->vt = VT_EMPTY; return S_OK; }
+
+#endif
Added: trunk/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1453 @@
+# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Alone - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Alone.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /D "_NO_CRYPTO" /D "BREAK_HANDLER" /D "BENCH_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /D "_NO_CRYPTO" /D "BREAK_HANDLER" /D "BENCH_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /D "_NO_CRYPTO" /D "BREAK_HANDLER" /D "BENCH_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# SUBTRACT BASE LINK32 /pdb:none
+# 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
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /D "_NO_CRYPTO" /D "BREAK_HANDLER" /D "BENCH_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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
+
+!ENDIF
+
+# Begin Target
+
+# Name "Alone - Win32 Release"
+# Name "Alone - Win32 Debug"
+# Name "Alone - Win32 ReleaseU"
+# Name "Alone - Win32 DebugU"
+# Begin Group "Console"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ArError.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\CompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\MainAr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.h
+# End Source File
+# End Group
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\AutoPtr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Buffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ComTry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\DynamicBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyException.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyGuidDef.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyInitGuid.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Types.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Device.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Handle.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Time.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\CreateCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\CreateCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodId.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodId.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodProps.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodProps.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\RegisterArc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\RegisterCodec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\Coder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.h
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyRegister.cpp
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMARegister.cpp
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "LZMA_Alone"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_Alone\LzmaBench.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_Alone\LzmaBench.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_Alone\LzmaBenchCon.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_Alone\LzmaBenchCon.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Archive"
+
+# PROP Default_Filter ""
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\HandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\HandlerOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "split"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Split\SplitHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Split\SplitHandler.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveCommandLine.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\EnumDirItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\EnumDirItems.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Property.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SetProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SetProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\TempFiles.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\TempFiles.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Update.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateAction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateAction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdatePair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdatePair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateProduce.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateProduce.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\WorkDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\WorkDir.h
+# End Source File
+# End Group
+# Begin Group "7-zip"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IMyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IPassword.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\PropID.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Group "C Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchARM.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchARM.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchARMThumb.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchARMThumb.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchIA64.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchIA64.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchPPC.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchPPC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchSPARC.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchSPARC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Types.h
+# End Source File
+# End Group
+# End Target
+# End Project
Added: trunk/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsw
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsw (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsw 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Alone"=.\Alone.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
Added: trunk/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Bundles/Alone7z/makefile
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Alone7z/makefile (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Alone7z/makefile 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,236 @@
+PROG = 7za.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib Advapi32.lib
+
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -D_NO_CRYPTO \
+ -DWIN_LONG_PATH \
+ -DCOMPRESS_MT \
+ -DCOMPRESS_MF_MT \
+ -D_NO_CRYPTO \
+ -DBREAK_HANDLER \
+ -DBENCH_MT \
+
+
+CONSOLE_OBJS = \
+ $O\ConsoleClose.obj \
+ $O\ExtractCallbackConsole.obj \
+ $O\List.obj \
+ $O\Main.obj \
+ $O\MainAr.obj \
+ $O\OpenCallbackConsole.obj \
+ $O\PercentPrinter.obj \
+ $O\UpdateCallbackConsole.obj \
+ $O\UserInputUtils.obj \
+
+COMMON_OBJS = \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\ListFileUtils.obj \
+ $O\NewHandler.obj \
+ $O\StdInStream.obj \
+ $O\StdOutStream.obj \
+ $O\MyString.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\UTFConvert.obj \
+ $O\MyVector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\MemoryLock.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Synchronization.obj \
+ $O\System.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\CreateCoder.obj \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\FilterCoder.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\MethodId.obj \
+ $O\MethodProps.obj \
+ $O\OffsetStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+ $O\VirtThread.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveCommandLine.obj \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\DefaultName.obj \
+ $O\EnumDirItems.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\LoadCodecs.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+ $O\SetProperties.obj \
+ $O\SortUtils.obj \
+ $O\TempFiles.obj \
+ $O\Update.obj \
+ $O\UpdateAction.obj \
+ $O\UpdateCallback.obj \
+ $O\UpdatePair.obj \
+ $O\UpdateProduce.obj \
+ $O\WorkDir.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\DummyOutStream.obj \
+ $O\HandlerOut.obj \
+ $O\InStreamWithCRC.obj \
+ $O\ItemNameUtils.obj \
+ $O\MultiStream.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zEncode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderInStream.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHandlerOut.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zOut.obj \
+ $O\7zProperties.obj \
+ $O\7zRegister.obj \
+ $O\7zSpecStream.obj \
+ $O\7zUpdate.obj \
+
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+ $O\ARM.obj \
+ $O\ARMThumb.obj \
+ $O\IA64.obj \
+ $O\PPC.obj \
+ $O\SPARC.obj \
+ $O\BranchRegister.obj \
+ $O\BCJRegister.obj \
+ $O\BCJ2Register.obj \
+
+SWAP_OPT_OBJS = \
+ $O\ByteSwap.obj \
+ $O\ByteSwapRegister.obj \
+
+COPY_OBJS = \
+ $O\CopyCoder.obj \
+ $O\CopyRegister.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+ $O\LZMARegister.obj \
+
+LZMA_BENCH_OBJS = \
+ $O\LzmaBench.obj \
+ $O\LzmaBenchCon.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\7zCrc.obj \
+ $O\Sort.obj \
+ $O\Threads.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+ $O\MatchFinderMt.obj \
+
+C_BRANCH_OBJS = \
+ $O\BranchARM.obj \
+ $O\BranchARMThumb.obj \
+ $O\BranchIA64.obj \
+ $O\BranchPPC.obj \
+ $O\BranchSPARC.obj \
+ $O\BranchX86.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(SWAP_OPT_OBJS) \
+ $(COPY_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(LZMA_BENCH_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $(C_BRANCH_OBJS) \
+ $O\RangeCoderBit.obj \
+ $(CRC_OBJS) \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
+ $(COMPL)
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(SWAP_OPT_OBJS): ../../Compress/ByteSwap/$(*B).cpp
+ $(COMPL_O2)
+$(COPY_OBJS): ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+$(LZMA_BENCH_OBJS): ../../Compress/LZMA_Alone/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp
+ $(COMPL)
+
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
+$(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c
+ $(COMPL_O2)
Added: trunk/lzma/CPP/7zip/Bundles/Alone7z/resource.rc
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Alone7z/resource.rc (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Alone7z/resource.rc 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za")
Added: trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,165 @@
+PROG = 7zxr.dll
+DEF_FILE = ../../Archive/Archive2.def
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXTRACT_ONLY \
+ -DCOMPRESS_MT \
+ -D_NO_CRYPTO
+
+COMMON_OBJS = \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\MyString.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\MyVector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\PropVariant.obj \
+ $O\Synchronization.obj \
+ $O\System.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\CreateCoder.obj \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\FilterCoder.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\MethodId.obj \
+ $O\MethodProps.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+ $O\VirtThread.obj \
+
+AR_OBJS = \
+ $O\ArchiveExports.obj \
+ $O\DllExports2.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\HandlerOut.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zProperties.obj \
+ $O\7zRegister.obj \
+
+
+COMPRESS_OBJS = \
+ $O\CodecExports.obj \
+
+SWAP_OPT_OBJS = \
+ $O\ByteSwap.obj \
+ $O\ByteSwapRegister.obj \
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+ $O\ARM.obj \
+ $O\ARMThumb.obj \
+ $O\IA64.obj \
+ $O\PPC.obj \
+ $O\SPARC.obj \
+ $O\BranchRegister.obj \
+ $O\BCJRegister.obj \
+ $O\BCJ2Register.obj \
+
+COPY_OBJS = \
+ $O\CopyCoder.obj \
+ $O\CopyRegister.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMARegister.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\7zCrc.obj \
+ $O\Threads.obj \
+
+C_BRANCH_OBJS = \
+ $O\BranchARM.obj \
+ $O\BranchARMThumb.obj \
+ $O\BranchIA64.obj \
+ $O\BranchPPC.obj \
+ $O\BranchSPARC.obj \
+ $O\BranchX86.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(COMPRESS_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(SWAP_OPT_OBJS) \
+ $(COPY_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(C_OBJS) \
+ $(C_BRANCH_OBJS) \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(AR_OBJS): ../../Archive/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(SWAP_OPT_OBJS): ../../Compress/ByteSwap/$(*B).cpp
+ $(COMPL_O2)
+$(COPY_OBJS): ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c
+ $(COMPL_O2)
Added: trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/resource.rc
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/resource.rc (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Format7zExtractR/resource.rc 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Standalone Extracting Plugin", "7zxr")
+
+101 ICON "../../Archive/7z/7z.ico"
Added: trunk/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Bundles/Format7zR/makefile
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Format7zR/makefile (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Format7zR/makefile 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,188 @@
+PROG = 7zra.dll
+DEF_FILE = ../../Archive/Archive2.def
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DCOMPRESS_MT \
+ -DCOMPRESS_MF_MT \
+ -D_NO_CRYPTO
+
+COMMON_OBJS = \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\MyString.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\MyVector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\PropVariant.obj \
+ $O\Synchronization.obj \
+ $O\System.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\CreateCoder.obj \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\FilterCoder.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\MethodId.obj \
+ $O\MethodProps.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+ $O\VirtThread.obj \
+
+AR_OBJS = \
+ $O\ArchiveExports.obj \
+ $O\DllExports2.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\HandlerOut.obj \
+ $O\InStreamWithCRC.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zEncode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderInStream.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHandlerOut.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zOut.obj \
+ $O\7zProperties.obj \
+ $O\7zSpecStream.obj \
+ $O\7zUpdate.obj \
+ $O\7zRegister.obj \
+
+
+COMPRESS_OBJS = \
+ $O\CodecExports.obj \
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+ $O\ARM.obj \
+ $O\ARMThumb.obj \
+ $O\IA64.obj \
+ $O\PPC.obj \
+ $O\SPARC.obj \
+ $O\BranchRegister.obj \
+ $O\BCJRegister.obj \
+ $O\BCJ2Register.obj \
+
+SWAP_OPT_OBJS = \
+ $O\ByteSwap.obj \
+ $O\ByteSwapRegister.obj \
+
+COPY_OBJS = \
+ $O\CopyCoder.obj \
+ $O\CopyRegister.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+ $O\LZMARegister.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\7zCrc.obj \
+ $O\Sort.obj \
+ $O\Threads.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+ $O\MatchFinderMt.obj \
+
+C_BRANCH_OBJS = \
+ $O\BranchARM.obj \
+ $O\BranchARMThumb.obj \
+ $O\BranchIA64.obj \
+ $O\BranchPPC.obj \
+ $O\BranchSPARC.obj \
+ $O\BranchX86.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BZIP2_OBJS) \
+ $(BZIP2_OPT_OBJS) \
+ $(COMPRESS_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(SWAP_OPT_OBJS) \
+ $(COPY_OBJS) \
+ $(DEFLATE_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(PPMD_OPT_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $(C_BRANCH_OBJS) \
+ $O\RangeCoderBit.obj \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(AR_OBJS): ../../Archive/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(SWAP_OPT_OBJS): ../../Compress/ByteSwap/$(*B).cpp
+ $(COMPL_O2)
+$(COPY_OBJS): ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp
+ $(COMPL)
+
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
+$(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c
+ $(COMPL_O2)
Added: trunk/lzma/CPP/7zip/Bundles/Format7zR/resource.rc
===================================================================
--- trunk/lzma/CPP/7zip/Bundles/Format7zR/resource.rc (rev 0)
+++ trunk/lzma/CPP/7zip/Bundles/Format7zR/resource.rc 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Standalone Plugin", "7zr")
+
+101 ICON "../../Archive/7z/7z.ico"
Added: trunk/lzma/CPP/7zip/Common/CreateCoder.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/CreateCoder.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/CreateCoder.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,292 @@
+// CreateCoder.cpp
+
+#include "StdAfx.h"
+
+#include "CreateCoder.h"
+
+#include "../../Windows/PropVariant.h"
+#include "../../Windows/Defs.h"
+#include "FilterCoder.h"
+#include "RegisterCodec.h"
+
+static const unsigned int kNumCodecsMax = 64;
+unsigned int g_NumCodecs = 0;
+const CCodecInfo *g_Codecs[kNumCodecsMax];
+void RegisterCodec(const CCodecInfo *codecInfo)
+{
+ if (g_NumCodecs < kNumCodecsMax)
+ g_Codecs[g_NumCodecs++] = codecInfo;
+}
+
+#ifdef EXTERNAL_CODECS
+static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)
+{
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(codecsInfo->GetProperty(index, propID, &prop));
+ if (prop.vt == VT_EMPTY)
+ res = 1;
+ else if (prop.vt == VT_UI4)
+ res = prop.ulVal;
+ else
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res)
+{
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(codecsInfo->GetProperty(index, propID, &prop));
+ if (prop.vt == VT_EMPTY)
+ res = true;
+ else if (prop.vt == VT_BOOL)
+ res = VARIANT_BOOLToBool(prop.boolVal);
+ else
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
+{
+ UInt32 num;
+ RINOK(codecsInfo->GetNumberOfMethods(&num));
+ for (UInt32 i = 0; i < num; i++)
+ {
+ CCodecInfoEx info;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
+ // if (prop.vt != VT_BSTR)
+ // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
+ // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
+ if (prop.vt != VT_UI8)
+ {
+ continue; // old Interface
+ // return E_INVALIDARG;
+ }
+ info.Id = prop.uhVal.QuadPart;
+ prop.Clear();
+
+ RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ info.Name = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;;
+
+ RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
+ RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
+ RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
+ RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
+
+ externalCodecs.Add(info);
+ }
+ return S_OK;
+}
+
+#endif
+
+bool FindMethod(
+ #ifdef EXTERNAL_CODECS
+ ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
+ #endif
+ const UString &name,
+ CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
+{
+ UInt32 i;
+ for (i = 0; i < g_NumCodecs; i++)
+ {
+ const CCodecInfo &codec = *g_Codecs[i];
+ if (name.CompareNoCase(codec.Name) == 0)
+ {
+ methodId = codec.Id;
+ numInStreams = codec.NumInStreams;
+ numOutStreams = 1;
+ return true;
+ }
+ }
+ #ifdef EXTERNAL_CODECS
+ if (externalCodecs)
+ for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ {
+ const CCodecInfoEx &codec = (*externalCodecs)[i];
+ if (codec.Name.CompareNoCase(name) == 0)
+ {
+ methodId = codec.Id;
+ numInStreams = codec.NumInStreams;
+ numOutStreams = codec.NumOutStreams;
+ return true;
+ }
+ }
+ #endif
+ return false;
+}
+
+bool FindMethod(
+ #ifdef EXTERNAL_CODECS
+ ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
+ #endif
+ CMethodId methodId, UString &name)
+{
+ UInt32 i;
+ for (i = 0; i < g_NumCodecs; i++)
+ {
+ const CCodecInfo &codec = *g_Codecs[i];
+ if (methodId == codec.Id)
+ {
+ name = codec.Name;
+ return true;
+ }
+ }
+ #ifdef EXTERNAL_CODECS
+ if (externalCodecs)
+ for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ {
+ const CCodecInfoEx &codec = (*externalCodecs)[i];
+ if (methodId == codec.Id)
+ {
+ name = codec.Name;
+ return true;
+ }
+ }
+ #endif
+ return false;
+}
+
+HRESULT CreateCoder(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressFilter> &filter,
+ CMyComPtr<ICompressCoder> &coder,
+ CMyComPtr<ICompressCoder2> &coder2,
+ bool encode, bool onlyCoder)
+{
+ bool created = false;
+ UInt32 i;
+ for (i = 0; i < g_NumCodecs; i++)
+ {
+ const CCodecInfo &codec = *g_Codecs[i];
+ if (codec.Id == methodId)
+ {
+ if (encode)
+ {
+ if (codec.CreateEncoder)
+ {
+ void *p = codec.CreateEncoder();
+ if (codec.IsFilter) filter = (ICompressFilter *)p;
+ else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
+ else coder2 = (ICompressCoder2 *)p;
+ created = (p != 0);
+ break;
+ }
+ }
+ else
+ if (codec.CreateDecoder)
+ {
+ void *p = codec.CreateDecoder();
+ if (codec.IsFilter) filter = (ICompressFilter *)p;
+ else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
+ else coder2 = (ICompressCoder2 *)p;
+ created = (p != 0);
+ break;
+ }
+ }
+ }
+
+ #ifdef EXTERNAL_CODECS
+ if (!created && externalCodecs)
+ for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+ {
+ const CCodecInfoEx &codec = (*externalCodecs)[i];
+ if (codec.Id == methodId)
+ {
+ if (encode)
+ {
+ if (codec.EncoderIsAssigned)
+ {
+ if (codec.IsSimpleCodec())
+ {
+ HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
+ if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
+ return result;
+ if (!coder)
+ {
+ RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
+ }
+ }
+ else
+ {
+ RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
+ }
+ break;
+ }
+ }
+ else
+ if (codec.DecoderIsAssigned)
+ {
+ if (codec.IsSimpleCodec())
+ {
+ HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
+ if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
+ return result;
+ if (!coder)
+ {
+ RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
+ }
+ }
+ else
+ {
+ RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
+ }
+ break;
+ }
+ }
+ }
+ #endif
+
+ if (onlyCoder && filter)
+ {
+ CFilterCoder *coderSpec = new CFilterCoder;
+ coder = coderSpec;
+ coderSpec->Filter = filter;
+ }
+ return S_OK;
+}
+
+HRESULT CreateCoder(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressCoder> &coder,
+ CMyComPtr<ICompressCoder2> &coder2,
+ bool encode)
+{
+ CMyComPtr<ICompressFilter> filter;
+ return CreateCoder(
+ EXTERNAL_CODECS_LOC_VARS
+ methodId,
+ filter, coder, coder2, encode, true);
+}
+
+HRESULT CreateCoder(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressCoder> &coder, bool encode)
+{
+ CMyComPtr<ICompressFilter> filter;
+ CMyComPtr<ICompressCoder2> coder2;
+ return CreateCoder(
+ EXTERNAL_CODECS_LOC_VARS
+ methodId,
+ coder, coder2, encode);
+}
+
+HRESULT CreateFilter(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressFilter> &filter,
+ bool encode)
+{
+ CMyComPtr<ICompressCoder> coder;
+ CMyComPtr<ICompressCoder2> coder2;
+ return CreateCoder(
+ EXTERNAL_CODECS_LOC_VARS
+ methodId,
+ filter, coder, coder2, encode, false);
+}
Added: trunk/lzma/CPP/7zip/Common/CreateCoder.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/CreateCoder.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/CreateCoder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,98 @@
+// CreateCoder.h
+
+#ifndef __CREATECODER_H
+#define __CREATECODER_H
+
+#include "Common/MyCom.h"
+#include "Common/MyString.h"
+#include "../ICoder.h"
+
+#include "MethodId.h"
+
+#ifdef EXTERNAL_CODECS
+
+struct CCodecInfoEx
+{
+ UString Name;
+ CMethodId Id;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ bool EncoderIsAssigned;
+ bool DecoderIsAssigned;
+ bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; }
+ CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {}
+};
+
+HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs);
+
+#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo,
+#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo)
+#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo);
+#define IMPL_ISetCompressCodecsInfo2(x) \
+STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \
+ COM_TRY_BEGIN _codecsInfo = compressCodecsInfo; return LoadExternalCodecs(_codecsInfo, _externalCodecs); COM_TRY_END }
+#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler)
+
+#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs
+
+#define DECL_EXTERNAL_CODECS_VARS CMyComPtr<ICompressCodecsInfo> _codecsInfo; CObjectVector<CCodecInfoEx> _externalCodecs;
+#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,
+
+#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector<CCodecInfoEx> *externalCodecs
+#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs
+
+#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2,
+#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2,
+
+#else
+
+#define PUBLIC_ISetCompressCodecsInfo
+#define QUERY_ENTRY_ISetCompressCodecsInfo
+#define DECL_ISetCompressCodecsInfo
+#define IMPL_ISetCompressCodecsInfo
+#define EXTERNAL_CODECS_VARS2
+#define DECL_EXTERNAL_CODECS_VARS
+#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2
+#define DECL_EXTERNAL_CODECS_LOC_VARS2
+#define EXTERNAL_CODECS_LOC_VARS2
+#define DECL_EXTERNAL_CODECS_LOC_VARS
+#define EXTERNAL_CODECS_LOC_VARS
+
+#endif
+
+bool FindMethod(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams);
+
+bool FindMethod(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, UString &name);
+
+
+HRESULT CreateCoder(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressFilter> &filter,
+ CMyComPtr<ICompressCoder> &coder,
+ CMyComPtr<ICompressCoder2> &coder2,
+ bool encode, bool onlyCoder);
+
+HRESULT CreateCoder(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressCoder> &coder,
+ CMyComPtr<ICompressCoder2> &coder2,
+ bool encode);
+
+HRESULT CreateCoder(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressCoder> &coder, bool encode);
+
+HRESULT CreateFilter(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId,
+ CMyComPtr<ICompressFilter> &filter,
+ bool encode);
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/FilePathAutoRename.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/FilePathAutoRename.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/FilePathAutoRename.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,57 @@
+// FilePathAutoRename.cpp
+
+#include "StdAfx.h"
+#include "FilePathAutoRename.h"
+
+#include "Common/Defs.h"
+#include "Common/IntToString.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+
+using namespace NWindows;
+
+static bool MakeAutoName(const UString &name,
+ const UString &extension, int value, UString &path)
+{
+ wchar_t number[32];
+ ConvertUInt64ToString(value, number);
+ path = name;
+ path += number;
+ path += extension;
+ return NFile::NFind::DoesFileExist(path);
+}
+
+bool AutoRenamePath(UString &fullProcessedPath)
+{
+ UString path;
+ int dotPos = fullProcessedPath.ReverseFind(L'.');
+
+ int slashPos = fullProcessedPath.ReverseFind(L'/');
+ #ifdef _WIN32
+ int slash1Pos = fullProcessedPath.ReverseFind(L'\\');
+ slashPos = MyMax(slashPos, slash1Pos);
+ #endif
+
+ UString name, extension;
+ if (dotPos > slashPos && dotPos > 0)
+ {
+ name = fullProcessedPath.Left(dotPos);
+ extension = fullProcessedPath.Mid(dotPos);
+ }
+ else
+ name = fullProcessedPath;
+ name += L'_';
+ int indexLeft = 1, indexRight = (1 << 30);
+ while (indexLeft != indexRight)
+ {
+ int indexMid = (indexLeft + indexRight) / 2;
+ if (MakeAutoName(name, extension, indexMid, path))
+ indexLeft = indexMid + 1;
+ else
+ indexRight = indexMid;
+ }
+ if (MakeAutoName(name, extension, indexRight, fullProcessedPath))
+ return false;
+ return true;
+}
Added: trunk/lzma/CPP/7zip/Common/FilePathAutoRename.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/FilePathAutoRename.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/FilePathAutoRename.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// Util/FilePathAutoRename.h
+
+#ifndef __FILEPATHAUTORENAME_H
+#define __FILEPATHAUTORENAME_H
+
+#include "Common/MyString.h"
+
+bool AutoRenamePath(UString &fullProcessedPath);
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/FileStreams.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/FileStreams.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/FileStreams.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,261 @@
+// FileStreams.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#include "FileStreams.h"
+
+static inline HRESULT ConvertBoolToHRESULT(bool result)
+{
+ #ifdef _WIN32
+ if (result)
+ return S_OK;
+ DWORD lastError = ::GetLastError();
+ if (lastError == 0)
+ return E_FAIL;
+ return lastError;
+ #else
+ return result ? S_OK: E_FAIL;
+ #endif
+}
+
+bool CInFileStream::Open(LPCTSTR fileName)
+{
+ return File.Open(fileName);
+}
+
+#ifdef USE_WIN_FILE
+#ifndef _UNICODE
+bool CInFileStream::Open(LPCWSTR fileName)
+{
+ return File.Open(fileName);
+}
+#endif
+#endif
+
+bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)
+{
+ return File.OpenShared(fileName, shareForWrite);
+}
+
+#ifdef USE_WIN_FILE
+#ifndef _UNICODE
+bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
+{
+ return File.OpenShared(fileName, shareForWrite);
+}
+#endif
+#endif
+
+STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef USE_WIN_FILE
+
+ UInt32 realProcessedSize;
+ bool result = File.ReadPart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Read(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
+ data, size, (DWORD *)&realProcessedSize, NULL);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
+ return S_OK;
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res;
+ do
+ {
+ res = read(0, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#endif
+
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+
+ #ifdef USE_WIN_FILE
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
+{
+ return ConvertBoolToHRESULT(File.GetLength(*size));
+}
+
+
+//////////////////////////
+// COutFileStream
+
+HRESULT COutFileStream::Close()
+{
+ return ConvertBoolToHRESULT(File.Close());
+}
+
+STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef USE_WIN_FILE
+
+ UInt32 realProcessedSize;
+ bool result = File.WritePart(data, size, realProcessedSize);
+ ProcessedSize += realProcessedSize;
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Write(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ ProcessedSize += res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ #ifdef USE_WIN_FILE
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
+{
+ #ifdef USE_WIN_FILE
+ UInt64 currentPos;
+ if(!File.Seek(0, FILE_CURRENT, currentPos))
+ return E_FAIL;
+ bool result = File.SetLength(newSize);
+ UInt64 currentPos2;
+ result = result && File.Seek(currentPos, currentPos2);
+ return result ? S_OK : E_FAIL;
+ #else
+ return E_FAIL;
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = TRUE;
+ if (size > 0)
+ {
+ // Seems that Windows doesn't like big amounts writing to stdout.
+ // So we limit portions by 32KB.
+ UInt32 sizeTemp = (1 << 15);
+ if (sizeTemp > size)
+ sizeTemp = size;
+ res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
+ data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
+ size -= realProcessedSize;
+ data = (const void *)((const Byte *)data + realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize += realProcessedSize;
+ }
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ ssize_t res;
+ do
+ {
+ res = write(1, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ return S_OK;
+ #endif
+}
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/FileStreams.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/FileStreams.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/FileStreams.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,143 @@
+// FileStreams.h
+
+#ifndef __FILESTREAMS_H
+#define __FILESTREAMS_H
+
+#ifdef _WIN32
+#define USE_WIN_FILE
+#endif
+
+#ifdef USE_WIN_FILE
+#include "../../Windows/FileIO.h"
+#else
+#include "../../Common/C_FileIO.h"
+#endif
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+class CInFileStream:
+ public IInStream,
+ public IStreamGetSize,
+ public CMyUnknownImp
+{
+public:
+ #ifdef USE_WIN_FILE
+ NWindows::NFile::NIO::CInFile File;
+ #else
+ NC::NFile::NIO::CInFile File;
+ #endif
+ CInFileStream() {}
+ virtual ~CInFileStream() {}
+
+ bool Open(LPCTSTR fileName);
+ #ifdef USE_WIN_FILE
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName);
+ #endif
+ #endif
+
+ bool OpenShared(LPCTSTR fileName, bool shareForWrite);
+ #ifdef USE_WIN_FILE
+ #ifndef _UNICODE
+ bool OpenShared(LPCWSTR fileName, bool shareForWrite);
+ #endif
+ #endif
+
+ MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ STDMETHOD(GetSize)(UInt64 *size);
+};
+
+#ifndef _WIN32_WCE
+class CStdInFileStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ // HANDLE File;
+ // CStdInFileStream() File(INVALID_HANDLE_VALUE): {}
+ // void Open() { File = GetStdHandle(STD_INPUT_HANDLE); };
+ MY_UNKNOWN_IMP
+
+ virtual ~CStdInFileStream() {}
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+class COutFileStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ #ifdef USE_WIN_FILE
+ NWindows::NFile::NIO::COutFile File;
+ #else
+ NC::NFile::NIO::COutFile File;
+ #endif
+public:
+ virtual ~COutFileStream() {}
+ bool Create(LPCTSTR fileName, bool createAlways)
+ {
+ ProcessedSize = 0;
+ return File.Create(fileName, createAlways);
+ }
+ bool Open(LPCTSTR fileName, DWORD creationDisposition)
+ {
+ ProcessedSize = 0;
+ return File.Open(fileName, creationDisposition);
+ }
+ #ifdef USE_WIN_FILE
+ #ifndef _UNICODE
+ bool Create(LPCWSTR fileName, bool createAlways)
+ {
+ ProcessedSize = 0;
+ return File.Create(fileName, createAlways);
+ }
+ bool Open(LPCWSTR fileName, DWORD creationDisposition)
+ {
+ ProcessedSize = 0;
+ return File.Open(fileName, creationDisposition);
+ }
+ #endif
+ #endif
+
+ HRESULT Close();
+
+ UInt64 ProcessedSize;
+
+ #ifdef USE_WIN_FILE
+ bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+ {
+ return File.SetTime(creationTime, lastAccessTime, lastWriteTime);
+ }
+ bool SetLastWriteTime(const FILETIME *lastWriteTime)
+ {
+ return File.SetLastWriteTime(lastWriteTime);
+ }
+ #endif
+
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#ifndef _WIN32_WCE
+class CStdOutFileStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ virtual ~CStdOutFileStream() {}
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/FilterCoder.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/FilterCoder.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/FilterCoder.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,264 @@
+// FilterCoder.cpp
+
+#include "StdAfx.h"
+
+#include "FilterCoder.h"
+extern "C"
+{
+#include "../../../C/Alloc.h"
+}
+#include "../../Common/Defs.h"
+#include "StreamUtils.h"
+
+static const UInt32 kBufferSize = 1 << 17;
+
+CFilterCoder::CFilterCoder()
+{
+ _buffer = (Byte *)::MidAlloc(kBufferSize);
+}
+
+CFilterCoder::~CFilterCoder()
+{
+ ::MidFree(_buffer);
+}
+
+HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
+{
+ if (_outSizeIsDefined)
+ {
+ UInt64 remSize = _outSize - _nowPos64;
+ if (size > remSize)
+ size = (UInt32)remSize;
+ }
+ UInt32 processedSize = 0;
+ RINOK(WriteStream(outStream, _buffer, size, &processedSize));
+ if (size != processedSize)
+ return E_FAIL;
+ _nowPos64 += processedSize;
+ return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ RINOK(Init());
+ UInt32 bufferPos = 0;
+ _outSizeIsDefined = (outSize != 0);
+ if (_outSizeIsDefined)
+ _outSize = *outSize;
+
+ while(NeedMore())
+ {
+ UInt32 processedSize;
+
+ // Change it: It can be optimized using ReadPart
+ RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize));
+
+ UInt32 endPos = bufferPos + processedSize;
+
+ bufferPos = Filter->Filter(_buffer, endPos);
+ if (bufferPos > endPos)
+ {
+ for (; endPos< bufferPos; endPos++)
+ _buffer[endPos] = 0;
+ bufferPos = Filter->Filter(_buffer, endPos);
+ }
+
+ if (bufferPos == 0)
+ {
+ if (endPos > 0)
+ return WriteWithLimit(outStream, endPos);
+ return S_OK;
+ }
+ RINOK(WriteWithLimit(outStream, bufferPos));
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
+ }
+ UInt32 i = 0;
+ while(bufferPos < endPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+ return S_OK;
+}
+
+// #ifdef _ST_MODE
+STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
+{
+ _bufferPos = 0;
+ _outStream = outStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseOutStream()
+{
+ _outStream.Release();
+ return S_OK;
+};
+
+
+STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ UInt32 sizeMax = kBufferSize - _bufferPos;
+ UInt32 sizeTemp = size;
+ if (sizeTemp > sizeMax)
+ sizeTemp = sizeMax;
+ memmove(_buffer + _bufferPos, data, sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ data = (const Byte *)data + sizeTemp;
+ UInt32 endPos = _bufferPos + sizeTemp;
+ _bufferPos = Filter->Filter(_buffer, endPos);
+ if (_bufferPos == 0)
+ {
+ _bufferPos = endPos;
+ break;
+ }
+ if (_bufferPos > endPos)
+ {
+ if (size != 0)
+ return E_FAIL;
+ break;
+ }
+ RINOK(WriteWithLimit(_outStream, _bufferPos));
+ UInt32 i = 0;
+ while(_bufferPos < endPos)
+ _buffer[i++] = _buffer[_bufferPos++];
+ _bufferPos = i;
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+STDMETHODIMP CFilterCoder::Flush()
+{
+ if (_bufferPos != 0)
+ {
+ UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
+ if (endPos > _bufferPos)
+ {
+ for (; _bufferPos < endPos; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ if (Filter->Filter(_buffer, endPos) != endPos)
+ return E_FAIL;
+ }
+ UInt32 processedSize;
+ RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
+ if (_bufferPos != processedSize)
+ return E_FAIL;
+ _bufferPos = 0;
+ }
+ CMyComPtr<IOutStreamFlush> flush;
+ _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
+ if (flush)
+ return flush->Flush();
+ return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+ _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
+ _inStream = inStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseInStream()
+{
+ _inStream.Release();
+ return S_OK;
+};
+
+STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ if (_convertedPosBegin != _convertedPosEnd)
+ {
+ UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
+ memmove(data, _buffer + _convertedPosBegin, sizeTemp);
+ _convertedPosBegin += sizeTemp;
+ data = (void *)((Byte *)data + sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ break;
+ }
+ int i;
+ for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
+ _buffer[i] = _buffer[i + _convertedPosEnd];
+ _bufferPos = i;
+ _convertedPosBegin = _convertedPosEnd = 0;
+ UInt32 processedSizeTemp;
+ UInt32 size0 = kBufferSize - _bufferPos;
+ // Optimize it:
+ RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
+ _bufferPos = _bufferPos + processedSizeTemp;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ if (_convertedPosEnd == 0)
+ {
+ if (_bufferPos == 0)
+ break;
+ else
+ {
+ _convertedPosEnd = _bufferPos; // check it
+ continue;
+ }
+ }
+ if (_convertedPosEnd > _bufferPos)
+ {
+ for (; _bufferPos < _convertedPosEnd; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+// #endif // _ST_MODE
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ return _setPassword->CryptoSetPassword(data, size);
+}
+#endif
+
+#ifndef EXTRACT_ONLY
+STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+{
+ return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties);
+}
+
+STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ return _writeCoderProperties->WriteCoderProperties(outStream);
+}
+
+/*
+STDMETHODIMP CFilterCoder::ResetSalt()
+{
+ return _CryptoResetSalt->ResetSalt();
+}
+*/
+
+STDMETHODIMP CFilterCoder::ResetInitVector()
+{
+ return _CryptoResetInitVector->ResetInitVector();
+}
+#endif
+
+STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ return _setDecoderProperties->SetDecoderProperties2(data, size);
+}
Added: trunk/lzma/CPP/7zip/Common/FilterCoder.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/FilterCoder.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/FilterCoder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,143 @@
+// FilterCoder.h
+
+#ifndef __FILTERCODER_H
+#define __FILTERCODER_H
+
+#include "../../Common/MyCom.h"
+#include "../ICoder.h"
+#include "../IPassword.h"
+
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
+{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+*outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+class CFilterCoder:
+ public ICompressCoder,
+ // #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ISequentialInStream,
+ public ICompressSetOutStream,
+ public ISequentialOutStream,
+ public IOutStreamFlush,
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ public ICryptoSetPassword,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ // public ICryptoResetSalt,
+ public ICryptoResetInitVector,
+ #endif
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+protected:
+ Byte *_buffer;
+ // #ifdef _ST_MODE
+ CMyComPtr<ISequentialInStream> _inStream;
+ CMyComPtr<ISequentialOutStream> _outStream;
+ UInt32 _bufferPos;
+ UInt32 _convertedPosBegin;
+ UInt32 _convertedPosEnd;
+ // #endif
+ bool _outSizeIsDefined;
+ UInt64 _outSize;
+ UInt64 _nowPos64;
+
+ HRESULT Init()
+ {
+ _nowPos64 = 0;
+ _outSizeIsDefined = false;
+ return Filter->Init();
+ }
+
+ CMyComPtr<ICryptoSetPassword> _setPassword;
+ #ifndef EXTRACT_ONLY
+ CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties;
+ CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
+ // CMyComPtr<ICryptoResetSalt> _CryptoResetSalt;
+ CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector;
+ #endif
+ CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;
+public:
+ CMyComPtr<ICompressFilter> Filter;
+
+ CFilterCoder();
+ ~CFilterCoder();
+ HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);
+ bool NeedMore() const
+ { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); }
+
+public:
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(ICompressCoder)
+ // #ifdef _ST_MODE
+ MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
+ MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties)
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)
+ // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt)
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector)
+ #endif
+
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ // #ifdef _ST_MODE
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+ STDMETHOD(ReleaseOutStream)();
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Flush)();
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+ #endif
+ #ifndef EXTRACT_ONLY
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ // STDMETHOD(ResetSalt)();
+ STDMETHOD(ResetInitVector)();
+ #endif
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+// #ifdef _ST_MODE
+class CInStreamReleaser
+{
+public:
+ CFilterCoder *FilterCoder;
+ CInStreamReleaser(): FilterCoder(0) {}
+ ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
+};
+
+class COutStreamReleaser
+{
+public:
+ CFilterCoder *FilterCoder;
+ COutStreamReleaser(): FilterCoder(0) {}
+ ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
+};
+// #endif
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/InBuffer.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/InBuffer.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/InBuffer.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,83 @@
+// InBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InBuffer.h"
+
+extern "C"
+{
+ #include "../../../C/Alloc.h"
+}
+
+CInBuffer::CInBuffer():
+ _buffer(0),
+ _bufferLimit(0),
+ _bufferBase(0),
+ _stream(0),
+ _bufferSize(0)
+{}
+
+bool CInBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_bufferBase != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _bufferBase = (Byte *)::MidAlloc(bufferSize);
+ return (_bufferBase != 0);
+}
+
+void CInBuffer::Free()
+{
+ ::MidFree(_bufferBase);
+ _bufferBase = 0;
+}
+
+void CInBuffer::SetStream(ISequentialInStream *stream)
+{
+ _stream = stream;
+}
+
+void CInBuffer::Init()
+{
+ _processedSize = 0;
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer;
+ _wasFinished = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+bool CInBuffer::ReadBlock()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return false;
+ #endif
+ if (_wasFinished)
+ return false;
+ _processedSize += (_buffer - _bufferBase);
+ UInt32 numProcessedBytes;
+ HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw CInBufferException(result);
+ #endif
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer + numProcessedBytes;
+ _wasFinished = (numProcessedBytes == 0);
+ return (!_wasFinished);
+}
+
+Byte CInBuffer::ReadBlock2()
+{
+ if(!ReadBlock())
+ return 0xFF;
+ return *_buffer++;
+}
Added: trunk/lzma/CPP/7zip/Common/InBuffer.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/InBuffer.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/InBuffer.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,75 @@
+// InBuffer.h
+
+#ifndef __INBUFFER_H
+#define __INBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+#include "../../Common/MyException.h"
+
+#ifndef _NO_EXCEPTIONS
+struct CInBufferException: public CSystemException
+{
+ CInBufferException(HRESULT errorCode): CSystemException(errorCode) {}
+};
+#endif
+
+class CInBuffer
+{
+ Byte *_buffer;
+ Byte *_bufferLimit;
+ Byte *_bufferBase;
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _processedSize;
+ UInt32 _bufferSize;
+ bool _wasFinished;
+
+ bool ReadBlock();
+ Byte ReadBlock2();
+
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ CInBuffer();
+ ~CInBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetStream(ISequentialInStream *stream);
+ void Init();
+ void ReleaseStream() { _stream.Release(); }
+
+ bool ReadByte(Byte &b)
+ {
+ if(_buffer >= _bufferLimit)
+ if(!ReadBlock())
+ return false;
+ b = *_buffer++;
+ return true;
+ }
+ Byte ReadByte()
+ {
+ if(_buffer >= _bufferLimit)
+ return ReadBlock2();
+ return *_buffer++;
+ }
+ void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+ {
+ for(processedSize = 0; processedSize < size; processedSize++)
+ if (!ReadByte(((Byte *)data)[processedSize]))
+ return;
+ }
+ bool ReadBytes(void *data, UInt32 size)
+ {
+ UInt32 processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+ UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/InOutTempBuffer.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/InOutTempBuffer.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/InOutTempBuffer.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,122 @@
+// InOutTempBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InOutTempBuffer.h"
+#include "../../Common/Defs.h"
+// #include "Windows/Defs.h"
+
+#include "StreamUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static UInt32 kTmpBufferMemorySize = (1 << 20);
+
+static LPCTSTR kTempFilePrefixString = TEXT("iot");
+
+CInOutTempBuffer::CInOutTempBuffer():
+ _buffer(NULL)
+{
+}
+
+void CInOutTempBuffer::Create()
+{
+ _buffer = new Byte[kTmpBufferMemorySize];
+}
+
+CInOutTempBuffer::~CInOutTempBuffer()
+{
+ delete []_buffer;
+}
+void CInOutTempBuffer::InitWriting()
+{
+ _bufferPosition = 0;
+ _tmpFileCreated = false;
+ _fileSize = 0;
+}
+
+bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
+{
+ if (size == 0)
+ return true;
+ if(!_tmpFileCreated)
+ {
+ CSysString tempDirPath;
+ if(!MyGetTempPath(tempDirPath))
+ return false;
+ if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0)
+ return false;
+ // _outFile.SetOpenCreationDispositionCreateAlways();
+ if(!_outFile.Create(_tmpFileName, true))
+ return false;
+ _tmpFileCreated = true;
+ }
+ UInt32 processedSize;
+ if(!_outFile.Write(data, size, processedSize))
+ return false;
+ _fileSize += processedSize;
+ return (processedSize == size);
+}
+
+bool CInOutTempBuffer::FlushWrite()
+{
+ return _outFile.Close();
+}
+
+bool CInOutTempBuffer::Write(const void *data, UInt32 size)
+{
+ if(_bufferPosition < kTmpBufferMemorySize)
+ {
+ UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size);
+ memmove(_buffer + _bufferPosition, (const Byte *)data, curSize);
+ _bufferPosition += curSize;
+ size -= curSize;
+ data = ((const Byte *)data) + curSize;
+ _fileSize += curSize;
+ }
+ return WriteToFile(data, size);
+}
+
+bool CInOutTempBuffer::InitReading()
+{
+ _currentPositionInBuffer = 0;
+ if(_tmpFileCreated)
+ return _inFile.Open(_tmpFileName);
+ return true;
+}
+
+HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
+{
+ if (_currentPositionInBuffer < _bufferPosition)
+ {
+ UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
+ RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
+ _currentPositionInBuffer += sizeToWrite;
+ }
+ if (!_tmpFileCreated)
+ return true;
+ for (;;)
+ {
+ UInt32 localProcessedSize;
+ if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
+ return E_FAIL;
+ if (localProcessedSize == 0)
+ return S_OK;
+ RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
+ }
+}
+
+STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (!_buffer->Write(data, size))
+ {
+ if (processedSize != NULL)
+ *processedSize = 0;
+ return E_FAIL;
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/Common/InOutTempBuffer.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/InOutTempBuffer.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/InOutTempBuffer.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,55 @@
+// Util/InOutTempBuffer.h
+
+#ifndef __IN_OUT_TEMP_BUFFER_H
+#define __IN_OUT_TEMP_BUFFER_H
+
+#include "../../Windows/FileIO.h"
+#include "../../Windows/FileDir.h"
+#include "../../Common/MyCom.h"
+
+#include "../IStream.h"
+
+class CInOutTempBuffer
+{
+ NWindows::NFile::NDirectory::CTempFile _tempFile;
+ NWindows::NFile::NIO::COutFile _outFile;
+ NWindows::NFile::NIO::CInFile _inFile;
+ Byte *_buffer;
+ UInt32 _bufferPosition;
+ UInt32 _currentPositionInBuffer;
+ CSysString _tmpFileName;
+ bool _tmpFileCreated;
+
+ UInt64 _fileSize;
+
+ bool WriteToFile(const void *data, UInt32 size);
+public:
+ CInOutTempBuffer();
+ ~CInOutTempBuffer();
+ void Create();
+
+ void InitWriting();
+ bool Write(const void *data, UInt32 size);
+ UInt64 GetDataSize() const { return _fileSize; }
+ bool FlushWrite();
+ bool InitReading();
+ HRESULT WriteToStream(ISequentialOutStream *stream);
+};
+
+class CSequentialOutTempBufferImp:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CInOutTempBuffer *_buffer;
+public:
+ // CSequentialOutStreamImp(): _size(0) {}
+ // UInt32 _size;
+ void Init(CInOutTempBuffer *buffer) { _buffer = buffer; }
+ // UInt32 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/LimitedStreams.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/LimitedStreams.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/LimitedStreams.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// LimitedStreams.cpp
+
+#include "StdAfx.h"
+
+#include "LimitedStreams.h"
+#include "../../Common/Defs.h"
+
+STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size);
+ HRESULT result = S_OK;
+ if (sizeToRead > 0)
+ {
+ result = _stream->Read(data, sizeToRead, &realProcessedSize);
+ _pos += realProcessedSize;
+ if (realProcessedSize == 0)
+ _wasFinished = true;
+ }
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
Added: trunk/lzma/CPP/7zip/Common/LimitedStreams.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/LimitedStreams.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/LimitedStreams.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,33 @@
+// LimitedStreams.h
+
+#ifndef __LIMITEDSTREAMS_H
+#define __LIMITEDSTREAMS_H
+
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLimitedSequentialInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+ UInt64 _pos;
+ bool _wasFinished;
+public:
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+ void Init(UInt64 streamSize)
+ {
+ _size = streamSize;
+ _pos = 0;
+ _wasFinished = false;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ UInt64 GetSize() const { return _pos; }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/LockedStream.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/LockedStream.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/LockedStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,23 @@
+// LockedStream.cpp
+
+#include "StdAfx.h"
+
+#include "LockedStream.h"
+
+HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size,
+ UInt32 *processedSize)
+{
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
+ return _stream->Read(data, size, processedSize);
+}
+
+STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize);
+ _pos += realProcessedSize;
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
Added: trunk/lzma/CPP/7zip/Common/LockedStream.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/LockedStream.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/LockedStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,38 @@
+// LockedStream.h
+
+#ifndef __LOCKEDSTREAM_H
+#define __LOCKEDSTREAM_H
+
+#include "../../Windows/Synchronization.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLockedInStream
+{
+ CMyComPtr<IInStream> _stream;
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+public:
+ void Init(IInStream *stream)
+ { _stream = stream; }
+ HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CLockedSequentialInStreamImp:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CLockedInStream *_lockedInStream;
+ UInt64 _pos;
+public:
+ void Init(CLockedInStream *lockedInStream, UInt64 startPos)
+ {
+ _lockedInStream = lockedInStream;
+ _pos = startPos;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/MethodId.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/MethodId.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/MethodId.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,27 @@
+// MethodId.cpp
+
+#include "StdAfx.h"
+
+#include "MethodId.h"
+#include "../../Common/MyString.h"
+
+static inline wchar_t GetHex(Byte value)
+{
+ return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+UString ConvertMethodIdToString(UInt64 id)
+{
+ wchar_t s[32];
+ int len = 32;
+ s[--len] = 0;
+ do
+ {
+ s[--len] = GetHex((Byte)id & 0xF);
+ id >>= 4;
+ s[--len] = GetHex((Byte)id & 0xF);
+ id >>= 4;
+ }
+ while (id != 0);
+ return s + len;
+}
Added: trunk/lzma/CPP/7zip/Common/MethodId.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/MethodId.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/MethodId.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// MethodId.h
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "../../Common/Types.h"
+
+typedef UInt64 CMethodId;
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/MethodProps.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/MethodProps.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/MethodProps.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,96 @@
+// MethodProps.cpp
+
+#include "StdAfx.h"
+
+#include "MethodProps.h"
+#include "../../Common/MyCom.h"
+
+static UInt64 k_LZMA = 0x030101;
+// static UInt64 k_LZMA2 = 0x030102;
+
+HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)
+{
+ bool tryReduce = false;
+ UInt32 reducedDictionarySize = 1 << 10;
+ if (inSizeForReduce != 0 && (method.Id == k_LZMA /* || methodFull.MethodID == k_LZMA2 */))
+ {
+ for (;;)
+ {
+ const UInt32 step = (reducedDictionarySize >> 1);
+ if (reducedDictionarySize >= *inSizeForReduce)
+ {
+ tryReduce = true;
+ break;
+ }
+ reducedDictionarySize += step;
+ if (reducedDictionarySize >= *inSizeForReduce)
+ {
+ tryReduce = true;
+ break;
+ }
+ if (reducedDictionarySize >= ((UInt32)3 << 30))
+ break;
+ reducedDictionarySize += step;
+ }
+ }
+
+ {
+ int numProperties = method.Properties.Size();
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
+ if (setCoderProperties == NULL)
+ {
+ if (numProperties != 0)
+ return E_INVALIDARG;
+ }
+ else
+ {
+ CRecordVector<PROPID> propIDs;
+ NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties];
+ HRESULT res = S_OK;
+ try
+ {
+ for (int i = 0; i < numProperties; i++)
+ {
+ const CProp &prop = method.Properties[i];
+ propIDs.Add(prop.Id);
+ NWindows::NCOM::CPropVariant &value = values[i];
+ value = prop.Value;
+ // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
+ if (tryReduce)
+ if (prop.Id == NCoderPropID::kDictionarySize)
+ if (value.vt == VT_UI4)
+ if (reducedDictionarySize < value.ulVal)
+ value.ulVal = reducedDictionarySize;
+ }
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
+ res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties);
+ }
+ catch(...)
+ {
+ delete []values;
+ throw;
+ }
+ delete []values;
+ RINOK(res);
+ }
+ }
+
+ /*
+ CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+ coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
+ if (writeCoderProperties != NULL)
+ {
+ CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init();
+ RINOK(writeCoderProperties->WriteCoderProperties(outStream));
+ size_t size = outStreamSpec->GetSize();
+ filterProps.SetCapacity(size);
+ memmove(filterProps, outStreamSpec->GetBuffer(), size);
+ }
+ */
+ return S_OK;
+}
+
Added: trunk/lzma/CPP/7zip/Common/MethodProps.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/MethodProps.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/MethodProps.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,41 @@
+// MethodProps.h
+
+#ifndef __7Z_METHOD_PROPS_H
+#define __7Z_METHOD_PROPS_H
+
+#include "MethodId.h"
+
+#include "../../Windows/PropVariant.h"
+#include "../../Common/MyVector.h"
+#include "../ICoder.h"
+
+struct CProp
+{
+ PROPID Id;
+ NWindows::NCOM::CPropVariant Value;
+};
+
+struct CMethod
+{
+ CMethodId Id;
+ CObjectVector<CProp> Properties;
+};
+
+struct CMethodsMode
+{
+ CObjectVector<CMethod> Methods;
+ #ifdef COMPRESS_MT
+ UInt32 NumThreads;
+ #endif
+
+ CMethodsMode()
+ #ifdef COMPRESS_MT
+ : NumThreads(1)
+ #endif
+ {}
+ bool IsEmpty() const { return Methods.IsEmpty() ; }
+};
+
+HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder);
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/OffsetStream.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/OffsetStream.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/OffsetStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,35 @@
+// OffsetStream.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "OffsetStream.h"
+
+HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
+{
+ _offset = offset;
+ _stream = stream;
+ return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ return _stream->Write(data, size, processedSize);
+}
+
+STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ UInt64 absoluteNewPosition;
+ if (seekOrigin == STREAM_SEEK_SET)
+ offset += _offset;
+ HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
+ if (newPosition != NULL)
+ *newPosition = absoluteNewPosition - _offset;
+ return result;
+}
+
+STDMETHODIMP COffsetOutStream::SetSize(Int64 newSize)
+{
+ return _stream->SetSize(_offset + newSize);
+}
Added: trunk/lzma/CPP/7zip/Common/OffsetStream.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/OffsetStream.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/OffsetStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,25 @@
+// OffsetStream.h
+
+#ifndef __OFFSETSTREAM_H
+#define __OFFSETSTREAM_H
+
+#include "Common/MyCom.h"
+#include "../IStream.h"
+
+class COffsetOutStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ UInt64 _offset;
+ CMyComPtr<IOutStream> _stream;
+public:
+ HRESULT Init(IOutStream *stream, UInt64 offset);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/OutBuffer.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/OutBuffer.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/OutBuffer.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,119 @@
+// OutByte.cpp
+
+#include "StdAfx.h"
+
+#include "OutBuffer.h"
+
+extern "C"
+{
+ #include "../../../C/Alloc.h"
+}
+
+bool COutBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_buffer != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _buffer = (Byte *)::MidAlloc(bufferSize);
+ return (_buffer != 0);
+}
+
+void COutBuffer::Free()
+{
+ ::MidFree(_buffer);
+ _buffer = 0;
+}
+
+void COutBuffer::SetStream(ISequentialOutStream *stream)
+{
+ _stream = stream;
+}
+
+void COutBuffer::Init()
+{
+ _streamPos = 0;
+ _limitPos = _bufferSize;
+ _pos = 0;
+ _processedSize = 0;
+ _overDict = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+UInt64 COutBuffer::GetProcessedSize() const
+{
+ UInt64 res = _processedSize + _pos - _streamPos;
+ if (_streamPos > _pos)
+ res += _bufferSize;
+ return res;
+}
+
+
+HRESULT COutBuffer::FlushPart()
+{
+ // _streamPos < _bufferSize
+ UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ HRESULT result = S_OK;
+ #ifdef _NO_EXCEPTIONS
+ result = ErrorCode;
+ #endif
+ if (_buffer2 != 0)
+ {
+ memmove(_buffer2, _buffer + _streamPos, size);
+ _buffer2 += size;
+ }
+
+ if (_stream != 0
+ #ifdef _NO_EXCEPTIONS
+ && (ErrorCode == S_OK)
+ #endif
+ )
+ {
+ UInt32 processedSize = 0;
+ result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ size = processedSize;
+ }
+ _streamPos += size;
+ if (_streamPos == _bufferSize)
+ _streamPos = 0;
+ if (_pos == _bufferSize)
+ {
+ _overDict = true;
+ _pos = 0;
+ }
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ _processedSize += size;
+ return result;
+}
+
+HRESULT COutBuffer::Flush()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return ErrorCode;
+ #endif
+
+ while(_streamPos != _pos)
+ {
+ HRESULT result = FlushPart();
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+void COutBuffer::FlushWithCheck()
+{
+ HRESULT result = Flush();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw COutBufferException(result);
+ #endif
+}
Added: trunk/lzma/CPP/7zip/Common/OutBuffer.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/OutBuffer.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/OutBuffer.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,64 @@
+// OutBuffer.h
+
+#ifndef __OUTBUFFER_H
+#define __OUTBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+#include "../../Common/MyException.h"
+
+#ifndef _NO_EXCEPTIONS
+struct COutBufferException: public CSystemException
+{
+ COutBufferException(HRESULT errorCode): CSystemException(errorCode) {}
+};
+#endif
+
+class COutBuffer
+{
+protected:
+ Byte *_buffer;
+ UInt32 _pos;
+ UInt32 _limitPos;
+ UInt32 _streamPos;
+ UInt32 _bufferSize;
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _processedSize;
+ Byte *_buffer2;
+ bool _overDict;
+
+ HRESULT FlushPart();
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+ ~COutBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
+ void SetStream(ISequentialOutStream *stream);
+ void Init();
+ HRESULT Flush();
+ void FlushWithCheck();
+ void ReleaseStream() { _stream.Release(); }
+
+ void WriteByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if(_pos == _limitPos)
+ FlushWithCheck();
+ }
+ void WriteBytes(const void *data, size_t size)
+ {
+ for (size_t i = 0; i < size; i++)
+ WriteByte(((const Byte *)data)[i]);
+ }
+
+ UInt64 GetProcessedSize() const;
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/ProgressUtils.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/ProgressUtils.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/ProgressUtils.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,42 @@
+// ProgressUtils.h
+
+#include "StdAfx.h"
+
+#include "ProgressUtils.h"
+
+CLocalProgress::CLocalProgress()
+{
+ ProgressOffset = InSize = OutSize = 0;
+ SendRatio = SendProgress = true;
+}
+
+void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
+{
+ _ratioProgress.Release();
+ _progress = progress;
+ _progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress);
+ _inSizeIsMain = inSizeIsMain;
+}
+
+STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ UInt64 inSizeNew = InSize, outSizeNew = OutSize;
+ if (inSize)
+ inSizeNew += (*inSize);
+ if (outSize)
+ outSizeNew += (*outSize);
+ if (SendRatio && _ratioProgress)
+ {
+ RINOK(_ratioProgress->SetRatioInfo(&inSizeNew, &outSizeNew));
+ }
+ inSizeNew += ProgressOffset;
+ outSizeNew += ProgressOffset;
+ if (SendProgress)
+ return _progress->SetCompleted(_inSizeIsMain ? &inSizeNew : &outSizeNew);
+ return S_OK;
+}
+
+HRESULT CLocalProgress::SetCur()
+{
+ return SetRatioInfo(NULL, NULL);
+}
Added: trunk/lzma/CPP/7zip/Common/ProgressUtils.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/ProgressUtils.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/ProgressUtils.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,34 @@
+// ProgressUtils.h
+
+#ifndef __PROGRESSUTILS_H
+#define __PROGRESSUTILS_H
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+#include "../IProgress.h"
+
+class CLocalProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<IProgress> _progress;
+ CMyComPtr<ICompressProgressInfo> _ratioProgress;
+ bool _inSizeIsMain;
+public:
+ UInt64 ProgressOffset;
+ UInt64 InSize;
+ UInt64 OutSize;
+ bool SendRatio;
+ bool SendProgress;
+
+ CLocalProgress();
+ void Init(IProgress *progress, bool inSizeIsMain);
+ HRESULT SetCur();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/RegisterArc.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/RegisterArc.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/RegisterArc.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,36 @@
+// RegisterArc.h
+
+#ifndef __REGISTERARC_H
+#define __REGISTERARC_H
+
+#include "../Archive/IArchive.h"
+
+typedef IInArchive * (*CreateInArchiveP)();
+typedef IOutArchive * (*CreateOutArchiveP)();
+
+struct CArcInfo
+{
+ const wchar_t *Name;
+ const wchar_t *Ext;
+ const wchar_t *AddExt;
+ Byte ClassId;
+ Byte Signature[16];
+ int SignatureSize;
+ bool KeepName;
+ CreateInArchiveP CreateInArchive;
+ CreateOutArchiveP CreateOutArchive;
+};
+
+void RegisterArc(const CArcInfo *arcInfo);
+
+#define REGISTER_ARC_NAME(x) CRegister ## x
+
+#define REGISTER_ARC_DEC_SIG(x) struct REGISTER_ARC_NAME(x) { \
+ REGISTER_ARC_NAME(x)() { g_ArcInfo.Signature[0]--; RegisterArc(&g_ArcInfo); }}; \
+ static REGISTER_ARC_NAME(x) g_RegisterArc;
+
+#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) { \
+ REGISTER_ARC_NAME(x)() { RegisterArc(&g_ArcInfo); }}; \
+ static REGISTER_ARC_NAME(x) g_RegisterArc;
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/RegisterCodec.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/RegisterCodec.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/RegisterCodec.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,33 @@
+// RegisterCodec.h
+
+#ifndef __REGISTERCODEC_H
+#define __REGISTERCODEC_H
+
+#include "../Common/MethodId.h"
+
+typedef void * (*CreateCodecP)();
+struct CCodecInfo
+{
+ CreateCodecP CreateDecoder;
+ CreateCodecP CreateEncoder;
+ CMethodId Id;
+ const wchar_t *Name;
+ UInt32 NumInStreams;
+ bool IsFilter;
+};
+
+void RegisterCodec(const CCodecInfo *codecInfo);
+
+#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x
+
+#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \
+ REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \
+ static REGISTER_CODEC_NAME(x) g_RegisterCodec;
+
+#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x
+#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \
+ REGISTER_CODECS_NAME(x)() { for (int i = 0; i < sizeof(g_CodecsInfo) / sizeof(g_CodecsInfo[0]); i++) \
+ RegisterCodec(&g_CodecsInfo[i]); }}; \
+ static REGISTER_CODECS_NAME(x) g_RegisterCodecs;
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/MyWindows.h"
+#include "../../Common/NewHandler.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/StreamBinder.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/StreamBinder.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/StreamBinder.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,150 @@
+// StreamBinder.cpp
+
+#include "StdAfx.h"
+
+#include "StreamBinder.h"
+#include "../../Common/Defs.h"
+#include "../../Common/MyCom.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+class CSequentialInStreamForBinder:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CStreamBinder *m_StreamBinder;
+public:
+ ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
+ void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+ { return m_StreamBinder->Read(data, size, processedSize); }
+
+class CSequentialOutStreamForBinder:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+
+private:
+ CStreamBinder *m_StreamBinder;
+public:
+ ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); }
+ void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+ { return m_StreamBinder->Write(data, size, processedSize); }
+
+
+//////////////////////////
+// CStreamBinder
+// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
+
+HRes CStreamBinder::CreateEvents()
+{
+ RINOK(_allBytesAreWritenEvent.Create(true));
+ RINOK(_thereAreBytesToReadEvent.Create());
+ return _readStreamIsClosedEvent.Create();
+}
+
+void CStreamBinder::ReInit()
+{
+ _thereAreBytesToReadEvent.Reset();
+ _readStreamIsClosedEvent.Reset();
+ ProcessedSize = 0;
+}
+
+
+
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
+ ISequentialOutStream **outStream)
+{
+ CSequentialInStreamForBinder *inStreamSpec = new
+ CSequentialInStreamForBinder;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ inStreamSpec->SetBinder(this);
+ *inStream = inStreamLoc.Detach();
+
+ CSequentialOutStreamForBinder *outStreamSpec = new
+ CSequentialOutStreamForBinder;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
+ outStreamSpec->SetBinder(this);
+ *outStream = outStreamLoc.Detach();
+
+ _buffer = NULL;
+ _bufferSize= 0;
+ ProcessedSize = 0;
+}
+
+HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 sizeToRead = size;
+ if (size > 0)
+ {
+ RINOK(_thereAreBytesToReadEvent.Lock());
+ sizeToRead = MyMin(_bufferSize, size);
+ if (_bufferSize > 0)
+ {
+ MoveMemory(data, _buffer, sizeToRead);
+ _buffer = ((const Byte *)_buffer) + sizeToRead;
+ _bufferSize -= sizeToRead;
+ if (_bufferSize == 0)
+ {
+ _thereAreBytesToReadEvent.Reset();
+ _allBytesAreWritenEvent.Set();
+ }
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = sizeToRead;
+ ProcessedSize += sizeToRead;
+ return S_OK;
+}
+
+void CStreamBinder::CloseRead()
+{
+ _readStreamIsClosedEvent.Set();
+}
+
+HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (size > 0)
+ {
+ _buffer = data;
+ _bufferSize = size;
+ _allBytesAreWritenEvent.Reset();
+ _thereAreBytesToReadEvent.Set();
+
+ HANDLE events[2];
+ events[0] = _allBytesAreWritenEvent;
+ events[1] = _readStreamIsClosedEvent;
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult != WAIT_OBJECT_0 + 0)
+ {
+ // ReadingWasClosed = true;
+ return S_FALSE;
+ }
+ // if(!_allBytesAreWritenEvent.Lock())
+ // return E_FAIL;
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+void CStreamBinder::CloseWrite()
+{
+ // _bufferSize must be = 0
+ _thereAreBytesToReadEvent.Set();
+}
Added: trunk/lzma/CPP/7zip/Common/StreamBinder.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/StreamBinder.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/StreamBinder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,32 @@
+// StreamBinder.h
+
+#ifndef __STREAMBINDER_H
+#define __STREAMBINDER_H
+
+#include "../IStream.h"
+#include "../../Windows/Synchronization.h"
+
+class CStreamBinder
+{
+ NWindows::NSynchronization::CManualResetEvent _allBytesAreWritenEvent;
+ NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent;
+ NWindows::NSynchronization::CManualResetEvent _readStreamIsClosedEvent;
+ UInt32 _bufferSize;
+ const void *_buffer;
+public:
+ // bool ReadingWasClosed;
+ UInt64 ProcessedSize;
+ CStreamBinder() {}
+ HRes CreateEvents();
+
+ void CreateStreams(ISequentialInStream **inStream,
+ ISequentialOutStream **outStream);
+ HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
+ void CloseRead();
+
+ HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
+ void CloseWrite();
+ void ReInit();
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/StreamObjects.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/StreamObjects.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/StreamObjects.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,68 @@
+// StreamObjects.cpp
+
+#include "StdAfx.h"
+
+#include "StreamObjects.h"
+#include "../../Common/Defs.h"
+
+
+STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 numBytesToRead = (UInt32)(MyMin(_pos + size, _size) - _pos);
+ memmove(data, _dataPointer + _pos, numBytesToRead);
+ _pos += numBytesToRead;
+ if(processedSize != NULL)
+ *processedSize = numBytesToRead;
+ return S_OK;
+}
+
+
+void CWriteBuffer::Write(const void *data, size_t size)
+{
+ size_t newCapacity = _size + size;
+ _buffer.EnsureCapacity(newCapacity);
+ memmove(_buffer + _size, data, size);
+ _size += size;
+}
+
+STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ _writeBuffer.Write(data, size);
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 newSize = size;
+ if (_pos + size > _size)
+ newSize = (UInt32)(_size - _pos);
+ memmove(_buffer + _pos, data, newSize);
+ if(processedSize != NULL)
+ *processedSize = newSize;
+ _pos += newSize;
+ if (newSize != size)
+ return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Write(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
Added: trunk/lzma/CPP/7zip/Common/StreamObjects.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/StreamObjects.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/StreamObjects.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,117 @@
+// StreamObjects.h
+
+#ifndef __STREAMOBJECTS_H
+#define __STREAMOBJECTS_H
+
+#include "../../Common/DynamicBuffer.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CSequentialInStreamImp:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *_dataPointer;
+ size_t _size;
+ size_t _pos;
+
+public:
+ void Init(const Byte *dataPointer, size_t size)
+ {
+ _dataPointer = dataPointer;
+ _size = size;
+ _pos = 0;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+
+class CWriteBuffer
+{
+ CByteDynamicBuffer _buffer;
+ size_t _size;
+public:
+ CWriteBuffer(): _size(0) {}
+ void Init() { _size = 0; }
+ void Write(const void *data, size_t size);
+ size_t GetSize() const { return _size; }
+ const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
+};
+
+class CSequentialOutStreamImp:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CWriteBuffer _writeBuffer;
+public:
+ void Init() { _writeBuffer.Init(); }
+ size_t GetSize() const { return _writeBuffer.GetSize(); }
+ const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialOutStreamImp2:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+ size_t _size;
+ size_t _pos;
+public:
+
+ void Init(Byte *buffer, size_t size)
+ {
+ _buffer = buffer;
+ _pos = 0;
+ _size = size;
+ }
+
+ size_t GetPos() const { return _pos; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialInStreamSizeCount:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+public:
+ void Init(ISequentialInStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialOutStreamSizeCount:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+public:
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void Init() { _size = 0; }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/StreamUtils.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/StreamUtils.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/StreamUtils.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,44 @@
+// StreamUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyCom.h"
+#include "StreamUtils.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Read(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (Byte *)((Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ return S_OK;
+ }
+ return S_OK;
+}
+
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Write(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (const void *)((const Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ return E_FAIL;
+ }
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/Common/StreamUtils.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/StreamUtils.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/StreamUtils.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,11 @@
+// StreamUtils.h
+
+#ifndef __STREAMUTILS_H
+#define __STREAMUTILS_H
+
+#include "../IStream.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
+
+#endif
Added: trunk/lzma/CPP/7zip/Common/VirtThread.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Common/VirtThread.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Common/VirtThread.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,45 @@
+// VirtThread.cpp
+
+#include "StdAfx.h"
+
+#include "VirtThread.h"
+
+static THREAD_FUNC_DECL CoderThread(void *p)
+{
+ for (;;)
+ {
+ CVirtThread *t = (CVirtThread *)p;
+ t->StartEvent.Lock();
+ if (t->ExitEvent)
+ return 0;
+ t->Execute();
+ t->FinishedEvent.Set();
+ }
+}
+
+HRes CVirtThread::Create()
+{
+ RINOK(StartEvent.CreateIfNotCreated());
+ RINOK(FinishedEvent.CreateIfNotCreated());
+ StartEvent.Reset();
+ FinishedEvent.Reset();
+ ExitEvent = false;
+ if (Thread.IsCreated())
+ return S_OK;
+ return Thread.Create(CoderThread, this);
+}
+
+void CVirtThread::Start()
+{
+ ExitEvent = false;
+ StartEvent.Set();
+}
+
+CVirtThread::~CVirtThread()
+{
+ ExitEvent = true;
+ if (StartEvent.IsCreated())
+ StartEvent.Set();
+ Thread.Wait();
+}
+
Added: trunk/lzma/CPP/7zip/Common/VirtThread.h
===================================================================
--- trunk/lzma/CPP/7zip/Common/VirtThread.h (rev 0)
+++ trunk/lzma/CPP/7zip/Common/VirtThread.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,23 @@
+// VirtThread.h
+
+#ifndef __VIRTTHREAD_H
+#define __VIRTTHREAD_H
+
+#include "../../Windows/Synchronization.h"
+#include "../../Windows/Thread.h"
+
+struct CVirtThread
+{
+ NWindows::NSynchronization::CAutoResetEvent StartEvent;
+ NWindows::NSynchronization::CAutoResetEvent FinishedEvent;
+ NWindows::CThread Thread;
+ bool ExitEvent;
+
+ ~CVirtThread();
+ HRes Create();
+ void Start();
+ void WaitFinish() { FinishedEvent.Lock(); }
+ virtual void Execute() = 0;
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/ARM.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/ARM.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/ARM.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,19 @@
+// ARM.cpp
+
+#include "StdAfx.h"
+#include "ARM.h"
+
+extern "C"
+{
+#include "../../../../C/Compress/Branch/BranchARM.h"
+}
+
+UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARM_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARM_Convert(data, size, _bufferPos, 0);
+}
Added: trunk/lzma/CPP/7zip/Compress/Branch/ARM.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/ARM.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/ARM.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// ARM.h
+
+#ifndef __ARM_H
+#define __ARM_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_ARM, 0x05, 1)
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/ARMThumb.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/ARMThumb.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/ARMThumb.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,20 @@
+// ARMThumb.cpp
+
+#include "StdAfx.h"
+
+#include "ARMThumb.h"
+
+extern "C"
+{
+#include "../../../../C/Compress/Branch/BranchARMThumb.h"
+}
+
+UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARMThumb_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARMThumb_Convert(data, size, _bufferPos, 0);
+}
Added: trunk/lzma/CPP/7zip/Compress/Branch/ARMThumb.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/ARMThumb.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/ARMThumb.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// ARMThumb.h
+
+#ifndef __ARMTHUMB_H
+#define __ARMTHUMB_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_ARMThumb, 0x07, 1)
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/BCJ2Register.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/BCJ2Register.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/BCJ2Register.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,18 @@
+// BranchRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "x86_2.h"
+static void *CreateCodec() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CDecoder()); }
+#ifndef EXTRACT_ONLY
+static void *CreateCodecOut() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CEncoder()); }
+#else
+#define CreateCodecOut 0
+#endif
+
+static CCodecInfo g_CodecInfo =
+ { CreateCodec, CreateCodecOut, 0x0303011B, L"BCJ2", 4, false };
+
+REGISTER_CODEC(BCJ2)
Added: trunk/lzma/CPP/7zip/Compress/Branch/BCJRegister.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/BCJRegister.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/BCJRegister.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,18 @@
+// BranchRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "x86.h"
+static void *CreateCodec() { return (void *)(ICompressFilter *)(new CBCJ_x86_Decoder()); }
+#ifndef EXTRACT_ONLY
+static void *CreateCodecOut() { return (void *)(ICompressFilter *)(new CBCJ_x86_Encoder()); }
+#else
+#define CreateCodecOut 0
+#endif
+
+static CCodecInfo g_CodecInfo =
+ { CreateCodec, CreateCodecOut, 0x03030103, L"BCJ", 1, true };
+
+REGISTER_CODEC(BCJ)
Added: trunk/lzma/CPP/7zip/Compress/Branch/BranchCoder.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/BranchCoder.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/BranchCoder.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,18 @@
+// BranchCoder.cpp
+
+#include "StdAfx.h"
+#include "BranchCoder.h"
+
+STDMETHODIMP CBranchConverter::Init()
+{
+ _bufferPos = 0;
+ SubInit();
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)
+{
+ UInt32 processedSize = SubFilter(data, size);
+ _bufferPos += processedSize;
+ return processedSize;
+}
Added: trunk/lzma/CPP/7zip/Compress/Branch/BranchCoder.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/BranchCoder.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/BranchCoder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,45 @@
+// BranchCoder.h
+
+#ifndef __BRANCH_CODER_H
+#define __BRANCH_CODER_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+
+#include "../../ICoder.h"
+
+class CBranchConverter:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+protected:
+ UInt32 _bufferPos;
+ virtual void SubInit() {}
+ virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;
+public:
+ MY_UNKNOWN_IMP;
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); };
+
+#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); };
+
+#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
+
+#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
+
+#define MyClassA(Name, id, subId) \
+MyClassEncoderA(Name ## _Encoder) \
+MyClassDecoderA(Name ## _Decoder)
+
+#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \
+MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \
+MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/BranchRegister.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/BranchRegister.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/BranchRegister.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,34 @@
+// BranchRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "PPC.h"
+#include "IA64.h"
+#include "ARM.h"
+#include "ARMThumb.h"
+#include "SPARC.h"
+
+#define CREATE_CODEC(x) \
+ static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## _Decoder); } \
+ static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## _Encoder); }
+
+CREATE_CODEC(BC_PPC_B)
+CREATE_CODEC(BC_IA64)
+CREATE_CODEC(BC_ARM)
+CREATE_CODEC(BC_ARMThumb)
+CREATE_CODEC(BC_SPARC)
+
+#define METHOD_ITEM(x, id1, id2, name) { CreateCodec ## x, CreateCodec ## x ## Out, 0x03030000 + (id1 * 256) + id2, name, 1, true }
+
+static CCodecInfo g_CodecsInfo[] =
+{
+ METHOD_ITEM(BC_PPC_B, 0x02, 0x05, L"BC_PPC_B"),
+ METHOD_ITEM(BC_IA64, 0x04, 1, L"BC_IA64"),
+ METHOD_ITEM(BC_ARM, 0x05, 1, L"BC_ARM"),
+ METHOD_ITEM(BC_ARMThumb,0x07, 1, L"BC_ARMThumb"),
+ METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"BC_SPARC")
+};
+
+REGISTER_CODECS(Branch)
Added: trunk/lzma/CPP/7zip/Compress/Branch/IA64.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/IA64.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/IA64.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,19 @@
+// IA64.cpp
+
+#include "StdAfx.h"
+#include "IA64.h"
+
+extern "C"
+{
+#include "../../../../C/Compress/Branch/BranchIA64.h"
+}
+
+UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::IA64_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::IA64_Convert(data, size, _bufferPos, 0);
+}
Added: trunk/lzma/CPP/7zip/Compress/Branch/IA64.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/IA64.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/IA64.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// IA64.h
+
+#ifndef __IA64_H
+#define __IA64_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_IA64, 0x04, 1)
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/PPC.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/PPC.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/PPC.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,19 @@
+// PPC.cpp
+
+#include "StdAfx.h"
+#include "PPC.h"
+
+extern "C"
+{
+#include "../../../../C/Compress/Branch/BranchPPC.h"
+}
+
+UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::PPC_B_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::PPC_B_Convert(data, size, _bufferPos, 0);
+}
Added: trunk/lzma/CPP/7zip/Compress/Branch/PPC.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/PPC.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/PPC.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// PPC.h
+
+#ifndef __PPC_H
+#define __PPC_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_PPC_B, 0x02, 5)
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/SPARC.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/SPARC.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/SPARC.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,19 @@
+// SPARC.cpp
+
+#include "StdAfx.h"
+#include "SPARC.h"
+
+extern "C"
+{
+#include "../../../../C/Compress/Branch/BranchSPARC.h"
+}
+
+UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::SPARC_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::SPARC_Convert(data, size, _bufferPos, 0);
+}
Added: trunk/lzma/CPP/7zip/Compress/Branch/SPARC.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/SPARC.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/SPARC.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// SPARC.h
+
+#ifndef __SPARC_H
+#define __SPARC_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_SPARC, 0x08, 5)
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Compress/Branch/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/x86.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/x86.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/x86.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,14 @@
+// x86.cpp
+
+#include "StdAfx.h"
+#include "x86.h"
+
+UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 1);
+}
+
+UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 0);
+}
Added: trunk/lzma/CPP/7zip/Compress/Branch/x86.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/x86.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/x86.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,21 @@
+// x86.h
+
+#ifndef __X86_H
+#define __X86_H
+
+#include "BranchCoder.h"
+extern "C"
+{
+#include "../../../../C/Compress/Branch/BranchX86.h"
+}
+
+struct CBranch86
+{
+ UInt32 _prevMask;
+ void x86Init() { x86_Convert_Init(_prevMask); }
+};
+
+MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
+ virtual void SubInit() { x86Init(); })
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Branch/x86_2.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/x86_2.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/x86_2.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,392 @@
+// x86_2.cpp
+
+#include "StdAfx.h"
+#include "x86_2.h"
+
+extern "C"
+{
+#include "../../../../C/Alloc.h"
+}
+
+namespace NCompress {
+namespace NBcj2 {
+
+inline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); }
+inline bool IsJ(Byte b0, Byte b1) { return ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)); }
+inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == 0xE9) ? 256 : 257)); }
+
+#ifndef EXTRACT_ONLY
+
+static const int kBufferSize = 1 << 17;
+
+static bool inline Test86MSByte(Byte b)
+{
+ return (b == 0 || b == 0xFF);
+}
+
+bool CEncoder::Create()
+{
+ if (!_mainStream.Create(1 << 16))
+ return false;
+ if (!_callStream.Create(1 << 20))
+ return false;
+ if (!_jumpStream.Create(1 << 20))
+ return false;
+ if (!_rangeEncoder.Create(1 << 20))
+ return false;
+ if (_buffer == 0)
+ {
+ _buffer = (Byte *)MidAlloc(kBufferSize);
+ if (_buffer == 0)
+ return false;
+ }
+ return true;
+}
+
+CEncoder::~CEncoder()
+{
+ ::MidFree(_buffer);
+}
+
+HRESULT CEncoder::Flush()
+{
+ RINOK(_mainStream.Flush());
+ RINOK(_callStream.Flush());
+ RINOK(_jumpStream.Flush());
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+const UInt32 kDefaultLimit = (1 << 24);
+
+HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 ** /* outSizes */,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 1 || numOutStreams != 4)
+ return E_INVALIDARG;
+
+ if (!Create())
+ return E_OUTOFMEMORY;
+
+ bool sizeIsDefined = false;
+ UInt64 inSize = 0;
+ if (inSizes != NULL)
+ if (inSizes[0] != NULL)
+ {
+ inSize = *inSizes[0];
+ if (inSize <= kDefaultLimit)
+ sizeIsDefined = true;
+ }
+
+ ISequentialInStream *inStream = inStreams[0];
+
+ _mainStream.SetStream(outStreams[0]);
+ _mainStream.Init();
+ _callStream.SetStream(outStreams[1]);
+ _callStream.Init();
+ _jumpStream.SetStream(outStreams[2]);
+ _jumpStream.Init();
+ _rangeEncoder.SetStream(outStreams[3]);
+ _rangeEncoder.Init();
+ for (int i = 0; i < 256 + 2; i++)
+ _statusEncoder[i].Init();
+ CCoderReleaser releaser(this);
+
+ CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
+ {
+ inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
+ }
+
+ UInt32 nowPos = 0;
+ UInt64 nowPos64 = 0;
+ UInt32 bufferPos = 0;
+
+ Byte prevByte = 0;
+
+ UInt64 subStreamIndex = 0;
+ UInt64 subStreamStartPos = 0;
+ UInt64 subStreamEndPos = 0;
+
+ for (;;)
+ {
+ UInt32 processedSize = 0;
+ for (;;)
+ {
+ UInt32 size = kBufferSize - (bufferPos + processedSize);
+ UInt32 processedSizeLoc;
+ if (size == 0)
+ break;
+ RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
+ if (processedSizeLoc == 0)
+ break;
+ processedSize += processedSizeLoc;
+ }
+ UInt32 endPos = bufferPos + processedSize;
+
+ if (endPos < 5)
+ {
+ // change it
+ for (bufferPos = 0; bufferPos < endPos; bufferPos++)
+ {
+ Byte b = _buffer[bufferPos];
+ _mainStream.WriteByte(b);
+ UInt32 index;
+ if (b == 0xE8)
+ index = prevByte;
+ else if (b == 0xE9)
+ index = 256;
+ else if (IsJcc(prevByte, b))
+ index = 257;
+ else
+ {
+ prevByte = b;
+ continue;
+ }
+ _statusEncoder[index].Encode(&_rangeEncoder, 0);
+ prevByte = b;
+ }
+ return Flush();
+ }
+
+ bufferPos = 0;
+
+ UInt32 limit = endPos - 5;
+ while(bufferPos <= limit)
+ {
+ Byte b = _buffer[bufferPos];
+ _mainStream.WriteByte(b);
+ if (!IsJ(prevByte, b))
+ {
+ bufferPos++;
+ prevByte = b;
+ continue;
+ }
+ Byte nextByte = _buffer[bufferPos + 4];
+ UInt32 src =
+ (UInt32(nextByte) << 24) |
+ (UInt32(_buffer[bufferPos + 3]) << 16) |
+ (UInt32(_buffer[bufferPos + 2]) << 8) |
+ (_buffer[bufferPos + 1]);
+ UInt32 dest = (nowPos + bufferPos + 5) + src;
+ // if (Test86MSByte(nextByte))
+ bool convert;
+ if (getSubStreamSize != NULL)
+ {
+ UInt64 currentPos = (nowPos64 + bufferPos);
+ while (subStreamEndPos < currentPos)
+ {
+ UInt64 subStreamSize;
+ HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
+ if (result == S_OK)
+ {
+ subStreamStartPos = subStreamEndPos;
+ subStreamEndPos += subStreamSize;
+ subStreamIndex++;
+ }
+ else if (result == S_FALSE || result == E_NOTIMPL)
+ {
+ getSubStreamSize.Release();
+ subStreamStartPos = 0;
+ subStreamEndPos = subStreamStartPos - 1;
+ }
+ else
+ return result;
+ }
+ if (getSubStreamSize == NULL)
+ {
+ if (sizeIsDefined)
+ convert = (dest < inSize);
+ else
+ convert = Test86MSByte(nextByte);
+ }
+ else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)
+ convert = Test86MSByte(nextByte);
+ else
+ {
+ UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
+ convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
+ }
+ }
+ else if (sizeIsDefined)
+ convert = (dest < inSize);
+ else
+ convert = Test86MSByte(nextByte);
+ unsigned index = GetIndex(prevByte, b);
+ if (convert)
+ {
+ _statusEncoder[index].Encode(&_rangeEncoder, 1);
+ bufferPos += 5;
+ COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
+ for (int i = 24; i >= 0; i -= 8)
+ s.WriteByte((Byte)(dest >> i));
+ prevByte = nextByte;
+ }
+ else
+ {
+ _statusEncoder[index].Encode(&_rangeEncoder, 0);
+ bufferPos++;
+ prevByte = b;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+
+ if (progress != NULL)
+ {
+ /*
+ const UInt64 compressedSize =
+ _mainStream.GetProcessedSize() +
+ _callStream.GetProcessedSize() +
+ _jumpStream.GetProcessedSize() +
+ _rangeEncoder.GetProcessedSize();
+ */
+ RINOK(progress->SetRatioInfo(&nowPos64, NULL));
+ }
+
+ UInt32 i = 0;
+ while(bufferPos < endPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ return CodeReal(inStreams, inSizes, numInStreams,
+ outStreams, outSizes,numOutStreams, progress);
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+#endif
+
+HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams,
+ const UInt64 ** /* inSizes */,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 ** /* outSizes */,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 4 || numOutStreams != 1)
+ return E_INVALIDARG;
+
+ if (!_mainInStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ if (!_callStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_jumpStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_outStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+
+ _mainInStream.SetStream(inStreams[0]);
+ _callStream.SetStream(inStreams[1]);
+ _jumpStream.SetStream(inStreams[2]);
+ _rangeDecoder.SetStream(inStreams[3]);
+ _outStream.SetStream(outStreams[0]);
+
+ _mainInStream.Init();
+ _callStream.Init();
+ _jumpStream.Init();
+ _rangeDecoder.Init();
+ _outStream.Init();
+
+ for (int i = 0; i < 256 + 2; i++)
+ _statusDecoder[i].Init();
+
+ CCoderReleaser releaser(this);
+
+ Byte prevByte = 0;
+ UInt32 processedBytes = 0;
+ for (;;)
+ {
+ if (processedBytes >= (1 << 20) && progress != NULL)
+ {
+ /*
+ const UInt64 compressedSize =
+ _mainInStream.GetProcessedSize() +
+ _callStream.GetProcessedSize() +
+ _jumpStream.GetProcessedSize() +
+ _rangeDecoder.GetProcessedSize();
+ */
+ const UInt64 nowPos64 = _outStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(NULL, &nowPos64));
+ processedBytes = 0;
+ }
+ UInt32 i;
+ Byte b = 0;
+ const UInt32 kBurstSize = (1 << 18);
+ for (i = 0; i < kBurstSize; i++)
+ {
+ if (!_mainInStream.ReadByte(b))
+ return Flush();
+ _outStream.WriteByte(b);
+ if (IsJ(prevByte, b))
+ break;
+ prevByte = b;
+ }
+ processedBytes += i;
+ if (i == kBurstSize)
+ continue;
+ unsigned index = GetIndex(prevByte, b);
+ if (_statusDecoder[index].Decode(&_rangeDecoder) == 1)
+ {
+ UInt32 src = 0;
+ CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b0;
+ if(!s.ReadByte(b0))
+ return S_FALSE;
+ src <<= 8;
+ src |= ((UInt32)b0);
+ }
+ UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
+ _outStream.WriteByte((Byte)(dest));
+ _outStream.WriteByte((Byte)(dest >> 8));
+ _outStream.WriteByte((Byte)(dest >> 16));
+ _outStream.WriteByte((Byte)(dest >> 24));
+ prevByte = (Byte)(dest >> 24);
+ processedBytes += 4;
+ }
+ else
+ prevByte = b;
+ }
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ return CodeReal(inStreams, inSizes, numInStreams,
+ outStreams, outSizes,numOutStreams, progress);
+ }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Compress/Branch/x86_2.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Branch/x86_2.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Branch/x86_2.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,123 @@
+// x86_2.h
+
+#ifndef __BRANCH_X86_2_H
+#define __BRANCH_X86_2_H
+
+#include "../../../Common/MyCom.h"
+#include "../RangeCoder/RangeCoderBit.h"
+#include "../../ICoder.h"
+
+namespace NCompress {
+namespace NBcj2 {
+
+const int kNumMoveBits = 5;
+
+#ifndef EXTRACT_ONLY
+
+class CEncoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ CEncoder(): _buffer(0) {};
+ ~CEncoder();
+ bool Create();
+
+ COutBuffer _mainStream;
+ COutBuffer _callStream;
+ COutBuffer _jumpStream;
+ NCompress::NRangeCoder::CEncoder _rangeEncoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];
+
+ HRESULT Flush();
+ void ReleaseStreams()
+ {
+ _mainStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeEncoder.ReleaseStream();
+ }
+
+ class CCoderReleaser
+ {
+ CEncoder *_coder;
+ public:
+ CCoderReleaser(CEncoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+
+ MY_UNKNOWN_IMP
+
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
+
+class CDecoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+public:
+ CInBuffer _mainInStream;
+ CInBuffer _callStream;
+ CInBuffer _jumpStream;
+ NCompress::NRangeCoder::CDecoder _rangeDecoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];
+
+ COutBuffer _outStream;
+
+ void ReleaseStreams()
+ {
+ _mainInStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeDecoder.ReleaseStream();
+ _outStream.ReleaseStream();
+ }
+
+ HRESULT Flush() { return _outStream.Flush(); }
+ class CCoderReleaser
+ {
+ CDecoder *_coder;
+ public:
+ CCoderReleaser(CDecoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+ MY_UNKNOWN_IMP
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,38 @@
+// ByteSwap.cpp
+
+#include "StdAfx.h"
+
+#include "ByteSwap.h"
+
+STDMETHODIMP CByteSwap2::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size)
+{
+ const UInt32 kStep = 2;
+ UInt32 i;
+ for (i = 0; i + kStep <= size; i += kStep)
+ {
+ Byte b = data[i];
+ data[i] = data[i + 1];
+ data[i + 1] = b;
+ }
+ return i;
+}
+
+STDMETHODIMP CByteSwap4::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)
+{
+ const UInt32 kStep = 4;
+ UInt32 i;
+ for (i = 0; i + kStep <= size; i += kStep)
+ {
+ Byte b0 = data[i];
+ Byte b1 = data[i + 1];
+ data[i] = data[i + 3];
+ data[i + 1] = data[i + 2];
+ data[i + 2] = b1;
+ data[i + 3] = b0;
+ }
+ return i;
+}
Added: trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,37 @@
+// ByteSwap.h
+
+#ifndef __BYTESWAP_H
+#define __BYTESWAP_H
+
+#include "../../ICoder.h"
+#include "Common/MyCom.h"
+
+// {23170F69-40C1-278B-0203-020000000000}
+DEFINE_GUID(CLSID_CCompressConvertByteSwap2,
+0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0203-040000000000}
+DEFINE_GUID(CLSID_CCompressConvertByteSwap4,
+0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+class CByteSwap2:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+class CByteSwap4:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwapRegister.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwapRegister.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/ByteSwap/ByteSwapRegister.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,17 @@
+// ByteSwapRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "ByteSwap.h"
+static void *CreateCodec2() { return (void *)(ICompressFilter *)(new CByteSwap2); }
+static void *CreateCodec4() { return (void *)(ICompressFilter *)(new CByteSwap4); }
+
+static CCodecInfo g_CodecsInfo[] =
+{
+ { CreateCodec2, CreateCodec4, 0x020302, L"Swap2", 1, true },
+ { CreateCodec4, CreateCodec4, 0x020304, L"Swap4", 1, true }
+};
+
+REGISTER_CODECS(ByteSwap)
Added: trunk/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/CodecExports.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/CodecExports.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/CodecExports.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,157 @@
+// CodecExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/ComTry.h"
+#include "../../Windows/PropVariant.h"
+#include "../Common/RegisterCodec.h"
+#include "../ICoder.h"
+
+extern unsigned int g_NumCodecs;
+extern const CCodecInfo *g_Codecs[];
+
+static const UInt16 kDecodeId = 0x2790;
+
+DEFINE_GUID(CLSID_CCodec,
+0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
+{
+ if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+}
+
+static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
+{
+ return SetPropString((const char *)&guid, sizeof(GUID), value);
+}
+
+static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value)
+{
+ GUID clsId = CLSID_CCodec;
+ for (int i = 0; i < sizeof(id); i++, id >>= 8)
+ clsId.Data4[i] = (Byte)(id & 0xFF);
+ if (encode)
+ clsId.Data3++;
+ return SetPropGUID(clsId, value);
+}
+
+static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index)
+{
+ index = -1;
+ if (clsID->Data1 != CLSID_CCodec.Data1 ||
+ clsID->Data2 != CLSID_CCodec.Data2 ||
+ (clsID->Data3 & ~1) != kDecodeId)
+ return S_OK;
+ encode = (clsID->Data3 != kDecodeId);
+ UInt64 id = 0;
+ for (int j = 0; j < 8; j++)
+ id |= ((UInt64)clsID->Data4[j]) << (8 * j);
+ for (UInt32 i = 0; i < g_NumCodecs; i++)
+ {
+ const CCodecInfo &codec = *g_Codecs[i];
+ if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder)
+ continue;
+ if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||
+ codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)
+ return E_NOINTERFACE;
+ index = i;
+ return S_OK;
+ }
+ return S_OK;
+}
+
+STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ bool isCoder = (*iid == IID_ICompressCoder) != 0;
+ bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;
+ bool isFilter = (*iid == IID_ICompressFilter) != 0;
+ const CCodecInfo &codec = *g_Codecs[index];
+ if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||
+ codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)
+ return E_NOINTERFACE;
+ if (encode)
+ {
+ if (!codec.CreateEncoder)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = codec.CreateEncoder();
+ }
+ else
+ {
+ if (!codec.CreateDecoder)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = codec.CreateDecoder();
+ }
+ if (isCoder)
+ ((ICompressCoder *)*outObject)->AddRef();
+ else if (isCoder2)
+ ((ICompressCoder2 *)*outObject)->AddRef();
+ else
+ ((ICompressFilter *)*outObject)->AddRef();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)
+{
+ *outObject = 0;
+ bool isCoder = (*iid == IID_ICompressCoder) != 0;
+ bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;
+ bool isFilter = (*iid == IID_ICompressFilter) != 0;
+ if (!isCoder && !isCoder2 && !isFilter)
+ return E_NOINTERFACE;
+ bool encode;
+ int codecIndex;
+ HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex);
+ if (res != S_OK)
+ return res;
+ if (codecIndex < 0)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ return CreateCoder2(encode, codecIndex, iid, outObject);
+}
+
+STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
+{
+ ::VariantClear((VARIANTARG *)value);
+ const CCodecInfo &codec = *g_Codecs[codecIndex];
+ switch(propID)
+ {
+ case NMethodPropID::kID:
+ {
+ value->uhVal.QuadPart = (UInt64)codec.Id;
+ value->vt = VT_UI8;
+ break;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0)
+ value->vt = VT_BSTR;
+ break;
+ case NMethodPropID::kDecoder:
+ if (codec.CreateDecoder)
+ return SetClassID(codec.Id, false, value);
+ break;
+ case NMethodPropID::kEncoder:
+ if (codec.CreateEncoder)
+ return SetClassID(codec.Id, true, value);
+ break;
+ case NMethodPropID::kInStreams:
+ {
+ if (codec.NumInStreams != 1)
+ {
+ value->vt = VT_UI4;
+ value->ulVal = codec.NumInStreams;
+ }
+ break;
+ }
+ }
+ return S_OK;
+}
+
+STDAPI GetNumberOfMethods(UINT32 *numCodecs)
+{
+ *numCodecs = g_NumCodecs;
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/Compress/Copy/CopyCoder.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Copy/CopyCoder.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Copy/CopyCoder.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,62 @@
+// Compress/CopyCoder.cpp
+
+#include "StdAfx.h"
+
+extern "C"
+{
+#include "../../../../C/Alloc.h"
+}
+
+#include "CopyCoder.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NCompress {
+
+static const UInt32 kBufferSize = 1 << 17;
+
+CCopyCoder::~CCopyCoder()
+{
+ ::MidFree(_buffer);
+}
+
+STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (_buffer == 0)
+ {
+ _buffer = (Byte *)::MidAlloc(kBufferSize);
+ if (_buffer == 0)
+ return E_OUTOFMEMORY;
+ }
+
+ TotalSize = 0;
+ for (;;)
+ {
+ UInt32 realProcessedSize;
+ UInt32 size = kBufferSize;
+ if (outSize != 0)
+ if (size > *outSize - TotalSize)
+ size = (UInt32)(*outSize - TotalSize);
+ RINOK(inStream->Read(_buffer, size, &realProcessedSize));
+ if (realProcessedSize == 0)
+ break;
+ RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL));
+ TotalSize += realProcessedSize;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = TotalSize;
+ return S_OK;
+}
+
+}
+
Added: trunk/lzma/CPP/7zip/Compress/Copy/CopyCoder.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Copy/CopyCoder.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Copy/CopyCoder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,33 @@
+// Compress/CopyCoder.h
+
+#ifndef __COMPRESS_COPYCODER_H
+#define __COMPRESS_COPYCODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+namespace NCompress {
+
+class CCopyCoder:
+ public ICompressCoder,
+ public ICompressGetInStreamProcessedSize,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ UInt64 TotalSize;
+ CCopyCoder(): TotalSize(0) , _buffer(0) {};
+ ~CCopyCoder();
+
+ MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+};
+
+}
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/Copy/CopyRegister.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Copy/CopyRegister.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Copy/CopyRegister.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,13 @@
+// LZMARegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "CopyCoder.h"
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::CCopyCoder); }
+
+static CCodecInfo g_CodecInfo =
+{ CreateCodec, CreateCodec, 0x00, L"Copy", 1, false };
+
+REGISTER_CODEC(Copy)
Added: trunk/lzma/CPP/7zip/Compress/Copy/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Copy/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Copy/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Compress/Copy/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/Copy/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/Copy/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZ/LZOutWindow.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZ/LZOutWindow.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZ/LZOutWindow.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,16 @@
+// LZOutWindow.cpp
+
+#include "StdAfx.h"
+
+#include "LZOutWindow.h"
+
+void CLZOutWindow::Init(bool solid)
+{
+ if(!solid)
+ COutBuffer::Init();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+
Added: trunk/lzma/CPP/7zip/Compress/LZ/LZOutWindow.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZ/LZOutWindow.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZ/LZOutWindow.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,65 @@
+// LZOutWindow.h
+
+#ifndef __LZ_OUT_WINDOW_H
+#define __LZ_OUT_WINDOW_H
+
+#include "../../IStream.h"
+#include "../../Common/OutBuffer.h"
+
+#ifndef _NO_EXCEPTIONS
+typedef COutBufferException CLZOutWindowException;
+#endif
+
+class CLZOutWindow: public COutBuffer
+{
+public:
+ void Init(bool solid = false);
+
+ // distance >= 0, len > 0,
+ bool CopyBlock(UInt32 distance, UInt32 len)
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (distance >= _pos)
+ {
+ if (!_overDict || distance >= _bufferSize)
+ return false;
+ pos += _bufferSize;
+ }
+ if (_limitPos - _pos > len && _bufferSize - pos > len)
+ {
+ const Byte *src = _buffer + pos;
+ Byte *dest = _buffer + _pos;
+ _pos += len;
+ do
+ *dest++ = *src++;
+ while(--len != 0);
+ }
+ else do
+ {
+ if (pos == _bufferSize)
+ pos = 0;
+ _buffer[_pos++] = _buffer[pos++];
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+ while(--len != 0);
+ return true;
+ }
+
+ void PutByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+
+ Byte GetByte(UInt32 distance) const
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (pos >= _bufferSize)
+ pos += _bufferSize;
+ return _buffer[pos];
+ }
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZ/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZ/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZ/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA/LZMA.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA/LZMA.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA/LZMA.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,82 @@
+// LZMA.h
+
+#ifndef __LZMA_H
+#define __LZMA_H
+
+namespace NCompress {
+namespace NLZMA {
+
+const UInt32 kNumRepDistances = 4;
+
+const int kNumStates = 12;
+
+const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+class CState
+{
+public:
+ Byte Index;
+ void Init() { Index = 0; }
+ void UpdateChar() { Index = kLiteralNextStates[Index]; }
+ void UpdateMatch() { Index = kMatchNextStates[Index]; }
+ void UpdateRep() { Index = kRepNextStates[Index]; }
+ void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
+ bool IsCharState() const { return Index < 7; }
+};
+
+const int kNumPosSlotBits = 6;
+const int kDicLogSizeMin = 0;
+const int kDicLogSizeMax = 32;
+const int kDistTableSizeMax = kDicLogSizeMax * 2;
+
+const UInt32 kNumLenToPosStates = 4;
+
+inline UInt32 GetLenToPosState(UInt32 len)
+{
+ len -= 2;
+ if (len < kNumLenToPosStates)
+ return len;
+ return kNumLenToPosStates - 1;
+}
+
+namespace NLength {
+
+const int kNumPosStatesBitsMax = 4;
+const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+
+const int kNumPosStatesBitsEncodingMax = 4;
+const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+const int kNumLowBits = 3;
+const int kNumMidBits = 3;
+const int kNumHighBits = 8;
+const UInt32 kNumLowSymbols = 1 << kNumLowBits;
+const UInt32 kNumMidSymbols = 1 << kNumMidBits;
+const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
+
+}
+
+const UInt32 kMatchMinLen = 2;
+const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
+
+const int kNumAlignBits = 4;
+const UInt32 kAlignTableSize = 1 << kNumAlignBits;
+const UInt32 kAlignMask = (kAlignTableSize - 1);
+
+const UInt32 kStartPosModelIndex = 4;
+const UInt32 kEndPosModelIndex = 14;
+const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+
+const int kNumLitPosStatesBitsEncodingMax = 4;
+const int kNumLitContextBitsMax = 8;
+
+const int kNumMoveBits = 5;
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,338 @@
+// LZMADecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LZMADecoder.h"
+#include "../../../Common/Defs.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
+void CDecoder::Init()
+{
+ {
+ for(int i = 0; i < kNumStates; i++)
+ {
+ for (UInt32 j = 0; j <= _posStateMask; j++)
+ {
+ _isMatch[i][j].Init();
+ _isRep0Long[i][j].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+ }
+ {
+ for (UInt32 i = 0; i < kNumLenToPosStates; i++)
+ _posSlotDecoder[i].Init();
+ }
+ {
+ for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ _posDecoders[i].Init();
+ }
+ _posAlignDecoder.Init();
+ _lenDecoder.Init(_posStateMask + 1);
+ _repMatchLenDecoder.Init(_posStateMask + 1);
+ _literalDecoder.Init();
+
+ _state.Init();
+ _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0;
+}
+
+HRESULT CDecoder::CodeSpec(UInt32 curSize)
+{
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize();
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ }
+
+ if (_remainLen == kLenIdFinished)
+ return S_OK;
+ if (_remainLen == kLenIdNeedInit)
+ {
+ _rangeDecoder.Init();
+ Init();
+ _remainLen = 0;
+ }
+ if (curSize == 0)
+ return S_OK;
+
+ UInt32 rep0 = _reps[0];
+ UInt32 rep1 = _reps[1];
+ UInt32 rep2 = _reps[2];
+ UInt32 rep3 = _reps[3];
+ CState state = _state;
+ Byte previousByte;
+
+ while(_remainLen > 0 && curSize > 0)
+ {
+ previousByte = _outWindowStream.GetByte(rep0);
+ _outWindowStream.PutByte(previousByte);
+ _remainLen--;
+ curSize--;
+ }
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ if (nowPos64 == 0)
+ previousByte = 0;
+ else
+ previousByte = _outWindowStream.GetByte(0);
+
+ while(curSize > 0)
+ {
+ {
+ #ifdef _NO_EXCEPTIONS
+ if (_rangeDecoder.Stream.ErrorCode != S_OK)
+ return _rangeDecoder.Stream.ErrorCode;
+ #endif
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+ if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ if(!state.IsCharState())
+ previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder,
+ (UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0));
+ else
+ previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder,
+ (UInt32)nowPos64, previousByte);
+ _outWindowStream.PutByte(previousByte);
+ state.UpdateChar();
+ curSize--;
+ nowPos64++;
+ }
+ else
+ {
+ UInt32 len;
+ if(_isRep[state.Index].Decode(&_rangeDecoder) == 1)
+ {
+ len = 0;
+ if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0)
+ {
+ if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ state.UpdateShortRep();
+ len = 1;
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = rep1;
+ else
+ {
+ if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ if (len == 0)
+ {
+ len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
+ state.UpdateRep();
+ }
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState);
+ state.UpdateMatch();
+ UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 numDirectBits = (posSlot >> 1) - 1;
+ rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+
+ if (posSlot < kEndPosModelIndex)
+ rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders +
+ rep0 - posSlot - 1, &_rangeDecoder, numDirectBits);
+ else
+ {
+ rep0 += (_rangeDecoder.DecodeDirectBits(
+ numDirectBits - kNumAlignBits) << kNumAlignBits);
+ rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder);
+ if (rep0 == 0xFFFFFFFF)
+ {
+ _remainLen = kLenIdFinished;
+ return S_OK;
+ }
+ }
+ }
+ else
+ rep0 = posSlot;
+ }
+ UInt32 locLen = len;
+ if (len > curSize)
+ locLen = (UInt32)curSize;
+ if (!_outWindowStream.CopyBlock(rep0, locLen))
+ return S_FALSE;
+ previousByte = _outWindowStream.GetByte(0);
+ curSize -= locLen;
+ nowPos64 += locLen;
+ len -= locLen;
+ if (len != 0)
+ {
+ _remainLen = (Int32)len;
+ break;
+ }
+
+ #ifdef _NO_EXCEPTIONS
+ if (_outWindowStream.ErrorCode != S_OK)
+ return _outWindowStream.ErrorCode;
+ #endif
+ }
+ }
+ }
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+ _reps[0] = rep0;
+ _reps[1] = rep1;
+ _reps[2] = rep2;
+ _reps[3] = rep3;
+ _state = state;
+
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ SetInStream(inStream);
+ _outWindowStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CDecoderFlusher flusher(this);
+
+ for (;;)
+ {
+ UInt32 curSize = 1 << 18;
+ RINOK(CodeSpec(curSize));
+ if (_remainLen == kLenIdFinished)
+ break;
+ if (progress != NULL)
+ {
+ UInt64 inSize = _rangeDecoder.GetProcessedSize();
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
+ }
+ if (_outSizeDefined)
+ if (_outWindowStream.GetProcessedSize() >= _outSize)
+ break;
+ }
+ flusher.NeedFlush = false;
+ return Flush();
+}
+
+
+#ifdef _NO_EXCEPTIONS
+
+#define LZMA_TRY_BEGIN
+#define LZMA_TRY_END
+
+#else
+
+#define LZMA_TRY_BEGIN try {
+#define LZMA_TRY_END } \
+ catch(const CInBufferException &e) { return e.ErrorCode; } \
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; } \
+ catch(...) { return S_FALSE; }
+
+#endif
+
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ LZMA_TRY_BEGIN
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ LZMA_TRY_END
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
+{
+ if (size < 5)
+ return E_INVALIDARG;
+ int lc = properties[0] % 9;
+ Byte remainder = (Byte)(properties[0] / 9);
+ int lp = remainder % 5;
+ int pb = remainder / 5;
+ if (pb > NLength::kNumPosStatesBitsMax)
+ return E_INVALIDARG;
+ _posStateMask = (1 << pb) - 1;
+ UInt32 dictionarySize = 0;
+ for (int i = 0; i < 4; i++)
+ dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
+ if (!_outWindowStream.Create(dictionarySize))
+ return E_OUTOFMEMORY;
+ if (!_literalDecoder.Create(lp, lc))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _rangeDecoder.GetProcessedSize();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
+{
+ _rangeDecoder.SetStream(inStream);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+ _rangeDecoder.ReleaseStream();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ _outSizeDefined = (outSize != NULL);
+ if (_outSizeDefined)
+ _outSize = *outSize;
+ _remainLen = kLenIdNeedInit;
+ _outWindowStream.Init();
+ return S_OK;
+}
+
+#ifndef NO_READ_FROM_CODER
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ LZMA_TRY_BEGIN
+ if (processedSize)
+ *processedSize = 0;
+ const UInt64 startPos = _outWindowStream.GetProcessedSize();
+ _outWindowStream.SetMemStream((Byte *)data);
+ RINOK(CodeSpec(size));
+ if (processedSize)
+ *processedSize = (UInt32)(_outWindowStream.GetProcessedSize() - startPos);
+ return Flush();
+ LZMA_TRY_END
+}
+
+#endif
+
+}}
Added: trunk/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,255 @@
+// LZMA/Decoder.h
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+extern "C"
+{
+ #include "../../../../C/Alloc.h"
+}
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
+
+class CLiteralDecoder2
+{
+ CMyBitDecoder _decoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _decoders[i].Init();
+ }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ UInt32 matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
+ // symbol = (symbol << 1) | bit;
+ UInt32 bit;
+ RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
+ bit = 0, bit = 1)
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+};
+
+class CLiteralDecoder
+{
+ CLiteralDecoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralDecoder(): _coders(0) {}
+ ~CLiteralDecoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) !=
+ (_numPrevBits + _numPosBits) )
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ UInt32 GetState(UInt32 pos, Byte prevByte) const
+ { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
+ { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
+ { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+};
+
+namespace NLength {
+
+class CDecoder
+{
+ CMyBitDecoder _choice;
+ CMyBitDecoder _choice2;
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates)
+ {
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+ }
+ UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
+ {
+ if(_choice.Decode(rangeDecoder) == 0)
+ return _lowCoder[posState].Decode(rangeDecoder);
+ if(_choice2.Decode(rangeDecoder) == 0)
+ return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
+ return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
+ }
+};
+
+}
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public ICompressGetInStreamProcessedSize,
+ #ifndef NO_READ_FROM_CODER
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ CLZOutWindow _outWindowStream;
+ NRangeCoder::CDecoder _rangeDecoder;
+
+ CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
+ CMyBitDecoder _isRep[kNumStates];
+ CMyBitDecoder _isRepG0[kNumStates];
+ CMyBitDecoder _isRepG1[kNumStates];
+ CMyBitDecoder _isRepG2[kNumStates];
+ CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
+
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
+
+ CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
+
+ NLength::CDecoder _lenDecoder;
+ NLength::CDecoder _repMatchLenDecoder;
+
+ CLiteralDecoder _literalDecoder;
+
+ UInt32 _posStateMask;
+
+ ///////////////////
+ // State
+ UInt32 _reps[4];
+ CState _state;
+ Int32 _remainLen; // -1 means end of stream. // -2 means need Init
+ UInt64 _outSize;
+ bool _outSizeDefined;
+
+ void Init();
+ HRESULT CodeSpec(UInt32 size);
+public:
+
+ #ifndef NO_READ_FROM_CODER
+ MY_UNKNOWN_IMP5(
+ ICompressSetDecoderProperties2,
+ ICompressGetInStreamProcessedSize,
+ ICompressSetInStream,
+ ICompressSetOutStreamSize,
+ ISequentialInStream)
+ #else
+ MY_UNKNOWN_IMP2(
+ ICompressSetDecoderProperties2,
+ ICompressGetInStreamProcessedSize)
+ #endif
+
+ void ReleaseStreams()
+ {
+ _outWindowStream.ReleaseStream();
+ ReleaseInStream();
+ }
+
+ class CDecoderFlusher
+ {
+ CDecoder *_decoder;
+ public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ _decoder->Flush();
+ _decoder->ReleaseStreams();
+ }
+ };
+
+ HRESULT Flush() { return _outWindowStream.Flush(); }
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ #ifndef NO_READ_FROM_CODER
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+
+ CDecoder(): _outSizeDefined(false) {}
+ virtual ~CDecoder() {}
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1547 @@
+// LZMA/Encoder.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#ifdef _WIN32
+#define USE_ALLOCA
+#endif
+
+#ifdef USE_ALLOCA
+#ifdef _WIN32
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#endif
+
+#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+#include "LZMAEncoder.h"
+
+// extern "C" { #include "../../../../C/7zCrc.h" }
+
+// #define SHOW_STAT
+
+
+namespace NCompress {
+namespace NLZMA {
+
+// struct CCrcInit { CCrcInit() { InitCrcTable(); } } g_CrcInit;
+
+const int kDefaultDictionaryLogSize = 22;
+const UInt32 kNumFastBytesDefault = 0x20;
+
+#ifndef LZMA_LOG_BSR
+Byte g_FastPos[1 << kNumLogBits];
+
+class CFastPosInit
+{
+public:
+ CFastPosInit() { Init(); }
+ void Init()
+ {
+ const Byte kFastSlots = kNumLogBits * 2;
+ int c = 2;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+
+ for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)
+ {
+ UInt32 k = (1 << ((slotFast >> 1) - 1));
+ for (UInt32 j = 0; j < k; j++, c++)
+ g_FastPos[c] = slotFast;
+ }
+ }
+} g_FastPosInit;
+#endif
+
+void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol)
+{
+ UInt32 context = 1;
+ int i = 8;
+ do
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ _encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ while(i != 0);
+}
+
+void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder,
+ Byte matchByte, Byte symbol)
+{
+ UInt32 context = 1;
+ int i = 8;
+ do
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ UInt32 matchBit = (matchByte >> i) & 1;
+ _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ {
+ while(i != 0)
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ _encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ break;
+ }
+ }
+ while(i != 0);
+}
+
+UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const
+{
+ UInt32 price = 0;
+ UInt32 context = 1;
+ int i = 8;
+ if (matchMode)
+ {
+ do
+ {
+ i--;
+ UInt32 matchBit = (matchByte >> i) & 1;
+ UInt32 bit = (symbol >> i) & 1;
+ price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ break;
+ }
+ while (i != 0);
+ }
+ while(i != 0)
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ price += _encoders[context].GetPrice(bit);
+ context = (context << 1) | bit;
+ }
+ return price;
+};
+
+
+namespace NLength {
+
+void CEncoder::Init(UInt32 numPosStates)
+{
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+}
+
+void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
+{
+ if(symbol < kNumLowSymbols)
+ {
+ _choice.Encode(rangeEncoder, 0);
+ _lowCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ _choice.Encode(rangeEncoder, 1);
+ if(symbol < kNumLowSymbols + kNumMidSymbols)
+ {
+ _choice2.Encode(rangeEncoder, 0);
+ _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols);
+ }
+ else
+ {
+ _choice2.Encode(rangeEncoder, 1);
+ _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols);
+ }
+ }
+}
+
+void CEncoder::SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const
+{
+ UInt32 a0 = _choice.GetPrice0();
+ UInt32 a1 = _choice.GetPrice1();
+ UInt32 b0 = a1 + _choice2.GetPrice0();
+ UInt32 b1 = a1 + _choice2.GetPrice1();
+ UInt32 i = 0;
+ for (i = 0; i < kNumLowSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = a0 + _lowCoder[posState].GetPrice(i);
+ }
+ for (; i < kNumLowSymbols + kNumMidSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = b0 + _midCoder[posState].GetPrice(i - kNumLowSymbols);
+ }
+ for (; i < numSymbols; i++)
+ prices[i] = b1 + _highCoder.GetPrice(i - kNumLowSymbols - kNumMidSymbols);
+}
+
+}
+
+CEncoder::CEncoder():
+ _numFastBytes(kNumFastBytesDefault),
+ _distTableSize(kDefaultDictionaryLogSize * 2),
+ _posStateBits(2),
+ _posStateMask(4 - 1),
+ _numLiteralPosStateBits(0),
+ _numLiteralContextBits(3),
+ _dictionarySize(1 << kDefaultDictionaryLogSize),
+ _matchFinderCycles(0),
+ #ifdef COMPRESS_MF_MT
+ _multiThread(false),
+ #endif
+ _writeEndMark(false)
+{
+ MatchFinder_Construct(&_matchFinderBase);
+ // _maxMode = false;
+ _fastMode = false;
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Construct(&_matchFinderMt);
+ _matchFinderMt.MatchFinder = &_matchFinderBase;
+ #endif
+}
+
+
+static void *SzAlloc(size_t size) { return BigAlloc(size); }
+static void SzFree(void *address) { BigFree(address); }
+ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+CEncoder::~CEncoder()
+{
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Destruct(&_matchFinderMt, &g_Alloc);
+ #endif
+ MatchFinder_Free(&_matchFinderBase, &g_Alloc);
+}
+
+static const UInt32 kBigHashDicLimit = (UInt32)1 << 24;
+
+HRESULT CEncoder::Create()
+{
+ if (!_rangeEncoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ bool btMode = (_matchFinderBase.btMode != 0);
+ #ifdef COMPRESS_MF_MT
+ _mtMode = (_multiThread && !_fastMode && btMode);
+ #endif
+
+ if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits))
+ return E_OUTOFMEMORY;
+
+ _matchFinderBase.bigHash = (_dictionarySize > kBigHashDicLimit);
+
+ UInt32 numCycles = 16 + (_numFastBytes >> 1);
+ if (!btMode)
+ numCycles >>= 1;
+ if (_matchFinderCycles != 0)
+ numCycles = _matchFinderCycles;
+ _matchFinderBase.cutValue = numCycles;
+ #ifdef COMPRESS_MF_MT
+ if (_mtMode)
+ {
+ RINOK(MatchFinderMt_Create(&_matchFinderMt, _dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen, &g_Alloc));
+ _matchFinderObj = &_matchFinderMt;
+ MatchFinderMt_CreateVTable(&_matchFinderMt, &_matchFinder);
+ }
+ else
+ #endif
+ {
+ if (!MatchFinder_Create(&_matchFinderBase, _dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen, &g_Alloc))
+ return E_OUTOFMEMORY;
+ _matchFinderObj = &_matchFinderBase;
+ MatchFinder_CreateVTable(&_matchFinderBase, &_matchFinder);
+ }
+ return S_OK;
+}
+
+inline wchar_t GetUpperChar(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ c -= 0x20;
+ return c;
+}
+
+static int ParseMatchFinder(const wchar_t *s, int *btMode, UInt32 *numHashBytes /* , int *skipModeBits */)
+{
+ wchar_t c = GetUpperChar(*s++);
+ if (c == L'H')
+ {
+ if (GetUpperChar(*s++) != L'C')
+ return 0;
+ int numHashBytesLoc = (int)(*s++ - L'0');
+ if (numHashBytesLoc < 4 || numHashBytesLoc > 4)
+ return 0;
+ if (*s++ != 0)
+ return 0;
+ *btMode = 0;
+ *numHashBytes = numHashBytesLoc;
+ return 1;
+ }
+ if (c != L'B')
+ return 0;
+
+ if (GetUpperChar(*s++) != L'T')
+ return 0;
+ int numHashBytesLoc = (int)(*s++ - L'0');
+ if (numHashBytesLoc < 2 || numHashBytesLoc > 4)
+ return 0;
+ c = GetUpperChar(*s++);
+ /*
+ int skipModeBitsLoc = 0;
+ if (c == L'D')
+ {
+ skipModeBitsLoc = 2;
+ c = GetUpperChar(*s++);
+ }
+ */
+ if (c != L'\0')
+ return 0;
+ *btMode = 1;
+ *numHashBytes = numHashBytesLoc;
+ // *skipModeBits = skipModeBitsLoc;
+ return 1;
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+{
+ for (UInt32 i = 0; i < numProperties; i++)
+ {
+ const PROPVARIANT &prop = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kNumFastBytes:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 numFastBytes = prop.ulVal;
+ if(numFastBytes < 5 || numFastBytes > kMatchMaxLen)
+ return E_INVALIDARG;
+ _numFastBytes = numFastBytes;
+ break;
+ }
+ case NCoderPropID::kMatchFinderCycles:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ _matchFinderCycles = prop.ulVal;
+ break;
+ }
+ case NCoderPropID::kAlgorithm:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 maximize = prop.ulVal;
+ _fastMode = (maximize == 0);
+ // _maxMode = (maximize >= 2);
+ break;
+ }
+ case NCoderPropID::kMatchFinder:
+ {
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ if (!ParseMatchFinder(prop.bstrVal, &_matchFinderBase.btMode, &_matchFinderBase.numHashBytes /* , &_matchFinderBase.skipModeBits */))
+ return E_INVALIDARG;
+ break;
+ }
+ case NCoderPropID::kMultiThread:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ #ifdef COMPRESS_MF_MT
+ Bool newMultiThread = (prop.boolVal == VARIANT_TRUE);
+ if (newMultiThread != _multiThread)
+ {
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ #endif
+ break;
+ }
+ case NCoderPropID::kNumThreads:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ #ifdef COMPRESS_MF_MT
+ Bool newMultiThread = (prop.ulVal > 1) ? True : False;
+ if (newMultiThread != _multiThread)
+ {
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ #endif
+ break;
+ }
+ case NCoderPropID::kDictionarySize:
+ {
+ const int kDicLogSizeMaxCompress = 30; // must be <= ((kNumLogBits - 1) * 2) + 7 = 31;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 dictionarySize = prop.ulVal;
+ if (dictionarySize < UInt32(1 << kDicLogSizeMin) ||
+ dictionarySize > UInt32(1 << kDicLogSizeMaxCompress))
+ return E_INVALIDARG;
+ _dictionarySize = dictionarySize;
+ UInt32 dicLogSize;
+ for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
+ if (dictionarySize <= (UInt32(1) << dicLogSize))
+ break;
+ _distTableSize = dicLogSize * 2;
+ break;
+ }
+ case NCoderPropID::kPosStateBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _posStateBits = value;
+ _posStateMask = (1 << _posStateBits) - 1;
+ break;
+ }
+ case NCoderPropID::kLitPosBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)kNumLitPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _numLiteralPosStateBits = value;
+ break;
+ }
+ case NCoderPropID::kLitContextBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)kNumLitContextBitsMax)
+ return E_INVALIDARG;
+ _numLiteralContextBits = value;
+ break;
+ }
+ case NCoderPropID::kEndMarker:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE);
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ const UInt32 kPropSize = 5;
+ Byte properties[kPropSize];
+ properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
+ for (int i = 0; i < 4; i++)
+ properties[1 + i] = Byte(_dictionarySize >> (8 * i));
+ return WriteStream(outStream, properties, kPropSize, NULL);
+}
+
+STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream)
+{
+ _rangeEncoder.SetStream(outStream);
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::ReleaseOutStream()
+{
+ _rangeEncoder.ReleaseStream();
+ return S_OK;
+}
+
+HRESULT CEncoder::Init()
+{
+ CBaseState::Init();
+
+ _rangeEncoder.Init();
+
+ for(int i = 0; i < kNumStates; i++)
+ {
+ for (UInt32 j = 0; j <= _posStateMask; j++)
+ {
+ _isMatch[i][j].Init();
+ _isRep0Long[i][j].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+
+ _literalEncoder.Init();
+
+ {
+ for(UInt32 i = 0; i < kNumLenToPosStates; i++)
+ _posSlotEncoder[i].Init();
+ }
+ {
+ for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ _posEncoders[i].Init();
+ }
+
+ _lenEncoder.Init(1 << _posStateBits);
+ _repMatchLenEncoder.Init(1 << _posStateBits);
+
+ _posAlignEncoder.Init();
+
+ _longestMatchWasFound = false;
+ _optimumEndIndex = 0;
+ _optimumCurrentIndex = 0;
+ _additionalOffset = 0;
+
+ return S_OK;
+}
+
+#ifdef SHOW_STAT
+static int ttt = 0;
+#endif
+
+void CEncoder::MovePos(UInt32 num)
+{
+ #ifdef SHOW_STAT
+ ttt += num;
+ printf("\n MovePos %d", num);
+ #endif
+ if (num != 0)
+ {
+ _additionalOffset += num;
+ _matchFinder.Skip(_matchFinderObj, num);
+ }
+}
+
+UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur)
+{
+ _optimumEndIndex = cur;
+ UInt32 posMem = _optimum[cur].PosPrev;
+ UInt32 backMem = _optimum[cur].BackPrev;
+ do
+ {
+ if (_optimum[cur].Prev1IsChar)
+ {
+ _optimum[posMem].MakeAsChar();
+ _optimum[posMem].PosPrev = posMem - 1;
+ if (_optimum[cur].Prev2)
+ {
+ _optimum[posMem - 1].Prev1IsChar = false;
+ _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+ _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+ }
+ }
+ UInt32 posPrev = posMem;
+ UInt32 backCur = backMem;
+
+ backMem = _optimum[posPrev].BackPrev;
+ posMem = _optimum[posPrev].PosPrev;
+
+ _optimum[posPrev].BackPrev = backCur;
+ _optimum[posPrev].PosPrev = cur;
+ cur = posPrev;
+ }
+ while(cur != 0);
+ backRes = _optimum[0].BackPrev;
+ _optimumCurrentIndex = _optimum[0].PosPrev;
+ return _optimumCurrentIndex;
+}
+
+/*
+Out:
+ (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal
+*/
+
+UInt32 CEncoder::GetOptimum(UInt32 position, UInt32 &backRes)
+{
+ if(_optimumEndIndex != _optimumCurrentIndex)
+ {
+ const COptimal &optimum = _optimum[_optimumCurrentIndex];
+ UInt32 lenRes = optimum.PosPrev - _optimumCurrentIndex;
+ backRes = optimum.BackPrev;
+ _optimumCurrentIndex = optimum.PosPrev;
+ return lenRes;
+ }
+ _optimumCurrentIndex = _optimumEndIndex = 0;
+
+ UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+
+ UInt32 lenMain, numDistancePairs;
+ if (!_longestMatchWasFound)
+ {
+ lenMain = ReadMatchDistances(numDistancePairs);
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ numDistancePairs = _numDistancePairs;
+ _longestMatchWasFound = false;
+ }
+
+ const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ if (numAvailableBytes < 2)
+ {
+ backRes = (UInt32)(-1);
+ return 1;
+ }
+ if (numAvailableBytes > kMatchMaxLen)
+ numAvailableBytes = kMatchMaxLen;
+
+ UInt32 reps[kNumRepDistances];
+ UInt32 repLens[kNumRepDistances];
+ UInt32 repMaxIndex = 0;
+ UInt32 i;
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ reps[i] = _repDistances[i];
+ const Byte *data2 = data - (reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 lenTest;
+ for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
+ repLens[i] = lenTest;
+ if (lenTest > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if(repLens[repMaxIndex] >= _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ UInt32 lenRes = repLens[repMaxIndex];
+ MovePos(lenRes - 1);
+ return lenRes;
+ }
+
+ UInt32 *matchDistances = _matchDistances;
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+ Byte currentByte = *data;
+ Byte matchByte = *(data - (reps[0] + 1));
+
+ if(lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+ {
+ backRes = (UInt32)-1;
+ return 1;
+ }
+
+ _optimum[0].State = _state;
+
+ UInt32 posState = (position & _posStateMask);
+
+ _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() +
+ _literalEncoder.GetSubCoder(position, _previousByte)->GetPrice(!_state.IsCharState(), matchByte, currentByte);
+ _optimum[1].MakeAsChar();
+
+ UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
+
+ if(matchByte == currentByte)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+ if(shortRepPrice < _optimum[1].Price)
+ {
+ _optimum[1].Price = shortRepPrice;
+ _optimum[1].MakeAsShortRep();
+ }
+ }
+ UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+ if(lenEnd < 2)
+ {
+ backRes = _optimum[1].BackPrev;
+ return 1;
+ }
+
+ _optimum[1].PosPrev = 0;
+ for (i = 0; i < kNumRepDistances; i++)
+ _optimum[0].Backs[i] = reps[i];
+
+ UInt32 len = lenEnd;
+ do
+ _optimum[len--].Price = kIfinityPrice;
+ while (len >= 2);
+
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 repLen = repLens[i];
+ if (repLen < 2)
+ continue;
+ UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
+ COptimal &optimum = _optimum[repLen];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = i;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while(--repLen >= 2);
+ }
+
+ UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();
+
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= lenMain)
+ {
+ UInt32 offs = 0;
+ while (len > matchDistances[offs])
+ offs += 2;
+ for(; ; len++)
+ {
+ UInt32 distance = matchDistances[offs + 1];
+ UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
+ COptimal &optimum = _optimum[len];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = distance + kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+ if (len == matchDistances[offs])
+ {
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ }
+ }
+ }
+
+ UInt32 cur = 0;
+
+ for (;;)
+ {
+ cur++;
+ if(cur == lenEnd)
+ {
+ return Backward(backRes, cur);
+ }
+ UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+ UInt32 newLen, numDistancePairs;
+ newLen = ReadMatchDistances(numDistancePairs);
+ if(newLen >= _numFastBytes)
+ {
+ _numDistancePairs = numDistancePairs;
+ _longestMatchLength = newLen;
+ _longestMatchWasFound = true;
+ return Backward(backRes, cur);
+ }
+ position++;
+ COptimal &curOptimum = _optimum[cur];
+ UInt32 posPrev = curOptimum.PosPrev;
+ CState state;
+ if (curOptimum.Prev1IsChar)
+ {
+ posPrev--;
+ if (curOptimum.Prev2)
+ {
+ state = _optimum[curOptimum.PosPrev2].State;
+ if (curOptimum.BackPrev2 < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ else
+ state = _optimum[posPrev].State;
+ state.UpdateChar();
+ }
+ else
+ state = _optimum[posPrev].State;
+ if (posPrev == cur - 1)
+ {
+ if (curOptimum.IsShortRep())
+ state.UpdateShortRep();
+ else
+ state.UpdateChar();
+ }
+ else
+ {
+ UInt32 pos;
+ if (curOptimum.Prev1IsChar && curOptimum.Prev2)
+ {
+ posPrev = curOptimum.PosPrev2;
+ pos = curOptimum.BackPrev2;
+ state.UpdateRep();
+ }
+ else
+ {
+ pos = curOptimum.BackPrev;
+ if (pos < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ const COptimal &prevOptimum = _optimum[posPrev];
+ if (pos < kNumRepDistances)
+ {
+ reps[0] = prevOptimum.Backs[pos];
+ UInt32 i;
+ for(i = 1; i <= pos; i++)
+ reps[i] = prevOptimum.Backs[i - 1];
+ for(; i < kNumRepDistances; i++)
+ reps[i] = prevOptimum.Backs[i];
+ }
+ else
+ {
+ reps[0] = (pos - kNumRepDistances);
+ for(UInt32 i = 1; i < kNumRepDistances; i++)
+ reps[i] = prevOptimum.Backs[i - 1];
+ }
+ }
+ curOptimum.State = state;
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ curOptimum.Backs[i] = reps[i];
+ UInt32 curPrice = curOptimum.Price;
+ const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ const Byte currentByte = *data;
+ const Byte matchByte = *(data - (reps[0] + 1));
+
+ UInt32 posState = (position & _posStateMask);
+
+ UInt32 curAnd1Price = curPrice +
+ _isMatch[state.Index][posState].GetPrice0() +
+ _literalEncoder.GetSubCoder(position, *(data - 1))->GetPrice(!state.IsCharState(), matchByte, currentByte);
+
+ COptimal &nextOptimum = _optimum[cur + 1];
+
+ bool nextIsChar = false;
+ if (curAnd1Price < nextOptimum.Price)
+ {
+ nextOptimum.Price = curAnd1Price;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsChar();
+ nextIsChar = true;
+ }
+
+ UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
+
+ if(matchByte == currentByte &&
+ !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+ if(shortRepPrice <= nextOptimum.Price)
+ {
+ nextOptimum.Price = shortRepPrice;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsShortRep();
+ nextIsChar = true;
+ }
+ }
+ /*
+ if(newLen == 2 && matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?
+ continue;
+ */
+
+ numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull);
+ UInt32 numAvailableBytes = numAvailableBytesFull;
+
+ if (numAvailableBytes < 2)
+ continue;
+ if (numAvailableBytes > _numFastBytes)
+ numAvailableBytes = _numFastBytes;
+ if (!nextIsChar && matchByte != currentByte) // speed optimization
+ {
+ // try Literal + rep0
+ const Byte *data2 = data - (reps[0] + 1);
+ UInt32 limit = MyMin(numAvailableBytesFull, _numFastBytes + 1);
+ UInt32 temp;
+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
+ UInt32 lenTest2 = temp - 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateChar();
+ UInt32 posStateNext = (position + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAnd1Price +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+ // for (; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = false;
+ }
+ }
+ }
+ }
+
+ UInt32 startLen = 2; // speed optimization
+ for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)
+ {
+ // UInt32 repLen = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;
+ const Byte *data2 = data - (reps[repIndex] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ UInt32 lenTest;
+ for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
+ while(lenEnd < cur + lenTest)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 lenTestTemp = lenTest;
+ UInt32 price = repMatchPrice + GetPureRepPrice(repIndex, state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState);
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = repIndex;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while(--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (repIndex == 0)
+ startLen = lenTest + 1;
+
+ // if (_maxMode)
+ {
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateRep();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice =
+ price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState) +
+ _isMatch[state2.Index][posStateNext].GetPrice0() +
+ _literalEncoder.GetSubCoder(position + lenTest, data[lenTest - 1])->GetPrice(
+ true, data2[lenTest], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAndLenCharPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+
+ // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++)
+ if (newLen > numAvailableBytes)
+ {
+ newLen = numAvailableBytes;
+ for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
+ matchDistances[numDistancePairs] = newLen;
+ numDistancePairs += 2;
+ }
+ if (newLen >= startLen)
+ {
+ UInt32 normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();
+ while(lenEnd < cur + newLen)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+
+ UInt32 offs = 0;
+ while(startLen > matchDistances[offs])
+ offs += 2;
+ UInt32 curBack = matchDistances[offs + 1];
+ UInt32 posSlot = GetPosSlot2(curBack);
+ for(UInt32 lenTest = /*2*/ startLen; ; lenTest++)
+ {
+ UInt32 curAndLenPrice = normalMatchPrice;
+ UInt32 lenToPosState = GetLenToPosState(lenTest);
+ if (curBack < kNumFullDistances)
+ curAndLenPrice += _distancesPrices[lenToPosState][curBack];
+ else
+ curAndLenPrice += _posSlotPrices[lenToPosState][posSlot] + _alignPrices[curBack & kAlignMask];
+
+ curAndLenPrice += _lenEncoder.GetPrice(lenTest - kMatchMinLen, posState);
+
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = curBack + kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+
+ if (/*_maxMode && */lenTest == matchDistances[offs])
+ {
+ // Try Match + Literal + Rep0
+ const Byte *data2 = data - (curBack + 1);
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateMatch();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice = curAndLenPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice0() +
+ _literalEncoder.GetSubCoder(position + lenTest, data[lenTest - 1])->GetPrice(
+ true, data2[lenTest], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (posStateNext + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAndLenCharPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = curBack + kNumRepDistances;
+ }
+ }
+ }
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ curBack = matchDistances[offs + 1];
+ if (curBack >= kNumFullDistances)
+ posSlot = GetPosSlot2(curBack);
+ }
+ }
+ }
+ }
+}
+
+static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist)
+{
+ return ((bigDist >> 7) > smallDist);
+}
+
+UInt32 CEncoder::ReadMatchDistances(UInt32 &numDistancePairs)
+{
+ UInt32 lenRes = 0;
+ numDistancePairs = _matchFinder.GetMatches(_matchFinderObj, _matchDistances);
+ #ifdef SHOW_STAT
+ printf("\n i = %d numPairs = %d ", ttt, numDistancePairs / 2);
+ if (ttt >= 61994)
+ ttt = ttt;
+
+ ttt++;
+ for (UInt32 i = 0; i < numDistancePairs; i += 2)
+ printf("%2d %6d | ", _matchDistances[i], _matchDistances[i + 1]);
+ #endif
+ if (numDistancePairs > 0)
+ {
+ lenRes = _matchDistances[numDistancePairs - 2];
+ if (lenRes == _numFastBytes)
+ {
+ UInt32 numAvail = _matchFinder.GetNumAvailableBytes(_matchFinderObj) + 1;
+ const Byte *pby = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ UInt32 distance = _matchDistances[numDistancePairs - 1] + 1;
+ if (numAvail > kMatchMaxLen)
+ numAvail = kMatchMaxLen;
+
+ const Byte *pby2 = pby - distance;
+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+ }
+ }
+ _additionalOffset++;
+ return lenRes;
+}
+
+UInt32 CEncoder::GetOptimumFast(UInt32 &backRes)
+{
+ UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+ UInt32 lenMain, numDistancePairs;
+ if (!_longestMatchWasFound)
+ {
+ lenMain = ReadMatchDistances(numDistancePairs);
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ numDistancePairs = _numDistancePairs;
+ _longestMatchWasFound = false;
+ }
+
+ const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ if (numAvailableBytes > kMatchMaxLen)
+ numAvailableBytes = kMatchMaxLen;
+ if (numAvailableBytes < 2)
+ {
+ backRes = (UInt32)(-1);
+ return 1;
+ }
+
+ UInt32 repLens[kNumRepDistances];
+ UInt32 repMaxIndex = 0;
+
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ {
+ const Byte *data2 = data - (_repDistances[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 len;
+ for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
+ if(len >= _numFastBytes)
+ {
+ backRes = i;
+ MovePos(len - 1);
+ return len;
+ }
+ repLens[i] = len;
+ if (len > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ UInt32 *matchDistances = _matchDistances;
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+
+ UInt32 backMain = 0; // for GCC
+ if (lenMain >= 2)
+ {
+ backMain = matchDistances[numDistancePairs - 1];
+ while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
+ {
+ if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
+ break;
+ numDistancePairs -= 2;
+ lenMain = matchDistances[numDistancePairs - 2];
+ backMain = matchDistances[numDistancePairs - 1];
+ }
+ if (lenMain == 2 && backMain >= 0x80)
+ lenMain = 1;
+ }
+
+ if (repLens[repMaxIndex] >= 2)
+ {
+ if (repLens[repMaxIndex] + 1 >= lenMain ||
+ repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9)) ||
+ repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))
+ {
+ backRes = repMaxIndex;
+ UInt32 lenRes = repLens[repMaxIndex];
+ MovePos(lenRes - 1);
+ return lenRes;
+ }
+ }
+
+ if (lenMain >= 2 && numAvailableBytes > 2)
+ {
+ numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+ _longestMatchLength = ReadMatchDistances(_numDistancePairs);
+ if (_longestMatchLength >= 2)
+ {
+ UInt32 newDistance = matchDistances[_numDistancePairs - 1];
+ if (_longestMatchLength >= lenMain && newDistance < backMain ||
+ _longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance) ||
+ _longestMatchLength > lenMain + 1 ||
+ _longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))
+ {
+ _longestMatchWasFound = true;
+ backRes = UInt32(-1);
+ return 1;
+ }
+ }
+ data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ {
+ const Byte *data2 = data - (_repDistances[i] + 1);
+ if (data[1] != data2[1] || data[2] != data2[2])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 len;
+ for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
+ if (len + 1 >= lenMain)
+ {
+ _longestMatchWasFound = true;
+ backRes = UInt32(-1);
+ return 1;
+ }
+ }
+ backRes = backMain + kNumRepDistances;
+ MovePos(lenMain - 2);
+ return lenMain;
+ }
+ backRes = UInt32(-1);
+ return 1;
+}
+
+HRESULT CEncoder::Flush(UInt32 nowPos)
+{
+ // ReleaseMFStream();
+ if (_matchFinderBase.result != SZ_OK)
+ return _matchFinderBase.result;
+ WriteEndMarker(nowPos & _posStateMask);
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+void CEncoder::WriteEndMarker(UInt32 posState)
+{
+ // This function for writing End Mark for stream version of LZMA.
+ // In current version this feature is not used.
+ if (!_writeEndMark)
+ return;
+
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+ _state.UpdateMatch();
+ UInt32 len = kMatchMinLen; // kMatchMaxLen;
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ UInt32 posSlot = (1 << kNumPosSlotBits) - 1;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot);
+ UInt32 footerBits = 30;
+ UInt32 posReduced = (UInt32(1) << footerBits) - 1;
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+}
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ // _needReleaseMFStream = false;
+ #ifdef COMPRESS_MF_MT
+ #ifdef USE_ALLOCA
+ alloca(0x300);
+ #endif
+ #endif
+ CCoderReleaser coderReleaser(this);
+ RINOK(SetStreams(inStream, outStream, inSize, outSize));
+ for (;;)
+ {
+ UInt64 processedInSize;
+ UInt64 processedOutSize;
+ Int32 finished;
+ RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished));
+ if (finished != 0)
+ break;
+ if (progress != 0)
+ {
+ RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize));
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CEncoder::SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */)
+{
+ _inStream = inStream;
+ _finished = false;
+ RINOK(Create());
+ RINOK(SetOutStream(outStream));
+ RINOK(Init());
+
+ if (!_fastMode)
+ {
+ FillDistancesPrices();
+ FillAlignPrices();
+ }
+
+ _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+ _lenEncoder.UpdateTables(1 << _posStateBits);
+ _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+ _repMatchLenEncoder.UpdateTables(1 << _posStateBits);
+
+ nowPos64 = 0;
+ return S_OK;
+}
+
+static HRes MyRead(void *object, void *data, UInt32 size, UInt32 *processedSize)
+{
+ return (HRes)((CSeqInStream *)object)->RealStream->Read(data, size, processedSize);
+}
+
+HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished)
+{
+ if (_inStream != 0)
+ {
+ _seqInStream.RealStream = _inStream;
+ _seqInStream.SeqInStream.Read = MyRead;
+ _matchFinderBase.stream = &_seqInStream.SeqInStream;
+ _matchFinder.Init(_matchFinderObj);
+ _needReleaseMFStream = true;
+ _inStream = 0;
+ }
+
+
+ *finished = 1;
+ if (_finished)
+ return _matchFinderBase.result;
+ _finished = true;
+
+ if (nowPos64 == 0)
+ {
+ if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+ return Flush((UInt32)nowPos64);
+ UInt32 len, numDistancePairs;
+ len = ReadMatchDistances(numDistancePairs);
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ _state.UpdateChar();
+ Byte curByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _additionalOffset);
+ _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte);
+ _previousByte = curByte;
+ _additionalOffset--;
+ nowPos64++;
+ }
+
+ UInt32 nowPos32 = (UInt32)nowPos64;
+ UInt32 progressPosValuePrev = nowPos32;
+
+ if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+ return Flush(nowPos32);
+
+ for (;;)
+ {
+ #ifdef _NO_EXCEPTIONS
+ if (_rangeEncoder.Stream.ErrorCode != S_OK)
+ return _rangeEncoder.Stream.ErrorCode;
+ #endif
+ UInt32 pos, len;
+
+ if (_fastMode)
+ len = GetOptimumFast(pos);
+ else
+ len = GetOptimum(nowPos32, pos);
+
+ UInt32 posState = nowPos32 & _posStateMask;
+ if(len == 1 && pos == 0xFFFFFFFF)
+ {
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ Byte curByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _additionalOffset);
+ CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(nowPos32, _previousByte);
+ if(_state.IsCharState())
+ subCoder->Encode(&_rangeEncoder, curByte);
+ else
+ {
+ Byte matchByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _repDistances[0] - 1 - _additionalOffset);
+ subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte);
+ }
+ _state.UpdateChar();
+ _previousByte = curByte;
+ }
+ else
+ {
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ if(pos < kNumRepDistances)
+ {
+ _isRep[_state.Index].Encode(&_rangeEncoder, 1);
+ if(pos == 0)
+ {
+ _isRepG0[_state.Index].Encode(&_rangeEncoder, 0);
+ _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, ((len == 1) ? 0 : 1));
+ }
+ else
+ {
+ UInt32 distance = _repDistances[pos];
+ _isRepG0[_state.Index].Encode(&_rangeEncoder, 1);
+ if (pos == 1)
+ _isRepG1[_state.Index].Encode(&_rangeEncoder, 0);
+ else
+ {
+ _isRepG1[_state.Index].Encode(&_rangeEncoder, 1);
+ _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2);
+ if (pos == 3)
+ _repDistances[3] = _repDistances[2];
+ _repDistances[2] = _repDistances[1];
+ }
+ _repDistances[1] = _repDistances[0];
+ _repDistances[0] = distance;
+ }
+ if (len == 1)
+ _state.UpdateShortRep();
+ else
+ {
+ _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ _state.UpdateRep();
+ }
+ }
+ else
+ {
+ _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+ _state.UpdateMatch();
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ pos -= kNumRepDistances;
+ UInt32 posSlot = GetPosSlot(pos);
+ _posSlotEncoder[GetLenToPosState(len)].Encode(&_rangeEncoder, posSlot);
+
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ UInt32 posReduced = pos - base;
+
+ if (posSlot < kEndPosModelIndex)
+ NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1,
+ &_rangeEncoder, footerBits, posReduced);
+ else
+ {
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+ _alignPriceCount++;
+ }
+ }
+ _repDistances[3] = _repDistances[2];
+ _repDistances[2] = _repDistances[1];
+ _repDistances[1] = _repDistances[0];
+ _repDistances[0] = pos;
+ _matchPriceCount++;
+ }
+ _previousByte = _matchFinder.GetIndexByte(_matchFinderObj, len - 1 - _additionalOffset);
+ }
+ _additionalOffset -= len;
+ nowPos32 += len;
+ if (_additionalOffset == 0)
+ {
+ if (!_fastMode)
+ {
+ if (_matchPriceCount >= (1 << 7))
+ FillDistancesPrices();
+ if (_alignPriceCount >= kAlignTableSize)
+ FillAlignPrices();
+ }
+ if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+ return Flush(nowPos32);
+ if (nowPos32 - progressPosValuePrev >= (1 << 14))
+ {
+ nowPos64 += nowPos32 - progressPosValuePrev;
+ *inSize = nowPos64;
+ *outSize = _rangeEncoder.GetProcessedSize();
+ _finished = false;
+ *finished = 0;
+ return _matchFinderBase.result;
+ }
+ }
+ }
+}
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ #ifndef _NO_EXCEPTIONS
+ try
+ {
+ #endif
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ #ifndef _NO_EXCEPTIONS
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+ #endif
+}
+
+void CEncoder::FillDistancesPrices()
+{
+ UInt32 tempPrices[kNumFullDistances];
+ for (UInt32 i = kStartPosModelIndex; i < kNumFullDistances; i++)
+ {
+ UInt32 posSlot = GetPosSlot(i);
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ tempPrices[i] = NRangeCoder::ReverseBitTreeGetPrice(_posEncoders +
+ base - posSlot - 1, footerBits, i - base);
+ }
+
+ for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 posSlot;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> &encoder = _posSlotEncoder[lenToPosState];
+ UInt32 *posSlotPrices = _posSlotPrices[lenToPosState];
+ for (posSlot = 0; posSlot < _distTableSize; posSlot++)
+ posSlotPrices[posSlot] = encoder.GetPrice(posSlot);
+ for (posSlot = kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits);
+
+ UInt32 *distancesPrices = _distancesPrices[lenToPosState];
+ UInt32 i;
+ for (i = 0; i < kStartPosModelIndex; i++)
+ distancesPrices[i] = posSlotPrices[i];
+ for (; i < kNumFullDistances; i++)
+ distancesPrices[i] = posSlotPrices[GetPosSlot(i)] + tempPrices[i];
+ }
+ _matchPriceCount = 0;
+}
+
+void CEncoder::FillAlignPrices()
+{
+ for (UInt32 i = 0; i < kAlignTableSize; i++)
+ _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+ _alignPriceCount = 0;
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,465 @@
+// LZMA/Encoder.h
+
+#ifndef __LZMA_ENCODER_H
+#define __LZMA_ENCODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+extern "C"
+{
+ #include "../../../../C/Alloc.h"
+ #include "../../../../C/Compress/Lz/MatchFinder.h"
+ #ifdef COMPRESS_MF_MT
+ #include "../../../../C/Compress/Lz/MatchFinderMt.h"
+ #endif
+}
+
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
+
+class CBaseState
+{
+protected:
+ CState _state;
+ Byte _previousByte;
+ UInt32 _repDistances[kNumRepDistances];
+ void Init()
+ {
+ _state.Init();
+ _previousByte = 0;
+ for(UInt32 i = 0 ; i < kNumRepDistances; i++)
+ _repDistances[i] = 0;
+ }
+};
+
+struct COptimal
+{
+ CState State;
+
+ bool Prev1IsChar;
+ bool Prev2;
+
+ UInt32 PosPrev2;
+ UInt32 BackPrev2;
+
+ UInt32 Price;
+ UInt32 PosPrev; // posNext;
+ UInt32 BackPrev;
+ UInt32 Backs[kNumRepDistances];
+ void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
+ void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+ bool IsShortRep() { return (BackPrev == 0); }
+};
+
+
+// #define LZMA_LOG_BRANCH
+
+#if _MSC_VER >= 1400
+// Must give gain in core 2. but slower ~2% on k8.
+// #define LZMA_LOG_BSR
+#endif
+
+#ifndef LZMA_LOG_BSR
+static const int kNumLogBits = 13; // don't change it !
+extern Byte g_FastPos[];
+#endif
+inline UInt32 GetPosSlot(UInt32 pos)
+{
+ #ifdef LZMA_LOG_BSR
+ if (pos < 2)
+ return pos;
+ unsigned long index;
+ _BitScanReverse(&index, pos);
+ return (index + index) + ((pos >> (index - 1)) & 1);
+ #else
+ if (pos < (1 << kNumLogBits))
+ return g_FastPos[pos];
+ if (pos < (1 << (kNumLogBits * 2 - 1)))
+ return g_FastPos[pos >> (kNumLogBits - 1)] + (kNumLogBits - 1) * 2;
+ return g_FastPos[pos >> (kNumLogBits - 1) * 2] + (kNumLogBits - 1) * 4;
+ #endif
+}
+
+inline UInt32 GetPosSlot2(UInt32 pos)
+{
+ #ifdef LZMA_LOG_BSR
+ unsigned long index;
+ _BitScanReverse(&index, pos);
+ return (index + index) + ((pos >> (index - 1)) & 1);
+ #else
+ #ifdef LZMA_LOG_BRANCH
+ if (pos < (1 << (kNumLogBits + 6)))
+ return g_FastPos[pos >> 6] + 12;
+ if (pos < (1 << (kNumLogBits * 2 + 5)))
+ return g_FastPos[pos >> (kNumLogBits + 5)] + (kNumLogBits + 5) * 2;
+ return g_FastPos[pos >> (kNumLogBits * 2 + 4)] + (kNumLogBits * 2 + 4) * 2;
+ #else
+ // it's faster with VC6-32bit.
+ UInt32 s = 6 + ((kNumLogBits - 1) & (UInt32)((Int32)(((1 << (kNumLogBits + 6)) - 1) - pos) >> 31));
+ return g_FastPos[pos >> s] + (s * 2);
+ #endif
+ #endif
+}
+
+const UInt32 kIfinityPrice = 0xFFFFFFF;
+
+const UInt32 kNumOpts = 1 << 12;
+
+
+class CLiteralEncoder2
+{
+ CMyBitEncoder _encoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _encoders[i].Init();
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
+ void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
+ UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
+};
+
+class CLiteralEncoder
+{
+ CLiteralEncoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralEncoder(): _coders(0) {}
+ ~CLiteralEncoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) != (_numPrevBits + _numPosBits))
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
+ { return &_coders[((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits))]; }
+};
+
+namespace NLength {
+
+class CEncoder
+{
+ CMyBitEncoder _choice;
+ CMyBitEncoder _choice2;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates);
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);
+ void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const;
+};
+
+const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
+
+class CPriceTableEncoder: public CEncoder
+{
+ UInt32 _prices[kNumPosStatesEncodingMax][kNumSymbolsTotal];
+ UInt32 _tableSize;
+ UInt32 _counters[kNumPosStatesEncodingMax];
+public:
+ void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
+ UInt32 GetPrice(UInt32 symbol, UInt32 posState) const { return _prices[posState][symbol]; }
+ void UpdateTable(UInt32 posState)
+ {
+ SetPrices(posState, _tableSize, _prices[posState]);
+ _counters[posState] = _tableSize;
+ }
+ void UpdateTables(UInt32 numPosStates)
+ {
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ UpdateTable(posState);
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState, bool updatePrice)
+ {
+ CEncoder::Encode(rangeEncoder, symbol, posState);
+ if (updatePrice)
+ if (--_counters[posState] == 0)
+ UpdateTable(posState);
+ }
+};
+
+}
+
+typedef struct _CSeqInStream
+{
+ ISeqInStream SeqInStream;
+ CMyComPtr<ISequentialInStream> RealStream;
+} CSeqInStream;
+
+
+class CEncoder :
+ public ICompressCoder,
+ public ICompressSetOutStream,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public CBaseState,
+ public CMyUnknownImp
+{
+ NRangeCoder::CEncoder _rangeEncoder;
+
+ IMatchFinder _matchFinder;
+ void *_matchFinderObj;
+
+ #ifdef COMPRESS_MF_MT
+ Bool _multiThread;
+ Bool _mtMode;
+ CMatchFinderMt _matchFinderMt;
+ #endif
+
+ CMatchFinder _matchFinderBase;
+ #ifdef COMPRESS_MF_MT
+ Byte _pad1[kMtCacheLineDummy];
+ #endif
+
+ COptimal _optimum[kNumOpts];
+
+ CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
+ CMyBitEncoder _isRep[kNumStates];
+ CMyBitEncoder _isRepG0[kNumStates];
+ CMyBitEncoder _isRepG1[kNumStates];
+ CMyBitEncoder _isRepG2[kNumStates];
+ CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
+
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
+
+ CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
+
+ NLength::CPriceTableEncoder _lenEncoder;
+ NLength::CPriceTableEncoder _repMatchLenEncoder;
+
+ CLiteralEncoder _literalEncoder;
+
+ UInt32 _matchDistances[kMatchMaxLen * 2 + 2 + 1];
+
+ bool _fastMode;
+ // bool _maxMode;
+ UInt32 _numFastBytes;
+ UInt32 _longestMatchLength;
+ UInt32 _numDistancePairs;
+
+ UInt32 _additionalOffset;
+
+ UInt32 _optimumEndIndex;
+ UInt32 _optimumCurrentIndex;
+
+ bool _longestMatchWasFound;
+
+ UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+
+ UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
+
+ UInt32 _alignPrices[kAlignTableSize];
+ UInt32 _alignPriceCount;
+
+ UInt32 _distTableSize;
+
+ UInt32 _posStateBits;
+ UInt32 _posStateMask;
+ UInt32 _numLiteralPosStateBits;
+ UInt32 _numLiteralContextBits;
+
+ UInt32 _dictionarySize;
+
+ UInt32 _matchPriceCount;
+ UInt64 nowPos64;
+ bool _finished;
+ ISequentialInStream *_inStream;
+
+ CSeqInStream _seqInStream;
+
+ UInt32 _matchFinderCycles;
+ // int _numSkip
+
+ bool _writeEndMark;
+
+ bool _needReleaseMFStream;
+
+ void ReleaseMatchFinder()
+ {
+ _matchFinder.Init = 0;
+ _seqInStream.RealStream.Release();
+ }
+
+ void ReleaseMFStream()
+ {
+ if (_matchFinderObj && _needReleaseMFStream)
+ {
+ #ifdef COMPRESS_MF_MT
+ if (_mtMode)
+ MatchFinderMt_ReleaseStream(&_matchFinderMt);
+ #endif
+ _needReleaseMFStream = false;
+ }
+ _seqInStream.RealStream.Release();
+ }
+
+ UInt32 ReadMatchDistances(UInt32 &numDistancePairs);
+
+ void MovePos(UInt32 num);
+ UInt32 GetRepLen1Price(CState state, UInt32 posState) const
+ {
+ return _isRepG0[state.Index].GetPrice0() +
+ _isRep0Long[state.Index][posState].GetPrice0();
+ }
+
+ UInt32 GetPureRepPrice(UInt32 repIndex, CState state, UInt32 posState) const
+ {
+ UInt32 price;
+ if(repIndex == 0)
+ {
+ price = _isRepG0[state.Index].GetPrice0();
+ price += _isRep0Long[state.Index][posState].GetPrice1();
+ }
+ else
+ {
+ price = _isRepG0[state.Index].GetPrice1();
+ if (repIndex == 1)
+ price += _isRepG1[state.Index].GetPrice0();
+ else
+ {
+ price += _isRepG1[state.Index].GetPrice1();
+ price += _isRepG2[state.Index].GetPrice(repIndex - 2);
+ }
+ }
+ return price;
+ }
+ UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
+ {
+ return _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState) +
+ GetPureRepPrice(repIndex, state, posState);
+ }
+ /*
+ UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
+ {
+ if (pos >= kNumFullDistances)
+ return kIfinityPrice;
+ return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
+ }
+ UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
+ {
+ UInt32 price;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+ */
+ UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
+ {
+ UInt32 price;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+
+ UInt32 Backward(UInt32 &backRes, UInt32 cur);
+ UInt32 GetOptimum(UInt32 position, UInt32 &backRes);
+ UInt32 GetOptimumFast(UInt32 &backRes);
+
+ void FillDistancesPrices();
+ void FillAlignPrices();
+
+ void ReleaseStreams()
+ {
+ ReleaseMFStream();
+ ReleaseOutStream();
+ }
+
+ HRESULT Flush(UInt32 nowPos);
+ class CCoderReleaser
+ {
+ CEncoder *_coder;
+ public:
+ CCoderReleaser(CEncoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+ friend class CCoderReleaser;
+
+ void WriteEndMarker(UInt32 posState);
+
+public:
+ CEncoder();
+ void SetWriteEndMarkerMode(bool writeEndMarker)
+ { _writeEndMark= writeEndMarker; }
+
+ HRESULT Create();
+
+ MY_UNKNOWN_IMP3(
+ ICompressSetOutStream,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties
+ )
+
+ HRESULT Init();
+
+ // ICompressCoder interface
+ HRESULT SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize);
+ HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressCoder interface
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressSetCoderProperties2
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+
+ // ICompressWriteCoderProperties
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+ STDMETHOD(ReleaseOutStream)();
+
+ virtual ~CEncoder();
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA/LZMARegister.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA/LZMARegister.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA/LZMARegister.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,19 @@
+// LZMARegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "LZMADecoder.h"
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLZMA::CDecoder); }
+#ifndef EXTRACT_ONLY
+#include "LZMAEncoder.h"
+static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLZMA::CEncoder); }
+#else
+#define CreateCodecOut 0
+#endif
+
+static CCodecInfo g_CodecInfo =
+ { CreateCodec, CreateCodecOut, 0x030101, L"LZMA", 1, false };
+
+REGISTER_CODEC(LZMA)
Added: trunk/lzma/CPP/7zip/Compress/LZMA/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Compress/LZMA/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,504 @@
+# Microsoft Developer Studio Project File - Name="AloneLZMA" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=AloneLZMA - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "AloneLZMA.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "AloneLZMA.mak" CFG="AloneLZMA - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "AloneLZMA - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "AloneLZMA - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "BENCH_MT" /FAcs /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "BENCH_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "BENCH_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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\7za2.exe" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# 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" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "BENCH_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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\7za2.exe" /pdbtype:sept
+# 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
+
+!ENDIF
+
+# Begin Target
+
+# Name "AloneLZMA - Win32 Release"
+# Name "AloneLZMA - Win32 Debug"
+# Name "AloneLZMA - Win32 ReleaseU"
+# Name "AloneLZMA - Win32 DebugU"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMADecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMAEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMAEncoder.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Types.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Group "C-Lz"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# End Group
+# Begin Group "LZMA_C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaDecode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaTypes.h
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Types.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaAlone.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBench.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBench.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBenchCon.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBenchCon.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRam.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRamDecode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRamDecode.h
+# End Source File
+# End Target
+# End Project
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "AloneLZMA"=.\AloneLZMA.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,554 @@
+// LzmaAlone.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/MyInitGuid.h"
+
+#include <stdio.h>
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#include <fcntl.h>
+#include <io.h>
+#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY)
+#else
+#define MY_SET_BINARY_MODE(file)
+#endif
+
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+
+#include "LzmaBenchCon.h"
+#include "LzmaRam.h"
+
+#ifdef COMPRESS_MF_MT
+#include "../../../Windows/System.h"
+#endif
+
+#include "../../MyVersion.h"
+
+extern "C"
+{
+#include "LzmaRamDecode.h"
+}
+
+using namespace NCommandLineParser;
+
+#ifdef _WIN32
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+static const char *kCantAllocate = "Can not allocate memory";
+static const char *kReadError = "Read error";
+static const char *kWriteError = "Write error";
+
+namespace NKey {
+enum Enum
+{
+ kHelp1 = 0,
+ kHelp2,
+ kMode,
+ kDictionary,
+ kFastBytes,
+ kMatchFinderCycles,
+ kLitContext,
+ kLitPos,
+ kPosBits,
+ kMatchFinder,
+ kMultiThread,
+ kEOS,
+ kStdIn,
+ kStdOut,
+ kFilter86
+};
+}
+
+static const CSwitchForm kSwitchForms[] =
+{
+ { L"?", NSwitchType::kSimple, false },
+ { L"H", NSwitchType::kSimple, false },
+ { L"A", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"D", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"MC", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"MF", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"MT", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"EOS", NSwitchType::kSimple, false },
+ { L"SI", NSwitchType::kSimple, false },
+ { L"SO", NSwitchType::kSimple, false },
+ { L"F86", NSwitchType::kPostChar, false, 0, 0, L"+" }
+};
+
+static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
+
+static void PrintHelp()
+{
+ fprintf(stderr, "\nUsage: LZMA <e|d> inputFile outputFile [<switches>...]\n"
+ " e: encode file\n"
+ " d: decode file\n"
+ " b: Benchmark\n"
+ "<Switches>\n"
+ " -a{N}: set compression mode - [0, 1], default: 1 (max)\n"
+ " -d{N}: set dictionary - [0,30], default: 23 (8MB)\n"
+ " -fb{N}: set number of fast bytes - [5, 273], default: 128\n"
+ " -mc{N}: set number of cycles for match finder\n"
+ " -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
+ " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
+ " -pb{N}: set number of pos bits - [0, 4], default: 2\n"
+ " -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4\n"
+ " -mt{N}: set number of CPU threads\n"
+ " -eos: write End Of Stream marker\n"
+ " -si: read data from stdin\n"
+ " -so: write data to stdout\n"
+ );
+}
+
+static void PrintHelpAndExit(const char *s)
+{
+ fprintf(stderr, "\nError: %s\n\n", s);
+ PrintHelp();
+ throw -1;
+}
+
+static void IncorrectCommand()
+{
+ PrintHelpAndExit("Incorrect command");
+}
+
+static void WriteArgumentsToStringList(int numArguments, const char *arguments[],
+ UStringVector &strings)
+{
+ for(int i = 1; i < numArguments; i++)
+ strings.Add(MultiByteToUnicodeString(arguments[i]));
+}
+
+static bool GetNumber(const wchar_t *s, UInt32 &value)
+{
+ value = 0;
+ if (MyStringLen(s) == 0)
+ return false;
+ const wchar_t *end;
+ UInt64 res = ConvertStringToUInt64(s, &end);
+ if (*end != L'\0')
+ return false;
+ if (res > 0xFFFFFFFF)
+ return false;
+ value = UInt32(res);
+ return true;
+}
+
+int main2(int n, const char *args[])
+{
+ #ifdef _WIN32
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ fprintf(stderr, "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");
+
+ if (n == 1)
+ {
+ PrintHelp();
+ return 0;
+ }
+
+ bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);
+ if (unsupportedTypes)
+ {
+ fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
+ return 1;
+ }
+
+ UStringVector commandStrings;
+ WriteArgumentsToStringList(n, args, commandStrings);
+ CParser parser(kNumSwitches);
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ }
+ catch(...)
+ {
+ IncorrectCommand();
+ }
+
+ if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
+ {
+ PrintHelp();
+ return 0;
+ }
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+
+ int paramIndex = 0;
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &command = nonSwitchStrings[paramIndex++];
+
+ bool dictionaryIsDefined = false;
+ UInt32 dictionary = (UInt32)-1;
+ if(parser[NKey::kDictionary].ThereIs)
+ {
+ UInt32 dicLog;
+ if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
+ IncorrectCommand();
+ dictionary = 1 << dicLog;
+ dictionaryIsDefined = true;
+ }
+ UString mf = L"BT4";
+ if (parser[NKey::kMatchFinder].ThereIs)
+ mf = parser[NKey::kMatchFinder].PostStrings[0];
+
+ UInt32 numThreads = (UInt32)-1;
+
+ #ifdef COMPRESS_MF_MT
+ if (parser[NKey::kMultiThread].ThereIs)
+ {
+ UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
+ const UString &s = parser[NKey::kMultiThread].PostStrings[0];
+ if (s.IsEmpty())
+ numThreads = numCPUs;
+ else
+ if (!GetNumber(s, numThreads))
+ IncorrectCommand();
+ }
+ #endif
+
+ if (command.CompareNoCase(L"b") == 0)
+ {
+ const UInt32 kNumDefaultItereations = 1;
+ UInt32 numIterations = kNumDefaultItereations;
+ {
+ if (paramIndex < nonSwitchStrings.Size())
+ if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
+ numIterations = kNumDefaultItereations;
+ }
+ return LzmaBenchCon(stderr, numIterations, numThreads, dictionary);
+ }
+
+ if (numThreads == (UInt32)-1)
+ numThreads = 1;
+
+ bool encodeMode = false;
+ if (command.CompareNoCase(L"e") == 0)
+ encodeMode = true;
+ else if (command.CompareNoCase(L"d") == 0)
+ encodeMode = false;
+ else
+ IncorrectCommand();
+
+ bool stdInMode = parser[NKey::kStdIn].ThereIs;
+ bool stdOutMode = parser[NKey::kStdOut].ThereIs;
+
+ CMyComPtr<ISequentialInStream> inStream;
+ CInFileStream *inStreamSpec = 0;
+ if (stdInMode)
+ {
+ inStream = new CStdInFileStream;
+ MY_SET_BINARY_MODE(stdin);
+ }
+ else
+ {
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &inputName = nonSwitchStrings[paramIndex++];
+ inStreamSpec = new CInFileStream;
+ inStream = inStreamSpec;
+ if (!inStreamSpec->Open(GetSystemString(inputName)))
+ {
+ fprintf(stderr, "\nError: can not open input file %s\n",
+ (const char *)GetOemString(inputName));
+ return 1;
+ }
+ }
+
+ CMyComPtr<ISequentialOutStream> outStream;
+ COutFileStream *outStreamSpec = NULL;
+ if (stdOutMode)
+ {
+ outStream = new CStdOutFileStream;
+ MY_SET_BINARY_MODE(stdout);
+ }
+ else
+ {
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &outputName = nonSwitchStrings[paramIndex++];
+ outStreamSpec = new COutFileStream;
+ outStream = outStreamSpec;
+ if (!outStreamSpec->Create(GetSystemString(outputName), true))
+ {
+ fprintf(stderr, "\nError: can not open output file %s\n",
+ (const char *)GetOemString(outputName));
+ return 1;
+ }
+ }
+
+ if (parser[NKey::kFilter86].ThereIs)
+ {
+ // -f86 switch is for x86 filtered mode: BCJ + LZMA.
+ if (parser[NKey::kEOS].ThereIs || stdInMode)
+ throw "Can not use stdin in this mode";
+ UInt64 fileSize;
+ inStreamSpec->File.GetLength(fileSize);
+ if (fileSize > 0xF0000000)
+ throw "File is too big";
+ UInt32 inSize = (UInt32)fileSize;
+ Byte *inBuffer = 0;
+ if (inSize != 0)
+ {
+ inBuffer = (Byte *)MyAlloc((size_t)inSize);
+ if (inBuffer == 0)
+ throw kCantAllocate;
+ }
+
+ UInt32 processedSize;
+ if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK)
+ throw "Can not read";
+ if ((UInt32)inSize != processedSize)
+ throw "Read size error";
+
+ Byte *outBuffer = 0;
+ size_t outSizeProcessed;
+ if (encodeMode)
+ {
+ // we allocate 105% of original size for output buffer
+ size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
+ if (outSize != 0)
+ {
+ outBuffer = (Byte *)MyAlloc((size_t)outSize);
+ if (outBuffer == 0)
+ throw kCantAllocate;
+ }
+ if (!dictionaryIsDefined)
+ dictionary = 1 << 23;
+ int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed,
+ dictionary, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
+ if (res != 0)
+ {
+ fprintf(stderr, "\nEncoder error = %d\n", (int)res);
+ return 1;
+ }
+ }
+ else
+ {
+ size_t outSize;
+ if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
+ throw "data error";
+ if (outSize != 0)
+ {
+ outBuffer = (Byte *)MyAlloc(outSize);
+ if (outBuffer == 0)
+ throw kCantAllocate;
+ }
+ int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
+ if (res != 0)
+ throw "LzmaDecoder error";
+ }
+ if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
+ throw kWriteError;
+ MyFree(outBuffer);
+ MyFree(inBuffer);
+ return 0;
+ }
+
+
+ UInt64 fileSize;
+ if (encodeMode)
+ {
+ NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ if (!dictionaryIsDefined)
+ dictionary = 1 << 23;
+
+ UInt32 posStateBits = 2;
+ UInt32 litContextBits = 3; // for normal files
+ // UInt32 litContextBits = 0; // for 32-bit data
+ UInt32 litPosBits = 0;
+ // UInt32 litPosBits = 2; // for 32-bit data
+ UInt32 algorithm = 1;
+ UInt32 numFastBytes = 128;
+ UInt32 matchFinderCycles = 16 + numFastBytes / 2;
+ bool matchFinderCyclesDefined = false;
+
+ bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
+
+ if(parser[NKey::kMode].ThereIs)
+ if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
+ IncorrectCommand();
+
+ if(parser[NKey::kFastBytes].ThereIs)
+ if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
+ IncorrectCommand();
+ matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs;
+ if (matchFinderCyclesDefined)
+ if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles))
+ IncorrectCommand();
+ if(parser[NKey::kLitContext].ThereIs)
+ if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
+ IncorrectCommand();
+ if(parser[NKey::kLitPos].ThereIs)
+ if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
+ IncorrectCommand();
+ if(parser[NKey::kPosBits].ThereIs)
+ if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
+ IncorrectCommand();
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kPosStateBits,
+ NCoderPropID::kLitContextBits,
+ NCoderPropID::kLitPosBits,
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kNumFastBytes,
+ NCoderPropID::kMatchFinder,
+ NCoderPropID::kEndMarker,
+ NCoderPropID::kNumThreads,
+ NCoderPropID::kMatchFinderCycles,
+ };
+ const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);
+
+ PROPVARIANT properties[kNumPropsMax];
+ for (int p = 0; p < 6; p++)
+ properties[p].vt = VT_UI4;
+
+ properties[0].ulVal = (UInt32)dictionary;
+ properties[1].ulVal = (UInt32)posStateBits;
+ properties[2].ulVal = (UInt32)litContextBits;
+ properties[3].ulVal = (UInt32)litPosBits;
+ properties[4].ulVal = (UInt32)algorithm;
+ properties[5].ulVal = (UInt32)numFastBytes;
+
+ properties[6].vt = VT_BSTR;
+ properties[6].bstrVal = (BSTR)(const wchar_t *)mf;
+
+ properties[7].vt = VT_BOOL;
+ properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
+
+ properties[8].vt = VT_UI4;
+ properties[8].ulVal = (UInt32)numThreads;
+
+ // it must be last in property list
+ properties[9].vt = VT_UI4;
+ properties[9].ulVal = (UInt32)matchFinderCycles;
+
+ int numProps = kNumPropsMax;
+ if (!matchFinderCyclesDefined)
+ numProps--;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK)
+ IncorrectCommand();
+ encoderSpec->WriteCoderProperties(outStream);
+
+ if (eos || stdInMode)
+ fileSize = (UInt64)(Int64)-1;
+ else
+ inStreamSpec->File.GetLength(fileSize);
+
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b = Byte(fileSize >> (8 * i));
+ if (outStream->Write(&b, 1, 0) != S_OK)
+ {
+ fprintf(stderr, kWriteError);
+ return 1;
+ }
+ }
+ HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
+ if (result == E_OUTOFMEMORY)
+ {
+ fprintf(stderr, "\nError: Can not allocate memory\n");
+ return 1;
+ }
+ else if (result != S_OK)
+ {
+ fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
+ return 1;
+ }
+ }
+ else
+ {
+ NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+ const UInt32 kPropertiesSize = 5;
+ Byte properties[kPropertiesSize];
+ UInt32 processedSize;
+ if (ReadStream(inStream, properties, kPropertiesSize, &processedSize) != S_OK)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (processedSize != kPropertiesSize)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
+ {
+ fprintf(stderr, "SetDecoderProperties error");
+ return 1;
+ }
+ fileSize = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ if (inStream->Read(&b, 1, &processedSize) != S_OK)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (processedSize != 1)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ fileSize |= ((UInt64)b) << (8 * i);
+ }
+ if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+ {
+ fprintf(stderr, "Decoder error");
+ return 1;
+ }
+ }
+ if (outStreamSpec != NULL)
+ {
+ if (outStreamSpec->Close() != S_OK)
+ {
+ fprintf(stderr, "File closing error");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main(int n, const char *args[])
+{
+ try { return main2(n, args); }
+ catch(const char *s)
+ {
+ fprintf(stderr, "\nError: %s\n", s);
+ return 1;
+ }
+ catch(...)
+ {
+ fprintf(stderr, "\nError\n");
+ return 1;
+ }
+}
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1024 @@
+// LzmaBench.cpp
+
+#include "StdAfx.h"
+
+#include "LzmaBench.h"
+
+#ifndef _WIN32
+#define USE_POSIX_TIME
+#define USE_POSIX_TIME2
+#endif
+
+#ifdef USE_POSIX_TIME
+#include <time.h>
+#ifdef USE_POSIX_TIME2
+#include <sys/time.h>
+#endif
+#endif
+
+#ifdef _WIN32
+#define USE_ALLOCA
+#endif
+
+#ifdef USE_ALLOCA
+#ifdef _WIN32
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#endif
+
+extern "C"
+{
+#include "../../../../C/Alloc.h"
+#include "../../../../C/7zCrc.h"
+}
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+#ifdef BENCH_MT
+#include "../../../Windows/Thread.h"
+#include "../../../Windows/Synchronization.h"
+#endif
+
+#ifdef EXTERNAL_LZMA
+#include "../../../Windows/PropVariant.h"
+#else
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+#endif
+
+static const UInt32 kUncompressMinBlockSize = 1 << 26;
+static const UInt32 kAdditionalSize = (1 << 16);
+static const UInt32 kCompressedAdditionalSize = (1 << 10);
+static const UInt32 kMaxLzmaPropSize = 5;
+
+class CBaseRandomGenerator
+{
+ UInt32 A1;
+ UInt32 A2;
+public:
+ CBaseRandomGenerator() { Init(); }
+ void Init() { A1 = 362436069; A2 = 521288629;}
+ UInt32 GetRnd()
+ {
+ return
+ ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +
+ ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
+ }
+};
+
+class CBenchBuffer
+{
+public:
+ size_t BufferSize;
+ Byte *Buffer;
+ CBenchBuffer(): Buffer(0) {}
+ virtual ~CBenchBuffer() { Free(); }
+ void Free()
+ {
+ ::MidFree(Buffer);
+ Buffer = 0;
+ }
+ bool Alloc(size_t bufferSize)
+ {
+ if (Buffer != 0 && BufferSize == bufferSize)
+ return true;
+ Free();
+ Buffer = (Byte *)::MidAlloc(bufferSize);
+ BufferSize = bufferSize;
+ return (Buffer != 0);
+ }
+};
+
+class CBenchRandomGenerator: public CBenchBuffer
+{
+ CBaseRandomGenerator *RG;
+public:
+ void Set(CBaseRandomGenerator *rg) { RG = rg; }
+ UInt32 GetVal(UInt32 &res, int numBits)
+ {
+ UInt32 val = res & (((UInt32)1 << numBits) - 1);
+ res >>= numBits;
+ return val;
+ }
+ UInt32 GetLen(UInt32 &res)
+ {
+ UInt32 len = GetVal(res, 2);
+ return GetVal(res, 1 + len);
+ }
+ void Generate()
+ {
+ UInt32 pos = 0;
+ UInt32 rep0 = 1;
+ while (pos < BufferSize)
+ {
+ UInt32 res = RG->GetRnd();
+ res >>= 1;
+ if (GetVal(res, 1) == 0 || pos < 1024)
+ Buffer[pos++] = (Byte)(res & 0xFF);
+ else
+ {
+ UInt32 len;
+ len = 1 + GetLen(res);
+ if (GetVal(res, 3) != 0)
+ {
+ len += GetLen(res);
+ do
+ {
+ UInt32 ppp = GetVal(res, 5) + 6;
+ res = RG->GetRnd();
+ if (ppp > 30)
+ continue;
+ rep0 = /* (1 << ppp) +*/ GetVal(res, ppp);
+ res = RG->GetRnd();
+ }
+ while (rep0 >= pos);
+ rep0++;
+ }
+
+ for (UInt32 i = 0; i < len && pos < BufferSize; i++, pos++)
+ Buffer[pos] = Buffer[pos - rep0];
+ }
+ }
+ }
+};
+
+
+class CBenchmarkInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *Data;
+ size_t Pos;
+ size_t Size;
+public:
+ MY_UNKNOWN_IMP
+ void Init(const Byte *data, size_t size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ }
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ size_t remain = Size - Pos;
+ UInt32 kMaxBlockSize = (1 << 20);
+ if (size > kMaxBlockSize)
+ size = kMaxBlockSize;
+ if (size > remain)
+ size = (UInt32)remain;
+ for (UInt32 i = 0; i < size; i++)
+ ((Byte *)data)[i] = Data[Pos + i];
+ Pos += size;
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+class CBenchmarkOutStream:
+ public ISequentialOutStream,
+ public CBenchBuffer,
+ public CMyUnknownImp
+{
+ // bool _overflow;
+public:
+ UInt32 Pos;
+ // CBenchmarkOutStream(): _overflow(false) {}
+ void Init()
+ {
+ // _overflow = false;
+ Pos = 0;
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ size_t curSize = BufferSize - Pos;
+ if (curSize > size)
+ curSize = size;
+ memcpy(Buffer + Pos, data, curSize);
+ Pos += (UInt32)curSize;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)curSize;
+ if (curSize != size)
+ {
+ // _overflow = true;
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+class CCrcOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ UInt32 Crc;
+ MY_UNKNOWN_IMP
+ void Init() { Crc = CRC_INIT_VAL; }
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ Crc = CrcUpdate(Crc, data, size);
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+static UInt64 GetTimeCount()
+{
+ #ifdef USE_POSIX_TIME
+ #ifdef USE_POSIX_TIME2
+ timeval v;
+ if (gettimeofday(&v, 0) == 0)
+ return (UInt64)(v.tv_sec) * 1000000 + v.tv_usec;
+ return (UInt64)time(NULL) * 1000000;
+ #else
+ return time(NULL);
+ #endif
+ #else
+ /*
+ LARGE_INTEGER value;
+ if (::QueryPerformanceCounter(&value))
+ return value.QuadPart;
+ */
+ return GetTickCount();
+ #endif
+}
+
+static UInt64 GetFreq()
+{
+ #ifdef USE_POSIX_TIME
+ #ifdef USE_POSIX_TIME2
+ return 1000000;
+ #else
+ return 1;
+ #endif
+ #else
+ /*
+ LARGE_INTEGER value;
+ if (::QueryPerformanceFrequency(&value))
+ return value.QuadPart;
+ */
+ return 1000;
+ #endif
+}
+
+#ifndef USE_POSIX_TIME
+static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
+#endif
+static UInt64 GetUserTime()
+{
+ #ifdef USE_POSIX_TIME
+ return clock();
+ #else
+ FILETIME creationTime, exitTime, kernelTime, userTime;
+ if (::GetProcessTimes(::GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime) != 0)
+ return GetTime64(userTime) + GetTime64(kernelTime);
+ return (UInt64)GetTickCount() * 10000;
+ #endif
+}
+
+static UInt64 GetUserFreq()
+{
+ #ifdef USE_POSIX_TIME
+ return CLOCKS_PER_SEC;
+ #else
+ return 10000000;
+ #endif
+}
+
+class CBenchProgressStatus
+{
+ #ifdef BENCH_MT
+ NWindows::NSynchronization::CCriticalSection CS;
+ #endif
+public:
+ HRESULT Res;
+ bool EncodeMode;
+ void SetResult(HRESULT res)
+ {
+ #ifdef BENCH_MT
+ NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ #endif
+ Res = res;
+ }
+ HRESULT GetResult()
+ {
+ #ifdef BENCH_MT
+ NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ #endif
+ return Res;
+ }
+};
+
+class CBenchProgressInfo:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ CBenchProgressStatus *Status;
+ CBenchInfo BenchInfo;
+ HRESULT Res;
+ IBenchCallback *callback;
+ CBenchProgressInfo(): callback(0) {}
+ MY_UNKNOWN_IMP
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+void SetStartTime(CBenchInfo &bi)
+{
+ bi.GlobalFreq = GetFreq();
+ bi.UserFreq = GetUserFreq();
+ bi.GlobalTime = ::GetTimeCount();
+ bi.UserTime = ::GetUserTime();
+}
+
+void SetFinishTime(const CBenchInfo &biStart, CBenchInfo &dest)
+{
+ dest.GlobalFreq = GetFreq();
+ dest.UserFreq = GetUserFreq();
+ dest.GlobalTime = ::GetTimeCount() - biStart.GlobalTime;
+ dest.UserTime = ::GetUserTime() - biStart.UserTime;
+}
+
+STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ HRESULT res = Status->GetResult();
+ if (res != S_OK)
+ return res;
+ if (!callback)
+ return res;
+ CBenchInfo info = BenchInfo;
+ SetFinishTime(BenchInfo, info);
+ if (Status->EncodeMode)
+ {
+ info.UnpackSize = *inSize;
+ info.PackSize = *outSize;
+ res = callback->SetEncodeResult(info, false);
+ }
+ else
+ {
+ info.PackSize = BenchInfo.PackSize + *inSize;
+ info.UnpackSize = BenchInfo.UnpackSize + *outSize;
+ res = callback->SetDecodeResult(info, false);
+ }
+ if (res != S_OK)
+ Status->SetResult(res);
+ return res;
+}
+
+static const int kSubBits = 8;
+
+static UInt32 GetLogSize(UInt32 size)
+{
+ for (int i = kSubBits; i < 32; i++)
+ for (UInt32 j = 0; j < (1 << kSubBits); j++)
+ if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
+ return (i << kSubBits) + j;
+ return (32 << kSubBits);
+}
+
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)
+{
+ while (v1 > 1000000)
+ {
+ v1 >>= 1;
+ v2 >>= 1;
+ }
+}
+
+UInt64 GetUsage(const CBenchInfo &info)
+{
+ UInt64 userTime = info.UserTime;
+ UInt64 userFreq = info.UserFreq;
+ UInt64 globalTime = info.GlobalTime;
+ UInt64 globalFreq = info.GlobalFreq;
+ NormalizeVals(userTime, userFreq);
+ NormalizeVals(globalFreq, globalTime);
+ if (userFreq == 0)
+ userFreq = 1;
+ if (globalTime == 0)
+ globalTime = 1;
+ return userTime * globalFreq * 1000000 / userFreq / globalTime;
+}
+
+UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating)
+{
+ UInt64 userTime = info.UserTime;
+ UInt64 userFreq = info.UserFreq;
+ UInt64 globalTime = info.GlobalTime;
+ UInt64 globalFreq = info.GlobalFreq;
+ NormalizeVals(userFreq, userTime);
+ NormalizeVals(globalTime, globalFreq);
+ if (globalFreq == 0)
+ globalFreq = 1;
+ if (userTime == 0)
+ userTime = 1;
+ return userFreq * globalTime / globalFreq * rating / userTime;
+}
+
+static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
+{
+ UInt64 elTime = elapsedTime;
+ NormalizeVals(freq, elTime);
+ if (elTime == 0)
+ elTime = 1;
+ return value * freq / elTime;
+}
+
+UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
+{
+ UInt64 t = GetLogSize(dictionarySize) - (kBenchMinDicLogSize << kSubBits);
+ // UInt64 numCommandsForOne = 1000 + ((t * t * 7) >> (2 * kSubBits)); // AMD K8
+ UInt64 numCommandsForOne = 870 + ((t * t * 5) >> (2 * kSubBits)); // Intel Core2
+
+ UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
+ return MyMultDiv64(numCommands, elapsedTime, freq);
+}
+
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)
+{
+ // UInt64 numCommands = (inSize * 216 + outSize * 14) * numIterations; // AMD K8
+ UInt64 numCommands = (inSize * 220 + outSize * 8) * numIterations; // Intel Core2
+ return MyMultDiv64(numCommands, elapsedTime, freq);
+}
+
+#ifdef EXTERNAL_LZMA
+typedef UInt32 (WINAPI * CreateObjectPointer)(const GUID *clsID,
+ const GUID *interfaceID, void **outObject);
+#endif
+
+struct CEncoderInfo;
+
+struct CEncoderInfo
+{
+ #ifdef BENCH_MT
+ NWindows::CThread thread[2];
+ #endif
+ CMyComPtr<ICompressCoder> encoder;
+ CBenchProgressInfo *progressInfoSpec[2];
+ CMyComPtr<ICompressProgressInfo> progressInfo[2];
+ UInt32 NumIterations;
+ #ifdef USE_ALLOCA
+ size_t AllocaSize;
+ #endif
+
+ struct CDecoderInfo
+ {
+ CEncoderInfo *Encoder;
+ UInt32 DecoderIndex;
+ #ifdef USE_ALLOCA
+ size_t AllocaSize;
+ #endif
+ bool CallbackMode;
+ };
+ CDecoderInfo decodersInfo[2];
+
+ CMyComPtr<ICompressCoder> decoders[2];
+ HRESULT Results[2];
+ CBenchmarkOutStream *outStreamSpec;
+ CMyComPtr<ISequentialOutStream> outStream;
+ IBenchCallback *callback;
+ UInt32 crc;
+ UInt32 kBufferSize;
+ UInt32 compressedSize;
+ CBenchRandomGenerator rg;
+ CBenchmarkOutStream *propStreamSpec;
+ CMyComPtr<ISequentialOutStream> propStream;
+ HRESULT Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rg);
+ HRESULT Encode();
+ HRESULT Decode(UInt32 decoderIndex);
+
+ CEncoderInfo(): outStreamSpec(0), callback(0), propStreamSpec(0) {}
+
+ #ifdef BENCH_MT
+ static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
+ {
+ CEncoderInfo *encoder = (CEncoderInfo *)param;
+ #ifdef USE_ALLOCA
+ alloca(encoder->AllocaSize);
+ #endif
+ HRESULT res = encoder->Encode();
+ encoder->Results[0] = res;
+ if (res != S_OK)
+ encoder->progressInfoSpec[0]->Status->SetResult(res);
+
+ return 0;
+ }
+ static THREAD_FUNC_DECL DecodeThreadFunction(void *param)
+ {
+ CDecoderInfo *decoder = (CDecoderInfo *)param;
+ #ifdef USE_ALLOCA
+ alloca(decoder->AllocaSize);
+ #endif
+ CEncoderInfo *encoder = decoder->Encoder;
+ encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);
+ return 0;
+ }
+
+ HRESULT CreateEncoderThread()
+ {
+ return thread[0].Create(EncodeThreadFunction, this);
+ }
+
+ HRESULT CreateDecoderThread(int index, bool callbackMode
+ #ifdef USE_ALLOCA
+ , size_t allocaSize
+ #endif
+ )
+ {
+ CDecoderInfo &decoder = decodersInfo[index];
+ decoder.DecoderIndex = index;
+ decoder.Encoder = this;
+ #ifdef USE_ALLOCA
+ decoder.AllocaSize = allocaSize;
+ #endif
+ decoder.CallbackMode = callbackMode;
+ return thread[index].Create(DecodeThreadFunction, &decoder);
+ }
+ #endif
+};
+
+HRESULT CEncoderInfo::Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rgLoc)
+{
+ rg.Set(rgLoc);
+ kBufferSize = dictionarySize + kAdditionalSize;
+ UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+ if (!rg.Alloc(kBufferSize))
+ return E_OUTOFMEMORY;
+ rg.Generate();
+ crc = CrcCalc(rg.Buffer, rg.BufferSize);
+
+ outStreamSpec = new CBenchmarkOutStream;
+ if (!outStreamSpec->Alloc(kCompressedBufferSize))
+ return E_OUTOFMEMORY;
+
+ outStream = outStreamSpec;
+
+ propStreamSpec = 0;
+ if (!propStream)
+ {
+ propStreamSpec = new CBenchmarkOutStream;
+ propStream = propStreamSpec;
+ }
+ if (!propStreamSpec->Alloc(kMaxLzmaPropSize))
+ return E_OUTOFMEMORY;
+ propStreamSpec->Init();
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kMultiThread
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ PROPVARIANT properties[kNumProps];
+ properties[0].vt = VT_UI4;
+ properties[0].ulVal = (UInt32)dictionarySize;
+
+ properties[1].vt = VT_BOOL;
+ properties[1].boolVal = (numThreads > 1) ? VARIANT_TRUE : VARIANT_FALSE;
+
+ {
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
+ if (!setCoderProperties)
+ return E_FAIL;
+ RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, kNumProps));
+
+ CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+ encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
+ if (writeCoderProperties)
+ {
+ RINOK(writeCoderProperties->WriteCoderProperties(propStream));
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CEncoderInfo::Encode()
+{
+ CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+ inStreamSpec->Init(rg.Buffer, rg.BufferSize);
+ outStreamSpec->Init();
+
+ RINOK(encoder->Code(inStream, outStream, 0, 0, progressInfo[0]));
+ compressedSize = outStreamSpec->Pos;
+ encoder.Release();
+ return S_OK;
+}
+
+HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
+{
+ CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+ CMyComPtr<ICompressCoder> &decoder = decoders[decoderIndex];
+
+ CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
+ decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
+ if (!compressSetDecoderProperties)
+ return E_FAIL;
+
+ CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
+ CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;
+
+ CBenchProgressInfo *pi = progressInfoSpec[decoderIndex];
+ pi->BenchInfo.UnpackSize = 0;
+ pi->BenchInfo.PackSize = 0;
+
+ for (UInt32 j = 0; j < NumIterations; j++)
+ {
+ inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
+ crcOutStreamSpec->Init();
+
+ RINOK(compressSetDecoderProperties->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos));
+ UInt64 outSize = kBufferSize;
+ RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));
+ if (CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
+ return S_FALSE;
+ pi->BenchInfo.UnpackSize += kBufferSize;
+ pi->BenchInfo.PackSize += compressedSize;
+ }
+ decoder.Release();
+ return S_OK;
+}
+
+static const UInt32 kNumThreadsMax = (1 << 16);
+
+struct CBenchEncoders
+{
+ CEncoderInfo *encoders;
+ CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }
+ ~CBenchEncoders() { delete []encoders; }
+};
+
+HRESULT LzmaBench(
+ #ifdef EXTERNAL_LZMA
+ CCodecs *codecs,
+ #endif
+ UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback)
+{
+ UInt32 numEncoderThreads =
+ #ifdef BENCH_MT
+ (numThreads > 1 ? numThreads / 2 : 1);
+ #else
+ 1;
+ #endif
+ UInt32 numSubDecoderThreads =
+ #ifdef BENCH_MT
+ (numThreads > 1 ? 2 : 1);
+ #else
+ 1;
+ #endif
+ if (dictionarySize < (1 << kBenchMinDicLogSize) || numThreads < 1 || numEncoderThreads > kNumThreadsMax)
+ {
+ return E_INVALIDARG;
+ }
+
+ CBenchEncoders encodersSpec(numEncoderThreads);
+ CEncoderInfo *encoders = encodersSpec.encoders;
+
+ #ifdef EXTERNAL_LZMA
+ UString name = L"LZMA";
+ #endif
+
+ UInt32 i;
+ for (i = 0; i < numEncoderThreads; i++)
+ {
+ CEncoderInfo &encoder = encoders[i];
+ encoder.callback = (i == 0) ? callback : 0;
+
+ #ifdef EXTERNAL_LZMA
+ RINOK(codecs->CreateCoder(name, true, encoder.encoder));
+ #else
+ encoder.encoder = new NCompress::NLZMA::CEncoder;
+ #endif
+ for (UInt32 j = 0; j < numSubDecoderThreads; j++)
+ {
+ #ifdef EXTERNAL_LZMA
+ RINOK(codecs->CreateCoder(name, false, encoder.decoders[j]));
+ #else
+ encoder.decoders[j] = new NCompress::NLZMA::CDecoder;
+ #endif
+ }
+ }
+
+ CBaseRandomGenerator rg;
+ rg.Init();
+ for (i = 0; i < numEncoderThreads; i++)
+ {
+ RINOK(encoders[i].Init(dictionarySize, numThreads, &rg));
+ }
+
+ CBenchProgressStatus status;
+ status.Res = S_OK;
+ status.EncodeMode = true;
+
+ for (i = 0; i < numEncoderThreads; i++)
+ {
+ CEncoderInfo &encoder = encoders[i];
+ for (int j = 0; j < 2; j++)
+ {
+ encoder.progressInfo[j] = encoder.progressInfoSpec[j] = new CBenchProgressInfo;
+ encoder.progressInfoSpec[j]->Status = &status;
+ }
+ if (i == 0)
+ {
+ encoder.progressInfoSpec[0]->callback = callback;
+ encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numEncoderThreads;
+ SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);
+ }
+
+ #ifdef BENCH_MT
+ if (numEncoderThreads > 1)
+ {
+ #ifdef USE_ALLOCA
+ encoder.AllocaSize = (i * 16 * 21) & 0x7FF;
+ #endif
+ RINOK(encoder.CreateEncoderThread())
+ }
+ else
+ #endif
+ {
+ RINOK(encoder.Encode());
+ }
+ }
+ #ifdef BENCH_MT
+ if (numEncoderThreads > 1)
+ for (i = 0; i < numEncoderThreads; i++)
+ encoders[i].thread[0].Wait();
+ #endif
+
+ RINOK(status.Res);
+
+ CBenchInfo info;
+
+ SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);
+ info.UnpackSize = 0;
+ info.PackSize = 0;
+ info.NumIterations = 1; // progressInfoSpec->NumIterations;
+ for (i = 0; i < numEncoderThreads; i++)
+ {
+ CEncoderInfo &encoder = encoders[i];
+ info.UnpackSize += encoder.kBufferSize;
+ info.PackSize += encoder.compressedSize;
+ }
+ RINOK(callback->SetEncodeResult(info, true));
+
+
+ status.Res = S_OK;
+ status.EncodeMode = false;
+
+ UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
+ for (i = 0; i < numEncoderThreads; i++)
+ {
+ CEncoderInfo &encoder = encoders[i];
+ encoder.NumIterations = 2 + kUncompressMinBlockSize / encoder.kBufferSize;
+
+ if (i == 0)
+ {
+ encoder.progressInfoSpec[0]->callback = callback;
+ encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numDecoderThreads;
+ SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);
+ }
+
+ #ifdef BENCH_MT
+ if (numDecoderThreads > 1)
+ {
+ for (UInt32 j = 0; j < numSubDecoderThreads; j++)
+ {
+ size_t allocaSize = ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF;
+ HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)
+ #ifdef USE_ALLOCA
+ , allocaSize
+ #endif
+ );
+ RINOK(res);
+ }
+ }
+ else
+ #endif
+ {
+ RINOK(encoder.Decode(0));
+ }
+ }
+ #ifdef BENCH_MT
+ HRESULT res = S_OK;
+ if (numDecoderThreads > 1)
+ for (i = 0; i < numEncoderThreads; i++)
+ for (UInt32 j = 0; j < numSubDecoderThreads; j++)
+ {
+ CEncoderInfo &encoder = encoders[i];
+ encoder.thread[j].Wait();
+ if (encoder.Results[j] != S_OK)
+ res = encoder.Results[j];
+ }
+ RINOK(res);
+ #endif
+ RINOK(status.Res);
+ SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);
+ info.UnpackSize = 0;
+ info.PackSize = 0;
+ info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations;
+ for (i = 0; i < numEncoderThreads; i++)
+ {
+ CEncoderInfo &encoder = encoders[i];
+ info.UnpackSize += encoder.kBufferSize;
+ info.PackSize += encoder.compressedSize;
+ }
+ RINOK(callback->SetDecodeResult(info, false));
+ RINOK(callback->SetDecodeResult(info, true));
+ return S_OK;
+}
+
+
+inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
+{
+ UInt32 hs = dictionary - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ hs |= 0xFFFF;
+ if (hs > (1 << 24))
+ hs >>= 1;
+ hs++;
+ return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 +
+ (1 << 20) + (multiThread ? (6 << 20) : 0);
+}
+
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary)
+{
+ const UInt32 kBufferSize = dictionary;
+ const UInt32 kCompressedBufferSize = (kBufferSize / 2);
+ UInt32 numSubThreads = (numThreads > 1) ? 2 : 1;
+ UInt32 numBigThreads = numThreads / numSubThreads;
+ return (kBufferSize + kCompressedBufferSize +
+ GetLZMAUsage((numThreads > 1), dictionary) + (2 << 20)) * numBigThreads;
+}
+
+static bool CrcBig(const void *data, UInt32 size, UInt32 numCycles, UInt32 crcBase)
+{
+ for (UInt32 i = 0; i < numCycles; i++)
+ if (CrcCalc(data, size) != crcBase)
+ return false;
+ return true;
+}
+
+#ifdef BENCH_MT
+struct CCrcInfo
+{
+ NWindows::CThread Thread;
+ const Byte *Data;
+ UInt32 Size;
+ UInt32 NumCycles;
+ UInt32 Crc;
+ bool Res;
+ void Wait()
+ {
+ Thread.Wait();
+ Thread.Close();
+ }
+};
+
+static THREAD_FUNC_DECL CrcThreadFunction(void *param)
+{
+ CCrcInfo *p = (CCrcInfo *)param;
+ p->Res = CrcBig(p->Data, p->Size, p->NumCycles, p->Crc);
+ return 0;
+}
+
+struct CCrcThreads
+{
+ UInt32 NumThreads;
+ CCrcInfo *Items;
+ CCrcThreads(): Items(0), NumThreads(0) {}
+ void WaitAll()
+ {
+ for (UInt32 i = 0; i < NumThreads; i++)
+ Items[i].Wait();
+ NumThreads = 0;
+ }
+ ~CCrcThreads()
+ {
+ WaitAll();
+ delete []Items;
+ }
+};
+#endif
+
+static UInt32 CrcCalc1(const Byte *buf, UInt32 size)
+{
+ UInt32 crc = CRC_INIT_VAL;;
+ for (UInt32 i = 0; i < size; i++)
+ crc = CRC_UPDATE_BYTE(crc, buf[i]);
+ return CRC_GET_DIGEST(crc);
+}
+
+static void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
+{
+ for (UInt32 i = 0; i < size; i++)
+ buf[i] = (Byte)RG.GetRnd();
+}
+
+static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
+{
+ RandGen(buf, size, RG);
+ return CrcCalc1(buf, size);
+}
+
+bool CrcInternalTest()
+{
+ CBenchBuffer buffer;
+ const UInt32 kBufferSize0 = (1 << 8);
+ const UInt32 kBufferSize1 = (1 << 10);
+ const UInt32 kCheckSize = (1 << 5);
+ if (!buffer.Alloc(kBufferSize0 + kBufferSize1))
+ return false;
+ Byte *buf = buffer.Buffer;
+ UInt32 i;
+ for (i = 0; i < kBufferSize0; i++)
+ buf[i] = (Byte)i;
+ UInt32 crc1 = CrcCalc1(buf, kBufferSize0);
+ if (crc1 != 0x29058C73)
+ return false;
+ CBaseRandomGenerator RG;
+ RandGen(buf + kBufferSize0, kBufferSize1, RG);
+ for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++)
+ for (UInt32 j = 0; j < kCheckSize; j++)
+ if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j))
+ return false;
+ return true;
+}
+
+HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed)
+{
+ if (numThreads == 0)
+ numThreads = 1;
+
+ CBenchBuffer buffer;
+ size_t totalSize = (size_t)bufferSize * numThreads;
+ if (totalSize / numThreads != bufferSize)
+ return E_OUTOFMEMORY;
+ if (!buffer.Alloc(totalSize))
+ return E_OUTOFMEMORY;
+
+ Byte *buf = buffer.Buffer;
+ CBaseRandomGenerator RG;
+ UInt32 numCycles = ((UInt32)1 << 30) / ((bufferSize >> 2) + 1) + 1;
+
+ UInt64 timeVal;
+ #ifdef BENCH_MT
+ CCrcThreads threads;
+ if (numThreads > 1)
+ {
+ threads.Items = new CCrcInfo[numThreads];
+ UInt32 i;
+ for (i = 0; i < numThreads; i++)
+ {
+ CCrcInfo &info = threads.Items[i];
+ Byte *data = buf + (size_t)bufferSize * i;
+ info.Data = data;
+ info.NumCycles = numCycles;
+ info.Size = bufferSize;
+ info.Crc = RandGenCrc(data, bufferSize, RG);
+ }
+ timeVal = GetTimeCount();
+ for (i = 0; i < numThreads; i++)
+ {
+ CCrcInfo &info = threads.Items[i];
+ RINOK(info.Thread.Create(CrcThreadFunction, &info));
+ threads.NumThreads++;
+ }
+ threads.WaitAll();
+ for (i = 0; i < numThreads; i++)
+ if (!threads.Items[i].Res)
+ return S_FALSE;
+ }
+ else
+ #endif
+ {
+ UInt32 crc = RandGenCrc(buf, bufferSize, RG);
+ timeVal = GetTimeCount();
+ if (!CrcBig(buf, bufferSize, numCycles, crc))
+ return S_FALSE;
+ }
+ timeVal = GetTimeCount() - timeVal;
+ if (timeVal == 0)
+ timeVal = 1;
+
+ UInt64 size = (UInt64)numCycles * totalSize;
+ speed = MyMultDiv64(size, timeVal, GetFreq());
+ return S_OK;
+}
+
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,48 @@
+// LzmaBench.h
+
+#ifndef __LZMABENCH_H
+#define __LZMABENCH_H
+
+#include <stdio.h>
+#include "../../../Common/Types.h"
+#ifdef EXTERNAL_LZMA
+#include "../../UI/Common/LoadCodecs.h"
+#endif
+
+struct CBenchInfo
+{
+ UInt64 GlobalTime;
+ UInt64 GlobalFreq;
+ UInt64 UserTime;
+ UInt64 UserFreq;
+ UInt64 UnpackSize;
+ UInt64 PackSize;
+ UInt32 NumIterations;
+ CBenchInfo(): NumIterations(0) {}
+};
+
+struct IBenchCallback
+{
+ virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0;
+ virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0;
+};
+
+UInt64 GetUsage(const CBenchInfo &benchOnfo);
+UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating);
+UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);
+
+HRESULT LzmaBench(
+ #ifdef EXTERNAL_LZMA
+ CCodecs *codecs,
+ #endif
+ UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback);
+
+const int kBenchMinDicLogSize = 18;
+
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary);
+
+bool CrcInternalTest();
+HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed);
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,311 @@
+// LzmaBenchCon.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "LzmaBench.h"
+#include "LzmaBenchCon.h"
+#include "../../../Common/IntToString.h"
+
+#if defined(BENCH_MT) || defined(_WIN32)
+#include "../../../Windows/System.h"
+#endif
+
+#ifdef BREAK_HANDLER
+#include "../../UI/Console/ConsoleClose.h"
+#endif
+#include "../../../Common/MyCom.h"
+
+struct CTotalBenchRes
+{
+ UInt64 NumIterations;
+ UInt64 Rating;
+ UInt64 Usage;
+ UInt64 RPU;
+ void Init() { NumIterations = 0; Rating = 0; Usage = 0; RPU = 0; }
+ void Normalize()
+ {
+ if (NumIterations == 0)
+ return;
+ Rating /= NumIterations;
+ Usage /= NumIterations;
+ RPU /= NumIterations;
+ NumIterations = 1;
+ }
+ void SetMid(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
+ {
+ Rating = (r1.Rating + r2.Rating) / 2;
+ Usage = (r1.Usage + r2.Usage) / 2;
+ RPU = (r1.RPU + r2.RPU) / 2;
+ NumIterations = (r1.NumIterations + r2.NumIterations) / 2;
+ }
+};
+
+struct CBenchCallback: public IBenchCallback
+{
+ CTotalBenchRes EncodeRes;
+ CTotalBenchRes DecodeRes;
+ FILE *f;
+ void Init() { EncodeRes.Init(); DecodeRes.Init(); }
+ void Normalize() { EncodeRes.Normalize(); DecodeRes.Normalize(); }
+ UInt32 dictionarySize;
+ HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
+ HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
+};
+
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)
+{
+ while (v1 > 1000000)
+ {
+ v1 >>= 1;
+ v2 >>= 1;
+ }
+}
+
+static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
+{
+ UInt64 elTime = elapsedTime;
+ NormalizeVals(freq, elTime);
+ if (elTime == 0)
+ elTime = 1;
+ return value * freq / elTime;
+}
+
+static void PrintNumber(FILE *f, UInt64 value, int size)
+{
+ char s[32];
+ ConvertUInt64ToString(value, s);
+ fprintf(f, " ");
+ for (int len = (int)strlen(s); len < size; len++)
+ fprintf(f, " ");
+ fprintf(f, "%s", s);
+}
+
+static void PrintRating(FILE *f, UInt64 rating)
+{
+ PrintNumber(f, rating / 1000000, 6);
+}
+
+static void PrintResults(FILE *f, UInt64 usage, UInt64 rpu, UInt64 rating)
+{
+ PrintNumber(f, (usage + 5000) / 10000, 5);
+ PrintRating(f, rpu);
+ PrintRating(f, rating);
+}
+
+
+static void PrintResults(FILE *f, const CBenchInfo &info, UInt64 rating, CTotalBenchRes &res)
+{
+ UInt64 speed = MyMultDiv64(info.UnpackSize, info.GlobalTime, info.GlobalFreq);
+ PrintNumber(f, speed / 1024, 7);
+ UInt64 usage = GetUsage(info);
+ UInt64 rpu = GetRatingPerUsage(info, rating);
+ PrintResults(f, usage, rpu, rating);
+ res.NumIterations++;
+ res.RPU += rpu;
+ res.Rating += rating;
+ res.Usage += usage;
+}
+
+static void PrintTotals(FILE *f, const CTotalBenchRes &res)
+{
+ fprintf(f, " ");
+ PrintResults(f, res.Usage, res.RPU, res.Rating);
+}
+
+
+HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final)
+{
+ #ifdef BREAK_HANDLER
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ #endif
+
+ if (final)
+ {
+ UInt64 rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, info.UnpackSize);
+ PrintResults(f, info, rating, EncodeRes);
+ }
+ return S_OK;
+}
+
+static const char *kSep = " | ";
+
+
+HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)
+{
+ #ifdef BREAK_HANDLER
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ #endif
+ if (final)
+ {
+ UInt64 rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
+ fprintf(f, kSep);
+ CBenchInfo info2 = info;
+ info2.UnpackSize *= info2.NumIterations;
+ info2.PackSize *= info2.NumIterations;
+ info2.NumIterations = 1;
+ PrintResults(f, info2, rating, DecodeRes);
+ }
+ return S_OK;
+}
+
+static void PrintRequirements(FILE *f, const char *sizeString, UInt64 size, const char *threadsString, UInt32 numThreads)
+{
+ fprintf(f, "\nRAM %s ", sizeString);
+ PrintNumber(f, (size >> 20), 5);
+ fprintf(f, " MB, # %s %3d", threadsString, (unsigned int)numThreads);
+}
+
+HRESULT LzmaBenchCon(
+ #ifdef EXTERNAL_LZMA
+ CCodecs *codecs,
+ #endif
+ FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
+{
+ if (!CrcInternalTest())
+ return S_FALSE;
+ #ifdef BENCH_MT
+ UInt64 ramSize = NWindows::NSystem::GetRamSize(); //
+ UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
+ PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
+ if (numThreads == (UInt32)-1)
+ numThreads = numCPUs;
+ if (numThreads > 1)
+ numThreads &= ~1;
+ if (dictionary == (UInt32)-1)
+ {
+ int dicSizeLog;
+ for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
+ if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)
+ break;
+ dictionary = (1 << dicSizeLog);
+ }
+ #else
+ if (dictionary == (UInt32)-1)
+ dictionary = (1 << 22);
+ numThreads = 1;
+ #endif
+
+ PrintRequirements(f, "usage:", GetBenchMemoryUsage(numThreads, dictionary), "Benchmark threads: ", numThreads);
+
+ CBenchCallback callback;
+ callback.Init();
+ callback.f = f;
+
+ fprintf(f, "\n\nDict Compressing | Decompressing\n ");
+ int j;
+ for (j = 0; j < 2; j++)
+ {
+ fprintf(f, " Speed Usage R/U Rating");
+ if (j == 0)
+ fprintf(f, kSep);
+ }
+ fprintf(f, "\n ");
+ for (j = 0; j < 2; j++)
+ {
+ fprintf(f, " KB/s %% MIPS MIPS");
+ if (j == 0)
+ fprintf(f, kSep);
+ }
+ fprintf(f, "\n\n");
+ for (UInt32 i = 0; i < numIterations; i++)
+ {
+ const int kStartDicLog = 22;
+ int pow = (dictionary < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
+ while (((UInt32)1 << pow) > dictionary)
+ pow--;
+ for (; ((UInt32)1 << pow) <= dictionary; pow++)
+ {
+ fprintf(f, "%2d:", pow);
+ callback.dictionarySize = (UInt32)1 << pow;
+ HRESULT res = LzmaBench(
+ #ifdef EXTERNAL_LZMA
+ codecs,
+ #endif
+ numThreads, callback.dictionarySize, &callback);
+ fprintf(f, "\n");
+ RINOK(res);
+ }
+ }
+ callback.Normalize();
+ fprintf(f, "----------------------------------------------------------------\nAvr:");
+ PrintTotals(f, callback.EncodeRes);
+ fprintf(f, " ");
+ PrintTotals(f, callback.DecodeRes);
+ fprintf(f, "\nTot:");
+ CTotalBenchRes midRes;
+ midRes.SetMid(callback.EncodeRes, callback.DecodeRes);
+ PrintTotals(f, midRes);
+ fprintf(f, "\n");
+ return S_OK;
+}
+
+struct CTempValues
+{
+ UInt64 *Values;
+ CTempValues(UInt32 num) { Values = new UInt64[num]; }
+ ~CTempValues() { delete []Values; }
+};
+
+HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
+{
+ if (!CrcInternalTest())
+ return S_FALSE;
+
+ #ifdef BENCH_MT
+ UInt64 ramSize = NWindows::NSystem::GetRamSize();
+ UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
+ PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
+ if (numThreads == (UInt32)-1)
+ numThreads = numCPUs;
+ #else
+ numThreads = 1;
+ #endif
+ if (dictionary == (UInt32)-1)
+ dictionary = (1 << 24);
+
+ CTempValues speedTotals(numThreads);
+ fprintf(f, "\n\nSize");
+ for (UInt32 ti = 0; ti < numThreads; ti++)
+ {
+ fprintf(f, " %5d", ti + 1);
+ speedTotals.Values[ti] = 0;
+ }
+ fprintf(f, "\n\n");
+
+ UInt64 numSteps = 0;
+ for (UInt32 i = 0; i < numIterations; i++)
+ {
+ for (int pow = 10; pow < 32; pow++)
+ {
+ UInt32 bufSize = (UInt32)1 << pow;
+ if (bufSize > dictionary)
+ break;
+ fprintf(f, "%2d: ", pow);
+ UInt64 speed;
+ for (UInt32 ti = 0; ti < numThreads; ti++)
+ {
+ #ifdef BREAK_HANDLER
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ #endif
+ RINOK(CrcBench(ti + 1, bufSize, speed));
+ PrintNumber(f, (speed >> 20), 5);
+ speedTotals.Values[ti] += speed;
+ }
+ fprintf(f, "\n");
+ numSteps++;
+ }
+ }
+ if (numSteps != 0)
+ {
+ fprintf(f, "\nAvg:");
+ for (UInt32 ti = 0; ti < numThreads; ti++)
+ PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), 5);
+ fprintf(f, "\n");
+ }
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,20 @@
+// LzmaBenchCon.h
+
+#ifndef __LZMABENCHCON_H
+#define __LZMABENCHCON_H
+
+#include <stdio.h>
+#include "../../../Common/Types.h"
+#ifdef EXTERNAL_LZMA
+#include "../../UI/Common/LoadCodecs.h"
+#endif
+HRESULT LzmaBenchCon(
+ #ifdef EXTERNAL_LZMA
+ CCodecs *codecs,
+ #endif
+ FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);
+
+HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);
+
+#endif
+
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,226 @@
+// LzmaRam.cpp
+
+#include "StdAfx.h"
+#include "../../../Common/Types.h"
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+#include "LzmaRam.h"
+
+extern "C"
+{
+ #include "../../../../C/Compress/Branch/BranchX86.h"
+}
+
+class CInStreamRam:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *Data;
+ size_t Size;
+ size_t Pos;
+public:
+ MY_UNKNOWN_IMP
+ void Init(const Byte *data, size_t size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ }
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (size > (Size - Pos))
+ size = (UInt32)(Size - Pos);
+ for (UInt32 i = 0; i < size; i++)
+ ((Byte *)data)[i] = Data[Pos + i];
+ Pos += size;
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+class COutStreamRam:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ size_t Size;
+public:
+ Byte *Data;
+ size_t Pos;
+ bool Overflow;
+ void Init(Byte *data, size_t size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ Overflow = false;
+ }
+ void SetPos(size_t pos)
+ {
+ Overflow = false;
+ Pos = pos;
+ }
+ MY_UNKNOWN_IMP
+ HRESULT WriteByte(Byte b)
+ {
+ if (Pos >= Size)
+ {
+ Overflow = true;
+ return E_FAIL;
+ }
+ Data[Pos++] = b;
+ return S_OK;
+ }
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 i;
+ for (i = 0; i < size && Pos < Size; i++)
+ Data[Pos++] = ((const Byte *)data)[i];
+ if(processedSize != NULL)
+ *processedSize = i;
+ if (i != size)
+ {
+ Overflow = true;
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+#define SZ_RAM_E_FAIL (1)
+#define SZ_RAM_E_OUTOFMEMORY (2)
+#define SZE_OUT_OVERFLOW (3)
+
+int LzmaRamEncode(
+ const Byte *inBuffer, size_t inSize,
+ Byte *outBuffer, size_t outSize, size_t *outSizeProcessed,
+ UInt32 dictionarySize, ESzFilterMode filterMode)
+{
+ #ifndef _NO_EXCEPTIONS
+ try {
+ #endif
+
+ *outSizeProcessed = 0;
+ const size_t kIdSize = 1;
+ const size_t kLzmaPropsSize = 5;
+ const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8;
+ if (outSize < kMinDestSize)
+ return SZE_OUT_OVERFLOW;
+ NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kNumFastBytes,
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ PROPVARIANT properties[kNumProps];
+ properties[0].vt = VT_UI4;
+ properties[1].vt = VT_UI4;
+ properties[2].vt = VT_UI4;
+ properties[0].ulVal = (UInt32)2;
+ properties[1].ulVal = (UInt32)dictionarySize;
+ properties[2].ulVal = (UInt32)64;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
+ return 1;
+
+ COutStreamRam *outStreamSpec = new COutStreamRam;
+ if (outStreamSpec == 0)
+ return SZ_RAM_E_OUTOFMEMORY;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ CInStreamRam *inStreamSpec = new CInStreamRam;
+ if (inStreamSpec == 0)
+ return SZ_RAM_E_OUTOFMEMORY;
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ outStreamSpec->Init(outBuffer, outSize);
+ if (outStreamSpec->WriteByte(0) != S_OK)
+ return SZE_OUT_OVERFLOW;
+
+ if (encoderSpec->WriteCoderProperties(outStream) != S_OK)
+ return SZE_OUT_OVERFLOW;
+ if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize)
+ return 1;
+
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ UInt64 t = (UInt64)(inSize);
+ if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK)
+ return SZE_OUT_OVERFLOW;
+ }
+
+ Byte *filteredStream = 0;
+
+ bool useFilter = (filterMode != SZ_FILTER_NO);
+ if (useFilter)
+ {
+ if (inSize != 0)
+ {
+ filteredStream = (Byte *)MyAlloc(inSize);
+ if (filteredStream == 0)
+ return SZ_RAM_E_OUTOFMEMORY;
+ memmove(filteredStream, inBuffer, inSize);
+ }
+ UInt32 x86State;
+ x86_Convert_Init(x86State);
+ x86_Convert(filteredStream, (SizeT)inSize, 0, &x86State, 1);
+ }
+
+ size_t minSize = 0;
+ int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
+ bool bestIsFiltered = false;
+ int mainResult = 0;
+ size_t startPos = outStreamSpec->Pos;
+ for (i = 0; i < numPasses; i++)
+ {
+ if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered)
+ break;
+ outStreamSpec->SetPos(startPos);
+ bool curModeIsFiltered = false;
+ if (useFilter && i == 0)
+ curModeIsFiltered = true;
+ if (numPasses > 1 && i == numPasses - 1)
+ curModeIsFiltered = true;
+
+ inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize);
+
+ HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0);
+
+ mainResult = 0;
+ if (lzmaResult == E_OUTOFMEMORY)
+ {
+ mainResult = SZ_RAM_E_OUTOFMEMORY;
+ break;
+ }
+ if (i == 0 || outStreamSpec->Pos <= minSize)
+ {
+ minSize = outStreamSpec->Pos;
+ bestIsFiltered = curModeIsFiltered;
+ }
+ if (outStreamSpec->Overflow)
+ mainResult = SZE_OUT_OVERFLOW;
+ else if (lzmaResult != S_OK)
+ {
+ mainResult = SZ_RAM_E_FAIL;
+ break;
+ }
+ }
+ *outSizeProcessed = outStreamSpec->Pos;
+ if (bestIsFiltered)
+ outBuffer[0] = 1;
+ if (useFilter)
+ MyFree(filteredStream);
+ return mainResult;
+
+ #ifndef _NO_EXCEPTIONS
+ } catch(...) { return SZ_RAM_E_OUTOFMEMORY; }
+ #endif
+}
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,46 @@
+// LzmaRam.h
+
+#ifndef __LzmaRam_h
+#define __LzmaRam_h
+
+#include <stdlib.h>
+#include "../../../Common/Types.h"
+
+/*
+LzmaRamEncode: BCJ + LZMA RAM->RAM compressing.
+It uses .lzma format, but it writes one additional byte to .lzma file:
+ 0: - no filter
+ 1: - x86(BCJ) filter.
+
+To provide best compression ratio dictionarySize mustbe >= inSize
+
+LzmaRamEncode allocates Data with MyAlloc/BigAlloc functions.
+RAM Requirements:
+ RamSize = dictionarySize * 9.5 + 6MB + FilterBlockSize
+ FilterBlockSize = 0, if useFilter == false
+ FilterBlockSize = inSize, if useFilter == true
+
+ Return code:
+ 0 - OK
+ 1 - Unspecified Error
+ 2 - Memory allocating error
+ 3 - Output buffer OVERFLOW
+
+If you use SZ_FILTER_AUTO mode, then encoder will use 2 or 3 passes:
+ 2 passes when FILTER_NO provides better compression.
+ 3 passes when FILTER_YES provides better compression.
+*/
+
+enum ESzFilterMode
+{
+ SZ_FILTER_NO,
+ SZ_FILTER_YES,
+ SZ_FILTER_AUTO
+};
+
+int LzmaRamEncode(
+ const Byte *inBuffer, size_t inSize,
+ Byte *outBuffer, size_t outSize, size_t *outSizeProcessed,
+ UInt32 dictionarySize, ESzFilterMode filterMode);
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,78 @@
+/* LzmaRamDecode.c */
+
+#include "LzmaRamDecode.h"
+#ifdef _SZ_ONE_DIRECTORY
+#include "LzmaDecode.h"
+#include "BranchX86.h"
+#else
+#include "../../../../C/Compress/Lzma/LzmaDecode.h"
+#include "../../../../C/Compress/Branch/BranchX86.h"
+#endif
+
+#define LZMA_PROPS_SIZE 14
+#define LZMA_SIZE_OFFSET 6
+
+int LzmaRamGetUncompressedSize(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ size_t *outSize)
+{
+ unsigned int i;
+ if (inSize < LZMA_PROPS_SIZE)
+ return 1;
+ *outSize = 0;
+ for(i = 0; i < sizeof(size_t); i++)
+ *outSize += ((size_t)inBuffer[LZMA_SIZE_OFFSET + i]) << (8 * i);
+ for(; i < 8; i++)
+ if (inBuffer[LZMA_SIZE_OFFSET + i] != 0)
+ return 1;
+ return 0;
+}
+
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+
+int LzmaRamDecompress(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ unsigned char *outBuffer,
+ size_t outSize,
+ size_t *outSizeProcessed,
+ void * (*allocFunc)(size_t size),
+ void (*freeFunc)(void *))
+{
+ CLzmaDecoderState state; /* it's about 24 bytes structure, if int is 32-bit */
+ int result;
+ SizeT outSizeProcessedLoc;
+ SizeT inProcessed;
+ int useFilter;
+
+ if (inSize < LZMA_PROPS_SIZE)
+ return 1;
+ useFilter = inBuffer[0];
+
+ *outSizeProcessed = 0;
+ if (useFilter > 1)
+ return 1;
+
+ if (LzmaDecodeProperties(&state.Properties, inBuffer + 1, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return 1;
+ state.Probs = (CProb *)allocFunc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return SZE_OUTOFMEMORY;
+
+ result = LzmaDecode(&state,
+ inBuffer + LZMA_PROPS_SIZE, (SizeT)inSize - LZMA_PROPS_SIZE, &inProcessed,
+ outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
+ freeFunc(state.Probs);
+ if (result != LZMA_RESULT_OK)
+ return 1;
+ *outSizeProcessed = (size_t)outSizeProcessedLoc;
+ if (useFilter == 1)
+ {
+ UInt32 x86State;
+ x86_Convert_Init(x86State);
+ x86_Convert(outBuffer, (SizeT)outSizeProcessedLoc, 0, &x86State, 0);
+ }
+ return 0;
+}
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,55 @@
+/* LzmaRamDecode.h */
+
+#ifndef __LzmaRamDecode_h
+#define __LzmaRamDecode_h
+
+#include <stdlib.h>
+
+/*
+LzmaRamGetUncompressedSize:
+ In:
+ inBuffer - input data
+ inSize - input data size
+ Out:
+ outSize - uncompressed size
+ Return code:
+ 0 - OK
+ 1 - Error in headers
+*/
+
+int LzmaRamGetUncompressedSize(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ size_t *outSize);
+
+
+/*
+LzmaRamDecompress:
+ In:
+ inBuffer - input data
+ inSize - input data size
+ outBuffer - output data
+ outSize - output size
+ allocFunc - alloc function (can be malloc)
+ freeFunc - free function (can be free)
+ Out:
+ outSizeProcessed - processed size
+ Return code:
+ 0 - OK
+ 1 - Error in headers / data stream
+ 2 - Memory allocating error
+
+Memory requirements depend from properties of LZMA stream.
+With default lzma settings it's about 16 KB.
+*/
+
+int LzmaRamDecompress(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ unsigned char *outBuffer,
+ size_t outSize,
+ size_t *outSizeProcessed,
+ void * (*allocFunc)(size_t size),
+ void (*freeFunc)(void *));
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/makefile
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/makefile (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/makefile 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,136 @@
+PROG = lzma.exe
+CFLAGS = $(CFLAGS) \
+ -DCOMPRESS_MF_MT \
+ -DBENCH_MT \
+
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+!IFDEF CPU
+LIBS = $(LIBS) bufferoverflowU.lib
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope -W4 -Wp64 -DUNICODE -D_UNICODE
+!ENDIF
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+!IFDEF MY_STATIC_LINK
+!IFNDEF MY_SINGLE_THREAD
+CFLAGS = $(CFLAGS) -MT
+!ENDIF
+!ELSE
+CFLAGS = $(CFLAGS) -MD
+!ENDIF
+
+CFLAGS = $(CFLAGS) -nologo -EHsc -c -Fo$O/
+CFLAGS_O1 = $(CFLAGS) -O1
+CFLAGS_O2 = $(CFLAGS) -O2
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
+COMPL = $(CPP) $(CFLAGS_O1) $**
+
+
+LZMA_OBJS = \
+ $O\LzmaAlone.obj \
+ $O\LzmaBench.obj \
+ $O\LzmaBenchCon.obj \
+ $O\LzmaRam.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+
+COMMON_OBJS = \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\MyString.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\MyVector.obj
+
+WIN_OBJS = \
+ $O\System.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+ $O\StreamUtils.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+C_OBJS = \
+ $O\Alloc.obj \
+ $O\7zCrc.obj \
+ $O\Threads.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+ $O\MatchFinderMt.obj \
+
+OBJS = \
+ $(LZMA_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(LZ_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $O\LzmaRamDecode.obj \
+ $O\LzmaDecode.obj \
+ $O\FileStreams.obj \
+ $O\FileIO.obj \
+ $O\RangeCoderBit.obj \
+ $O\BranchX86.obj \
+
+all: $(PROGPATH)
+
+clean:
+ -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
+
+$O:
+ if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS)
+ link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+
+
+$(LZMA_OBJS): $(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../LZMA/$(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../LZ/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp
+ $(COMPL)
+$O\LzmaRamDecode.obj: LzmaRamDecode.c
+ $(COMPL_O1)
+$O\LzmaDecode.obj: ../../../../C/Compress/Lzma/LzmaDecode.c
+ $(COMPL_O2)
+$O\BranchX86.obj: ../../../../C/Compress/Branch/BranchX86.c
+ $(COMPL_O2)
+$O\FileStreams.obj: ../../Common/FileStreams.cpp
+ $(COMPL)
+$O\FileIO.obj: ../../../Windows/FileIO.cpp
+ $(COMPL)
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
Added: trunk/lzma/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
===================================================================
--- trunk/lzma/CPP/7zip/Compress/LZMA_Alone/makefile.gcc (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/LZMA_Alone/makefile.gcc 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,139 @@
+PROG = lzma
+CXX = g++ -O2 -Wall
+CXX_C = gcc -O2 -Wall
+LIB = -lm
+RM = rm -f
+CFLAGS = -c
+
+ifdef SystemDrive
+IS_MINGW = 1
+endif
+
+ifdef IS_MINGW
+FILE_IO =FileIO
+FILE_IO_2 =Windows/$(FILE_IO)
+LIB2 = -luuid
+else
+FILE_IO =C_FileIO
+FILE_IO_2 =Common/$(FILE_IO)
+endif
+
+OBJS = \
+ LzmaAlone.o \
+ LzmaBench.o \
+ LzmaBenchCon.o \
+ LzmaRam.o \
+ LZMADecoder.o \
+ LZMAEncoder.o \
+ LZOutWindow.o \
+ RangeCoderBit.o \
+ InBuffer.o \
+ OutBuffer.o \
+ FileStreams.o \
+ StreamUtils.o \
+ $(FILE_IO).o \
+ CommandLineParser.o \
+ CRC.o \
+ IntToString.o \
+ MyString.o \
+ StringConvert.o \
+ StringToInt.o \
+ MyVector.o \
+ 7zCrc.o \
+ Alloc.o \
+ BranchX86.o \
+ MatchFinder.o \
+ LzmaDecode.o \
+ LzmaRamDecode.o \
+
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)
+
+LzmaAlone.o: LzmaAlone.cpp
+ $(CXX) $(CFLAGS) LzmaAlone.cpp
+
+LzmaBench.o: LzmaBench.cpp
+ $(CXX) $(CFLAGS) LzmaBench.cpp
+
+LzmaBenchCon.o: LzmaBenchCon.cpp
+ $(CXX) $(CFLAGS) LzmaBenchCon.cpp
+
+LzmaRam.o: LzmaRam.cpp
+ $(CXX) $(CFLAGS) LzmaRam.cpp
+
+LZMADecoder.o: ../LZMA/LZMADecoder.cpp
+ $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp
+
+LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp
+ $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp
+
+LZOutWindow.o: ../LZ/LZOutWindow.cpp
+ $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp
+
+RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp
+ $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp
+
+InBuffer.o: ../../Common/InBuffer.cpp
+ $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp
+
+OutBuffer.o: ../../Common/OutBuffer.cpp
+ $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp
+
+FileStreams.o: ../../Common/FileStreams.cpp
+ $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp
+
+StreamUtils.o: ../../Common/StreamUtils.cpp
+ $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp
+
+$(FILE_IO).o: ../../../$(FILE_IO_2).cpp
+ $(CXX) $(CFLAGS) ../../../$(FILE_IO_2).cpp
+
+
+CommandLineParser.o: ../../../Common/CommandLineParser.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp
+
+CRC.o: ../../../Common/CRC.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CRC.cpp
+
+MyWindows.o: ../../../Common/MyWindows.cpp
+ $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp
+
+IntToString.o: ../../../Common/IntToString.cpp
+ $(CXX) $(CFLAGS) ../../../Common/IntToString.cpp
+
+MyString.o: ../../../Common/MyString.cpp
+ $(CXX) $(CFLAGS) ../../../Common/MyString.cpp
+
+StringConvert.o: ../../../Common/StringConvert.cpp
+ $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp
+
+StringToInt.o: ../../../Common/StringToInt.cpp
+ $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp
+
+MyVector.o: ../../../Common/MyVector.cpp
+ $(CXX) $(CFLAGS) ../../../Common/MyVector.cpp
+
+7zCrc.o: ../../../../C/7zCrc.c
+ $(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c
+
+Alloc.o: ../../../../C/Alloc.c
+ $(CXX_C) $(CFLAGS) ../../../../C/Alloc.c
+
+BranchX86.o: ../../../../C/Compress/Branch/BranchX86.c
+ $(CXX_C) $(CFLAGS) ../../../../C/Compress/Branch/BranchX86.c
+
+MatchFinder.o: ../../../../C/Compress/Lz/MatchFinder.c
+ $(CXX_C) $(CFLAGS) ../../../../C/Compress/Lz/MatchFinder.c
+
+LzmaDecode.o: ../../../../C/Compress/Lzma/LzmaDecode.c
+ $(CXX_C) $(CFLAGS) ../../../../C/Compress/Lzma/LzmaDecode.c
+
+LzmaRamDecode.o: LzmaRamDecode.c
+ $(CXX_C) $(CFLAGS) LzmaRamDecode.c
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
Added: trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoder.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoder.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,205 @@
+// Compress/RangeCoder/RangeCoder.h
+
+#ifndef __COMPRESS_RANGECODER_H
+#define __COMPRESS_RANGECODER_H
+
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumTopBits = 24;
+const UInt32 kTopValue = (1 << kNumTopBits);
+
+class CEncoder
+{
+ UInt32 _cacheSize;
+ Byte _cache;
+public:
+ UInt64 Low;
+ UInt32 Range;
+ COutBuffer Stream;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Low = 0;
+ Range = 0xFFFFFFFF;
+ _cacheSize = 1;
+ _cache = 0;
+ }
+
+ void FlushData()
+ {
+ // Low += 1;
+ for(int i = 0; i < 5; i++)
+ ShiftLow();
+ }
+
+ HRESULT FlushStream() { return Stream.Flush(); }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ void Encode(UInt32 start, UInt32 size, UInt32 total)
+ {
+ Low += start * (Range /= total);
+ Range *= size;
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ void ShiftLow()
+ {
+ if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
+ {
+ Byte temp = _cache;
+ do
+ {
+ Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
+ temp = 0xFF;
+ }
+ while(--_cacheSize != 0);
+ _cache = (Byte)((UInt32)Low >> 24);
+ }
+ _cacheSize++;
+ Low = (UInt32)Low << 8;
+ }
+
+ void EncodeDirectBits(UInt32 value, int numTotalBits)
+ {
+ for (int i = numTotalBits - 1; i >= 0; i--)
+ {
+ Range >>= 1;
+ if (((value >> i) & 1) == 1)
+ Low += Range;
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+ }
+
+ void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ if (symbol == 0)
+ Range = newBound;
+ else
+ {
+ Low += newBound;
+ Range -= newBound;
+ }
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
+};
+
+class CDecoder
+{
+public:
+ CInBuffer Stream;
+ UInt32 Range;
+ UInt32 Code;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void Normalize()
+ {
+ while (Range < kTopValue)
+ {
+ Code = (Code << 8) | Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Code = 0;
+ Range = 0xFFFFFFFF;
+ for(int i = 0; i < 5; i++)
+ Code = (Code << 8) | Stream.ReadByte();
+ }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ UInt32 GetThreshold(UInt32 total)
+ {
+ return (Code) / ( Range /= total);
+ }
+
+ void Decode(UInt32 start, UInt32 size)
+ {
+ Code -= start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ UInt32 DecodeDirectBits(int numTotalBits)
+ {
+ UInt32 range = Range;
+ UInt32 code = Code;
+ UInt32 result = 0;
+ for (int i = numTotalBits; i != 0; i--)
+ {
+ range >>= 1;
+ /*
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ */
+ UInt32 t = (code - range) >> 31;
+ code -= range & (t - 1);
+ result = (result << 1) | (1 - t);
+
+ if (range < kTopValue)
+ {
+ code = (code << 8) | Stream.ReadByte();
+ range <<= 8;
+ }
+ }
+ Range = range;
+ Code = code;
+ return result;
+ }
+
+ UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ UInt32 symbol;
+ if (Code < newBound)
+ {
+ symbol = 0;
+ Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ Code -= newBound;
+ Range -= newBound;
+ }
+ Normalize();
+ return symbol;
+ }
+
+ UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp
===================================================================
--- trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,80 @@
+// Compress/RangeCoder/RangeCoderBit.cpp
+
+#include "StdAfx.h"
+
+#include "RangeCoderBit.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+static CPriceTables g_PriceTables;
+
+CPriceTables::CPriceTables() { Init(); }
+
+void CPriceTables::Init()
+{
+ const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+ for(int i = kNumBits - 1; i >= 0; i--)
+ {
+ UInt32 start = 1 << (kNumBits - i - 1);
+ UInt32 end = 1 << (kNumBits - i);
+ for (UInt32 j = start; j < end; j++)
+ ProbPrices[j] = (i << kNumBitPriceShiftBits) +
+ (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+ }
+
+ /*
+ // simplest: bad solution
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = kBitPrice;
+ */
+
+ /*
+ const double kDummyMultMid = (1.0 / kBitPrice) / 2;
+ const double kDummyMultMid = 0;
+ // float solution
+ double ln2 = log(double(2));
+ double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
+ */
+
+ /*
+ // experimental, slow, solution:
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ {
+ const int kCyclesBits = 5;
+ const UInt32 kCycles = (1 << kCyclesBits);
+
+ UInt32 range = UInt32(-1);
+ UInt32 bitCount = 0;
+ for (UInt32 j = 0; j < kCycles; j++)
+ {
+ range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
+ range *= i;
+ while(range < (1 << 31))
+ {
+ range <<= 1;
+ bitCount++;
+ }
+ }
+ bitCount <<= kNumBitPriceShiftBits;
+ range -= (1 << 31);
+ for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
+ {
+ range <<= 1;
+ if (range > (1 << 31))
+ {
+ bitCount += (1 << k);
+ range -= (1 << 31);
+ }
+ }
+ ProbPrices[i] = (bitCount
+ // + (1 << (kCyclesBits - 1))
+ ) >> kCyclesBits;
+ }
+ */
+}
+
+}}
Added: trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,120 @@
+// Compress/RangeCoder/RangeCoderBit.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_H
+#define __COMPRESS_RANGECODER_BIT_H
+
+#include "RangeCoder.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumBitModelTotalBits = 11;
+const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+const int kNumBitPriceShiftBits = 6;
+const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
+
+class CPriceTables
+{
+public:
+ static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ static void Init();
+ CPriceTables();
+};
+
+template <int numMoveBits>
+class CBitModel
+{
+public:
+ UInt32 Prob;
+ void UpdateModel(UInt32 symbol)
+ {
+ /*
+ Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
+ Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
+ */
+ if (symbol == 0)
+ Prob += (kBitModelTotal - Prob) >> numMoveBits;
+ else
+ Prob -= (Prob) >> numMoveBits;
+ }
+public:
+ void Init() { Prob = kBitModelTotal / 2; }
+};
+
+template <int numMoveBits>
+class CBitEncoder: public CBitModel<numMoveBits>
+{
+public:
+ void Encode(CEncoder *encoder, UInt32 symbol)
+ {
+ /*
+ encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
+ this->UpdateModel(symbol);
+ */
+ UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (symbol == 0)
+ {
+ encoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ }
+ else
+ {
+ encoder->Low += newBound;
+ encoder->Range -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ }
+ if (encoder->Range < kTopValue)
+ {
+ encoder->Range <<= 8;
+ encoder->ShiftLow();
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ return CPriceTables::ProbPrices[
+ (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+ UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
+ UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
+};
+
+
+template <int numMoveBits>
+class CBitDecoder: public CBitModel<numMoveBits>
+{
+public:
+ UInt32 Decode(CDecoder *decoder)
+ {
+ UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (decoder->Code < newBound)
+ {
+ decoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ decoder->Range -= newBound;
+ decoder->Code -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 1;
+ }
+ }
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,161 @@
+// Compress/RangeCoder/RangeCoderBitTree.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
+#define __COMPRESS_RANGECODER_BIT_TREE_H
+
+#include "RangeCoderBit.h"
+#include "RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeEncoder
+{
+ CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ void Encode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
+ {
+ bitIndex--;
+ UInt32 bit = (symbol >> bitIndex) & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ };
+ void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ symbol |= (1 << NumBitLevels);
+ UInt32 price = 0;
+ while (symbol != 1)
+ {
+ price += Models[symbol >> 1].GetPrice(symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+ }
+ UInt32 ReverseGetPrice(UInt32 symbol) const
+ {
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+ }
+};
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeDecoder
+{
+ CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ UInt32 Decode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ RC_INIT_VAR
+ for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+ {
+ // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+ RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
+ }
+ RC_FLUSH_VAR
+ return modelIndex - (1 << NumBitLevels);
+ };
+ UInt32 ReverseDecode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+ }
+};
+
+template <int numMoveBits>
+void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
+ CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
+{
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
+ UInt32 NumBitLevels, UInt32 symbol)
+{
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
+ CDecoder *rangeDecoder, int NumBitLevels)
+{
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+}
+
+}}
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,31 @@
+// Compress/RangeCoder/RangeCoderOpt.h
+
+#ifndef __COMPRESS_RANGECODER_OPT_H
+#define __COMPRESS_RANGECODER_OPT_H
+
+#define RC_INIT_VAR \
+ UInt32 range = rangeDecoder->Range; \
+ UInt32 code = rangeDecoder->Code;
+
+#define RC_FLUSH_VAR \
+ rangeDecoder->Range = range; \
+ rangeDecoder->Code = code;
+
+#define RC_NORMALIZE \
+ if (range < NCompress::NRangeCoder::kTopValue) \
+ { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
+
+#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
+ { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
+ if (code < bound) \
+ { A0; range = bound; \
+ prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
+ mi <<= 1; } \
+ else \
+ { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
+ mi = (mi + mi) + 1; }} \
+ RC_NORMALIZE
+
+#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
+
+#endif
Added: trunk/lzma/CPP/7zip/Compress/RangeCoder/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/Compress/RangeCoder/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/Compress/RangeCoder/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
Added: trunk/lzma/CPP/7zip/ICoder.h
===================================================================
--- trunk/lzma/CPP/7zip/ICoder.h (rev 0)
+++ trunk/lzma/CPP/7zip/ICoder.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,185 @@
+// ICoder.h
+
+#ifndef __ICODER_H
+#define __ICODER_H
+
+#include "IStream.h"
+
+#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x)
+
+CODER_INTERFACE(ICompressProgressInfo, 0x04)
+{
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder, 0x05)
+{
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize,
+ const UInt64 *outSize,
+ ICompressProgressInfo *progress) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder2, 0x18)
+{
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress) PURE;
+};
+
+namespace NCoderPropID
+{
+ enum EEnum
+ {
+ kDictionarySize = 0x400,
+ kUsedMemorySize,
+ kOrder,
+ kPosStateBits = 0x440,
+ kLitContextBits,
+ kLitPosBits,
+ kNumFastBytes = 0x450,
+ kMatchFinder,
+ kMatchFinderCycles,
+ kNumPasses = 0x460,
+ kAlgorithm = 0x470,
+ kMultiThread = 0x480,
+ kNumThreads,
+ kEndMarker = 0x490
+ };
+}
+
+CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
+{
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties) PURE;
+};
+
+/*
+CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
+{
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
+};
+*/
+
+CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
+{
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
+{
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
+};
+
+CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
+{
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetCoderMt, 0x25)
+{
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
+};
+
+CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
+{
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStream, 0x31)
+{
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
+ STDMETHOD(ReleaseInStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStream, 0x32)
+{
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
+ STDMETHOD(ReleaseOutStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
+{
+ STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
+{
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressFilter, 0x40)
+{
+ STDMETHOD(Init)() PURE;
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
+ // Filter return outSize (UInt32)
+ // if (outSize <= size): Filter have converted outSize bytes
+ // if (outSize > size): Filter have not converted anything.
+ // and it needs at least outSize bytes to convert one block
+ // (it's for crypto block algorithms).
+};
+
+CODER_INTERFACE(ICompressCodecsInfo, 0x60)
+{
+ STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods) PURE;
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE;
+ STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE;
+};
+CODER_INTERFACE(ISetCompressCodecsInfo, 0x61)
+{
+ STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE;
+};
+
+CODER_INTERFACE(ICryptoProperties, 0x80)
+{
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
+};
+
+/*
+CODER_INTERFACE(ICryptoResetSalt, 0x88)
+{
+ STDMETHOD(ResetSalt)() PURE;
+};
+*/
+
+CODER_INTERFACE(ICryptoResetInitVector, 0x8C)
+{
+ STDMETHOD(ResetInitVector)() PURE;
+};
+
+CODER_INTERFACE(ICryptoSetPassword, 0x90)
+{
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetCRC, 0xA0)
+{
+ STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
+};
+
+//////////////////////
+// It's for DLL file
+namespace NMethodPropID
+{
+ enum EEnum
+ {
+ kID,
+ kName,
+ kDecoder,
+ kEncoder,
+ kInStreams,
+ kOutStreams,
+ kDescription,
+ kDecoderIsAssigned,
+ kEncoderIsAssigned
+ };
+}
+
+#endif
Added: trunk/lzma/CPP/7zip/IDecl.h
===================================================================
--- trunk/lzma/CPP/7zip/IDecl.h (rev 0)
+++ trunk/lzma/CPP/7zip/IDecl.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,15 @@
+// IDecl.h
+
+#ifndef __IDECL_H
+#define __IDECL_H
+
+#include "../Common/MyUnknown.h"
+
+#define DECL_INTERFACE_SUB(i, base, groupId, subId) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0, 0, 0, (groupId), 0, (subId), 0, 0); \
+struct i: public base
+
+#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId)
+
+#endif
Added: trunk/lzma/CPP/7zip/IPassword.h
===================================================================
--- trunk/lzma/CPP/7zip/IPassword.h (rev 0)
+++ trunk/lzma/CPP/7zip/IPassword.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// IPassword.h
+
+#ifndef __IPASSWORD_H
+#define __IPASSWORD_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+#include "IDecl.h"
+
+#define PASSWORD_INTERFACE(i, x) DECL_INTERFACE(i, 5, x)
+
+PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10)
+{
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE;
+};
+
+PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)
+{
+ STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE;
+};
+
+#endif
+
Added: trunk/lzma/CPP/7zip/IProgress.h
===================================================================
--- trunk/lzma/CPP/7zip/IProgress.h (rev 0)
+++ trunk/lzma/CPP/7zip/IProgress.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,30 @@
+// Interface/IProgress.h
+
+#ifndef __IPROGRESS_H
+#define __IPROGRESS_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+#include "IDecl.h"
+
+DECL_INTERFACE(IProgress, 0, 5)
+{
+ STDMETHOD(SetTotal)(UInt64 total) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000000050002}
+DEFINE_GUID(IID_IProgress2,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002")
+IProgress2: public IUnknown
+{
+public:
+ STDMETHOD(SetTotal)(const UInt64 *total) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
+};
+*/
+
+#endif
Added: trunk/lzma/CPP/7zip/IStream.h
===================================================================
--- trunk/lzma/CPP/7zip/IStream.h (rev 0)
+++ trunk/lzma/CPP/7zip/IStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,58 @@
+// IStream.h
+
+#ifndef __ISTREAM_H
+#define __ISTREAM_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+#include "IDecl.h"
+
+#define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x)
+#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
+
+STREAM_INTERFACE(ISequentialInStream, 0x01)
+{
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ Out: if size != 0, return_value = S_OK and (*processedSize == 0),
+ then there are no more bytes in stream.
+ if (size > 0) && there are bytes in stream,
+ this function must read at least 1 byte.
+ This function is allowed to read less than number of remaining bytes in stream.
+ You must call Read function in loop, if you need exact amount of data
+ */
+};
+
+STREAM_INTERFACE(ISequentialOutStream, 0x02)
+{
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ if (size > 0) this function must write at least 1 byte.
+ This function is allowed to write less than "size".
+ You must call Write function in loop, if you need to write exact amount of data
+ */
+};
+
+STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+};
+
+STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+ STDMETHOD(SetSize)(Int64 newSize) PURE;
+};
+
+STREAM_INTERFACE(IStreamGetSize, 0x06)
+{
+ STDMETHOD(GetSize)(UInt64 *size) PURE;
+};
+
+STREAM_INTERFACE(IOutStreamFlush, 0x07)
+{
+ STDMETHOD(Flush)() PURE;
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/MyVersion.h
===================================================================
--- trunk/lzma/CPP/7zip/MyVersion.h (rev 0)
+++ trunk/lzma/CPP/7zip/MyVersion.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,8 @@
+#define MY_VER_MAJOR 4
+#define MY_VER_MINOR 57
+#define MY_VER_BUILD 0
+#define MY_VERSION "4.57"
+#define MY_7ZIP_VERSION "7-Zip 4.57"
+#define MY_DATE "2007-12-06"
+#define MY_COPYRIGHT "Copyright (c) 1999-2007 Igor Pavlov"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
Added: trunk/lzma/CPP/7zip/MyVersionInfo.rc
===================================================================
--- trunk/lzma/CPP/7zip/MyVersionInfo.rc (rev 0)
+++ trunk/lzma/CPP/7zip/MyVersionInfo.rc 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,45 @@
+#include <WinVer.h>
+#include "MyVersion.h"
+
+#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0
+
+#ifdef DEBUG
+#define DBG_FL VS_FF_DEBUG
+#else
+#define DBG_FL 0
+#endif
+
+#define MY_VERSION_INFO(fileType, descr, intName, origName) \
+LANGUAGE 9, 1 \
+1 VERSIONINFO \
+ FILEVERSION MY_VER \
+ PRODUCTVERSION MY_VER \
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK \
+ FILEFLAGS DBG_FL \
+ FILEOS VOS_NT_WINDOWS32 \
+ FILETYPE fileType \
+ FILESUBTYPE 0x0L \
+BEGIN \
+ BLOCK "StringFileInfo" \
+ BEGIN \
+ BLOCK "040904b0" \
+ BEGIN \
+ VALUE "CompanyName", "Igor Pavlov" \
+ VALUE "FileDescription", descr \
+ VALUE "FileVersion", MY_VERSION \
+ VALUE "InternalName", intName \
+ VALUE "LegalCopyright", MY_COPYRIGHT \
+ VALUE "OriginalFilename", origName \
+ VALUE "ProductName", "7-Zip" \
+ VALUE "ProductVersion", MY_VERSION \
+ END \
+ END \
+ BLOCK "VarFileInfo" \
+ BEGIN \
+ VALUE "Translation", 0x409, 1200 \
+ END \
+END
+
+#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(VFT_APP, descr, intName, intName ".exe")
+
+#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(VFT_DLL, descr, intName, intName ".dll")
Added: trunk/lzma/CPP/7zip/PropID.h
===================================================================
--- trunk/lzma/CPP/7zip/PropID.h (rev 0)
+++ trunk/lzma/CPP/7zip/PropID.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,60 @@
+// Interface/PropID.h
+
+#ifndef __INTERFACE_PROPID_H
+#define __INTERFACE_PROPID_H
+
+enum
+{
+ kpidNoProperty = 0,
+
+ kpidHandlerItemIndex = 2,
+ kpidPath,
+ kpidName,
+ kpidExtension,
+ kpidIsFolder,
+ kpidSize,
+ kpidPackedSize,
+ kpidAttributes,
+ kpidCreationTime,
+ kpidLastAccessTime,
+ kpidLastWriteTime,
+ kpidSolid,
+ kpidCommented,
+ kpidEncrypted,
+ kpidSplitBefore,
+ kpidSplitAfter,
+ kpidDictionarySize,
+ kpidCRC,
+ kpidType,
+ kpidIsAnti,
+ kpidMethod,
+ kpidHostOS,
+ kpidFileSystem,
+ kpidUser,
+ kpidGroup,
+ kpidBlock,
+ kpidComment,
+ kpidPosition,
+ kpidPrefix,
+ kpidNumSubFolders,
+ kpidNumSubFiles,
+ kpidUnpackVer,
+ kpidVolume,
+ kpidIsVolume,
+ kpidOffset,
+ kpidLinks,
+ kpidNumBlocks,
+ kpidNumVolumes,
+
+ kpidTotalSize = 0x1100,
+ kpidFreeSpace,
+ kpidClusterSize,
+ kpidVolumeName,
+
+ kpidLocalName = 0x1200,
+ kpidProvider,
+
+ kpidUserDefined = 0x10000
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Client7z/Client7z.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Client7z/Client7z.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Client7z/Client7z.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,880 @@
+// Client7z.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/DLL.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Archive/IArchive.h"
+#include "../../IPassword.h"
+#include "../../MyVersion.h"
+
+
+// {23170F69-40C1-278A-1000-000110070000}
+DEFINE_GUID(CLSID_CFormat7z,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+
+using namespace NWindows;
+
+#define kDllName "7z.dll"
+
+static const char *kCopyrightString = MY_7ZIP_VERSION
+" (" kDllName " client) "
+MY_COPYRIGHT " " MY_DATE;
+
+static const char *kHelpString =
+"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"
+"Examples:\n"
+" Client7z.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n"
+" Client7z.exe l archive.7z : List contents of archive.7z\n"
+" Client7z.exe x archive.7z : eXtract files from archive.7z\n";
+
+
+typedef UINT32 (WINAPI * CreateObjectFunc)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+#endif
+
+void PrintString(const UString &s)
+{
+ printf("%s", (LPCSTR)GetOemString(s));
+}
+
+void PrintString(const AString &s)
+{
+ printf("%s", (LPCSTR)s);
+}
+
+void PrintNewLine()
+{
+ PrintString("\n");
+}
+
+void PrintStringLn(const AString &s)
+{
+ PrintString(s);
+ PrintNewLine();
+}
+
+void PrintError(const AString &s)
+{
+ PrintNewLine();
+ PrintString(s);
+ PrintNewLine();
+}
+
+static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, propID, &prop));
+ if(prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt == VT_EMPTY)
+ result = false;
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+{
+ return IsArchiveItemProp(archive, index, kpidIsFolder, result);
+}
+
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+
+//////////////////////////////////////////////////////////////
+// Archive Open callback class
+
+
+class CArchiveOpenCallback:
+ public IArchiveOpenCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+ bool PasswordIsDefined;
+ UString Password;
+
+ CArchiveOpenCallback() : PasswordIsDefined(false) {}
+};
+
+STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ // You can ask real password here from user
+ // Password = GetPassword(OutStream);
+ // PasswordIsDefined = true;
+ PrintError("Password is not defined");
+ return E_ABORT;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////
+// Archive Extracting callback class
+
+static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
+
+static const char *kTestingString = "Testing ";
+static const char *kExtractingString = "Extracting ";
+static const char *kSkippingString = "Skipping ";
+
+static const char *kUnsupportedMethod = "Unsupported Method";
+static const char *kCRCFailed = "CRC Failed";
+static const char *kDataError = "Data Error";
+static const char *kUnknownError = "Unknown Error";
+
+class CArchiveExtractCallback:
+ public IArchiveExtractCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IArchiveExtractCallback
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
+
+private:
+ CMyComPtr<IInArchive> _archiveHandler;
+ UString _directoryPath; // Output directory
+ UString _filePath; // name inside arcvhive
+ UString _diskFilePath; // full path to file on disk
+ bool _extractMode;
+ struct CProcessedFileInfo
+ {
+ FILETIME UTCLastWriteTime;
+ UInt32 Attributes;
+ bool IsDirectory;
+ bool AttributesAreDefined;
+ bool UTCLastWriteTimeIsDefined;
+ } _processedFileInfo;
+
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+
+public:
+ void Init(IInArchive *archiveHandler, const UString &directoryPath);
+
+ UInt64 NumErrors;
+ bool PasswordIsDefined;
+ UString Password;
+
+ CArchiveExtractCallback() : PasswordIsDefined(false) {}
+};
+
+void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath)
+{
+ NumErrors = 0;
+ _archiveHandler = archiveHandler;
+ _directoryPath = directoryPath;
+ NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
+ ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+ *outStream = 0;
+ _outFileStream.Release();
+
+ {
+ // Get Name
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariant));
+
+ UString fullPath;
+ if(propVariant.vt == VT_EMPTY)
+ fullPath = kEmptyFileAlias;
+ else
+ {
+ if(propVariant.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath = propVariant.bstrVal;
+ }
+ _filePath = fullPath;
+ }
+
+ if (askExtractMode != NArchive::NExtract::NAskMode::kExtract)
+ return S_OK;
+
+ {
+ // Get Attributes
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ {
+ _processedFileInfo.Attributes = 0;
+ _processedFileInfo.AttributesAreDefined = false;
+ }
+ else
+ {
+ if (propVariant.vt != VT_UI4)
+ throw "incorrect item";
+ _processedFileInfo.Attributes = propVariant.ulVal;
+ _processedFileInfo.AttributesAreDefined = true;
+ }
+ }
+
+ RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory));
+
+ {
+ // Get Modified Time
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
+ _processedFileInfo.UTCLastWriteTimeIsDefined = false;
+ switch(propVariant.vt)
+ {
+ case VT_EMPTY:
+ // _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault;
+ break;
+ case VT_FILETIME:
+ _processedFileInfo.UTCLastWriteTime = propVariant.filetime;
+ _processedFileInfo.UTCLastWriteTimeIsDefined = true;
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ }
+ {
+ // Get Size
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidSize, &propVariant));
+ bool newFileSizeDefined = (propVariant.vt != VT_EMPTY);
+ UInt64 newFileSize;
+ if (newFileSizeDefined)
+ newFileSize = ConvertPropVariantToUInt64(propVariant);
+ }
+
+
+ {
+ // Create folders for file
+ int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (slashPos >= 0)
+ NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos));
+ }
+
+ UString fullProcessedPath = _directoryPath + _filePath;
+ _diskFilePath = fullProcessedPath;
+
+ if (_processedFileInfo.IsDirectory)
+ {
+ NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);
+ }
+ else
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath);
+ return E_ABORT;
+ }
+ }
+
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))
+ {
+ PrintString((UString)L"can not open output file " + fullProcessedPath);
+ return E_ABORT;
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
+{
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ _extractMode = true;
+ };
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ PrintString(kExtractingString);
+ break;
+ case NArchive::NExtract::NAskMode::kTest:
+ PrintString(kTestingString);
+ break;
+ case NArchive::NExtract::NAskMode::kSkip:
+ PrintString(kSkippingString);
+ break;
+ };
+ PrintString(_filePath);
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
+{
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+ default:
+ {
+ NumErrors++;
+ PrintString(" ");
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ PrintString(kUnsupportedMethod);
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ PrintString(kCRCFailed);
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ PrintString(kDataError);
+ break;
+ default:
+ PrintString(kUnknownError);
+ }
+ }
+ }
+
+ if (_outFileStream != NULL)
+ {
+ if (_processedFileInfo.UTCLastWriteTimeIsDefined)
+ _outFileStreamSpec->SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
+ RINOK(_outFileStreamSpec->Close());
+ }
+ _outFileStream.Release();
+ if (_extractMode && _processedFileInfo.AttributesAreDefined)
+ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ PrintNewLine();
+ return S_OK;
+}
+
+
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ // You can ask real password here from user
+ // Password = GetPassword(OutStream);
+ // PasswordIsDefined = true;
+ PrintError("Password is not defined");
+ return E_ABORT;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////
+// Archive Creating callback class
+
+struct CDirItem
+{
+ UInt32 Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ UInt64 Size;
+ UString Name;
+ UString FullPath;
+ bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
+};
+
+class CArchiveUpdateCallback:
+ public IArchiveUpdateCallback2,
+ public ICryptoGetTextPassword2,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IUpdateCallback2
+ STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index,
+ Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
+ STDMETHOD(SetOperationResult)(Int32 operationResult);
+ STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
+ STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
+
+ STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
+
+public:
+ CRecordVector<UInt64> VolumesSizes;
+ UString VolName;
+ UString VolExt;
+
+ UString DirPrefix;
+ const CObjectVector<CDirItem> *DirItems;
+
+ bool PasswordIsDefined;
+ UString Password;
+ bool AskPassword;
+
+ bool m_NeedBeClosed;
+
+ UStringVector FailedFiles;
+ CRecordVector<HRESULT> FailedCodes;
+
+ CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};
+
+ ~CArchiveUpdateCallback() { Finilize(); }
+ HRESULT Finilize();
+
+ void Init(const CObjectVector<CDirItem> *dirItems)
+ {
+ DirItems = dirItems;
+ m_NeedBeClosed = false;
+ FailedFiles.Clear();
+ FailedCodes.Clear();
+ }
+};
+
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)
+{
+ return S_OK;
+}
+
+
+STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,
+ Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
+{
+ if(newData != NULL)
+ *newData = BoolToInt(true);
+ if(newProperties != NULL)
+ *newProperties = BoolToInt(true);
+ if(indexInArchive != NULL)
+ *indexInArchive = UInt32(-1);
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+
+ if (propID == kpidIsAnti)
+ {
+ propVariant = false;
+ propVariant.Detach(value);
+ return S_OK;
+ }
+
+ {
+ const CDirItem &dirItem = (*DirItems)[index];
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = dirItem.Name;
+ break;
+ case kpidIsFolder:
+ propVariant = dirItem.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = dirItem.Size;
+ break;
+ case kpidAttributes:
+ propVariant = dirItem.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = dirItem.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = dirItem.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = dirItem.LastWriteTime;
+ break;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+HRESULT CArchiveUpdateCallback::Finilize()
+{
+ if (m_NeedBeClosed)
+ {
+ PrintNewLine();
+ m_NeedBeClosed = false;
+ }
+ return S_OK;
+}
+
+static void GetStream2(const wchar_t *name)
+{
+ PrintString("Compressing ");
+ if (name[0] == 0)
+ name = kEmptyFileAlias;
+ PrintString(name);
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
+{
+ RINOK(Finilize());
+
+ const CDirItem &dirItem = (*DirItems)[index];
+ GetStream2(dirItem.Name);
+
+ if(dirItem.IsDirectory())
+ return S_OK;
+
+ {
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ UString path = DirPrefix + dirItem.FullPath;
+ if(!inStreamSpec->Open(path))
+ {
+ DWORD sysError = ::GetLastError();
+ FailedCodes.Add(sysError);
+ FailedFiles.Add(path);
+ // if (systemError == ERROR_SHARING_VIOLATION)
+ {
+ PrintNewLine();
+ PrintError("WARNING: can't open file");
+ // PrintString(NError::MyFormatMessageW(systemError));
+ return S_FALSE;
+ }
+ // return sysError;
+ }
+ *inStream = inStreamLoc.Detach();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)
+{
+ m_NeedBeClosed = true;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
+{
+ if (VolumesSizes.Size() == 0)
+ return S_FALSE;
+ if (index >= (UInt32)VolumesSizes.Size())
+ index = VolumesSizes.Size() - 1;
+ *size = VolumesSizes[index];
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
+{
+ wchar_t temp[32];
+ ConvertUInt64ToString(index + 1, temp);
+ UString res = temp;
+ while (res.Length() < 2)
+ res = UString(L'0') + res;
+ UString fileName = VolName;
+ fileName += L'.';
+ fileName += res;
+ fileName += VolExt;
+ COutFileStream *streamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
+ if(!streamSpec->Create(fileName, false))
+ return ::GetLastError();
+ *volumeStream = streamLoc.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ if (AskPassword)
+ {
+ // You can ask real password here from user
+ // Password = GetPassword(OutStream);
+ // PasswordIsDefined = true;
+ PrintError("Password is not defined");
+ return E_ABORT;
+ }
+ }
+ *passwordIsDefined = BoolToInt(PasswordIsDefined);
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// Main function
+
+int
+#ifdef _MSC_VER
+__cdecl
+#endif
+main(int argc, char* argv[])
+{
+ #ifdef _WIN32
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ #endif
+
+ PrintStringLn(kCopyrightString);
+
+ if (argc < 3)
+ {
+ PrintStringLn(kHelpString);
+ return 1;
+ }
+ NWindows::NDLL::CLibrary library;
+ if (!library.Load(TEXT(kDllName)))
+ {
+ PrintError("Can not load library");
+ return 1;
+ }
+ CreateObjectFunc createObjectFunc = (CreateObjectFunc)library.GetProcAddress("CreateObject");
+ if (createObjectFunc == 0)
+ {
+ PrintError("Can not get CreateObject");
+ return 1;
+ }
+
+ AString command = argv[1];
+ UString archiveName = GetUnicodeString(argv[2], CP_OEMCP);
+ if (command.CompareNoCase("a") == 0)
+ {
+ // create archive command
+ if (argc < 4)
+ {
+ PrintStringLn(kHelpString);
+ return 1;
+ }
+ CObjectVector<CDirItem> dirItems;
+ int i;
+ for (i = 3; i < argc; i++)
+ {
+ CDirItem item;
+ UString name = GetUnicodeString(argv[i], CP_OEMCP);
+
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(name, fileInfo))
+ {
+ PrintString(UString(L"Can't find file") + name);
+ return 1;
+ }
+
+ item.Attributes = fileInfo.Attributes;
+ item.Size = fileInfo.Size;
+ item.CreationTime = fileInfo.CreationTime;
+ item.LastAccessTime = fileInfo.LastAccessTime;
+ item.LastWriteTime = fileInfo.LastWriteTime;
+ item.Name = name;
+ item.FullPath = name;
+ dirItems.Add(item);
+ }
+ COutFileStream *outFileStreamSpec = new COutFileStream;
+ CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
+ if (!outFileStreamSpec->Create(archiveName, false))
+ {
+ PrintError("can't create archive file");
+ return 1;
+ }
+
+ CMyComPtr<IOutArchive> outArchive;
+ if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK)
+ {
+ PrintError("Can not get class object");
+ return 1;
+ }
+
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
+ updateCallbackSpec->Init(&dirItems);
+ // updateCallbackSpec->PasswordIsDefined = true;
+ // updateCallbackSpec->Password = L"1";
+
+ HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);
+ updateCallbackSpec->Finilize();
+ if (result != S_OK)
+ {
+ PrintError("Update Error");
+ return 1;
+ }
+ for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)
+ {
+ PrintNewLine();
+ PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]);
+ }
+ if (updateCallbackSpec->FailedFiles.Size() != 0)
+ return 1;
+ }
+ else
+ {
+ if (argc != 3)
+ {
+ PrintStringLn(kHelpString);
+ return 1;
+ }
+
+ bool listCommand;
+ if (command.CompareNoCase("l") == 0)
+ listCommand = true;
+ else if (command.CompareNoCase("x") == 0)
+ listCommand = false;
+ else
+ {
+ PrintError("incorrect command");
+ return 1;
+ }
+
+ CMyComPtr<IInArchive> archive;
+ if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK)
+ {
+ PrintError("Can not get class object");
+ return 1;
+ }
+
+ CInFileStream *fileSpec = new CInFileStream;
+ CMyComPtr<IInStream> file = fileSpec;
+
+ if (!fileSpec->Open(archiveName))
+ {
+ PrintError("Can not open archive file");
+ return 1;
+ }
+
+ {
+ CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;
+ CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
+ openCallbackSpec->PasswordIsDefined = false;
+ // openCallbackSpec->PasswordIsDefined = true;
+ // openCallbackSpec->Password = L"1";
+
+ if (archive->Open(file, 0, openCallback) != S_OK)
+ {
+ PrintError("Can not open archive");
+ return 1;
+ }
+ }
+
+ if (listCommand)
+ {
+ // List command
+ UInt32 numItems = 0;
+ archive->GetNumberOfItems(&numItems);
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ {
+ // Get uncompressed size of file
+ NWindows::NCOM::CPropVariant propVariant;
+ archive->GetProperty(i, kpidSize, &propVariant);
+ UString s = ConvertPropVariantToString(propVariant);
+ PrintString(s);
+ PrintString(" ");
+ }
+ {
+ // Get name of file
+ NWindows::NCOM::CPropVariant propVariant;
+ archive->GetProperty(i, kpidPath, &propVariant);
+ UString s = ConvertPropVariantToString(propVariant);
+ PrintString(s);
+ }
+ PrintString("\n");
+ }
+ }
+ else
+ {
+ // Extract command
+ CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
+ extractCallbackSpec->Init(archive, L""); // second parameter is output folder path
+ extractCallbackSpec->PasswordIsDefined = false;
+ // extractCallbackSpec->PasswordIsDefined = true;
+ // extractCallbackSpec->Password = L"1";
+ HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);
+ if (result != S_OK)
+ {
+ PrintError("Extract Error");
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
Added: trunk/lzma/CPP/7zip/UI/Client7z/Client7z.dsp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Client7z/Client7z.dsp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Client7z/Client7z.dsp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,226 @@
+# Microsoft Developer Studio Project File - Name="Client7z" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Client7z - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Client7z.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Client7z.mak" CFG="Client7z - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Client7z - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Client7z - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Client7z - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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
+
+!ELSEIF "$(CFG)" == "Client7z - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# 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
+# 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
+
+!ENDIF
+
+# Begin Target
+
+# Name "Client7z - Win32 Release"
+# Name "Client7z - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Client7z.cpp
+# End Source File
+# End Target
+# End Project
Added: trunk/lzma/CPP/7zip/UI/Client7z/Client7z.dsw
===================================================================
--- trunk/lzma/CPP/7zip/UI/Client7z/Client7z.dsw (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Client7z/Client7z.dsw 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Client7z"=.\Client7z.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
Added: trunk/lzma/CPP/7zip/UI/Client7z/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Client7z/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Client7z/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/UI/Client7z/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Client7z/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Client7z/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <stdio.h>
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Client7z/makefile
===================================================================
--- trunk/lzma/CPP/7zip/UI/Client7z/makefile (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Client7z/makefile 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,45 @@
+PROG = 7z.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib
+CFLAGS = $(CFLAGS) -I ../../../
+
+CONSOLE_OBJS = \
+ $O\Client7z.obj \
+
+COMMON_OBJS = \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\MyString.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\MyVector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FileStreams.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+
+!include "../../../Build.mak"
+
+$(CONSOLE_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
Added: trunk/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1003 @@
+// ArchiveCommandLine.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include <io.h>
+#endif
+#include <stdio.h>
+
+#include "Common/ListFileUtils.h"
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#ifdef _WIN32
+#include "Windows/FileMapping.h"
+#include "Windows/Synchronization.h"
+#endif
+
+#include "ArchiveCommandLine.h"
+#include "UpdateAction.h"
+#include "Update.h"
+#include "SortUtils.h"
+#include "EnumDirItems.h"
+
+extern bool g_CaseSensitive;
+
+#if _MSC_VER >= 1400
+#define MY_isatty_fileno(x) _isatty(_fileno(x))
+#else
+#define MY_isatty_fileno(x) isatty(fileno(x))
+#endif
+
+#define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0);
+
+using namespace NCommandLineParser;
+using namespace NWindows;
+using namespace NFile;
+
+namespace NKey {
+enum Enum
+{
+ kHelp1 = 0,
+ kHelp2,
+ kHelp3,
+ kDisableHeaders,
+ kDisablePercents,
+ kArchiveType,
+ kYes,
+ kPassword,
+ kProperty,
+ kOutputDir,
+ kWorkingDir,
+ kInclude,
+ kExclude,
+ kArInclude,
+ kArExclude,
+ kNoArName,
+ kUpdate,
+ kVolume,
+ kRecursed,
+ kSfx,
+ kStdIn,
+ kStdOut,
+ kOverwrite,
+ kEmail,
+ kShowDialog,
+ kLargePages,
+ kCharSet,
+ kTechMode,
+ kShareForWrite,
+ kCaseSensitive
+};
+
+}
+
+
+static const wchar_t kRecursedIDChar = 'R';
+static const wchar_t *kRecursedPostCharSet = L"0-";
+
+namespace NRecursedPostCharIndex {
+ enum EEnum
+ {
+ kWildCardRecursionOnly = 0,
+ kNoRecursion = 1
+ };
+}
+
+static const char kImmediateNameID = '!';
+static const char kMapNameID = '#';
+static const char kFileListID = '@';
+
+static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
+static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
+
+static const wchar_t *kOverwritePostCharSet = L"asut";
+
+NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
+{
+ NExtract::NOverwriteMode::kWithoutPrompt,
+ NExtract::NOverwriteMode::kSkipExisting,
+ NExtract::NOverwriteMode::kAutoRename,
+ NExtract::NOverwriteMode::kAutoRenameExisting
+};
+
+static const CSwitchForm kSwitchForms[] =
+ {
+ { L"?", NSwitchType::kSimple, false },
+ { L"H", NSwitchType::kSimple, false },
+ { L"-HELP", NSwitchType::kSimple, false },
+ { L"BA", NSwitchType::kSimple, false },
+ { L"BD", NSwitchType::kSimple, false },
+ { L"T", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"Y", NSwitchType::kSimple, false },
+ { L"P", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"M", NSwitchType::kUnLimitedPostString, true, 1 },
+ { L"O", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"W", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+ { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+ { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+ { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+ { L"AN", NSwitchType::kSimple, false },
+ { L"U", NSwitchType::kUnLimitedPostString, true, 1},
+ { L"V", NSwitchType::kUnLimitedPostString, true, 1},
+ { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
+ { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"SI", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"SO", NSwitchType::kSimple, false, 0 },
+ { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
+ { L"SEML", NSwitchType::kUnLimitedPostString, false, 0},
+ { L"AD", NSwitchType::kSimple, false },
+ { L"SLP", NSwitchType::kUnLimitedPostString, false, 0},
+ { L"SCS", NSwitchType::kUnLimitedPostString, false, 0},
+ { L"SLT", NSwitchType::kSimple, false },
+ { L"SSW", NSwitchType::kSimple, false },
+ { L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" }
+ };
+
+static const CCommandForm g_CommandForms[] =
+{
+ { L"A", false },
+ { L"U", false },
+ { L"D", false },
+ { L"T", false },
+ { L"E", false },
+ { L"X", false },
+ { L"L", false },
+ { L"B", false },
+ { L"I", false }
+};
+
+static const int kNumCommandForms = sizeof(g_CommandForms) / sizeof(g_CommandForms[0]);
+
+static const wchar_t *kUniversalWildcard = L"*";
+static const int kMinNonSwitchWords = 1;
+static const int kCommandIndex = 0;
+
+// ---------------------------
+// exception messages
+
+static const char *kUserErrorMessage = "Incorrect command line";
+static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
+static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile";
+static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line";
+static const char *kTerminalOutError = "I won't write compressed data to a terminal";
+static const char *kSameTerminalError = "I won't write data and program's messages to same terminal";
+
+static void ThrowException(const char *errorMessage)
+{
+ throw CArchiveCommandLineException(errorMessage);
+};
+
+static void ThrowUserErrorException()
+{
+ ThrowException(kUserErrorMessage);
+};
+
+// ---------------------------
+
+bool CArchiveCommand::IsFromExtractGroup() const
+{
+ switch(CommandType)
+ {
+ case NCommandType::kTest:
+ case NCommandType::kExtract:
+ case NCommandType::kFullExtract:
+ return true;
+ default:
+ return false;
+ }
+}
+
+NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const
+{
+ switch(CommandType)
+ {
+ case NCommandType::kTest:
+ case NCommandType::kFullExtract:
+ return NExtract::NPathMode::kFullPathnames;
+ default:
+ return NExtract::NPathMode::kNoPathnames;
+ }
+}
+
+bool CArchiveCommand::IsFromUpdateGroup() const
+{
+ return (CommandType == NCommandType::kAdd ||
+ CommandType == NCommandType::kUpdate ||
+ CommandType == NCommandType::kDelete);
+}
+
+static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
+{
+ switch (index)
+ {
+ case NRecursedPostCharIndex::kWildCardRecursionOnly:
+ return NRecursedType::kWildCardOnlyRecursed;
+ case NRecursedPostCharIndex::kNoRecursion:
+ return NRecursedType::kNonRecursed;
+ default:
+ return NRecursedType::kRecursed;
+ }
+}
+
+static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
+{
+ UString commandStringUpper = commandString;
+ commandStringUpper.MakeUpper();
+ UString postString;
+ int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper,
+ postString) ;
+ if (commandIndex < 0)
+ return false;
+ command.CommandType = (NCommandType::EEnum)commandIndex;
+ return true;
+}
+
+// ------------------------------------------------------------------
+// filenames functions
+
+static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum type)
+{
+ bool isWildCard = DoesNameContainWildCard(name);
+ bool recursed = false;
+
+ switch (type)
+ {
+ case NRecursedType::kWildCardOnlyRecursed:
+ recursed = isWildCard;
+ break;
+ case NRecursedType::kRecursed:
+ recursed = true;
+ break;
+ case NRecursedType::kNonRecursed:
+ recursed = false;
+ break;
+ }
+ wildcardCensor.AddItem(include, name, recursed);
+ return true;
+}
+
+static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
+ LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)
+{
+ UStringVector names;
+ if (!ReadNamesFromListFile(fileName, names, codePage))
+ throw kIncorrectListFile;
+ for (int i = 0; i < names.Size(); i++)
+ if (!AddNameToCensor(wildcardCensor, names[i], include, type))
+ throw kIncorrectWildCardInListFile;
+}
+
+static void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum recursedType)
+{
+ if (!AddNameToCensor(wildcardCensor, name, include, recursedType))
+ throw kIncorrectWildCardInCommandLine;
+}
+
+static void AddToCensorFromNonSwitchesStrings(
+ int startIndex,
+ NWildcard::CCensor &wildcardCensor,
+ const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
+ bool thereAreSwitchIncludes, UINT codePage)
+{
+ if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))
+ AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);
+ for(int i = startIndex; i < nonSwitchStrings.Size(); i++)
+ {
+ const UString &s = nonSwitchStrings[i];
+ if (s[0] == kFileListID)
+ AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);
+ else
+ AddCommandLineWildCardToCensr(wildcardCensor, s, true, type);
+ }
+}
+
+#ifdef _WIN32
+static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,
+ const UString &switchParam, bool include,
+ NRecursedType::EEnum commonRecursedType)
+{
+ int splitPos = switchParam.Find(L':');
+ if (splitPos < 0)
+ ThrowUserErrorException();
+ UString mappingName = switchParam.Left(splitPos);
+
+ UString switchParam2 = switchParam.Mid(splitPos + 1);
+ splitPos = switchParam2.Find(L':');
+ if (splitPos < 0)
+ ThrowUserErrorException();
+
+ UString mappingSize = switchParam2.Left(splitPos);
+ UString eventName = switchParam2.Mid(splitPos + 1);
+
+ UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL);
+ UInt32 dataSize = (UInt32)dataSize64;
+ {
+ CFileMapping fileMapping;
+ if (!fileMapping.Open(FILE_MAP_READ, false, GetSystemString(mappingName)))
+ ThrowException("Can not open mapping");
+ LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize);
+ if (data == NULL)
+ ThrowException("MapViewOfFile error");
+ try
+ {
+ const wchar_t *curData = (const wchar_t *)data;
+ if (*curData != 0)
+ ThrowException("Incorrect mapping data");
+ UInt32 numChars = dataSize / sizeof(wchar_t);
+ UString name;
+ for (UInt32 i = 1; i < numChars; i++)
+ {
+ wchar_t c = curData[i];
+ if (c == L'\0')
+ {
+ AddCommandLineWildCardToCensr(wildcardCensor,
+ name, include, commonRecursedType);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ if (!name.IsEmpty())
+ ThrowException("data error");
+ }
+ catch(...)
+ {
+ UnmapViewOfFile(data);
+ throw;
+ }
+ UnmapViewOfFile(data);
+ }
+
+ {
+ NSynchronization::CManualResetEvent event;
+ if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)) == S_OK)
+ event.Set();
+ }
+}
+#endif
+
+static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
+ const UStringVector &strings, bool include,
+ NRecursedType::EEnum commonRecursedType, UINT codePage)
+{
+ for(int i = 0; i < strings.Size(); i++)
+ {
+ const UString &name = strings[i];
+ NRecursedType::EEnum recursedType;
+ int pos = 0;
+ if (name.Length() < kSomeCludePostStringMinSize)
+ ThrowUserErrorException();
+ if (::MyCharUpper(name[pos]) == kRecursedIDChar)
+ {
+ pos++;
+ int index = UString(kRecursedPostCharSet).Find(name[pos]);
+ recursedType = GetRecursedTypeFromIndex(index);
+ if (index >= 0)
+ pos++;
+ }
+ else
+ recursedType = commonRecursedType;
+ if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)
+ ThrowUserErrorException();
+ UString tail = name.Mid(pos + 1);
+ if (name[pos] == kImmediateNameID)
+ AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType);
+ else if (name[pos] == kFileListID)
+ AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage);
+ #ifdef _WIN32
+ else if (name[pos] == kMapNameID)
+ ParseMapWithPaths(wildcardCensor, tail, include, recursedType);
+ #endif
+ else
+ ThrowUserErrorException();
+ }
+}
+
+#ifdef _WIN32
+
+// This code converts all short file names to long file names.
+
+static void ConvertToLongName(const UString &prefix, UString &name)
+{
+ if (name.IsEmpty() || DoesNameContainWildCard(name))
+ return;
+ NFind::CFileInfoW fileInfo;
+ if (NFind::FindFile(prefix + name, fileInfo))
+ name = fileInfo.Name;
+}
+
+static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
+{
+ for (int i = 0; i < items.Size(); i++)
+ {
+ NWildcard::CItem &item = items[i];
+ if (item.Recursive || item.PathParts.Size() != 1)
+ continue;
+ ConvertToLongName(prefix, item.PathParts.Front());
+ }
+}
+
+static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
+{
+ ConvertToLongNames(prefix, node.IncludeItems);
+ ConvertToLongNames(prefix, node.ExcludeItems);
+ int i;
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ ConvertToLongName(prefix, node.SubNodes[i].Name);
+ // mix folders with same name
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
+ for (int j = i + 1; j < node.SubNodes.Size();)
+ {
+ const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
+ if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0)
+ {
+ nextNode1.IncludeItems += nextNode2.IncludeItems;
+ nextNode1.ExcludeItems += nextNode2.ExcludeItems;
+ node.SubNodes.Delete(j);
+ }
+ else
+ j++;
+ }
+ }
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ NWildcard::CCensorNode &nextNode = node.SubNodes[i];
+ ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode);
+ }
+}
+
+static void ConvertToLongNames(NWildcard::CCensor &censor)
+{
+ for (int i = 0; i < censor.Pairs.Size(); i++)
+ {
+ NWildcard::CPair &pair = censor.Pairs[i];
+ ConvertToLongNames(pair.Prefix, pair.Head);
+ }
+}
+
+#endif
+
+static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
+{
+ switch(i)
+ {
+ case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;
+ case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;
+ case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress;
+ case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti;
+ }
+ throw 98111603;
+}
+
+const UString kUpdatePairStateIDSet = L"PQRXYZW";
+const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
+
+const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti
+
+const wchar_t *kUpdateIgnoreItselfPostStringID = L"-";
+const wchar_t kUpdateNewArchivePostCharID = '!';
+
+
+static bool ParseUpdateCommandString2(const UString &command,
+ NUpdateArchive::CActionSet &actionSet, UString &postString)
+{
+ for(int i = 0; i < command.Length();)
+ {
+ wchar_t c = MyCharUpper(command[i]);
+ int statePos = kUpdatePairStateIDSet.Find(c);
+ if (statePos < 0)
+ {
+ postString = command.Mid(i);
+ return true;
+ }
+ i++;
+ if (i >= command.Length())
+ return false;
+ int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));
+ if (actionPos < 0)
+ return false;
+ actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);
+ if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)
+ return false;
+ i++;
+ }
+ postString.Empty();
+ return true;
+}
+
+static void ParseUpdateCommandString(CUpdateOptions &options,
+ const UStringVector &updatePostStrings,
+ const NUpdateArchive::CActionSet &defaultActionSet)
+{
+ for(int i = 0; i < updatePostStrings.Size(); i++)
+ {
+ const UString &updateString = updatePostStrings[i];
+ if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
+ {
+ if(options.UpdateArchiveItself)
+ {
+ options.UpdateArchiveItself = false;
+ options.Commands.Delete(0);
+ }
+ }
+ else
+ {
+ NUpdateArchive::CActionSet actionSet = defaultActionSet;
+
+ UString postString;
+ if (!ParseUpdateCommandString2(updateString, actionSet, postString))
+ ThrowUserErrorException();
+ if(postString.IsEmpty())
+ {
+ if(options.UpdateArchiveItself)
+ options.Commands[0].ActionSet = actionSet;
+ }
+ else
+ {
+ if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
+ ThrowUserErrorException();
+ CUpdateArchiveCommand uc;
+ UString archivePath = postString.Mid(1);
+ if (archivePath.IsEmpty())
+ ThrowUserErrorException();
+ uc.UserArchivePath = archivePath;
+ uc.ActionSet = actionSet;
+ options.Commands.Add(uc);
+ }
+ }
+ }
+}
+
+static const char kByteSymbol = 'B';
+static const char kKiloSymbol = 'K';
+static const char kMegaSymbol = 'M';
+static const char kGigaSymbol = 'G';
+
+static bool ParseComplexSize(const UString &src, UInt64 &result)
+{
+ UString s = src;
+ s.MakeUpper();
+
+ const wchar_t *start = s;
+ const wchar_t *end;
+ UInt64 number = ConvertStringToUInt64(start, &end);
+ int numDigits = (int)(end - start);
+ if (numDigits == 0 || s.Length() > numDigits + 1)
+ return false;
+ if (s.Length() == numDigits)
+ {
+ result = number;
+ return true;
+ }
+ int numBits;
+ switch (s[numDigits])
+ {
+ case kByteSymbol:
+ result = number;
+ return true;
+ case kKiloSymbol:
+ numBits = 10;
+ break;
+ case kMegaSymbol:
+ numBits = 20;
+ break;
+ case kGigaSymbol:
+ numBits = 30;
+ break;
+ default:
+ return false;
+ }
+ if (number >= ((UInt64)1 << (64 - numBits)))
+ return false;
+ result = number << numBits;
+ return true;
+}
+
+static void SetAddCommandOptions(
+ NCommandType::EEnum commandType,
+ const CParser &parser,
+ CUpdateOptions &options)
+{
+ NUpdateArchive::CActionSet defaultActionSet;
+ switch(commandType)
+ {
+ case NCommandType::kAdd:
+ defaultActionSet = NUpdateArchive::kAddActionSet;
+ break;
+ case NCommandType::kDelete:
+ defaultActionSet = NUpdateArchive::kDeleteActionSet;
+ break;
+ default:
+ defaultActionSet = NUpdateArchive::kUpdateActionSet;
+ }
+
+ options.UpdateArchiveItself = true;
+
+ options.Commands.Clear();
+ CUpdateArchiveCommand updateMainCommand;
+ updateMainCommand.ActionSet = defaultActionSet;
+ options.Commands.Add(updateMainCommand);
+ if(parser[NKey::kUpdate].ThereIs)
+ ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings,
+ defaultActionSet);
+ if(parser[NKey::kWorkingDir].ThereIs)
+ {
+ const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
+ if (postString.IsEmpty())
+ NDirectory::MyGetTempPath(options.WorkingDir);
+ else
+ options.WorkingDir = postString;
+ }
+ options.SfxMode = parser[NKey::kSfx].ThereIs;
+ if (options.SfxMode)
+ options.SfxModule = parser[NKey::kSfx].PostStrings[0];
+
+ if (parser[NKey::kVolume].ThereIs)
+ {
+ const UStringVector &sv = parser[NKey::kVolume].PostStrings;
+ for (int i = 0; i < sv.Size(); i++)
+ {
+ UInt64 size;
+ if (!ParseComplexSize(sv[i], size))
+ ThrowException("Incorrect volume size");
+ options.VolumesSizes.Add(size);
+ }
+ }
+}
+
+static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &properties)
+{
+ if (parser[NKey::kProperty].ThereIs)
+ {
+ // options.MethodMode.Properties.Clear();
+ for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
+ {
+ CProperty property;
+ const UString &postString = parser[NKey::kProperty].PostStrings[i];
+ int index = postString.Find(L'=');
+ if (index < 0)
+ property.Name = postString;
+ else
+ {
+ property.Name = postString.Left(index);
+ property.Value = postString.Mid(index + 1);
+ }
+ properties.Add(property);
+ }
+ }
+}
+
+CArchiveCommandLineParser::CArchiveCommandLineParser():
+ parser(sizeof(kSwitchForms) / sizeof(kSwitchForms[0])) {}
+
+void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
+ CArchiveCommandLineOptions &options)
+{
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ }
+ catch(...)
+ {
+ ThrowUserErrorException();
+ }
+
+ options.IsInTerminal = MY_IS_TERMINAL(stdin);
+ options.IsStdOutTerminal = MY_IS_TERMINAL(stdout);
+ options.IsStdErrTerminal = MY_IS_TERMINAL(stderr);
+ options.StdOutMode = parser[NKey::kStdOut].ThereIs;
+ options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
+ options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs;
+
+ #ifdef _WIN32
+ options.LargePages = false;
+ if (parser[NKey::kLargePages].ThereIs)
+ {
+ const UString &postString = parser[NKey::kLargePages].PostStrings.Front();
+ if (postString.IsEmpty())
+ options.LargePages = true;
+ }
+ #endif
+}
+
+struct CCodePagePair
+{
+ const wchar_t *Name;
+ UINT CodePage;
+};
+
+static CCodePagePair g_CodePagePairs[] =
+{
+ { L"UTF-8", CP_UTF8 },
+ { L"WIN", CP_ACP },
+ { L"DOS", CP_OEMCP }
+};
+
+static const int kNumCodePages = sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]);
+
+static bool ConvertStringToUInt32(const wchar_t *s, UInt32 &v)
+{
+ const wchar_t *end;
+ UInt64 number = ConvertStringToUInt64(s, &end);
+ if (*end != 0)
+ return false;
+ if (number > (UInt32)0xFFFFFFFF)
+ return false;
+ v = (UInt32)number;
+ return true;
+}
+
+void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
+{
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+ int numNonSwitchStrings = nonSwitchStrings.Size();
+ if(numNonSwitchStrings < kMinNonSwitchWords)
+ ThrowUserErrorException();
+
+ if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
+ ThrowUserErrorException();
+
+ options.TechMode = parser[NKey::kTechMode].ThereIs;
+
+ if (parser[NKey::kCaseSensitive].ThereIs)
+ g_CaseSensitive = (parser[NKey::kCaseSensitive].PostCharIndex < 0);
+
+ NRecursedType::EEnum recursedType;
+ if (parser[NKey::kRecursed].ThereIs)
+ recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
+ else
+ recursedType = NRecursedType::kNonRecursed;
+
+ UINT codePage = CP_UTF8;
+ if (parser[NKey::kCharSet].ThereIs)
+ {
+ UString name = parser[NKey::kCharSet].PostStrings.Front();
+ name.MakeUpper();
+ int i;
+ for (i = 0; i < kNumCodePages; i++)
+ {
+ const CCodePagePair &pair = g_CodePagePairs[i];
+ if (name.Compare(pair.Name) == 0)
+ {
+ codePage = pair.CodePage;
+ break;
+ }
+ }
+ if (i >= kNumCodePages)
+ ThrowUserErrorException();
+ }
+
+ bool thereAreSwitchIncludes = false;
+ if (parser[NKey::kInclude].ThereIs)
+ {
+ thereAreSwitchIncludes = true;
+ AddSwitchWildCardsToCensor(options.WildcardCensor,
+ parser[NKey::kInclude].PostStrings, true, recursedType, codePage);
+ }
+ if (parser[NKey::kExclude].ThereIs)
+ AddSwitchWildCardsToCensor(options.WildcardCensor,
+ parser[NKey::kExclude].PostStrings, false, recursedType, codePage);
+
+ int curCommandIndex = kCommandIndex + 1;
+ bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs &&
+ options.Command.CommandType != NCommandType::kBenchmark &&
+ options.Command.CommandType != NCommandType::kInfo;
+ if (thereIsArchiveName)
+ {
+ if(curCommandIndex >= numNonSwitchStrings)
+ ThrowUserErrorException();
+ options.ArchiveName = nonSwitchStrings[curCommandIndex++];
+ }
+
+ AddToCensorFromNonSwitchesStrings(
+ curCommandIndex, options.WildcardCensor,
+ nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage);
+
+ options.YesToAll = parser[NKey::kYes].ThereIs;
+
+ bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
+
+ options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
+
+ if(options.PasswordEnabled)
+ options.Password = parser[NKey::kPassword].PostStrings[0];
+
+ options.StdInMode = parser[NKey::kStdIn].ThereIs;
+ options.ShowDialog = parser[NKey::kShowDialog].ThereIs;
+
+ if(isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
+ {
+ if (options.StdInMode)
+ ThrowException("Reading archives from stdin is not implemented");
+ if (!options.WildcardCensor.AllAreRelative())
+ ThrowException("Cannot use absolute pathnames for this command");
+
+ NWildcard::CCensor archiveWildcardCensor;
+
+ if (parser[NKey::kArInclude].ThereIs)
+ {
+ AddSwitchWildCardsToCensor(archiveWildcardCensor,
+ parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage);
+ }
+ if (parser[NKey::kArExclude].ThereIs)
+ AddSwitchWildCardsToCensor(archiveWildcardCensor,
+ parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage);
+
+ if (thereIsArchiveName)
+ AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
+
+ #ifdef _WIN32
+ ConvertToLongNames(archiveWildcardCensor);
+ #endif
+
+ archiveWildcardCensor.ExtendExclude();
+
+ CObjectVector<CDirItem> dirItems;
+ {
+ UStringVector errorPaths;
+ CRecordVector<DWORD> errorCodes;
+ HRESULT res = EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPaths, errorCodes);
+ if (res != S_OK || errorPaths.Size() > 0)
+ throw "cannot find archive";
+ }
+ UStringVector archivePaths;
+ int i;
+ for (i = 0; i < dirItems.Size(); i++)
+ {
+ const CDirItem &dirItem = dirItems[i];
+ if (!dirItem.IsDirectory())
+ archivePaths.Add(dirItem.FullPath);
+ }
+
+ if (archivePaths.Size() == 0)
+ throw "there is no such archive";
+
+ UStringVector archivePathsFull;
+
+ for (i = 0; i < archivePaths.Size(); i++)
+ {
+ UString fullPath;
+ NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath);
+ archivePathsFull.Add(fullPath);
+ }
+ CIntVector indices;
+ SortFileNames(archivePathsFull, indices);
+ options.ArchivePathsSorted.Reserve(indices.Size());
+ options.ArchivePathsFullSorted.Reserve(indices.Size());
+ for (i = 0; i < indices.Size(); i++)
+ {
+ options.ArchivePathsSorted.Add(archivePaths[indices[i]]);
+ options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]);
+ }
+
+ if (isExtractGroupCommand)
+ {
+ SetMethodOptions(parser, options.ExtractProperties);
+ if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal)
+ throw kSameTerminalError;
+ if(parser[NKey::kOutputDir].ThereIs)
+ {
+ options.OutputDir = parser[NKey::kOutputDir].PostStrings[0];
+ NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
+ }
+
+ options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+ if(parser[NKey::kOverwrite].ThereIs)
+ options.OverwriteMode =
+ k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
+ else if (options.YesToAll)
+ options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+ }
+ }
+ else if(options.Command.IsFromUpdateGroup())
+ {
+ CUpdateOptions &updateOptions = options.UpdateOptions;
+
+ if(parser[NKey::kArchiveType].ThereIs)
+ options.ArcType = parser[NKey::kArchiveType].PostStrings[0];
+
+ SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);
+
+ SetMethodOptions(parser, updateOptions.MethodMode.Properties);
+
+ if (parser[NKey::kShareForWrite].ThereIs)
+ updateOptions.OpenShareForWrite = true;
+
+ options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
+
+ if (options.EnablePercents)
+ {
+ if ((options.StdOutMode && !options.IsStdErrTerminal) ||
+ (!options.StdOutMode && !options.IsStdOutTerminal))
+ options.EnablePercents = false;
+ }
+
+ updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
+ if (updateOptions.EMailMode)
+ {
+ updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
+ if (updateOptions.EMailAddress.Length() > 0)
+ if (updateOptions.EMailAddress[0] == L'.')
+ {
+ updateOptions.EMailRemoveAfter = true;
+ updateOptions.EMailAddress.Delete(0);
+ }
+ }
+
+ updateOptions.StdOutMode = options.StdOutMode;
+ updateOptions.StdInMode = options.StdInMode;
+
+ if (updateOptions.StdOutMode && updateOptions.EMailMode)
+ throw "stdout mode and email mode cannot be combined";
+ if (updateOptions.StdOutMode && options.IsStdOutTerminal)
+ throw kTerminalOutError;
+ if(updateOptions.StdInMode)
+ updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
+
+ #ifdef _WIN32
+ ConvertToLongNames(options.WildcardCensor);
+ #endif
+ }
+ else if(options.Command.CommandType == NCommandType::kBenchmark)
+ {
+ options.NumThreads = (UInt32)-1;
+ options.DictionarySize = (UInt32)-1;
+ options.NumIterations = 1;
+ if (curCommandIndex < numNonSwitchStrings)
+ {
+ if (!ConvertStringToUInt32(nonSwitchStrings[curCommandIndex++], options.NumIterations))
+ ThrowUserErrorException();
+ }
+ for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
+ {
+ UString postString = parser[NKey::kProperty].PostStrings[i];
+ postString.MakeUpper();
+ if (postString.Length() < 2)
+ ThrowUserErrorException();
+ if (postString[0] == 'D')
+ {
+ int pos = 1;
+ if (postString[pos] == '=')
+ pos++;
+ UInt32 logSize;
+ if (!ConvertStringToUInt32((const wchar_t *)postString + pos, logSize))
+ ThrowUserErrorException();
+ if (logSize > 31)
+ ThrowUserErrorException();
+ options.DictionarySize = 1 << logSize;
+ }
+ else if (postString[0] == 'M' && postString[1] == 'T' )
+ {
+ int pos = 2;
+ if (postString[pos] == '=')
+ pos++;
+ if (postString[pos] != 0)
+ if (!ConvertStringToUInt32((const wchar_t *)postString + pos, options.NumThreads))
+ ThrowUserErrorException();
+ }
+ else if (postString[0] == 'M' && postString[1] == '=' )
+ {
+ int pos = 2;
+ if (postString[pos] != 0)
+ options.Method = postString.Mid(2);
+ }
+ else
+ ThrowUserErrorException();
+ }
+ }
+ else if(options.Command.CommandType == NCommandType::kInfo)
+ {
+ }
+ else
+ ThrowUserErrorException();
+ options.WildcardCensor.ExtendExclude();
+}
Added: trunk/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,104 @@
+// ArchiveCommandLine.h
+
+#ifndef __ARCHIVECOMMANDLINE_H
+#define __ARCHIVECOMMANDLINE_H
+
+#include "Common/Wildcard.h"
+#include "Common/CommandLineParser.h"
+
+#include "Extract.h"
+#include "Update.h"
+
+struct CArchiveCommandLineException: public AString
+{
+ CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {}
+};
+
+namespace NCommandType { enum EEnum
+{
+ kAdd = 0,
+ kUpdate,
+ kDelete,
+ kTest,
+ kExtract,
+ kFullExtract,
+ kList,
+ kBenchmark,
+ kInfo
+};}
+
+namespace NRecursedType { enum EEnum
+{
+ kRecursed,
+ kWildCardOnlyRecursed,
+ kNonRecursed
+};}
+
+struct CArchiveCommand
+{
+ NCommandType::EEnum CommandType;
+ bool IsFromExtractGroup() const;
+ bool IsFromUpdateGroup() const;
+ bool IsTestMode() const { return CommandType == NCommandType::kTest; }
+ NExtract::NPathMode::EEnum GetPathMode() const;
+};
+
+struct CArchiveCommandLineOptions
+{
+ bool HelpMode;
+
+ #ifdef _WIN32
+ bool LargePages;
+ #endif
+
+ bool IsInTerminal;
+ bool IsStdOutTerminal;
+ bool IsStdErrTerminal;
+ bool StdInMode;
+ bool StdOutMode;
+ bool EnableHeaders;
+
+ bool YesToAll;
+ bool ShowDialog;
+ // NWildcard::CCensor ArchiveWildcardCensor;
+ NWildcard::CCensor WildcardCensor;
+
+ CArchiveCommand Command;
+ UString ArchiveName;
+
+ bool PasswordEnabled;
+ UString Password;
+
+ bool TechMode;
+ // Extract
+ bool AppendName;
+ UString OutputDir;
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+ UStringVector ArchivePathsSorted;
+ UStringVector ArchivePathsFullSorted;
+ CObjectVector<CProperty> ExtractProperties;
+
+ CUpdateOptions UpdateOptions;
+ UString ArcType;
+ bool EnablePercents;
+
+ // Benchmark
+ UInt32 NumIterations;
+ UInt32 NumThreads;
+ UInt32 DictionarySize;
+ UString Method;
+
+
+ CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};
+};
+
+class CArchiveCommandLineParser
+{
+ NCommandLineParser::CParser parser;
+public:
+ CArchiveCommandLineParser();
+ void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options);
+ void Parse2(CArchiveCommandLineOptions &options);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,479 @@
+// ArchiveExtractCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveExtractCallback.h"
+
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Time.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "Windows/PropVariantConversions.h"
+
+#include "../../Common/FilePathAutoRename.h"
+
+#include "../Common/ExtractingFilePath.h"
+#include "OpenArchive.h"
+
+using namespace NWindows;
+
+static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name";
+static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";
+static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
+
+
+void CArchiveExtractCallback::Init(
+ IInArchive *archiveHandler,
+ IFolderArchiveExtractCallback *extractCallback2,
+ bool stdOutMode,
+ const UString &directoryPath,
+ const UStringVector &removePathParts,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault,
+ UInt64 packSize)
+{
+ _stdOutMode = stdOutMode;
+ _numErrors = 0;
+ _unpTotal = 1;
+ _packTotal = packSize;
+
+ _extractCallback2 = extractCallback2;
+ _compressProgress.Release();
+ _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
+
+ LocalProgressSpec->Init(extractCallback2, true);
+ LocalProgressSpec->SendProgress = false;
+
+ _itemDefaultName = itemDefaultName;
+ _utcLastWriteTimeDefault = utcLastWriteTimeDefault;
+ _attributesDefault = attributesDefault;
+ _removePathParts = removePathParts;
+ _archiveHandler = archiveHandler;
+ _directoryPath = directoryPath;
+ NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
+{
+ COM_TRY_BEGIN
+ _unpTotal = size;
+ if (!_multiArchives && _extractCallback2)
+ return _extractCallback2->SetTotal(size);
+ return S_OK;
+ COM_TRY_END
+}
+
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)
+{
+ const UInt64 kMax = (UInt64)1 << 31;
+ while (v1 > kMax)
+ {
+ v1 >>= 1;
+ v2 >>= 1;
+ }
+}
+
+static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal)
+{
+ NormalizeVals(packTotal, unpTotal);
+ NormalizeVals(unpCur, unpTotal);
+ if (unpTotal == 0)
+ unpTotal = 1;
+ return unpCur * packTotal / unpTotal;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)
+{
+ COM_TRY_BEGIN
+ if (!_extractCallback2)
+ return S_OK;
+
+ if (_multiArchives)
+ {
+ if (completeValue != NULL)
+ {
+ UInt64 packCur = LocalProgressSpec->InSize + MyMultDiv64(*completeValue, _unpTotal, _packTotal);
+ return _extractCallback2->SetCompleted(&packCur);
+ }
+ }
+ return _extractCallback2->SetCompleted(completeValue);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ COM_TRY_BEGIN
+ return _localProgress->SetRatioInfo(inSize, outSize);
+ COM_TRY_END
+}
+
+void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath)
+{
+ fullPath = _directoryPath;
+ for(int i = 0; i < dirPathParts.Size(); i++)
+ {
+ if (i > 0)
+ fullPath += wchar_t(NFile::NName::kDirDelimiter);
+ fullPath += dirPathParts[i];
+ NFile::NDirectory::MyCreateDirectory(fullPath);
+ }
+}
+
+static UString MakePathNameFromParts(const UStringVector &parts)
+{
+ UString result;
+ for(int i = 0; i < parts.Size(); i++)
+ {
+ if(i != 0)
+ result += wchar_t(NFile::NName::kDirDelimiter);
+ result += parts[i];
+ }
+ return result;
+}
+
+
+HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
+{
+ filetimeIsDefined = false;
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, propID, &prop));
+ if (prop.vt == VT_FILETIME)
+ {
+ filetime = prop.filetime;
+ filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0);
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+ COM_TRY_BEGIN
+ *outStream = 0;
+ _outFileStream.Release();
+
+ _encrypted = false;
+ _isSplit = false;
+ _curSize = 0;
+
+ UString fullPath;
+
+ RINOK(GetArchiveItemPath(_archiveHandler, index, _itemDefaultName, fullPath));
+ RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory));
+
+ _filePath = fullPath;
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidPosition, &prop));
+ if (prop.vt != VT_EMPTY)
+ {
+ if (prop.vt != VT_UI8)
+ return E_FAIL;
+ _position = prop.uhVal.QuadPart;
+ _isSplit = true;
+ }
+ }
+
+ RINOK(IsArchiveItemProp(_archiveHandler, index, kpidEncrypted, _encrypted));
+
+ bool newFileSizeDefined;
+ UInt64 newFileSize;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
+ newFileSizeDefined = (prop.vt != VT_EMPTY);
+ if (newFileSizeDefined)
+ {
+ newFileSize = ConvertPropVariantToUInt64(prop);
+ _curSize = newFileSize;
+ }
+ }
+
+ if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ if (_stdOutMode)
+ {
+ CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream;
+ *outStream = outStreamLoc.Detach();
+ return S_OK;
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &prop));
+ if (prop.vt == VT_EMPTY)
+ {
+ _processedFileInfo.Attributes = _attributesDefault;
+ _processedFileInfo.AttributesAreDefined = false;
+ }
+ else
+ {
+ if (prop.vt != VT_UI4)
+ return E_FAIL;
+ _processedFileInfo.Attributes = prop.ulVal;
+ _processedFileInfo.AttributesAreDefined = true;
+ }
+ }
+
+ RINOK(GetTime(index, kpidCreationTime, _processedFileInfo.CreationTime,
+ _processedFileInfo.IsCreationTimeDefined));
+ RINOK(GetTime(index, kpidLastWriteTime, _processedFileInfo.LastWriteTime,
+ _processedFileInfo.IsLastWriteTimeDefined));
+ RINOK(GetTime(index, kpidLastAccessTime, _processedFileInfo.LastAccessTime,
+ _processedFileInfo.IsLastAccessTimeDefined));
+
+ bool isAnti = false;
+ RINOK(IsArchiveItemProp(_archiveHandler, index, kpidIsAnti, isAnti));
+
+ UStringVector pathParts;
+ SplitPathToParts(fullPath, pathParts);
+
+ if(pathParts.IsEmpty())
+ return E_FAIL;
+ int numRemovePathParts = 0;
+ switch(_pathMode)
+ {
+ case NExtract::NPathMode::kFullPathnames:
+ break;
+ case NExtract::NPathMode::kCurrentPathnames:
+ {
+ numRemovePathParts = _removePathParts.Size();
+ if (pathParts.Size() <= numRemovePathParts)
+ return E_FAIL;
+ for (int i = 0; i < numRemovePathParts; i++)
+ if (_removePathParts[i].CompareNoCase(pathParts[i]) != 0)
+ return E_FAIL;
+ break;
+ }
+ case NExtract::NPathMode::kNoPathnames:
+ {
+ numRemovePathParts = pathParts.Size() - 1;
+ break;
+ }
+ }
+ pathParts.Delete(0, numRemovePathParts);
+ MakeCorrectPath(pathParts);
+ UString processedPath = MakePathNameFromParts(pathParts);
+ if (!isAnti)
+ {
+ if (!_processedFileInfo.IsDirectory)
+ {
+ if (!pathParts.IsEmpty())
+ pathParts.DeleteBack();
+ }
+
+ if (!pathParts.IsEmpty())
+ {
+ UString fullPathNew;
+ CreateComplexDirectory(pathParts, fullPathNew);
+ if (_processedFileInfo.IsDirectory)
+ NFile::NDirectory::SetDirTime(fullPathNew,
+ (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL,
+ (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL,
+ (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault);
+ }
+ }
+
+
+ UString fullProcessedPath = _directoryPath + processedPath;
+
+ if(_processedFileInfo.IsDirectory)
+ {
+ _diskFilePath = fullProcessedPath;
+ if (isAnti)
+ NFile::NDirectory::MyRemoveDirectory(_diskFilePath);
+ return S_OK;
+ }
+
+ if (!_isSplit)
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ switch(_overwriteMode)
+ {
+ case NExtract::NOverwriteMode::kSkipExisting:
+ return S_OK;
+ case NExtract::NOverwriteMode::kAskBefore:
+ {
+ Int32 overwiteResult;
+ RINOK(_extractCallback2->AskOverwrite(
+ fullProcessedPath, &fileInfo.LastWriteTime, &fileInfo.Size, fullPath,
+ _processedFileInfo.IsLastWriteTimeDefined ? &_processedFileInfo.LastWriteTime : NULL,
+ newFileSizeDefined ? &newFileSize : NULL,
+ &overwiteResult))
+
+ switch(overwiteResult)
+ {
+ case NOverwriteAnswer::kCancel:
+ return E_ABORT;
+ case NOverwriteAnswer::kNo:
+ return S_OK;
+ case NOverwriteAnswer::kNoToAll:
+ _overwriteMode = NExtract::NOverwriteMode::kSkipExisting;
+ return S_OK;
+ case NOverwriteAnswer::kYesToAll:
+ _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+ break;
+ case NOverwriteAnswer::kYes:
+ break;
+ case NOverwriteAnswer::kAutoRename:
+ _overwriteMode = NExtract::NOverwriteMode::kAutoRename;
+ break;
+ default:
+ return E_FAIL;
+ }
+ }
+ }
+ if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename)
+ {
+ if (!AutoRenamePath(fullProcessedPath))
+ {
+ UString message = UString(kCantAutoRename) + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_FAIL;
+ }
+ }
+ else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)
+ {
+ UString existPath = fullProcessedPath;
+ if (!AutoRenamePath(existPath))
+ {
+ UString message = kCantAutoRename + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_FAIL;
+ }
+ if(!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
+ {
+ UString message = UString(kCantRenameFile) + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_FAIL;
+ }
+ }
+ else
+ if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ UString message = UString(kCantDeleteOutputFile) + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return S_OK;
+ // return E_FAIL;
+ }
+ }
+ }
+ if (!isAnti)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
+ {
+ // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
+ {
+ UString message = L"can not open output file " + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return S_OK;
+ }
+ }
+ if (_isSplit)
+ {
+ RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ _diskFilePath = fullProcessedPath;
+ }
+ else
+ {
+ *outStream = NULL;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
+{
+ COM_TRY_BEGIN
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ _extractMode = true;
+ };
+ return _extractCallback2->PrepareOperation(_filePath, _processedFileInfo.IsDirectory,
+ askExtractMode, _isSplit ? &_position: 0);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
+{
+ COM_TRY_BEGIN
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ case NArchive::NExtract::NOperationResult::kDataError:
+ break;
+ default:
+ _outFileStream.Release();
+ return E_FAIL;
+ }
+ if (_outFileStream != NULL)
+ {
+ _outFileStreamSpec->SetTime(
+ (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL,
+ (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL,
+ (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault);
+ _curSize = _outFileStreamSpec->ProcessedSize;
+ RINOK(_outFileStreamSpec->Close());
+ _outFileStream.Release();
+ }
+ UnpackSize += _curSize;
+ if (_processedFileInfo.IsDirectory)
+ NumFolders++;
+ else
+ NumFiles++;
+
+ if (_extractMode && _processedFileInfo.AttributesAreDefined)
+ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));
+ return S_OK;
+ COM_TRY_END
+}
+
+/*
+STDMETHODIMP CArchiveExtractCallback::GetInStream(
+ const wchar_t *name, ISequentialInStream **inStream)
+{
+ COM_TRY_BEGIN
+ CInFileStream *inFile = new CInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamTemp = inFile;
+ if (!inFile->Open(_srcDirectoryPrefix + name))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+*/
+
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
+{
+ COM_TRY_BEGIN
+ if (!_cryptoGetTextPassword)
+ {
+ RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword,
+ &_cryptoGetTextPassword));
+ }
+ return _cryptoGetTextPassword->CryptoGetTextPassword(password);
+ COM_TRY_END
+}
+
Added: trunk/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,139 @@
+// ArchiveExtractCallback.h
+
+#ifndef __ARCHIVEEXTRACTCALLBACK_H
+#define __ARCHIVEEXTRACTCALLBACK_H
+
+#include "../../Archive/IArchive.h"
+#include "IFileExtractCallback.h"
+
+#include "Common/MyString.h"
+#include "Common/MyCom.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../IPassword.h"
+
+#include "ExtractMode.h"
+
+class CArchiveExtractCallback:
+ public IArchiveExtractCallback,
+ // public IArchiveVolumeExtractCallback,
+ public ICryptoGetTextPassword,
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
+ // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+
+ // IExtractCallBack
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+ // IArchiveVolumeExtractCallback
+ // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
+
+private:
+ CMyComPtr<IInArchive> _archiveHandler;
+ CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
+ CMyComPtr<ICompressProgressInfo> _compressProgress;
+ CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
+ UString _directoryPath;
+ NExtract::NPathMode::EEnum _pathMode;
+ NExtract::NOverwriteMode::EEnum _overwriteMode;
+
+ UString _filePath;
+ UInt64 _position;
+ bool _isSplit;
+
+ UString _diskFilePath;
+
+ bool _extractMode;
+
+ bool WriteModified;
+ bool WriteCreated;
+ bool WriteAccessed;
+
+ bool _encrypted;
+
+ struct CProcessedFileInfo
+ {
+ FILETIME CreationTime;
+ FILETIME LastWriteTime;
+ FILETIME LastAccessTime;
+ UInt32 Attributes;
+
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+
+ bool IsDirectory;
+ bool AttributesAreDefined;
+ } _processedFileInfo;
+
+ UInt64 _curSize;
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+ UStringVector _removePathParts;
+
+ UString _itemDefaultName;
+ FILETIME _utcLastWriteTimeDefault;
+ UInt32 _attributesDefault;
+ bool _stdOutMode;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath);
+ HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
+public:
+ CArchiveExtractCallback():
+ WriteModified(true),
+ WriteCreated(false),
+ WriteAccessed(false),
+ _multiArchives(false)
+ {
+ LocalProgressSpec = new CLocalProgress();
+ _localProgress = LocalProgressSpec;
+ }
+
+ CLocalProgress *LocalProgressSpec;
+ CMyComPtr<ICompressProgressInfo> _localProgress;
+ UInt64 _packTotal;
+ UInt64 _unpTotal;
+
+ bool _multiArchives;
+ UInt64 NumFolders;
+ UInt64 NumFiles;
+ UInt64 UnpackSize;
+
+ void InitForMulti(bool multiArchives,
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode)
+ {
+ _multiArchives = multiArchives; NumFolders = NumFiles = UnpackSize = 0;
+ _pathMode = pathMode;
+ _overwriteMode = overwriteMode;
+ }
+
+ void Init(
+ IInArchive *archiveHandler,
+ IFolderArchiveExtractCallback *extractCallback2,
+ bool stdOutMode,
+ const UString &directoryPath,
+ const UStringVector &removePathParts,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault,
+ UInt64 packSize);
+
+ UInt64 _numErrors;
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/ArchiveName.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ArchiveName.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ArchiveName.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,46 @@
+// ArchiveName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+
+using namespace NWindows;
+
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
+{
+ UString resultName = L"Archive";
+ if (fromPrev)
+ {
+ UString dirPrefix;
+ if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix))
+ {
+ if (dirPrefix.Length() > 0)
+ if (dirPrefix[dirPrefix.Length() - 1] == '\\')
+ {
+ dirPrefix.Delete(dirPrefix.Length() - 1);
+ NFile::NFind::CFileInfoW fileInfo;
+ if (NFile::NFind::FindFile(dirPrefix, fileInfo))
+ resultName = fileInfo.Name;
+ }
+ }
+ }
+ else
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(srcName, fileInfo))
+ return resultName;
+ resultName = fileInfo.Name;
+ if (!fileInfo.IsDirectory() && !keepName)
+ {
+ int dotPos = resultName.ReverseFind('.');
+ if (dotPos > 0)
+ {
+ UString archiveName2 = resultName.Left(dotPos);
+ if (archiveName2.ReverseFind('.') < 0)
+ resultName = archiveName2;
+ }
+ }
+ }
+ return resultName;
+}
Added: trunk/lzma/CPP/7zip/UI/Common/ArchiveName.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ArchiveName.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ArchiveName.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// ArchiveName.h
+
+#ifndef __ARCHIVENAME_H
+#define __ARCHIVENAME_H
+
+#include "Common/MyString.h"
+
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,137 @@
+// ArchiveOpenCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveOpenCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+using namespace NWindows;
+
+STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
+{
+ COM_TRY_BEGIN
+ if (!Callback)
+ return S_OK;
+ return Callback->SetTotal(files, bytes);
+ COM_TRY_END
+}
+
+STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
+{
+ COM_TRY_BEGIN
+ if (!Callback)
+ return S_OK;
+ return Callback->SetTotal(files, bytes);
+ COM_TRY_END
+}
+
+STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant propVariant;
+ if (_subArchiveMode)
+ {
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = _subArchiveName;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = _fileInfo.Name;
+ break;
+ case kpidIsFolder:
+ propVariant = _fileInfo.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = _fileInfo.Size;
+ break;
+ case kpidAttributes:
+ propVariant = (UInt32)_fileInfo.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = _fileInfo.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = _fileInfo.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = _fileInfo.LastWriteTime;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+int COpenCallbackImp::FindName(const UString &name)
+{
+ for (int i = 0; i < FileNames.Size(); i++)
+ if (name.CompareNoCase(FileNames[i]) == 0)
+ return i;
+ return -1;
+}
+
+struct CInFileStreamVol: public CInFileStream
+{
+ UString Name;
+ COpenCallbackImp *OpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
+ ~CInFileStreamVol()
+ {
+ int index = OpenCallbackImp->FindName(Name);
+ if (index >= 0)
+ OpenCallbackImp->FileNames.Delete(index);
+ }
+};
+
+STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
+{
+ COM_TRY_BEGIN
+ if (_subArchiveMode)
+ return S_FALSE;
+ if (Callback)
+ {
+ RINOK(Callback->CheckBreak());
+ }
+ *inStream = NULL;
+ UString fullPath = _folderPrefix + name;
+ if (!NFile::NFind::FindFile(fullPath, _fileInfo))
+ return S_FALSE;
+ if (_fileInfo.IsDirectory())
+ return S_FALSE;
+ CInFileStreamVol *inFile = new CInFileStreamVol;
+ CMyComPtr<IInStream> inStreamTemp = inFile;
+ if (!inFile->Open(fullPath))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ inFile->Name = name;
+ inFile->OpenCallbackImp = this;
+ inFile->OpenCallbackRef = this;
+ FileNames.Add(name);
+ TotalSize += _fileInfo.Size;
+ return S_OK;
+ COM_TRY_END
+}
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ COM_TRY_BEGIN
+ if (!Callback)
+ return E_NOTIMPL;
+ return Callback->CryptoGetTextPassword(password);
+ COM_TRY_END
+}
+#endif
+
Added: trunk/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,93 @@
+// ArchiveOpenCallback.h
+
+#ifndef __ARCHIVE_OPEN_CALLBACK_H
+#define __ARCHIVE_OPEN_CALLBACK_H
+
+#include "Common/MyString.h"
+#include "Common/MyCom.h"
+#include "Windows/FileFind.h"
+
+#ifndef _NO_CRYPTO
+#include "../../IPassword.h"
+#endif
+#include "../../Archive/IArchive.h"
+
+struct IOpenCallbackUI
+{
+ virtual HRESULT CheckBreak() = 0;
+ virtual HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes) = 0;
+ virtual HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes) = 0;
+ #ifndef _NO_CRYPTO
+ virtual HRESULT CryptoGetTextPassword(BSTR *password) = 0;
+ virtual HRESULT GetPasswordIfAny(UString &password) = 0;
+ virtual bool WasPasswordAsked() = 0;
+ virtual void ClearPasswordWasAskedFlag() = 0;
+ #endif
+};
+
+class COpenCallbackImp:
+ public IArchiveOpenCallback,
+ public IArchiveOpenVolumeCallback,
+ public IArchiveOpenSetSubArchiveName,
+ #ifndef _NO_CRYPTO
+ public ICryptoGetTextPassword,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ #ifndef _NO_CRYPTO
+ MY_UNKNOWN_IMP3(
+ IArchiveOpenVolumeCallback,
+ ICryptoGetTextPassword,
+ IArchiveOpenSetSubArchiveName
+ )
+ #else
+ MY_UNKNOWN_IMP2(
+ IArchiveOpenVolumeCallback,
+ IArchiveOpenSetSubArchiveName
+ )
+ #endif
+
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+
+ // IArchiveOpenVolumeCallback
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
+
+ #ifndef _NO_CRYPTO
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+ #endif
+
+ STDMETHOD(SetSubArchiveName(const wchar_t *name))
+ {
+ _subArchiveMode = true;
+ _subArchiveName = name;
+ return S_OK;
+ }
+
+private:
+ UString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfoW _fileInfo;
+ bool _subArchiveMode;
+ UString _subArchiveName;
+public:
+ UStringVector FileNames;
+ IOpenCallbackUI *Callback;
+ UInt64 TotalSize;
+
+ COpenCallbackImp(): Callback(NULL) {}
+ void Init(const UString &folderPrefix, const UString &fileName)
+ {
+ _folderPrefix = folderPrefix;
+ if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
+ throw 1;
+ FileNames.Clear();
+ _subArchiveMode = false;
+ TotalSize = 0;
+ }
+ int FindName(const UString &name);
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/DefaultName.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/DefaultName.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/DefaultName.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,26 @@
+// DefaultName.cpp
+
+#include "StdAfx.h"
+
+#include "DefaultName.h"
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+UString GetDefaultName2(const UString &fileName,
+ const UString &extension, const UString &addSubExtension)
+{
+ int extLength = extension.Length();
+ int fileNameLength = fileName.Length();
+ if (fileNameLength > extLength + 1)
+ {
+ int dotPos = fileNameLength - (extLength + 1);
+ if (fileName[dotPos] == '.')
+ if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0)
+ return fileName.Left(dotPos) + addSubExtension;
+ }
+ int dotPos = fileName.ReverseFind(L'.');
+ if (dotPos > 0)
+ return fileName.Left(dotPos) + addSubExtension;
+ return kEmptyFileAlias;
+}
+
Added: trunk/lzma/CPP/7zip/UI/Common/DefaultName.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/DefaultName.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/DefaultName.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,11 @@
+// DefaultName.h
+
+#ifndef __DEFAULTNAME_H
+#define __DEFAULTNAME_H
+
+#include "Common/MyString.h"
+
+UString GetDefaultName2(const UString &fileName,
+ const UString &extension, const UString &addSubExtension);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/DirItem.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/DirItem.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/DirItem.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,34 @@
+// DirItem.h
+
+#ifndef __DIR_ITEM_H
+#define __DIR_ITEM_H
+
+#include "Common/MyString.h"
+#include "Common/Types.h"
+
+struct CDirItem
+{
+ UInt32 Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ UInt64 Size;
+ UString Name;
+ UString FullPath;
+ bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
+};
+
+struct CArchiveItem
+{
+ bool IsDirectory;
+ // DWORD Attributes;
+ // NWindows::NCOM::CPropVariant LastWriteTime;
+ FILETIME LastWriteTime;
+ bool SizeIsDefined;
+ UInt64 Size;
+ UString Name;
+ bool Censored;
+ int IndexInServer;
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,281 @@
+// EnumDirItems.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+#include "Common/MyCom.h"
+
+#include "EnumDirItems.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+void AddDirFileInfo(
+ const UString &prefix, // prefix for logical path
+ const UString &fullPathName, // path on disk: can be relative to some basePrefix
+ const NFind::CFileInfoW &fileInfo,
+ CObjectVector<CDirItem> &dirItems)
+{
+ CDirItem item;
+ item.Attributes = fileInfo.Attributes;
+ item.Size = fileInfo.Size;
+ item.CreationTime = fileInfo.CreationTime;
+ item.LastAccessTime = fileInfo.LastAccessTime;
+ item.LastWriteTime = fileInfo.LastWriteTime;
+ item.Name = prefix + fileInfo.Name;
+ item.FullPath = fullPathName;
+ dirItems.Add(item);
+}
+
+static void EnumerateDirectory(
+ const UString &baseFolderPrefix, // base (disk) prefix for scanning
+ const UString &directory, // additional disk prefix starting from baseFolderPrefix
+ const UString &prefix, // logical prefix
+ CObjectVector<CDirItem> &dirItems,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes)
+{
+ NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard));
+ for (;;)
+ {
+ NFind::CFileInfoW fileInfo;
+ bool found;
+ if (!enumerator.Next(fileInfo, found))
+ {
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(baseFolderPrefix + directory);
+ return;
+ }
+ if (!found)
+ break;
+ AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems);
+ if (fileInfo.IsDirectory())
+ {
+ EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter),
+ prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPaths, errorCodes);
+ }
+ }
+}
+
+void EnumerateDirItems(
+ const UString &baseFolderPrefix, // base (disk) prefix for scanning
+ const UStringVector &fileNames, // names relative to baseFolderPrefix
+ const UString &archiveNamePrefix,
+ CObjectVector<CDirItem> &dirItems,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes)
+{
+ for(int i = 0; i < fileNames.Size(); i++)
+ {
+ const UString &fileName = fileNames[i];
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo))
+ {
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(baseFolderPrefix + fileName);
+ continue;
+ }
+ AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems);
+ if (fileInfo.IsDirectory())
+ {
+ EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter),
+ archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
+ dirItems, errorPaths, errorCodes);
+ }
+ }
+}
+
+static HRESULT EnumerateDirItems(
+ const NWildcard::CCensorNode &curNode,
+ const UString &diskPrefix, // full disk path prefix
+ const UString &archivePrefix, // prefix from root
+ const UStringVector &addArchivePrefix, // prefix from curNode
+ CObjectVector<CDirItem> &dirItems,
+ bool enterToSubFolders,
+ IEnumDirItemCallback *callback,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes)
+{
+ if (!enterToSubFolders)
+ if (curNode.NeedCheckSubDirs())
+ enterToSubFolders = true;
+ if (callback)
+ RINOK(callback->CheckBreak());
+
+ // try direct_names case at first
+ if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
+ {
+ // check that all names are direct
+ int i;
+ for (i = 0; i < curNode.IncludeItems.Size(); i++)
+ {
+ const NWildcard::CItem &item = curNode.IncludeItems[i];
+ if (item.Recursive || item.PathParts.Size() != 1)
+ break;
+ const UString &name = item.PathParts.Front();
+ if (name.IsEmpty() || DoesNameContainWildCard(name))
+ break;
+ }
+ if (i == curNode.IncludeItems.Size())
+ {
+ // all names are direct (no wildcards)
+ // so we don't need file_system's dir enumerator
+ CRecordVector<bool> needEnterVector;
+ for (i = 0; i < curNode.IncludeItems.Size(); i++)
+ {
+ const NWildcard::CItem &item = curNode.IncludeItems[i];
+ const UString &name = item.PathParts.Front();
+ const UString fullPath = diskPrefix + name;
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(fullPath, fileInfo))
+ {
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(fullPath);
+ continue;
+ }
+ bool isDir = fileInfo.IsDirectory();
+ if (isDir && !item.ForDir || !isDir && !item.ForFile)
+ {
+ errorCodes.Add((DWORD)E_FAIL);
+ errorPaths.Add(fullPath);
+ continue;
+ }
+ const UString realName = fileInfo.Name;
+ const UString realDiskPath = diskPrefix + realName;
+ {
+ UStringVector pathParts;
+ pathParts.Add(fileInfo.Name);
+ if (curNode.CheckPathToRoot(false, pathParts, !isDir))
+ continue;
+ }
+ AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems);
+ if (!isDir)
+ continue;
+
+ UStringVector addArchivePrefixNew;
+ const NWildcard::CCensorNode *nextNode = 0;
+ int index = curNode.FindSubNode(name);
+ if (index >= 0)
+ {
+ for (int t = needEnterVector.Size(); t <= index; t++)
+ needEnterVector.Add(true);
+ needEnterVector[index] = false;
+ nextNode = &curNode.SubNodes[index];
+ }
+ else
+ {
+ nextNode = &curNode;
+ addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support
+ }
+ RINOK(EnumerateDirItems(*nextNode,
+ realDiskPath + wchar_t(kDirDelimiter),
+ archivePrefix + realName + wchar_t(kDirDelimiter),
+ addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));
+ }
+ for (i = 0; i < curNode.SubNodes.Size(); i++)
+ {
+ if (i < needEnterVector.Size())
+ if (!needEnterVector[i])
+ continue;
+ const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
+ const UString fullPath = diskPrefix + nextNode.Name;
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(fullPath, fileInfo))
+ {
+ if (!nextNode.AreThereIncludeItems())
+ continue;
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(fullPath);
+ continue;
+ }
+ if (!fileInfo.IsDirectory())
+ {
+ errorCodes.Add((DWORD)E_FAIL);
+ errorPaths.Add(fullPath);
+ continue;
+ }
+ RINOK(EnumerateDirItems(nextNode,
+ diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),
+ archivePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
+ UStringVector(), dirItems, false, callback, errorPaths, errorCodes));
+ }
+ return S_OK;
+ }
+ }
+
+
+ NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard));
+ for (;;)
+ {
+ NFind::CFileInfoW fileInfo;
+ bool found;
+ if (!enumerator.Next(fileInfo, found))
+ {
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(diskPrefix);
+ break;
+ }
+ if (!found)
+ break;
+
+ if (callback)
+ RINOK(callback->CheckBreak());
+ const UString &name = fileInfo.Name;
+ bool enterToSubFolders2 = enterToSubFolders;
+ UStringVector addArchivePrefixNew = addArchivePrefix;
+ addArchivePrefixNew.Add(name);
+ {
+ UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
+ if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory()))
+ continue;
+ }
+ if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory()))
+ {
+ AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems);
+ if (fileInfo.IsDirectory())
+ enterToSubFolders2 = true;
+ }
+ if (!fileInfo.IsDirectory())
+ continue;
+
+ const NWildcard::CCensorNode *nextNode = 0;
+ if (addArchivePrefix.IsEmpty())
+ {
+ int index = curNode.FindSubNode(name);
+ if (index >= 0)
+ nextNode = &curNode.SubNodes[index];
+ }
+ if (!enterToSubFolders2 && nextNode == 0)
+ continue;
+
+ addArchivePrefixNew = addArchivePrefix;
+ if (nextNode == 0)
+ {
+ nextNode = &curNode;
+ addArchivePrefixNew.Add(name);
+ }
+ RINOK(EnumerateDirItems(*nextNode,
+ diskPrefix + name + wchar_t(kDirDelimiter),
+ archivePrefix + name + wchar_t(kDirDelimiter),
+ addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));
+ }
+ return S_OK;
+}
+
+HRESULT EnumerateItems(
+ const NWildcard::CCensor &censor,
+ CObjectVector<CDirItem> &dirItems,
+ IEnumDirItemCallback *callback,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes)
+{
+ for (int i = 0; i < censor.Pairs.Size(); i++)
+ {
+ const NWildcard::CPair &pair = censor.Pairs[i];
+ RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", UStringVector(), dirItems, false,
+ callback, errorPaths, errorCodes));
+ }
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/UI/Common/EnumDirItems.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/EnumDirItems.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/EnumDirItems.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,39 @@
+// EnumDirItems.h
+
+#ifndef __ENUM_DIR_ITEMS_H
+#define __ENUM_DIR_ITEMS_H
+
+#include "Common/Wildcard.h"
+#include "DirItem.h"
+
+#include "Windows/FileFind.h"
+
+void AddDirFileInfo(
+ const UString &prefix,
+ const UString &fullPathName,
+ const NWindows::NFile::NFind::CFileInfoW &fileInfo,
+ CObjectVector<CDirItem> &dirItems);
+
+
+void EnumerateDirItems(
+ const UString &baseFolderPrefix,
+ const UStringVector &fileNames,
+ const UString &archiveNamePrefix,
+ CObjectVector<CDirItem> &dirItems,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes);
+
+struct IEnumDirItemCallback
+{
+ virtual HRESULT CheckBreak() { return S_OK; }
+};
+
+
+HRESULT EnumerateItems(
+ const NWildcard::CCensor &censor,
+ CObjectVector<CDirItem> &dirItems,
+ IEnumDirItemCallback *callback,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/ExitCode.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ExitCode.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ExitCode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,27 @@
+// ExitCode.h
+
+#ifndef __EXIT_CODE_H
+#define __EXIT_CODE_H
+
+namespace NExitCode {
+
+enum EEnum {
+
+ kSuccess = 0, // Successful operation
+ kWarning = 1, // Non fatal error(s) occurred
+ kFatalError = 2, // A fatal error occurred
+ // kCRCError = 3, // A CRC error occurred when unpacking
+ // kLockedArchive = 4, // Attempt to modify an archive previously locked
+ // kWriteError = 5, // Write to disk error
+ // kOpenError = 6, // Open file error
+ kUserError = 7, // Command line option error
+ kMemoryError = 8, // Not enough memory for operation
+ // kCreateFileError = 9, // Create file error
+
+ kUserBreak = 255 // User stopped the process
+
+};
+
+}
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/Extract.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/Extract.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/Extract.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,187 @@
+// Extract.cpp
+
+#include "StdAfx.h"
+
+#include "Extract.h"
+
+#include "Windows/Defs.h"
+#include "Windows/FileDir.h"
+
+#include "OpenArchive.h"
+#include "SetProperties.h"
+
+using namespace NWindows;
+
+HRESULT DecompressArchive(
+ IInArchive *archive,
+ UInt64 packSize,
+ const UString &defaultName,
+ const NWildcard::CCensorNode &wildcardCensor,
+ const CExtractOptions &options,
+ IExtractCallbackUI *callback,
+ CArchiveExtractCallback *extractCallbackSpec,
+ UString &errorMessage)
+{
+ CRecordVector<UInt32> realIndices;
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ UString filePath;
+ RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath));
+ bool isFolder;
+ RINOK(IsArchiveItemFolder(archive, i, isFolder));
+ if (!wildcardCensor.CheckPath(filePath, !isFolder))
+ continue;
+ realIndices.Add(i);
+ }
+ if (realIndices.Size() == 0)
+ {
+ callback->ThereAreNoFiles();
+ return S_OK;
+ }
+
+ UStringVector removePathParts;
+
+ UString outDir = options.OutputDir;
+ outDir.Replace(L"*", defaultName);
+ if(!outDir.IsEmpty())
+ if(!NFile::NDirectory::CreateComplexDirectory(outDir))
+ {
+ HRESULT res = ::GetLastError();
+ if (res == S_OK)
+ res = E_FAIL;
+ errorMessage = ((UString)L"Can not create output directory ") + outDir;
+ return res;
+ }
+
+ extractCallbackSpec->Init(
+ archive,
+ callback,
+ options.StdOutMode,
+ outDir,
+ removePathParts,
+ options.DefaultItemName,
+ options.ArchiveFileInfo.LastWriteTime,
+ options.ArchiveFileInfo.Attributes,
+ packSize);
+
+ #ifdef COMPRESS_MT
+ RINOK(SetProperties(archive, options.Properties));
+ #endif
+
+ HRESULT result = archive->Extract(&realIndices.Front(),
+ realIndices.Size(), options.TestMode? 1: 0, extractCallbackSpec);
+
+ return callback->ExtractResult(result);
+}
+
+HRESULT DecompressArchives(
+ CCodecs *codecs,
+ UStringVector &archivePaths, UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ const CExtractOptions &optionsSpec,
+ IOpenCallbackUI *openCallback,
+ IExtractCallbackUI *extractCallback,
+ UString &errorMessage,
+ CDecompressStat &stat)
+{
+ stat.Clear();
+ CExtractOptions options = optionsSpec;
+ int i;
+ UInt64 totalPackSize = 0;
+ CRecordVector<UInt64> archiveSizes;
+ for (i = 0; i < archivePaths.Size(); i++)
+ {
+ const UString &archivePath = archivePaths[i];
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
+ throw "there is no such archive";
+ if (archiveFileInfo.IsDirectory())
+ throw "can't decompress folder";
+ archiveSizes.Add(archiveFileInfo.Size);
+ totalPackSize += archiveFileInfo.Size;
+ }
+ CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);
+ bool multi = (archivePaths.Size() > 1);
+ extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);
+ if (multi)
+ {
+ RINOK(extractCallback->SetTotal(totalPackSize));
+ }
+ for (i = 0; i < archivePaths.Size(); i++)
+ {
+ const UString &archivePath = archivePaths[i];
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
+ throw "there is no such archive";
+
+ if (archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+
+ options.ArchiveFileInfo = archiveFileInfo;
+
+ #ifndef _NO_CRYPTO
+ openCallback->ClearPasswordWasAskedFlag();
+ #endif
+
+ RINOK(extractCallback->BeforeOpen(archivePath));
+ CArchiveLink archiveLink;
+ HRESULT result = MyOpenArchive(codecs, archivePath, archiveLink, openCallback);
+
+ bool crypted = false;
+ #ifndef _NO_CRYPTO
+ crypted = openCallback->WasPasswordAsked();
+ #endif
+
+ RINOK(extractCallback->OpenResult(archivePath, result, crypted));
+ if (result != S_OK)
+ continue;
+
+ for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
+ {
+ int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
+ if (index >= 0 && index > i)
+ {
+ archivePaths.Delete(index);
+ archivePathsFull.Delete(index);
+ totalPackSize -= archiveSizes[index];
+ archiveSizes.Delete(index);
+ }
+ }
+ if (archiveLink.VolumePaths.Size() != 0)
+ {
+ totalPackSize += archiveLink.VolumesSize;
+ RINOK(extractCallback->SetTotal(totalPackSize));
+ }
+
+ #ifndef _NO_CRYPTO
+ UString password;
+ RINOK(openCallback->GetPasswordIfAny(password));
+ if (!password.IsEmpty())
+ {
+ RINOK(extractCallback->SetPassword(password));
+ }
+ #endif
+
+ options.DefaultItemName = archiveLink.GetDefaultItemName();
+ RINOK(DecompressArchive(
+ archiveLink.GetArchive(),
+ archiveFileInfo.Size + archiveLink.VolumesSize,
+ archiveLink.GetDefaultItemName(),
+ wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage));
+ extractCallbackSpec->LocalProgressSpec->InSize += archiveFileInfo.Size +
+ archiveLink.VolumesSize;
+ extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;
+ if (!errorMessage.IsEmpty())
+ return E_FAIL;
+ }
+ stat.NumFolders = extractCallbackSpec->NumFolders;
+ stat.NumFiles = extractCallbackSpec->NumFiles;
+ stat.UnpackSize = extractCallbackSpec->UnpackSize;
+ stat.NumArchives = archivePaths.Size();
+ stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/UI/Common/Extract.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/Extract.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/Extract.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,77 @@
+// Extract.h
+
+#ifndef __EXTRACT_H
+#define __EXTRACT_H
+
+#include "Common/Wildcard.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "ArchiveExtractCallback.h"
+#include "ArchiveOpenCallback.h"
+#include "ExtractMode.h"
+#include "Property.h"
+
+#include "../Common/LoadCodecs.h"
+
+class CExtractOptions
+{
+public:
+ bool StdOutMode;
+ bool TestMode;
+ NExtract::NPathMode::EEnum PathMode;
+
+ UString OutputDir;
+ bool YesToAll;
+ UString DefaultItemName;
+ NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo;
+
+ // bool ShowDialog;
+ // bool PasswordEnabled;
+ // UString Password;
+ #ifdef COMPRESS_MT
+ CObjectVector<CProperty> Properties;
+ #endif
+
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+ #ifdef EXTERNAL_CODECS
+ CCodecs *Codecs;
+ #endif
+
+ CExtractOptions():
+ StdOutMode(false),
+ YesToAll(false),
+ TestMode(false),
+ PathMode(NExtract::NPathMode::kFullPathnames),
+ OverwriteMode(NExtract::NOverwriteMode::kAskBefore)
+ {}
+
+ /*
+ bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) ||
+ (ExtractMode == NExtractMode::kFullPath); }
+ */
+};
+
+struct CDecompressStat
+{
+ UInt64 NumArchives;
+ UInt64 UnpackSize;
+ UInt64 PackSize;
+ UInt64 NumFolders;
+ UInt64 NumFiles;
+ void Clear() { NumArchives = PackSize = UnpackSize = NumFolders = NumFiles = 0; }
+};
+
+HRESULT DecompressArchives(
+ CCodecs *codecs,
+ UStringVector &archivePaths, UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ const CExtractOptions &options,
+ IOpenCallbackUI *openCallback,
+ IExtractCallbackUI *extractCallback,
+ UString &errorMessage,
+ CDecompressStat &stat);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/ExtractMode.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ExtractMode.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ExtractMode.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,31 @@
+// ExtractMode.h
+
+#ifndef __EXTRACT_MODE_H
+#define __EXTRACT_MODE_H
+
+namespace NExtract {
+
+ namespace NPathMode
+ {
+ enum EEnum
+ {
+ kFullPathnames,
+ kCurrentPathnames,
+ kNoPathnames
+ };
+ }
+
+ namespace NOverwriteMode
+ {
+ enum EEnum
+ {
+ kAskBefore,
+ kWithoutPrompt,
+ kSkipExisting,
+ kAutoRename,
+ kAutoRenameExisting
+ };
+ }
+}
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,96 @@
+// ExtractingFilePath.cpp
+
+#include "StdAfx.h"
+#include "ExtractingFilePath.h"
+
+static UString ReplaceIncorrectChars(const UString &s)
+{
+ #ifdef _WIN32
+ UString res;
+ for (int i = 0; i < s.Length(); i++)
+ {
+ wchar_t c = s[i];
+ if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == ':' || c == '"')
+ c = '_';
+ res += c;
+ }
+ return res;
+ #else
+ return s;
+ #endif
+}
+
+#ifdef _WIN32
+static const wchar_t *g_ReservedNames[] =
+{
+ L"CON", L"PRN", L"AUX", L"NUL"
+};
+
+static bool CheckTail(const UString &name, int len)
+{
+ int dotPos = name.Find(L'.');
+ if (dotPos < 0)
+ dotPos = name.Length();
+ UString s = name.Left(dotPos);
+ s.TrimRight();
+ return (s.Length() != len);
+}
+
+static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
+{
+ int len = MyStringLen(reservedName);
+ if (name.Length() <= len)
+ return true;
+ if (name.Left(len).CompareNoCase(reservedName) != 0)
+ return true;
+ wchar_t c = name[len];
+ if (c < L'0' || c > L'9')
+ return true;
+ return CheckTail(name, len + 1);
+}
+
+static bool IsSupportedName(const UString &name)
+{
+ for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)
+ {
+ const wchar_t *reservedName = g_ReservedNames[i];
+ int len = MyStringLen(reservedName);
+ if (name.Length() < len)
+ continue;
+ if (name.Left(len).CompareNoCase(reservedName) != 0)
+ continue;
+ if (!CheckTail(name, len))
+ return false;
+ }
+ if (!CheckNameNum(name, L"COM"))
+ return false;
+ return CheckNameNum(name, L"LPT");
+}
+#endif
+
+static UString GetCorrectFileName(const UString &path)
+{
+ if (path == L".." || path == L".")
+ return UString();
+ return ReplaceIncorrectChars(path);
+}
+
+void MakeCorrectPath(UStringVector &pathParts)
+{
+ for (int i = 0; i < pathParts.Size();)
+ {
+ UString &s = pathParts[i];
+ s = GetCorrectFileName(s);
+ if (s.IsEmpty())
+ pathParts.Delete(i);
+ else
+ {
+ #ifdef _WIN32
+ if (!IsSupportedName(s))
+ s = (UString)L"_" + s;
+ #endif
+ i++;
+ }
+ }
+}
+
Added: trunk/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// ExtractingFilePath.h
+
+#ifndef __EXTRACTINGFILEPATH_H
+#define __EXTRACTINGFILEPATH_H
+
+#include "Common/MyString.h"
+
+void MakeCorrectPath(UStringVector &pathParts);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,43 @@
+// IFileExtractCallback.h
+
+#ifndef __IFILEEXTRACTCALLBACK_H
+#define __IFILEEXTRACTCALLBACK_H
+
+#include "Common/MyString.h"
+#include "../../IDecl.h"
+
+namespace NOverwriteAnswer
+{
+ enum EEnum
+ {
+ kYes,
+ kYesToAll,
+ kNo,
+ kNoToAll,
+ kAutoRename,
+ kCancel
+ };
+}
+
+DECL_INTERFACE_SUB(IFolderArchiveExtractCallback, IProgress, 0x01, 0x07)
+{
+public:
+ STDMETHOD(AskOverwrite)(
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+ Int32 *answer) PURE;
+ STDMETHOD(PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position) PURE;
+ STDMETHOD(MessageError)(const wchar_t *message) PURE;
+ STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted) PURE;
+};
+
+struct IExtractCallbackUI: IFolderArchiveExtractCallback
+{
+ virtual HRESULT BeforeOpen(const wchar_t *name) = 0;
+ virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0;
+ virtual HRESULT ThereAreNoFiles() = 0;
+ virtual HRESULT ExtractResult(HRESULT result) = 0;
+ virtual HRESULT SetPassword(const UString &password) = 0;
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,644 @@
+// LoadCodecs.cpp
+
+#include "StdAfx.h"
+
+#include "LoadCodecs.h"
+
+#include "../../../Common/MyCom.h"
+#ifdef NEW_FOLDER_INTERFACE
+#include "../../../Common/StringToInt.h"
+#endif
+#include "../../../Windows/PropVariant.h"
+
+#include "../../ICoder.h"
+#include "../../Common/RegisterArc.h"
+
+#ifdef EXTERNAL_CODECS
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/DLL.h"
+#ifdef NEW_FOLDER_INTERFACE
+#include "../../../Windows/ResourceString.h"
+static const UINT kIconTypesResId = 100;
+#endif
+
+#ifdef _WIN32
+#include "Windows/Registry.h"
+#endif
+
+using namespace NWindows;
+using namespace NFile;
+
+#ifdef _WIN32
+extern HINSTANCE g_hInstance;
+#endif
+
+static CSysString GetLibraryFolderPrefix()
+{
+ #ifdef _WIN32
+ TCHAR fullPath[MAX_PATH + 1];
+ ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
+ CSysString path = fullPath;
+ int pos = path.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+ return path.Left(pos + 1);
+ #else
+ return CSysString(); // FIX IT
+ #endif
+}
+
+#define kCodecsFolderName TEXT("Codecs")
+#define kFormatsFolderName TEXT("Formats")
+static TCHAR *kMainDll = TEXT("7z.dll");
+
+#ifdef _WIN32
+static LPCTSTR kRegistryPath = TEXT("Software\\7-zip");
+static LPCTSTR kProgramPathValue = TEXT("Path");
+static bool ReadPathFromRegistry(HKEY baseKey, CSysString &path)
+{
+ NRegistry::CKey key;
+ if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
+ if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS)
+ {
+ NName::NormalizeDirPathPrefix(path);
+ return true;
+ }
+ return false;
+}
+
+#endif
+
+CSysString GetBaseFolderPrefixFromRegistry()
+{
+ CSysString moduleFolderPrefix = GetLibraryFolderPrefix();
+ NFind::CFileInfo fileInfo;
+ if (NFind::FindFile(moduleFolderPrefix + kMainDll, fileInfo))
+ if (!fileInfo.IsDirectory())
+ return moduleFolderPrefix;
+ if (NFind::FindFile(moduleFolderPrefix + kCodecsFolderName, fileInfo))
+ if (fileInfo.IsDirectory())
+ return moduleFolderPrefix;
+ if (NFind::FindFile(moduleFolderPrefix + kFormatsFolderName, fileInfo))
+ if (fileInfo.IsDirectory())
+ return moduleFolderPrefix;
+ #ifdef _WIN32
+ CSysString path;
+ if (ReadPathFromRegistry(HKEY_CURRENT_USER, path))
+ return path;
+ if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
+ return path;
+ #endif
+ return moduleFolderPrefix;
+}
+
+typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
+typedef UInt32 (WINAPI *GetNumberOfFormatsFunc)(UInt32 *numFormats);
+typedef UInt32 (WINAPI *GetHandlerPropertyFunc)(PROPID propID, PROPVARIANT *value);
+typedef UInt32 (WINAPI *GetHandlerPropertyFunc2)(UInt32 index, PROPID propID, PROPVARIANT *value);
+typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *iid, void **outObject);
+typedef UInt32 (WINAPI *SetLargePageModeFunc)();
+
+
+static HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 index,
+ PROPID propId, CLSID &clsId, bool &isAssigned)
+{
+ NWindows::NCOM::CPropVariant prop;
+ isAssigned = false;
+ RINOK(getMethodProperty(index, propId, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ isAssigned = true;
+ clsId = *(const GUID *)prop.bstrVal;
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT CCodecs::LoadCodecs()
+{
+ CCodecLib &lib = Libs.Back();
+ lib.GetMethodProperty = (GetMethodPropertyFunc)lib.Lib.GetProcAddress("GetMethodProperty");
+ if (lib.GetMethodProperty == NULL)
+ return S_OK;
+
+ UInt32 numMethods = 1;
+ GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)lib.Lib.GetProcAddress("GetNumberOfMethods");
+ if (getNumberOfMethodsFunc != NULL)
+ {
+ RINOK(getNumberOfMethodsFunc(&numMethods));
+ }
+
+ for(UInt32 i = 0; i < numMethods; i++)
+ {
+ CDllCodecInfo info;
+ info.LibIndex = Libs.Size() - 1;
+ info.CodecIndex = i;
+
+ RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));
+ RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));
+
+ Codecs.Add(info);
+ }
+ return S_OK;
+}
+
+static HRESULT ReadProp(
+ GetHandlerPropertyFunc getProp,
+ GetHandlerPropertyFunc2 getProp2,
+ UInt32 index, PROPID propID, NCOM::CPropVariant &prop)
+{
+ if (getProp2)
+ return getProp2(index, propID, &prop);;
+ return getProp(propID, &prop);
+}
+
+static HRESULT ReadBoolProp(
+ GetHandlerPropertyFunc getProp,
+ GetHandlerPropertyFunc2 getProp2,
+ UInt32 index, PROPID propID, bool &res)
+{
+ NCOM::CPropVariant prop;
+ RINOK(ReadProp(getProp, getProp2, index, propID, prop));
+ if (prop.vt == VT_BOOL)
+ res = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+static HRESULT ReadStringProp(
+ GetHandlerPropertyFunc getProp,
+ GetHandlerPropertyFunc2 getProp2,
+ UInt32 index, PROPID propID, UString &res)
+{
+ NCOM::CPropVariant prop;
+ RINOK(ReadProp(getProp, getProp2, index, propID, prop));
+ if (prop.vt == VT_BSTR)
+ res = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+#endif
+
+static const unsigned int kNumArcsMax = 32;
+static unsigned int g_NumArcs = 0;
+static const CArcInfo *g_Arcs[kNumArcsMax];
+void RegisterArc(const CArcInfo *arcInfo)
+{
+ if (g_NumArcs < kNumArcsMax)
+ g_Arcs[g_NumArcs++] = arcInfo;
+}
+
+static void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+ destStrings.Clear();
+ UString s;
+ int len = srcString.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L' ')
+ {
+ if (!s.IsEmpty())
+ {
+ destStrings.Add(s);
+ s.Empty();
+ }
+ }
+ else
+ s += c;
+ }
+ if (!s.IsEmpty())
+ destStrings.Add(s);
+}
+
+void CArcInfoEx::AddExts(const wchar_t* ext, const wchar_t* addExt)
+{
+ UStringVector exts, addExts;
+ SplitString(ext, exts);
+ if (addExt != 0)
+ SplitString(addExt, addExts);
+ for (int i = 0; i < exts.Size(); i++)
+ {
+ CArcExtInfo extInfo;
+ extInfo.Ext = exts[i];
+ if (i < addExts.Size())
+ {
+ extInfo.AddExt = addExts[i];
+ if (extInfo.AddExt == L"*")
+ extInfo.AddExt.Empty();
+ }
+ Exts.Add(extInfo);
+ }
+}
+
+#ifdef EXTERNAL_CODECS
+
+HRESULT CCodecs::LoadFormats()
+{
+ const NDLL::CLibrary &lib = Libs.Back().Lib;
+ GetHandlerPropertyFunc getProp = 0;
+ GetHandlerPropertyFunc2 getProp2 = (GetHandlerPropertyFunc2)
+ lib.GetProcAddress("GetHandlerProperty2");
+ if (getProp2 == NULL)
+ {
+ getProp = (GetHandlerPropertyFunc)
+ lib.GetProcAddress("GetHandlerProperty");
+ if (getProp == NULL)
+ return S_OK;
+ }
+
+ UInt32 numFormats = 1;
+ GetNumberOfFormatsFunc getNumberOfFormats = (GetNumberOfFormatsFunc)
+ lib.GetProcAddress("GetNumberOfFormats");
+ if (getNumberOfFormats != NULL)
+ {
+ RINOK(getNumberOfFormats(&numFormats));
+ }
+ if (getProp2 == NULL)
+ numFormats = 1;
+
+ for(UInt32 i = 0; i < numFormats; i++)
+ {
+ CArcInfoEx item;
+ item.LibIndex = Libs.Size() - 1;
+ item.FormatIndex = i;
+
+ RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kName, item.Name));
+
+ NCOM::CPropVariant prop;
+ if (ReadProp(getProp, getProp2, i, NArchive::kClassID, prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+ item.ClassID = *(const GUID *)prop.bstrVal;
+ prop.Clear();
+
+ UString ext, addExt;
+ RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kExtension, ext));
+ RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kAddExtension, addExt));
+ item.AddExts(ext, addExt);
+
+ ReadBoolProp(getProp, getProp2, i, NArchive::kUpdate, item.UpdateEnabled);
+ if (item.UpdateEnabled)
+ ReadBoolProp(getProp, getProp2, i, NArchive::kKeepName, item.KeepName);
+
+ if (ReadProp(getProp, getProp2, i, NArchive::kStartSignature, prop) == S_OK)
+ if (prop.vt == VT_BSTR)
+ {
+ UINT len = ::SysStringByteLen(prop.bstrVal);
+ item.StartSignature.SetCapacity(len);
+ memmove(item.StartSignature, prop.bstrVal, len);
+ }
+ Formats.Add(item);
+ }
+ return S_OK;
+}
+
+#ifdef NEW_FOLDER_INTERFACE
+void CCodecLib::LoadIcons()
+{
+ UString iconTypes = MyLoadStringW((HMODULE)Lib, kIconTypesResId);
+ UStringVector pairs;
+ SplitString(iconTypes, pairs);
+ for (int i = 0; i < pairs.Size(); i++)
+ {
+ const UString &s = pairs[i];
+ int pos = s.Find(L':');
+ if (pos < 0)
+ continue;
+ CIconPair iconPair;
+ const wchar_t *end;
+ UString num = s.Mid(pos + 1);
+ iconPair.IconIndex = (UInt32)ConvertStringToUInt64(num, &end);
+ if (*end != L'\0')
+ continue;
+ iconPair.Ext = s.Left(pos);
+ IconPairs.Add(iconPair);
+ }
+}
+
+int CCodecLib::FindIconIndex(const UString &ext) const
+{
+ for (int i = 0; i < IconPairs.Size(); i++)
+ {
+ const CIconPair &pair = IconPairs[i];
+ if (ext.CompareNoCase(pair.Ext) == 0)
+ return pair.IconIndex;
+ }
+ return -1;
+}
+#endif
+
+#ifdef _7ZIP_LARGE_PAGES
+extern "C"
+{
+ extern SIZE_T g_LargePageSize;
+}
+#endif
+
+HRESULT CCodecs::LoadDll(const CSysString &dllPath)
+{
+ {
+ NDLL::CLibrary library;
+ if (!library.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE))
+ return S_OK;
+ }
+ Libs.Add(CCodecLib());
+ CCodecLib &lib = Libs.Back();
+ #ifdef NEW_FOLDER_INTERFACE
+ lib.Path = dllPath;
+ #endif
+ bool used = false;
+ HRESULT res = S_OK;
+ if (lib.Lib.Load(dllPath))
+ {
+ #ifdef NEW_FOLDER_INTERFACE
+ lib.LoadIcons();
+ #endif
+
+ #ifdef _7ZIP_LARGE_PAGES
+ if (g_LargePageSize != 0)
+ {
+ SetLargePageModeFunc setLargePageMode = (SetLargePageModeFunc)lib.Lib.GetProcAddress("SetLargePageMode");
+ if (setLargePageMode != 0)
+ setLargePageMode();
+ }
+ #endif
+
+ lib.CreateObject = (CreateObjectFunc)lib.Lib.GetProcAddress("CreateObject");
+ if (lib.CreateObject != 0)
+ {
+ int startSize = Codecs.Size();
+ res = LoadCodecs();
+ used = (Codecs.Size() != startSize);
+ if (res == S_OK)
+ {
+ startSize = Formats.Size();
+ res = LoadFormats();
+ used = used || (Formats.Size() != startSize);
+ }
+ }
+ }
+ if (!used)
+ Libs.DeleteBack();
+ return res;
+}
+
+HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix)
+{
+ NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
+ NFile::NFind::CFileInfo fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ RINOK(LoadDll(folderPrefix + fileInfo.Name));
+ }
+ return S_OK;
+}
+
+#endif
+
+#ifndef _SFX
+static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
+{
+ bb.SetCapacity(size);
+ memmove((Byte *)bb, data, size);
+}
+#endif
+
+HRESULT CCodecs::Load()
+{
+ Formats.Clear();
+ #ifdef EXTERNAL_CODECS
+ Codecs.Clear();
+ #endif
+ for (UInt32 i = 0; i < g_NumArcs; i++)
+ {
+ const CArcInfo &arc = *g_Arcs[i];
+ CArcInfoEx item;
+ item.Name = arc.Name;
+ item.CreateInArchive = arc.CreateInArchive;
+ item.CreateOutArchive = arc.CreateOutArchive;
+ item.AddExts(arc.Ext, arc.AddExt);
+ item.UpdateEnabled = (arc.CreateOutArchive != 0);
+ item.KeepName = arc.KeepName;
+
+ #ifndef _SFX
+ SetBuffer(item.StartSignature, arc.Signature, arc.SignatureSize);
+ #endif
+ Formats.Add(item);
+ }
+ #ifdef EXTERNAL_CODECS
+ const CSysString baseFolder = GetBaseFolderPrefixFromRegistry();
+ RINOK(LoadDll(baseFolder + kMainDll));
+ RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName TEXT(STRING_PATH_SEPARATOR)));
+ RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName TEXT(STRING_PATH_SEPARATOR)));
+ #endif
+ return S_OK;
+}
+
+int CCodecs::FindFormatForArchiveName(const UString &archivePath) const
+{
+ int slashPos1 = archivePath.ReverseFind(L'\\');
+ int slashPos2 = archivePath.ReverseFind(L'.');
+ int dotPos = archivePath.ReverseFind(L'.');
+ if (dotPos < 0 || dotPos < slashPos1 || dotPos < slashPos2)
+ return -1;
+ UString ext = archivePath.Mid(dotPos + 1);
+ for (int i = 0; i < Formats.Size(); i++)
+ {
+ const CArcInfoEx &arc = Formats[i];
+ if (!arc.UpdateEnabled)
+ continue;
+ // if (arc.FindExtension(ext) >= 0)
+ UString mainExt = arc.GetMainExt();
+ if (!mainExt.IsEmpty() && ext.CompareNoCase(mainExt) == 0)
+ return i;
+ }
+ return -1;
+}
+
+int CCodecs::FindFormatForArchiveType(const UString &arcType) const
+{
+ for (int i = 0; i < Formats.Size(); i++)
+ {
+ const CArcInfoEx &arc = Formats[i];
+ if (!arc.UpdateEnabled)
+ continue;
+ if (arc.Name.CompareNoCase(arcType) == 0)
+ return i;
+ }
+ return -1;
+}
+
+#ifdef EXTERNAL_CODECS
+
+#ifdef EXPORT_CODECS
+extern unsigned int g_NumCodecs;
+STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject);
+STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
+// STDAPI GetNumberOfMethods(UINT32 *numCodecs);
+#endif
+
+STDMETHODIMP CCodecs::GetNumberOfMethods(UINT32 *numMethods)
+{
+ *numMethods =
+ #ifdef EXPORT_CODECS
+ g_NumCodecs +
+ #endif
+ Codecs.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CCodecs::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumCodecs)
+ return GetMethodProperty(index, propID, value);
+ #endif
+
+ const CDllCodecInfo &ci = Codecs[index
+ #ifdef EXPORT_CODECS
+ - g_NumCodecs
+ #endif
+ ];
+
+ if (propID == NMethodPropID::kDecoderIsAssigned)
+ {
+ NWindows::NCOM::CPropVariant propVariant;
+ propVariant = ci.DecoderIsAssigned;
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ if (propID == NMethodPropID::kEncoderIsAssigned)
+ {
+ NWindows::NCOM::CPropVariant propVariant;
+ propVariant = ci.EncoderIsAssigned;
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ return Libs[ci.LibIndex].GetMethodProperty(ci.CodecIndex, propID, value);
+}
+
+STDMETHODIMP CCodecs::CreateDecoder(UINT32 index, const GUID *iid, void **coder)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumCodecs)
+ return CreateCoder2(false, index, iid, coder);
+ #endif
+ const CDllCodecInfo &ci = Codecs[index
+ #ifdef EXPORT_CODECS
+ - g_NumCodecs
+ #endif
+ ];
+ if (ci.DecoderIsAssigned)
+ return Libs[ci.LibIndex].CreateObject(&ci.Decoder, iid, (void **)coder);
+ return S_OK;
+}
+
+STDMETHODIMP CCodecs::CreateEncoder(UINT32 index, const GUID *iid, void **coder)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumCodecs)
+ return CreateCoder2(true, index, iid, coder);
+ #endif
+ const CDllCodecInfo &ci = Codecs[index
+ #ifdef EXPORT_CODECS
+ - g_NumCodecs
+ #endif
+ ];
+ if (ci.EncoderIsAssigned)
+ return Libs[ci.LibIndex].CreateObject(&ci.Encoder, iid, (void **)coder);
+ return S_OK;
+}
+
+HRESULT CCodecs::CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const
+{
+ for (int i = 0; i < Codecs.Size(); i++)
+ {
+ const CDllCodecInfo &codec = Codecs[i];
+ if (encode && !codec.EncoderIsAssigned || !encode && !codec.DecoderIsAssigned)
+ continue;
+ const CCodecLib &lib = Libs[codec.LibIndex];
+ UString res;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(lib.GetMethodProperty(codec.CodecIndex, NMethodPropID::kName, &prop));
+ if (prop.vt == VT_BSTR)
+ res = prop.bstrVal;
+ else if (prop.vt != VT_EMPTY)
+ continue;
+ if (name.CompareNoCase(res) == 0)
+ return lib.CreateObject(encode ? &codec.Encoder : &codec.Decoder, &IID_ICompressCoder, (void **)&coder);
+ }
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+int CCodecs::GetCodecLibIndex(UInt32 index)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumCodecs)
+ return -1;
+ #endif
+ #ifdef EXTERNAL_CODECS
+ const CDllCodecInfo &ci = Codecs[index
+ #ifdef EXPORT_CODECS
+ - g_NumCodecs
+ #endif
+ ];
+ return ci.LibIndex;
+ #else
+ return -1;
+ #endif
+}
+
+bool CCodecs::GetCodecEncoderIsAssigned(UInt32 index)
+{
+ #ifdef EXPORT_CODECS
+ if (index < g_NumCodecs)
+ {
+ NWindows::NCOM::CPropVariant prop;
+ if (GetProperty(index, NMethodPropID::kEncoder, &prop) == S_OK)
+ if (prop.vt != VT_EMPTY)
+ return true;
+ return false;
+ }
+ #endif
+ #ifdef EXTERNAL_CODECS
+ const CDllCodecInfo &ci = Codecs[index
+ #ifdef EXPORT_CODECS
+ - g_NumCodecs
+ #endif
+ ];
+ return ci.EncoderIsAssigned;
+ #else
+ return false;
+ #endif
+}
+
+HRESULT CCodecs::GetCodecId(UInt32 index, UInt64 &id)
+{
+ UString s;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(GetProperty(index, NMethodPropID::kID, &prop));
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ id = prop.uhVal.QuadPart;
+ return S_OK;
+}
+
+UString CCodecs::GetCodecName(UInt32 index)
+{
+ UString s;
+ NWindows::NCOM::CPropVariant prop;
+ if (GetProperty(index, NMethodPropID::kName, &prop) == S_OK)
+ if (prop.vt == VT_BSTR)
+ s = prop.bstrVal;
+ return s;
+}
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/LoadCodecs.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/LoadCodecs.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/LoadCodecs.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,215 @@
+// LoadCodecs.h
+
+#ifndef __LOADCODECS_H
+#define __LOADCODECS_H
+
+#include "../../../Common/Types.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/MyString.h"
+#include "../../../Common/Buffer.h"
+#include "../../ICoder.h"
+
+#ifdef EXTERNAL_CODECS
+#include "../../../Windows/DLL.h"
+#endif
+
+struct CDllCodecInfo
+{
+ CLSID Encoder;
+ CLSID Decoder;
+ bool EncoderIsAssigned;
+ bool DecoderIsAssigned;
+ int LibIndex;
+ UInt32 CodecIndex;
+};
+
+#include "../../Archive/IArchive.h"
+
+typedef IInArchive * (*CreateInArchiveP)();
+typedef IOutArchive * (*CreateOutArchiveP)();
+
+struct CArcExtInfo
+{
+ UString Ext;
+ UString AddExt;
+ CArcExtInfo() {}
+ CArcExtInfo(const UString &ext): Ext(ext) {}
+ CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
+};
+
+
+struct CArcInfoEx
+{
+ #ifdef EXTERNAL_CODECS
+ int LibIndex;
+ UInt32 FormatIndex;
+ CLSID ClassID;
+ #endif
+ bool UpdateEnabled;
+ CreateInArchiveP CreateInArchive;
+ CreateOutArchiveP CreateOutArchive;
+ UString Name;
+ CObjectVector<CArcExtInfo> Exts;
+ #ifndef _SFX
+ CByteBuffer StartSignature;
+ // CByteBuffer FinishSignature;
+ #ifdef NEW_FOLDER_INTERFACE
+ UStringVector AssociateExts;
+ #endif
+ #endif
+ bool KeepName;
+ UString GetMainExt() const
+ {
+ if (Exts.IsEmpty())
+ return UString();
+ return Exts[0].Ext;
+ }
+ int FindExtension(const UString &ext) const
+ {
+ for (int i = 0; i < Exts.Size(); i++)
+ if (ext.CompareNoCase(Exts[i].Ext) == 0)
+ return i;
+ return -1;
+ }
+ UString GetAllExtensions() const
+ {
+ UString s;
+ for (int i = 0; i < Exts.Size(); i++)
+ {
+ if (i > 0)
+ s += ' ';
+ s += Exts[i].Ext;
+ }
+ return s;
+ }
+
+ void AddExts(const wchar_t* ext, const wchar_t* addExt);
+
+ CArcInfoEx():
+ #ifdef EXTERNAL_CODECS
+ LibIndex(-1),
+ #endif
+ UpdateEnabled(false),
+ CreateInArchive(0), CreateOutArchive(0),
+ KeepName(false)
+ #ifndef _SFX
+ #endif
+ {}
+};
+
+#ifdef EXTERNAL_CODECS
+typedef UInt32 (WINAPI *GetMethodPropertyFunc)(UInt32 index, PROPID propID, PROPVARIANT *value);
+typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject);
+
+
+struct CCodecLib
+{
+ NWindows::NDLL::CLibrary Lib;
+ GetMethodPropertyFunc GetMethodProperty;
+ CreateObjectFunc CreateObject;
+ #ifdef NEW_FOLDER_INTERFACE
+ struct CIconPair
+ {
+ UString Ext;
+ UInt32 IconIndex;
+ };
+ CSysString Path;
+ CObjectVector<CIconPair> IconPairs;
+ void LoadIcons();
+ int FindIconIndex(const UString &ext) const;
+ #endif
+ CCodecLib(): GetMethodProperty(0) {}
+};
+#endif
+
+class CCodecs:
+ #ifdef EXTERNAL_CODECS
+ public ICompressCodecsInfo,
+ #else
+ public IUnknown,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ #ifdef EXTERNAL_CODECS
+ CObjectVector<CCodecLib> Libs;
+ CObjectVector<CDllCodecInfo> Codecs;
+ HRESULT LoadCodecs();
+ HRESULT LoadFormats();
+ HRESULT LoadDll(const CSysString &path);
+ HRESULT LoadDllsFromFolder(const CSysString &folderPrefix);
+
+ HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const
+ {
+ return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
+ }
+ #endif
+
+public:
+ CObjectVector<CArcInfoEx> Formats;
+ HRESULT Load();
+ int FindFormatForArchiveName(const UString &archivePath) const;
+ int FindFormatForArchiveType(const UString &arcType) const;
+
+ MY_UNKNOWN_IMP
+
+ #ifdef EXTERNAL_CODECS
+ STDMETHOD(GetNumberOfMethods)(UINT32 *numMethods);
+ STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(CreateDecoder)(UINT32 index, const GUID *interfaceID, void **coder);
+ STDMETHOD(CreateEncoder)(UINT32 index, const GUID *interfaceID, void **coder);
+ #endif
+
+ int GetCodecLibIndex(UInt32 index);
+ bool GetCodecEncoderIsAssigned(UInt32 index);
+ HRESULT GetCodecId(UInt32 index, UInt64 &id);
+ UString GetCodecName(UInt32 index);
+
+ HRESULT CreateInArchive(int formatIndex, CMyComPtr<IInArchive> &archive) const
+ {
+ const CArcInfoEx &ai = Formats[formatIndex];
+ #ifdef EXTERNAL_CODECS
+ if (ai.LibIndex < 0)
+ #endif
+ {
+ archive = ai.CreateInArchive();
+ return S_OK;
+ }
+ #ifdef EXTERNAL_CODECS
+ return CreateArchiveHandler(ai, (void **)&archive, false);
+ #endif
+ }
+ HRESULT CreateOutArchive(int formatIndex, CMyComPtr<IOutArchive> &archive) const
+ {
+ const CArcInfoEx &ai = Formats[formatIndex];
+ #ifdef EXTERNAL_CODECS
+ if (ai.LibIndex < 0)
+ #endif
+ {
+ archive = ai.CreateOutArchive();
+ return S_OK;
+ }
+ #ifdef EXTERNAL_CODECS
+ return CreateArchiveHandler(ai, (void **)&archive, true);
+ #endif
+ }
+ int FindOutFormatFromName(const UString &name) const
+ {
+ for (int i = 0; i < Formats.Size(); i++)
+ {
+ const CArcInfoEx &arc = Formats[i];
+ if (!arc.UpdateEnabled)
+ continue;
+ if (arc.Name.CompareNoCase(name) == 0)
+ return i;
+ }
+ return -1;
+ }
+
+ #ifdef EXTERNAL_CODECS
+ HRESULT CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const;
+ #endif
+
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/OpenArchive.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/OpenArchive.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,461 @@
+// OpenArchive.cpp
+
+#include "StdAfx.h"
+
+#include "OpenArchive.h"
+
+#include "Common/Wildcard.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "Common/StringConvert.h"
+
+#include "DefaultName.h"
+
+using namespace NWindows;
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidPath, &prop));
+ if(prop.vt == VT_BSTR)
+ result = prop.bstrVal;
+ else if (prop.vt == VT_EMPTY)
+ result.Empty();
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result)
+{
+ RINOK(GetArchiveItemPath(archive, index, result));
+ if (result.IsEmpty())
+ result = defaultName;
+ return S_OK;
+}
+
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
+ const FILETIME &defaultFileTime, FILETIME &fileTime)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidLastWriteTime, &prop));
+ if (prop.vt == VT_FILETIME)
+ fileTime = prop.filetime;
+ else if (prop.vt == VT_EMPTY)
+ fileTime = defaultFileTime;
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, propID, &prop));
+ if(prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt == VT_EMPTY)
+ result = false;
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+{
+ return IsArchiveItemProp(archive, index, kpidIsFolder, result);
+}
+
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result)
+{
+ return IsArchiveItemProp(archive, index, kpidIsAnti, result);
+}
+
+// Static-SFX (for Linux) can be big.
+const UInt64 kMaxCheckStartPosition = 1 << 22;
+
+HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName, IArchiveOpenCallback *openArchiveCallback)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ inStreamSpec->Open(fileName);
+ return archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+}
+
+#ifndef _SFX
+static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ if (p1[i] != p2[i])
+ return false;
+ return true;
+}
+#endif
+
+HRESULT OpenArchive(
+ CCodecs *codecs,
+ IInStream *inStream,
+ const UString &fileName,
+ IInArchive **archiveResult,
+ int &formatIndex,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ *archiveResult = NULL;
+ UString extension;
+ {
+ int dotPos = fileName.ReverseFind(L'.');
+ if (dotPos >= 0)
+ extension = fileName.Mid(dotPos + 1);
+ }
+ CIntVector orderIndices;
+ int i;
+ int numFinded = 0;
+ for (i = 0; i < codecs->Formats.Size(); i++)
+ if (codecs->Formats[i].FindExtension(extension) >= 0)
+ orderIndices.Insert(numFinded++, i);
+ else
+ orderIndices.Add(i);
+
+ #ifndef _SFX
+ if (numFinded != 1)
+ {
+ CIntVector orderIndices2;
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (200 << 10);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize));
+ for (UInt32 pos = 0; pos < processedSize; pos++)
+ {
+ for (int i = 0; i < orderIndices.Size(); i++)
+ {
+ int index = orderIndices[i];
+ const CArcInfoEx &ai = codecs->Formats[index];
+ const CByteBuffer &sig = ai.StartSignature;
+ if (sig.GetCapacity() == 0)
+ continue;
+ if (pos + sig.GetCapacity() > processedSize)
+ continue;
+ if (TestSignature(buffer + pos, sig, sig.GetCapacity()))
+ {
+ orderIndices2.Add(index);
+ orderIndices.Delete(i--);
+ }
+ }
+ }
+ orderIndices2 += orderIndices;
+ orderIndices = orderIndices2;
+ }
+ else if (extension == L"000" || extension == L"001")
+ {
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (1 << 10);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize));
+ if (processedSize >= 16)
+ {
+ Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
+ if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[10] && 1) != 0)
+ {
+ for (int i = 0; i < orderIndices.Size(); i++)
+ {
+ int index = orderIndices[i];
+ const CArcInfoEx &ai = codecs->Formats[index];
+ if (ai.Name.CompareNoCase(L"rar") != 0)
+ continue;
+ orderIndices.Delete(i--);
+ orderIndices.Insert(0, index);
+ break;
+ }
+ }
+ }
+ }
+ #endif
+
+ HRESULT badResult = S_OK;
+ for(i = 0; i < orderIndices.Size(); i++)
+ {
+ inStream->Seek(0, STREAM_SEEK_SET, NULL);
+
+ CMyComPtr<IInArchive> archive;
+
+ formatIndex = orderIndices[i];
+ RINOK(codecs->CreateInArchive(formatIndex, archive));
+ if (!archive)
+ continue;
+
+ #ifdef EXTERNAL_CODECS
+ {
+ CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+ archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+ if (setCompressCodecsInfo)
+ {
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
+ }
+ }
+ #endif
+
+ HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+ if (result == S_FALSE)
+ continue;
+ if(result != S_OK)
+ {
+ badResult = result;
+ if(result == E_ABORT)
+ break;
+ continue;
+ }
+ *archiveResult = archive.Detach();
+ const CArcInfoEx &format = codecs->Formats[formatIndex];
+ if (format.Exts.Size() == 0)
+ {
+ defaultItemName = GetDefaultName2(fileName, L"", L"");
+ }
+ else
+ {
+ int subExtIndex = format.FindExtension(extension);
+ if (subExtIndex < 0)
+ subExtIndex = 0;
+ defaultItemName = GetDefaultName2(fileName,
+ format.Exts[subExtIndex].Ext,
+ format.Exts[subExtIndex].AddExt);
+ }
+ return S_OK;
+ }
+ if (badResult != S_OK)
+ return badResult;
+ return S_FALSE;
+}
+
+HRESULT OpenArchive(
+ CCodecs *codecs,
+ const UString &filePath,
+ IInArchive **archiveResult,
+ int &formatIndex,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ if (!inStreamSpec->Open(filePath))
+ return GetLastError();
+ return OpenArchive(codecs, inStream, ExtractFileNameFromPath(filePath),
+ archiveResult, formatIndex,
+ defaultItemName, openArchiveCallback);
+}
+
+static void MakeDefaultName(UString &name)
+{
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos < 0)
+ return;
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.IsEmpty())
+ return;
+ for (int pos = 0; pos < ext.Length(); pos++)
+ if (ext[pos] < L'0' || ext[pos] > L'9')
+ return;
+ name = name.Left(dotPos);
+}
+
+HRESULT OpenArchive(
+ CCodecs *codecs,
+ const UString &fileName,
+ IInArchive **archive0,
+ IInArchive **archive1,
+ int &formatIndex0,
+ int &formatIndex1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ HRESULT result = OpenArchive(codecs, fileName,
+ archive0, formatIndex0, defaultItemName0, openArchiveCallback);
+ RINOK(result);
+ CMyComPtr<IInArchiveGetStream> getStream;
+ result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream);
+ if (result != S_OK || getStream == 0)
+ return S_OK;
+
+ CMyComPtr<ISequentialInStream> subSeqStream;
+ result = getStream->GetStream(0, &subSeqStream);
+ if (result != S_OK)
+ return S_OK;
+
+ CMyComPtr<IInStream> subStream;
+ if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK)
+ return S_OK;
+ if (!subStream)
+ return S_OK;
+
+ UInt32 numItems;
+ RINOK((*archive0)->GetNumberOfItems(&numItems));
+ if (numItems < 1)
+ return S_OK;
+
+ UString subPath;
+ RINOK(GetArchiveItemPath(*archive0, 0, subPath))
+ if (subPath.IsEmpty())
+ {
+ MakeDefaultName(defaultItemName0);
+ subPath = defaultItemName0;
+ const CArcInfoEx &format = codecs->Formats[formatIndex0];
+ if (format.Name.CompareNoCase(L"7z") == 0)
+ {
+ if (subPath.Right(3).CompareNoCase(L".7z") != 0)
+ subPath += L".7z";
+ }
+ }
+ else
+ subPath = ExtractFileNameFromPath(subPath);
+
+ CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
+ openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+ if (setSubArchiveName)
+ setSubArchiveName->SetSubArchiveName(subPath);
+
+ result = OpenArchive(codecs, subStream, subPath,
+ archive1, formatIndex1, defaultItemName1, openArchiveCallback);
+ return S_OK;
+}
+
+static void SetCallback(const UString &archiveName,
+ IOpenCallbackUI *openCallbackUI, CMyComPtr<IArchiveOpenCallback> &openCallback)
+{
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ openCallback = openCallbackSpec;
+ openCallbackSpec->Callback = openCallbackUI;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ openCallbackSpec->Init(
+ fullName.Left(fileNamePartStartIndex),
+ fullName.Mid(fileNamePartStartIndex));
+}
+
+HRESULT MyOpenArchive(
+ CCodecs *codecs,
+ const UString &archiveName,
+ IInArchive **archive, UString &defaultItemName, IOpenCallbackUI *openCallbackUI)
+{
+ CMyComPtr<IArchiveOpenCallback> openCallback;
+ SetCallback(archiveName, openCallbackUI, openCallback);
+ int formatInfo;
+ return OpenArchive(codecs, archiveName, archive, formatInfo, defaultItemName, openCallback);
+}
+
+HRESULT MyOpenArchive(
+ CCodecs *codecs,
+ const UString &archiveName,
+ IInArchive **archive0,
+ IInArchive **archive1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ UStringVector &volumePaths,
+ UInt64 &volumesSize,
+ IOpenCallbackUI *openCallbackUI)
+{
+ volumesSize = 0;
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->Callback = openCallbackUI;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ UString prefix = fullName.Left(fileNamePartStartIndex);
+ UString name = fullName.Mid(fileNamePartStartIndex);
+ openCallbackSpec->Init(prefix, name);
+
+ int formatIndex0, formatIndex1;
+ RINOK(OpenArchive(codecs, archiveName,
+ archive0,
+ archive1,
+ formatIndex0,
+ formatIndex1,
+ defaultItemName0,
+ defaultItemName1,
+ openCallback));
+ volumePaths.Add(prefix + name);
+ for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
+ volumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
+ volumesSize = openCallbackSpec->TotalSize;
+ return S_OK;
+}
+
+HRESULT CArchiveLink::Close()
+{
+ if (Archive1 != 0)
+ RINOK(Archive1->Close());
+ if (Archive0 != 0)
+ RINOK(Archive0->Close());
+ IsOpen = false;
+ return S_OK;
+}
+
+void CArchiveLink::Release()
+{
+ IsOpen = false;
+ Archive1.Release();
+ Archive0.Release();
+}
+
+HRESULT OpenArchive(
+ CCodecs *codecs,
+ const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IArchiveOpenCallback *openCallback)
+{
+ HRESULT res = OpenArchive(codecs, archiveName,
+ &archiveLink.Archive0, &archiveLink.Archive1,
+ archiveLink.FormatIndex0, archiveLink.FormatIndex1,
+ archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
+ openCallback);
+ archiveLink.IsOpen = (res == S_OK);
+ return res;
+}
+
+HRESULT MyOpenArchive(CCodecs *codecs,
+ const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IOpenCallbackUI *openCallbackUI)
+{
+ HRESULT res = MyOpenArchive(codecs, archiveName,
+ &archiveLink.Archive0, &archiveLink.Archive1,
+ archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
+ archiveLink.VolumePaths,
+ archiveLink.VolumesSize,
+ openCallbackUI);
+ archiveLink.IsOpen = (res == S_OK);
+ return res;
+}
+
+HRESULT ReOpenArchive(CCodecs *codecs, CArchiveLink &archiveLink, const UString &fileName)
+{
+ if (archiveLink.GetNumLevels() > 1)
+ return E_NOTIMPL;
+
+ if (archiveLink.GetNumLevels() == 0)
+ return MyOpenArchive(codecs, fileName, archiveLink, 0);
+
+ CMyComPtr<IArchiveOpenCallback> openCallback;
+ SetCallback(fileName, NULL, openCallback);
+
+ HRESULT res = ReOpenArchive(archiveLink.GetArchive(), fileName, openCallback);
+ archiveLink.IsOpen = (res == S_OK);
+ return res;
+}
Added: trunk/lzma/CPP/7zip/UI/Common/OpenArchive.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/OpenArchive.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/OpenArchive.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,130 @@
+// OpenArchive.h
+
+#ifndef __OPENARCHIVE_H
+#define __OPENARCHIVE_H
+
+#include "Common/MyString.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+#include "LoadCodecs.h"
+#include "ArchiveOpenCallback.h"
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result);
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result);
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
+ const FILETIME &defaultFileTime, FILETIME &fileTime);
+HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result);
+
+struct ISetSubArchiveName
+{
+ virtual void SetSubArchiveName(const wchar_t *name) = 0;
+};
+
+HRESULT OpenArchive(
+ CCodecs *codecs,
+ IInStream *inStream,
+ const UString &fileName,
+ IInArchive **archiveResult,
+ int &formatIndex,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(
+ CCodecs *codecs,
+ const UString &filePath,
+ IInArchive **archive,
+ int &formatIndex,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(
+ CCodecs *codecs,
+ const UString &filePath,
+ IInArchive **archive0,
+ IInArchive **archive1,
+ int &formatIndex0,
+ int &formatIndex1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ IArchiveOpenCallback *openArchiveCallback);
+
+
+HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName, IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT MyOpenArchive(
+ CCodecs *codecs,
+ const UString &archiveName,
+ IInArchive **archive,
+ UString &defaultItemName,
+ IOpenCallbackUI *openCallbackUI);
+
+HRESULT MyOpenArchive(
+ CCodecs *codecs,
+ const UString &archiveName,
+ IInArchive **archive0,
+ IInArchive **archive1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ UStringVector &volumePaths,
+ UInt64 &volumesSize,
+ IOpenCallbackUI *openCallbackUI);
+
+struct CArchiveLink
+{
+ CMyComPtr<IInArchive> Archive0;
+ CMyComPtr<IInArchive> Archive1;
+ UString DefaultItemName0;
+ UString DefaultItemName1;
+
+ int FormatIndex0;
+ int FormatIndex1;
+
+ UStringVector VolumePaths;
+
+ UInt64 VolumesSize;
+
+ int GetNumLevels() const
+ {
+ int result = 0;
+ if (Archive0)
+ {
+ result++;
+ if (Archive1)
+ result++;
+ }
+ return result;
+ }
+
+ bool IsOpen;
+
+ CArchiveLink(): IsOpen(false), VolumesSize(0) {};
+
+ IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; }
+ UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; }
+ int GetArchiverIndex() const { return Archive1 != 0 ? FormatIndex1: FormatIndex0; }
+ HRESULT Close();
+ void Release();
+};
+
+HRESULT OpenArchive(
+ CCodecs *codecs,
+ const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IArchiveOpenCallback *openCallback);
+
+HRESULT MyOpenArchive(
+ CCodecs *codecs,
+ const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IOpenCallbackUI *openCallbackUI);
+
+HRESULT ReOpenArchive(
+ CCodecs *codecs,
+ CArchiveLink &archiveLink,
+ const UString &fileName);
+
+#endif
+
Added: trunk/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,89 @@
+// PropIDUtils.cpp
+
+#include "StdAfx.h"
+
+#include "PropIDUtils.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "../../PropID.h"
+
+using namespace NWindows;
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ int t = value & 0xF;
+ value >>= 4;
+ s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
+ }
+ s[8] = L'\0';
+}
+
+UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full)
+{
+ switch(propID)
+ {
+ case kpidCreationTime:
+ case kpidLastWriteTime:
+ case kpidLastAccessTime:
+ {
+ if (propVariant.vt != VT_FILETIME)
+ return UString(); // It is error;
+ FILETIME localFileTime;
+ if (propVariant.filetime.dwHighDateTime == 0 &&
+ propVariant.filetime.dwLowDateTime == 0)
+ return UString();
+ if (!::FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
+ return UString(); // It is error;
+ return ConvertFileTimeToString(localFileTime, true, full);
+ }
+ case kpidCRC:
+ {
+ if(propVariant.vt != VT_UI4)
+ break;
+ wchar_t temp[12];
+ ConvertUInt32ToHex(propVariant.ulVal, temp);
+ return temp;
+ }
+ case kpidAttributes:
+ {
+ if(propVariant.vt != VT_UI4)
+ break;
+ UString result;
+ UInt32 attributes = propVariant.ulVal;
+ if (NFile::NFind::NAttributes::IsReadOnly(attributes)) result += L'R';
+ if (NFile::NFind::NAttributes::IsHidden(attributes)) result += L'H';
+ if (NFile::NFind::NAttributes::IsSystem(attributes)) result += L'S';
+ if (NFile::NFind::NAttributes::IsDirectory(attributes)) result += L'D';
+ if (NFile::NFind::NAttributes::IsArchived(attributes)) result += L'A';
+ if (NFile::NFind::NAttributes::IsCompressed(attributes)) result += L'C';
+ if (NFile::NFind::NAttributes::IsEncrypted(attributes)) result += L'E';
+ return result;
+ }
+ case kpidDictionarySize:
+ {
+ if(propVariant.vt != VT_UI4)
+ break;
+ UInt32 size = propVariant.ulVal;
+ if (size % (1 << 20) == 0)
+ return ConvertUInt32ToString(size >> 20) + L"MB";
+ if (size % (1 << 10) == 0)
+ return ConvertUInt32ToString(size >> 10) + L"KB";
+ return ConvertUInt32ToString(size);
+ }
+ }
+ return ConvertPropVariantToString(propVariant);
+}
Added: trunk/lzma/CPP/7zip/UI/Common/PropIDUtils.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/PropIDUtils.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/PropIDUtils.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// PropIDUtils.h
+
+#ifndef __PROPIDUTILS_H
+#define __PROPIDUTILS_H
+
+#include "Common/MyString.h"
+
+UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full = true);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/Property.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/Property.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/Property.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,14 @@
+// Property.h
+
+#ifndef __PROPERTY_H
+#define __PROPERTY_H
+
+#include "Common/MyString.h"
+
+struct CProperty
+{
+ UString Name;
+ UString Value;
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/SetProperties.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/SetProperties.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/SetProperties.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,65 @@
+// SetProperties.cpp
+
+#include "StdAfx.h"
+
+#include "SetProperties.h"
+
+#include "Windows/PropVariant.h"
+#include "Common/MyString.h"
+#include "Common/StringToInt.h"
+#include "Common/MyCom.h"
+
+#include "../../Archive/IArchive.h"
+
+using namespace NWindows;
+using namespace NCOM;
+
+static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
+{
+ const wchar_t *endPtr;
+ UInt64 result = ConvertStringToUInt64(s, &endPtr);
+ if (endPtr - (const wchar_t *)s != s.Length())
+ prop = s;
+ else if (result <= 0xFFFFFFFF)
+ prop = (UInt32)result;
+ else
+ prop = result;
+}
+
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
+{
+ if (properties.IsEmpty())
+ return S_OK;
+ CMyComPtr<ISetProperties> setProperties;
+ unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties);
+ if (!setProperties)
+ return S_OK;
+
+ UStringVector realNames;
+ CPropVariant *values = new CPropVariant[properties.Size()];
+ try
+ {
+ int i;
+ for(i = 0; i < properties.Size(); i++)
+ {
+ const CProperty &property = properties[i];
+ NCOM::CPropVariant propVariant;
+ if (!property.Value.IsEmpty())
+ ParseNumberString(property.Value, propVariant);
+ realNames.Add(property.Name);
+ values[i] = propVariant;
+ }
+ CRecordVector<const wchar_t *> names;
+ for(i = 0; i < realNames.Size(); i++)
+ names.Add((const wchar_t *)realNames[i]);
+
+ RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
+ }
+ catch(...)
+ {
+ delete []values;
+ throw;
+ }
+ delete []values;
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/UI/Common/SetProperties.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/SetProperties.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/SetProperties.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// SetProperties.h
+
+#ifndef __SETPROPERTIES_H
+#define __SETPROPERTIES_H
+
+#include "Property.h"
+
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/SortUtils.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/SortUtils.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/SortUtils.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,22 @@
+// SortUtils.cpp
+
+#include "StdAfx.h"
+
+#include "SortUtils.h"
+#include "Common/Wildcard.h"
+
+static int CompareStrings(const int *p1, const int *p2, void *param)
+{
+ const UStringVector &strings = *(const UStringVector *)param;
+ return CompareFileNames(strings[*p1], strings[*p2]);
+}
+
+void SortFileNames(const UStringVector &strings, CIntVector &indices)
+{
+ indices.Clear();
+ int numItems = strings.Size();
+ indices.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ indices.Add(i);
+ indices.Sort(CompareStrings, (void *)&strings);
+}
Added: trunk/lzma/CPP/7zip/UI/Common/SortUtils.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/SortUtils.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/SortUtils.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// SortUtils.h
+
+#ifndef __SORTUTLS_H
+#define __SORTUTLS_H
+
+#include "Common/MyString.h"
+
+void SortFileNames(const UStringVector &strings, CIntVector &indices);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/TempFiles.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/TempFiles.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/TempFiles.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,22 @@
+// TempFiles.cpp
+
+#include "StdAfx.h"
+
+#include "TempFiles.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+void CTempFiles::Clear()
+{
+ while(!Paths.IsEmpty())
+ {
+ NDirectory::DeleteFileAlways((LPCWSTR)Paths.Back());
+ Paths.DeleteBack();
+ }
+}
+
+
Added: trunk/lzma/CPP/7zip/UI/Common/TempFiles.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/TempFiles.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/TempFiles.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,16 @@
+// TempFiles.h
+
+#ifndef __TEMPFILES_H
+#define __TEMPFILES_H
+
+#include "Common/MyString.h"
+
+class CTempFiles
+{
+ void Clear();
+public:
+ UStringVector Paths;
+ ~CTempFiles() { Clear(); }
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/Update.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/Update.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/Update.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,852 @@
+// Update.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include <mapi.h>
+#endif
+
+#include "Update.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+#include "Common/CommandLineParser.h"
+
+#ifdef _WIN32
+#include "Windows/DLL.h"
+#endif
+
+#include "Windows/Defs.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+// #include "Windows/Synchronization.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/DirItem.h"
+#include "../Common/EnumDirItems.h"
+#include "../Common/UpdateProduce.h"
+#include "../Common/OpenArchive.h"
+
+#include "TempFiles.h"
+#include "UpdateCallback.h"
+#include "EnumDirItems.h"
+#include "SetProperties.h"
+
+static const char *kUpdateIsNotSupoorted =
+ "update operations are not supported for this archive";
+
+using namespace NCommandLineParser;
+using namespace NWindows;
+using namespace NCOM;
+using namespace NFile;
+using namespace NName;
+
+static const wchar_t *kTempFolderPrefix = L"7zE";
+
+using namespace NUpdateArchive;
+
+static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+class COutMultiVolStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ int _streamIndex; // required stream
+ UInt64 _offsetPos; // offset from start of _streamIndex index
+ UInt64 _absPos;
+ UInt64 _length;
+
+ struct CSubStreamInfo
+ {
+ COutFileStream *StreamSpec;
+ CMyComPtr<IOutStream> Stream;
+ UString Name;
+ UInt64 Pos;
+ UInt64 RealSize;
+ };
+ CObjectVector<CSubStreamInfo> Streams;
+public:
+ // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+ CRecordVector<UInt64> Sizes;
+ UString Prefix;
+ CTempFiles *TempFiles;
+
+ void Init()
+ {
+ _streamIndex = 0;
+ _offsetPos = 0;
+ _absPos = 0;
+ _length = 0;
+ }
+
+ HRESULT Close();
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+// static NSynchronization::CCriticalSection g_TempPathsCS;
+
+HRESULT COutMultiVolStream::Close()
+{
+ HRESULT res = S_OK;
+ for (int i = 0; i < Streams.Size(); i++)
+ {
+ CSubStreamInfo &s = Streams[i];
+ if (s.StreamSpec)
+ {
+ HRESULT res2 = s.StreamSpec->Close();
+ if (res2 != S_OK)
+ res = res2;
+ }
+ }
+ return res;
+}
+
+STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+ while(size > 0)
+ {
+ if (_streamIndex >= Streams.Size())
+ {
+ CSubStreamInfo subStream;
+
+ wchar_t temp[32];
+ ConvertUInt64ToString(_streamIndex + 1, temp);
+ UString res = temp;
+ while (res.Length() < 3)
+ res = UString(L'0') + res;
+ UString name = Prefix + res;
+ subStream.StreamSpec = new COutFileStream;
+ subStream.Stream = subStream.StreamSpec;
+ if(!subStream.StreamSpec->Create(name, false))
+ return ::GetLastError();
+ {
+ // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
+ TempFiles->Paths.Add(name);
+ }
+
+ subStream.Pos = 0;
+ subStream.RealSize = 0;
+ subStream.Name = name;
+ Streams.Add(subStream);
+ continue;
+ }
+ CSubStreamInfo &subStream = Streams[_streamIndex];
+
+ int index = _streamIndex;
+ if (index >= Sizes.Size())
+ index = Sizes.Size() - 1;
+ UInt64 volSize = Sizes[index];
+
+ if (_offsetPos >= volSize)
+ {
+ _offsetPos -= volSize;
+ _streamIndex++;
+ continue;
+ }
+ if (_offsetPos != subStream.Pos)
+ {
+ // CMyComPtr<IOutStream> outStream;
+ // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
+ RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+ subStream.Pos = _offsetPos;
+ }
+
+ UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos);
+ UInt32 realProcessed;
+ RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
+ data = (void *)((Byte *)data + realProcessed);
+ size -= realProcessed;
+ subStream.Pos += realProcessed;
+ _offsetPos += realProcessed;
+ _absPos += realProcessed;
+ if (_absPos > _length)
+ _length = _absPos;
+ if (_offsetPos > subStream.RealSize)
+ subStream.RealSize = _offsetPos;
+ if(processedSize != NULL)
+ *processedSize += realProcessed;
+ if (subStream.Pos == volSize)
+ {
+ _streamIndex++;
+ _offsetPos = 0;
+ }
+ if (realProcessed == 0 && curSize != 0)
+ return E_FAIL;
+ break;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ switch(seekOrigin)
+ {
+ case STREAM_SEEK_SET:
+ _absPos = offset;
+ break;
+ case STREAM_SEEK_CUR:
+ _absPos += offset;
+ break;
+ case STREAM_SEEK_END:
+ _absPos = _length + offset;
+ break;
+ }
+ _offsetPos = _absPos;
+ if (newPosition != NULL)
+ *newPosition = _absPos;
+ _streamIndex = 0;
+ return S_OK;
+}
+
+STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize)
+{
+ if (newSize < 0)
+ return E_INVALIDARG;
+ int i = 0;
+ while (i < Streams.Size())
+ {
+ CSubStreamInfo &subStream = Streams[i++];
+ if ((UInt64)newSize < subStream.RealSize)
+ {
+ RINOK(subStream.Stream->SetSize(newSize));
+ subStream.RealSize = newSize;
+ break;
+ }
+ newSize -= subStream.RealSize;
+ }
+ while (i < Streams.Size())
+ {
+ {
+ CSubStreamInfo &subStream = Streams.Back();
+ subStream.Stream.Release();
+ NDirectory::DeleteFileAlways(subStream.Name);
+ }
+ Streams.DeleteBack();
+ }
+ _offsetPos = _absPos;
+ _streamIndex = 0;
+ _length = newSize;
+ return S_OK;
+}
+
+static const wchar_t *kDefaultArchiveType = L"7z";
+static const wchar_t *kSFXExtension =
+ #ifdef _WIN32
+ L"exe";
+ #else
+ L"";
+ #endif
+
+bool CUpdateOptions::Init(const CCodecs *codecs, const UString &arcPath, const UString &arcType)
+{
+ if (!arcType.IsEmpty())
+ MethodMode.FormatIndex = codecs->FindFormatForArchiveType(arcType);
+ else
+ {
+ MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
+ if (MethodMode.FormatIndex < 0)
+ MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType);
+ }
+ if (MethodMode.FormatIndex < 0)
+ return false;
+ const CArcInfoEx &arcInfo = codecs->Formats[MethodMode.FormatIndex];
+ UString typeExt = arcInfo.GetMainExt();
+ UString ext = typeExt;
+ if (SfxMode)
+ ext = kSFXExtension;
+ ArchivePath.BaseExtension = ext;
+ ArchivePath.VolExtension = typeExt;
+ ArchivePath.ParseFromPath(arcPath);
+ for (int i = 0; i < Commands.Size(); i++)
+ {
+ CUpdateArchiveCommand &uc = Commands[i];
+ uc.ArchivePath.BaseExtension = ext;
+ uc.ArchivePath.VolExtension = typeExt;
+ uc.ArchivePath.ParseFromPath(uc.UserArchivePath);
+ }
+ return true;
+}
+
+
+static HRESULT Compress(
+ CCodecs *codecs,
+ const CActionSet &actionSet,
+ IInArchive *archive,
+ const CCompressionMethodMode &compressionMethod,
+ CArchivePath &archivePath,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ bool shareForWrite,
+ bool stdInMode,
+ /* const UString & stdInFileName, */
+ bool stdOutMode,
+ const CObjectVector<CDirItem> &dirItems,
+ bool sfxMode,
+ const UString &sfxModule,
+ const CRecordVector<UInt64> &volumesSizes,
+ CTempFiles &tempFiles,
+ CUpdateErrorInfo &errorInfo,
+ IUpdateCallbackUI *callback)
+{
+ CMyComPtr<IOutArchive> outArchive;
+ if(archive != NULL)
+ {
+ CMyComPtr<IInArchive> archive2 = archive;
+ HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
+ if(result != S_OK)
+ throw kUpdateIsNotSupoorted;
+ }
+ else
+ {
+ RINOK(codecs->CreateOutArchive(compressionMethod.FormatIndex, outArchive));
+
+ #ifdef EXTERNAL_CODECS
+ {
+ CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+ outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+ if (setCompressCodecsInfo)
+ {
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
+ }
+ }
+ #endif
+ }
+ if (outArchive == 0)
+ throw kUpdateIsNotSupoorted;
+
+ NFileTimeType::EEnum fileTimeType;
+ UInt32 value;
+ RINOK(outArchive->GetFileTimeType(&value));
+
+ switch(value)
+ {
+ case NFileTimeType::kWindows:
+ case NFileTimeType::kDOS:
+ case NFileTimeType::kUnix:
+ fileTimeType = NFileTimeType::EEnum(value);
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ CObjectVector<CUpdatePair> updatePairs;
+ GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!!
+
+ CObjectVector<CUpdatePair2> updatePairs2;
+ UpdateProduce(updatePairs, actionSet, updatePairs2);
+
+ UInt32 numFiles = 0;
+ for (int i = 0; i < updatePairs2.Size(); i++)
+ if (updatePairs2[i].NewData)
+ numFiles++;
+
+ RINOK(callback->SetNumFiles(numFiles));
+
+
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ updateCallbackSpec->ShareForWrite = shareForWrite;
+ updateCallbackSpec->StdInMode = stdInMode;
+ updateCallbackSpec->Callback = callback;
+ updateCallbackSpec->DirItems = &dirItems;
+ updateCallbackSpec->ArchiveItems = &archiveItems;
+ updateCallbackSpec->UpdatePairs = &updatePairs2;
+
+ CMyComPtr<ISequentialOutStream> outStream;
+
+ const UString &archiveName = archivePath.GetFinalPath();
+ if (!stdOutMode)
+ {
+ UString resultPath;
+ int pos;
+ if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
+ throw 1417161;
+ NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
+ }
+
+ COutFileStream *outStreamSpec = NULL;
+ COutMultiVolStream *volStreamSpec = NULL;
+
+ if (volumesSizes.Size() == 0)
+ {
+ if (stdOutMode)
+ outStream = new CStdOutFileStream;
+ else
+ {
+ outStreamSpec = new COutFileStream;
+ outStream = outStreamSpec;
+ bool isOK = false;
+ UString realPath;
+ for (int i = 0; i < (1 << 16); i++)
+ {
+ if (archivePath.Temp)
+ {
+ if (i > 0)
+ {
+ wchar_t s[32];
+ ConvertUInt64ToString(i, s);
+ archivePath.TempPostfix = s;
+ }
+ realPath = archivePath.GetTempPath();
+ }
+ else
+ realPath = archivePath.GetFinalPath();
+ if (outStreamSpec->Create(realPath, false))
+ {
+ tempFiles.Paths.Add(realPath);
+ isOK = true;
+ break;
+ }
+ if (::GetLastError() != ERROR_FILE_EXISTS)
+ break;
+ if (!archivePath.Temp)
+ break;
+ }
+ if (!isOK)
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.FileName = realPath;
+ errorInfo.Message = L"Can not open file";
+ return E_FAIL;
+ }
+ }
+ }
+ else
+ {
+ if (stdOutMode)
+ return E_FAIL;
+ volStreamSpec = new COutMultiVolStream;
+ outStream = volStreamSpec;
+ volStreamSpec->Sizes = volumesSizes;
+ volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L".");
+ volStreamSpec->TempFiles = &tempFiles;
+ volStreamSpec->Init();
+
+ /*
+ updateCallbackSpec->VolumesSizes = volumesSizes;
+ updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
+ if (!archivePath.VolExtension.IsEmpty())
+ updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;
+ */
+ }
+
+ RINOK(SetProperties(outArchive, compressionMethod.Properties));
+
+ if (sfxMode)
+ {
+ CInFileStream *sfxStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
+ if (!sfxStreamSpec->Open(sfxModule))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"Can't open sfx module";
+ errorInfo.FileName = sfxModule;
+ return E_FAIL;
+ }
+
+ CMyComPtr<ISequentialOutStream> sfxOutStream;
+ COutFileStream *outStreamSpec = NULL;
+ if (volumesSizes.Size() == 0)
+ sfxOutStream = outStream;
+ else
+ {
+ outStreamSpec = new COutFileStream;
+ sfxOutStream = outStreamSpec;
+ UString realPath = archivePath.GetFinalPath();
+ if (!outStreamSpec->Create(realPath, false))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.FileName = realPath;
+ errorInfo.Message = L"Can not open file";
+ return E_FAIL;
+ }
+ }
+ RINOK(CopyBlock(sfxStream, sfxOutStream));
+ if (outStreamSpec)
+ {
+ RINOK(outStreamSpec->Close());
+ }
+ }
+
+ HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback);
+ callback->Finilize();
+ RINOK(result);
+ if (outStreamSpec)
+ result = outStreamSpec->Close();
+ else if (volStreamSpec)
+ result = volStreamSpec->Close();
+ return result;
+}
+
+HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
+ IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ CObjectVector<CArchiveItem> &archiveItems)
+{
+ archiveItems.Clear();
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+ archiveItems.Reserve(numItems);
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ CArchiveItem ai;
+
+ RINOK(GetArchiveItemPath(archive, i, ai.Name));
+ RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory));
+ ai.Censored = censor.CheckPath(ai.Name.IsEmpty() ? defaultItemName : ai.Name, !ai.IsDirectory);
+ RINOK(GetArchiveItemFileTime(archive, i,
+ archiveFileInfo.LastWriteTime, ai.LastWriteTime));
+
+ CPropVariant propertySize;
+ RINOK(archive->GetProperty(i, kpidSize, &propertySize));
+ ai.SizeIsDefined = (propertySize.vt != VT_EMPTY);
+ if (ai.SizeIsDefined)
+ ai.Size = ConvertPropVariantToUInt64(propertySize);
+
+ ai.IndexInServer = i;
+ archiveItems.Add(ai);
+ }
+ return S_OK;
+}
+
+
+static HRESULT UpdateWithItemLists(
+ CCodecs *codecs,
+ CUpdateOptions &options,
+ IInArchive *archive,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ const CObjectVector<CDirItem> &dirItems,
+ CTempFiles &tempFiles,
+ CUpdateErrorInfo &errorInfo,
+ IUpdateCallbackUI2 *callback)
+{
+ for(int i = 0; i < options.Commands.Size(); i++)
+ {
+ CUpdateArchiveCommand &command = options.Commands[i];
+ if (options.StdOutMode)
+ {
+ RINOK(callback->StartArchive(0, archive != 0));
+ }
+ else
+ {
+ RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(),
+ i == 0 && options.UpdateArchiveItself && archive != 0));
+ }
+
+ RINOK(Compress(
+ codecs,
+ command.ActionSet, archive,
+ options.MethodMode,
+ command.ArchivePath,
+ archiveItems,
+ options.OpenShareForWrite,
+ options.StdInMode,
+ /* options.StdInFileName, */
+ options.StdOutMode,
+ dirItems,
+ options.SfxMode, options.SfxModule,
+ options.VolumesSizes,
+ tempFiles,
+ errorInfo, callback));
+
+ RINOK(callback->FinishArchive());
+ }
+ return S_OK;
+}
+
+#ifdef _WIN32
+class CCurrentDirRestorer
+{
+ UString m_CurrentDirectory;
+public:
+ CCurrentDirRestorer()
+ { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
+ ~CCurrentDirRestorer()
+ { RestoreDirectory();}
+ bool RestoreDirectory()
+ { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory)); }
+};
+#endif
+
+struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
+{
+ IUpdateCallbackUI2 *Callback;
+ HRESULT CheckBreak() { return Callback->CheckBreak(); }
+};
+
+HRESULT UpdateArchive(
+ CCodecs *codecs,
+ const NWildcard::CCensor &censor,
+ CUpdateOptions &options,
+ CUpdateErrorInfo &errorInfo,
+ IOpenCallbackUI *openCallback,
+ IUpdateCallbackUI2 *callback)
+{
+ if (options.StdOutMode && options.EMailMode)
+ return E_FAIL;
+
+ if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode))
+ return E_NOTIMPL;
+
+ if (options.SfxMode)
+ {
+ CProperty property;
+ property.Name = L"rsfx";
+ property.Value = L"on";
+ options.MethodMode.Properties.Add(property);
+ if (options.SfxModule.IsEmpty())
+ {
+ errorInfo.Message = L"sfx file is not specified";
+ return E_FAIL;
+ }
+ UString name = options.SfxModule;
+ if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule))
+ {
+ errorInfo.Message = L"can't find specified sfx module";
+ return E_FAIL;
+ }
+ }
+
+ const UString archiveName = options.ArchivePath.GetFinalPath();
+
+ UString defaultItemName;
+ NFind::CFileInfoW archiveFileInfo;
+
+ CArchiveLink archiveLink;
+ IInArchive *archive = 0;
+ if (NFind::FindFile(archiveName, archiveFileInfo))
+ {
+ if (archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+ if (options.VolumesSizes.Size() > 0)
+ return E_NOTIMPL;
+ HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, openCallback);
+ RINOK(callback->OpenResult(archiveName, result));
+ RINOK(result);
+ if (archiveLink.VolumePaths.Size() > 1)
+ {
+ errorInfo.SystemError = (DWORD)E_NOTIMPL;
+ errorInfo.Message = L"Updating for multivolume archives is not implemented";
+ return E_NOTIMPL;
+ }
+ archive = archiveLink.GetArchive();
+ defaultItemName = archiveLink.GetDefaultItemName();
+ }
+ else
+ {
+ /*
+ if (archiveType.IsEmpty())
+ throw "type of archive is not specified";
+ */
+ }
+
+ CObjectVector<CDirItem> dirItems;
+ if (options.StdInMode)
+ {
+ CDirItem item;
+ item.FullPath = item.Name = options.StdInFileName;
+ item.Size = (UInt64)(Int64)-1;
+ item.Attributes = 0;
+ SYSTEMTIME st;
+ FILETIME ft;
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+ item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft;
+ dirItems.Add(item);
+ }
+ else
+ {
+ bool needScanning = false;
+ for(int i = 0; i < options.Commands.Size(); i++)
+ if (options.Commands[i].ActionSet.NeedScanning())
+ needScanning = true;
+ if (needScanning)
+ {
+ CEnumDirItemUpdateCallback enumCallback;
+ enumCallback.Callback = callback;
+ RINOK(callback->StartScanning());
+ UStringVector errorPaths;
+ CRecordVector<DWORD> errorCodes;
+ HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes);
+ for (int i = 0; i < errorPaths.Size(); i++)
+ {
+ RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i]));
+ }
+ if(res != S_OK)
+ {
+ errorInfo.Message = L"Scanning error";
+ // errorInfo.FileName = errorPath;
+ return res;
+ }
+ RINOK(callback->FinishScanning());
+ }
+ }
+
+ UString tempDirPrefix;
+ bool usesTempDir = false;
+
+ #ifdef _WIN32
+ NDirectory::CTempDirectoryW tempDirectory;
+ if (options.EMailMode && options.EMailRemoveAfter)
+ {
+ tempDirectory.Create(kTempFolderPrefix);
+ tempDirPrefix = tempDirectory.GetPath();
+ NormalizeDirPathPrefix(tempDirPrefix);
+ usesTempDir = true;
+ }
+ #endif
+
+ CTempFiles tempFiles;
+
+ bool createTempFile = false;
+ if(!options.StdOutMode && options.UpdateArchiveItself)
+ {
+ CArchivePath &ap = options.Commands[0].ArchivePath;
+ ap = options.ArchivePath;
+ // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty())
+ if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
+ {
+ createTempFile = true;
+ ap.Temp = true;
+ if (!options.WorkingDir.IsEmpty())
+ {
+ ap.TempPrefix = options.WorkingDir;
+ NormalizeDirPathPrefix(ap.TempPrefix);
+ }
+ }
+ }
+
+ for(int i = 0; i < options.Commands.Size(); i++)
+ {
+ CArchivePath &ap = options.Commands[i].ArchivePath;
+ if (usesTempDir)
+ {
+ // Check it
+ ap.Prefix = tempDirPrefix;
+ // ap.Temp = true;
+ // ap.TempPrefix = tempDirPrefix;
+ }
+ if (i > 0 || !createTempFile)
+ {
+ const UString &path = ap.GetFinalPath();
+ if (NFind::DoesFileExist(path))
+ {
+ errorInfo.SystemError = 0;
+ errorInfo.Message = L"File already exists";
+ errorInfo.FileName = path;
+ return E_FAIL;
+ }
+ }
+ }
+
+ CObjectVector<CArchiveItem> archiveItems;
+ if (archive != NULL)
+ {
+ RINOK(EnumerateInArchiveItems(censor,
+ archive, defaultItemName, archiveFileInfo, archiveItems));
+ }
+
+ RINOK(UpdateWithItemLists(codecs, options, archive, archiveItems, dirItems,
+ tempFiles, errorInfo, callback));
+
+ if (archive != NULL)
+ {
+ RINOK(archiveLink.Close());
+ archiveLink.Release();
+ }
+
+ tempFiles.Paths.Clear();
+ if(createTempFile)
+ {
+ try
+ {
+ CArchivePath &ap = options.Commands[0].ArchivePath;
+ const UString &tempPath = ap.GetTempPath();
+ if (archive != NULL)
+ if (!NDirectory::DeleteFileAlways(archiveName))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"delete file error";
+ errorInfo.FileName = archiveName;
+ return E_FAIL;
+ }
+ if (!NDirectory::MyMoveFile(tempPath, archiveName))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"move file error";
+ errorInfo.FileName = tempPath;
+ errorInfo.FileName2 = archiveName;
+ return E_FAIL;
+ }
+ }
+ catch(...)
+ {
+ throw;
+ }
+ }
+
+ #ifdef _WIN32
+ if (options.EMailMode)
+ {
+ NDLL::CLibrary mapiLib;
+ if (!mapiLib.Load(TEXT("Mapi32.dll")))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"can not load Mapi32.dll";
+ return E_FAIL;
+ }
+ LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)
+ mapiLib.GetProcAddress("MAPISendDocuments");
+ if (fnSend == 0)
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"can not find MAPISendDocuments function";
+ return E_FAIL;
+ }
+ UStringVector fullPaths;
+ int i;
+ for(i = 0; i < options.Commands.Size(); i++)
+ {
+ CArchivePath &ap = options.Commands[i].ArchivePath;
+ UString arcPath;
+ if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ return E_FAIL;
+ }
+ fullPaths.Add(arcPath);
+ }
+ CCurrentDirRestorer curDirRestorer;
+ for(i = 0; i < fullPaths.Size(); i++)
+ {
+ UString arcPath = fullPaths[i];
+ UString fileName = ExtractFileNameFromPath(arcPath);
+ AString path = GetAnsiString(arcPath);
+ AString name = GetAnsiString(fileName);
+ // Warning!!! MAPISendDocuments function changes Current directory
+ fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
+ }
+ }
+ #endif
+ return S_OK;
+}
+
Added: trunk/lzma/CPP/7zip/UI/Common/Update.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/Update.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/Update.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,165 @@
+// Update.h
+
+#ifndef __UPDATE_H
+#define __UPDATE_H
+
+#include "Common/Wildcard.h"
+#include "Windows/FileFind.h"
+#include "../../Archive/IArchive.h"
+
+#include "UpdateAction.h"
+#include "ArchiveOpenCallback.h"
+#include "UpdateCallback.h"
+#include "Property.h"
+#include "LoadCodecs.h"
+
+struct CArchivePath
+{
+ UString Prefix; // path(folder) prefix including slash
+ UString Name; // base name
+ UString BaseExtension; // archive type extension or "exe" extension
+ UString VolExtension; // archive type extension for volumes
+
+ bool Temp;
+ UString TempPrefix; // path(folder) for temp location
+ UString TempPostfix;
+
+ CArchivePath(): Temp(false) {};
+
+ void ParseFromPath(const UString &path)
+ {
+ SplitPathToParts(path, Prefix, Name);
+ if (Name.IsEmpty())
+ return;
+ int dotPos = Name.ReverseFind(L'.');
+ if (dotPos <= 0)
+ return;
+ if (dotPos == Name.Length() - 1)
+ {
+ Name = Name.Left(dotPos);
+ BaseExtension.Empty();
+ return;
+ }
+ if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0)
+ {
+ BaseExtension = Name.Mid(dotPos + 1);
+ Name = Name.Left(dotPos);
+ }
+ else
+ BaseExtension.Empty();
+ }
+
+ UString GetPathWithoutExt() const
+ {
+ return Prefix + Name;
+ }
+
+ UString GetFinalPath() const
+ {
+ UString path = GetPathWithoutExt();
+ if (!BaseExtension.IsEmpty())
+ path += UString(L'.') + BaseExtension;
+ return path;
+ }
+
+
+ UString GetTempPath() const
+ {
+ UString path = TempPrefix + Name;
+ if (!BaseExtension.IsEmpty())
+ path += UString(L'.') + BaseExtension;
+ path += L".tmp";
+ path += TempPostfix;
+ return path;
+ }
+};
+
+struct CUpdateArchiveCommand
+{
+ UString UserArchivePath;
+ CArchivePath ArchivePath;
+ NUpdateArchive::CActionSet ActionSet;
+};
+
+struct CCompressionMethodMode
+{
+ int FormatIndex;
+ CObjectVector<CProperty> Properties;
+ CCompressionMethodMode(): FormatIndex(-1) {}
+};
+
+struct CUpdateOptions
+{
+ CCompressionMethodMode MethodMode;
+
+ CObjectVector<CUpdateArchiveCommand> Commands;
+ bool UpdateArchiveItself;
+ CArchivePath ArchivePath;
+
+ bool SfxMode;
+ UString SfxModule;
+
+ bool OpenShareForWrite;
+
+ bool StdInMode;
+ UString StdInFileName;
+ bool StdOutMode;
+
+ bool EMailMode;
+ bool EMailRemoveAfter;
+ UString EMailAddress;
+
+ UString WorkingDir;
+
+ bool Init(const CCodecs *codecs, const UString &arcPath, const UString &arcType);
+
+ CUpdateOptions():
+ UpdateArchiveItself(true),
+ SfxMode(false),
+ StdInMode(false),
+ StdOutMode(false),
+ EMailMode(false),
+ EMailRemoveAfter(false),
+ OpenShareForWrite(false)
+ {};
+ CRecordVector<UInt64> VolumesSizes;
+};
+
+struct CErrorInfo
+{
+ DWORD SystemError;
+ UString FileName;
+ UString FileName2;
+ UString Message;
+ // UStringVector ErrorPaths;
+ // CRecordVector<DWORD> ErrorCodes;
+ CErrorInfo(): SystemError(0) {};
+};
+
+struct CUpdateErrorInfo: public CErrorInfo
+{
+};
+
+#define INTERFACE_IUpdateCallbackUI2(x) \
+ INTERFACE_IUpdateCallbackUI(x) \
+ virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) x; \
+ virtual HRESULT StartScanning() x; \
+ virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) x; \
+ virtual HRESULT FinishScanning() x; \
+ virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \
+ virtual HRESULT FinishArchive() x; \
+
+struct IUpdateCallbackUI2: public IUpdateCallbackUI
+{
+ INTERFACE_IUpdateCallbackUI2(=0)
+};
+
+HRESULT UpdateArchive(
+ CCodecs *codecs,
+ const NWildcard::CCensor &censor,
+ CUpdateOptions &options,
+ CUpdateErrorInfo &errorInfo,
+ IOpenCallbackUI *openCallback,
+ IUpdateCallbackUI2 *callback);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/UpdateAction.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/UpdateAction.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/UpdateAction.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,64 @@
+// UpdateAction.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateAction.h"
+
+namespace NUpdateArchive {
+
+const CActionSet kAddActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCompress,
+ NPairAction::kCompress,
+ NPairAction::kCompress,
+ NPairAction::kCompress
+};
+
+const CActionSet kUpdateActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress
+};
+
+const CActionSet kFreshActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kCopy,
+ NPairAction::kIgnore,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress
+};
+
+const CActionSet kSynchronizeActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kIgnore,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+};
+
+const CActionSet kDeleteActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore
+};
+
+}
Added: trunk/lzma/CPP/7zip/UI/Common/UpdateAction.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/UpdateAction.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/UpdateAction.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,57 @@
+// UpdateAction.h
+
+#ifndef __UPDATE_ACTION_H
+#define __UPDATE_ACTION_H
+
+namespace NUpdateArchive {
+
+ namespace NPairState
+ {
+ const int kNumValues = 7;
+ enum EEnum
+ {
+ kNotMasked = 0,
+ kOnlyInArchive,
+ kOnlyOnDisk,
+ kNewInArchive,
+ kOldInArchive,
+ kSameFiles,
+ kUnknowNewerFiles
+ };
+ }
+ namespace NPairAction
+ {
+ enum EEnum
+ {
+ kIgnore = 0,
+ kCopy,
+ kCompress,
+ kCompressAsAnti
+ };
+ }
+ struct CActionSet
+ {
+ NPairAction::EEnum StateActions[NPairState::kNumValues];
+ bool NeedScanning() const
+ {
+ int i;
+ for (i = 0; i < NPairState::kNumValues; i++)
+ if (StateActions[i] == NPairAction::kCompress)
+ return true;
+ for (i = 1; i < NPairState::kNumValues; i++)
+ if (StateActions[i] != NPairAction::kIgnore)
+ return true;
+ return false;
+ }
+ };
+ extern const CActionSet kAddActionSet;
+ extern const CActionSet kUpdateActionSet;
+ extern const CActionSet kFreshActionSet;
+ extern const CActionSet kSynchronizeActionSet;
+ extern const CActionSet kDeleteActionSet;
+};
+
+
+#endif
+
+
Added: trunk/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,267 @@
+// UpdateCallback.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Common/Defs.h"
+#include "Common/ComTry.h"
+
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+using namespace NWindows;
+
+CArchiveUpdateCallback::CArchiveUpdateCallback():
+ Callback(0),
+ ShareForWrite(false),
+ StdInMode(false),
+ DirItems(0),
+ ArchiveItems(0),
+ UpdatePairs(0)
+ {}
+
+
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
+{
+ COM_TRY_BEGIN
+ return Callback->SetTotal(size);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
+{
+ COM_TRY_BEGIN
+ return Callback->SetCompleted(completeValue);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ COM_TRY_BEGIN
+ return Callback->SetRatioInfo(inSize, outSize);
+ COM_TRY_END
+}
+
+
+/*
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidLastAccessTime, VT_FILETIME},
+ { NULL, kpidCreationTime, VT_FILETIME},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidAttributes, VT_UI4},
+ { NULL, kpidIsAnti, VT_BOOL}
+};
+*/
+
+STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
+{
+ return E_NOTIMPL;
+ /*
+ return CStatPropEnumerator::CreateEnumerator(kProperties,
+ sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
+ */
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
+ Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
+{
+ COM_TRY_BEGIN
+ RINOK(Callback->CheckBreak());
+ const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+ if(newData != NULL)
+ *newData = BoolToInt(updatePair.NewData);
+ if(newProperties != NULL)
+ *newProperties = BoolToInt(updatePair.NewProperties);
+ if(indexInArchive != NULL)
+ {
+ if (updatePair.ExistInArchive)
+ {
+ if (ArchiveItems == 0)
+ *indexInArchive = updatePair.ArchiveItemIndex;
+ else
+ *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+ }
+ else
+ *indexInArchive = UInt32(-1);
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+ NWindows::NCOM::CPropVariant propVariant;
+
+ if (propID == kpidIsAnti)
+ {
+ propVariant = updatePair.IsAnti;
+ propVariant.Detach(value);
+ return S_OK;
+ }
+
+ if (updatePair.IsAnti)
+ {
+ switch(propID)
+ {
+ case kpidIsFolder:
+ case kpidPath:
+ break;
+ case kpidSize:
+ propVariant = (UInt64)0;
+ propVariant.Detach(value);
+ return S_OK;
+ default:
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ }
+
+ if(updatePair.ExistOnDisk)
+ {
+ const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = dirItem.Name;
+ break;
+ case kpidIsFolder:
+ propVariant = dirItem.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = dirItem.Size;
+ break;
+ case kpidAttributes:
+ propVariant = dirItem.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = dirItem.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = dirItem.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = dirItem.LastWriteTime;
+ break;
+ }
+ }
+ else
+ {
+ if (propID == kpidPath)
+ {
+ if (updatePair.NewNameIsDefined)
+ {
+ propVariant = updatePair.NewName;
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ }
+ if (updatePair.ExistInArchive && Archive)
+ {
+ UInt32 indexInArchive;
+ if (ArchiveItems == 0)
+ indexInArchive = updatePair.ArchiveItemIndex;
+ else
+ indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+ return Archive->GetProperty(indexInArchive, propID, value);
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
+{
+ COM_TRY_BEGIN
+ const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+ if(!updatePair.NewData)
+ return E_FAIL;
+
+ RINOK(Callback->CheckBreak());
+ RINOK(Callback->Finilize());
+
+ if(updatePair.IsAnti)
+ {
+ return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true);
+ }
+ const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
+ RINOK(Callback->GetStream(dirItem.Name, false));
+
+ if(dirItem.IsDirectory())
+ return S_OK;
+
+ if (StdInMode)
+ {
+ CStdInFileStream *inStreamSpec = new CStdInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ *inStream = inStreamLoc.Detach();
+ }
+ else
+ {
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ UString path = DirPrefix + dirItem.FullPath;
+ if(!inStreamSpec->OpenShared(path, ShareForWrite))
+ {
+ return Callback->OpenFileError(path, ::GetLastError());
+ }
+ *inStream = inStreamLoc.Detach();
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
+{
+ COM_TRY_BEGIN
+ return Callback->SetOperationResult(operationResult);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
+{
+ if (VolumesSizes.Size() == 0)
+ return S_FALSE;
+ if (index >= (UInt32)VolumesSizes.Size())
+ index = VolumesSizes.Size() - 1;
+ *size = VolumesSizes[index];
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
+{
+ COM_TRY_BEGIN
+ wchar_t temp[32];
+ ConvertUInt64ToString(index + 1, temp);
+ UString res = temp;
+ while (res.Length() < 2)
+ res = UString(L'0') + res;
+ UString fileName = VolName;
+ fileName += L'.';
+ fileName += res;
+ fileName += VolExt;
+ COutFileStream *streamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
+ if(!streamSpec->Create(fileName, false))
+ return ::GetLastError();
+ *volumeStream = streamLoc.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+ COM_TRY_BEGIN
+ return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
+ COM_TRY_END
+}
Added: trunk/lzma/CPP/7zip/UI/Common/UpdateCallback.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/UpdateCallback.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/UpdateCallback.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,82 @@
+// UpdateCallback.h
+
+#ifndef __UPDATECALLBACK_H
+#define __UPDATECALLBACK_H
+
+#include "Common/MyCom.h"
+#include "Common/MyString.h"
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+
+#include "../Common/UpdatePair.h"
+#include "../Common/UpdateProduce.h"
+
+#define INTERFACE_IUpdateCallbackUI(x) \
+ virtual HRESULT SetTotal(UInt64 size) x; \
+ virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \
+ virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \
+ virtual HRESULT CheckBreak() x; \
+ virtual HRESULT Finilize() x; \
+ virtual HRESULT SetNumFiles(UInt64 numFiles) x; \
+ virtual HRESULT GetStream(const wchar_t *name, bool isAnti) x; \
+ virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) x; \
+ virtual HRESULT SetOperationResult(Int32 operationResult) x; \
+ virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \
+
+ // virtual HRESULT CloseProgress() { return S_OK; };
+
+struct IUpdateCallbackUI
+{
+ INTERFACE_IUpdateCallbackUI(=0)
+};
+
+class CArchiveUpdateCallback:
+ public IArchiveUpdateCallback2,
+ public ICryptoGetTextPassword2,
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP3(
+ IArchiveUpdateCallback2,
+ ICryptoGetTextPassword2,
+ ICompressProgressInfo)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+
+ // IUpdateCallback
+ STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index,
+ Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
+ STDMETHOD(SetOperationResult)(Int32 operationResult);
+
+ STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
+ STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
+
+ STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
+
+public:
+ CRecordVector<UInt64> VolumesSizes;
+ UString VolName;
+ UString VolExt;
+
+ IUpdateCallbackUI *Callback;
+
+ UString DirPrefix;
+ bool ShareForWrite;
+ bool StdInMode;
+ const CObjectVector<CDirItem> *DirItems;
+ const CObjectVector<CArchiveItem> *ArchiveItems;
+ const CObjectVector<CUpdatePair2> *UpdatePairs;
+ CMyComPtr<IInArchive> Archive;
+
+ CArchiveUpdateCallback();
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/UpdatePair.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/UpdatePair.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,166 @@
+// UpdatePair.cpp
+
+#include "StdAfx.h"
+
+#include <time.h>
+
+#include "Common/Defs.h"
+#include "Common/Wildcard.h"
+#include "Windows/Time.h"
+
+#include "UpdatePair.h"
+#include "SortUtils.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+static int MyCompareTime(NFileTimeType::EEnum fileTimeType,
+ const FILETIME &time1, const FILETIME &time2)
+{
+ switch(fileTimeType)
+ {
+ case NFileTimeType::kWindows:
+ return ::CompareFileTime(&time1, &time2);
+ case NFileTimeType::kUnix:
+ {
+ UInt32 unixTime1, unixTime2;
+ if (!FileTimeToUnixTime(time1, unixTime1))
+ {
+ unixTime1 = 0;
+ // throw 4191614;
+ }
+ if (!FileTimeToUnixTime(time2, unixTime2))
+ {
+ unixTime2 = 0;
+ // throw 4191615;
+ }
+ return MyCompare(unixTime1, unixTime2);
+ }
+ case NFileTimeType::kDOS:
+ {
+ UInt32 dosTime1, dosTime2;
+ FileTimeToDosTime(time1, dosTime1);
+ FileTimeToDosTime(time2, dosTime2);
+ /*
+ if (!FileTimeToDosTime(time1, dosTime1))
+ throw 4191616;
+ if (!FileTimeToDosTime(time2, dosTime2))
+ throw 4191617;
+ */
+ return MyCompare(dosTime1, dosTime2);
+ }
+ }
+ throw 4191618;
+}
+
+static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
+
+/*
+static const char *kNotCensoredCollisionMessaged = "Internal file name collision:\n";
+static const char *kSameTimeChangedSizeCollisionMessaged =
+ "Collision between files with same date/time and different sizes:\n";
+*/
+
+static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
+{
+ for(int i = 0; i + 1 < indices.Size(); i++)
+ if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)
+ {
+ UString message = kDuplicateFileNameMessage;
+ message += L"\n";
+ message += strings[indices[i]];
+ message += L"\n";
+ message += strings[indices[i + 1]];
+ throw message;
+ }
+}
+
+void GetUpdatePairInfoList(
+ const CObjectVector<CDirItem> &dirItems,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ NFileTimeType::EEnum fileTimeType,
+ CObjectVector<CUpdatePair> &updatePairs)
+{
+ CIntVector dirIndices, archiveIndices;
+ UStringVector dirNames, archiveNames;
+
+ int numDirItems = dirItems.Size();
+ int i;
+ for(i = 0; i < numDirItems; i++)
+ dirNames.Add(dirItems[i].Name);
+ SortFileNames(dirNames, dirIndices);
+ TestDuplicateString(dirNames, dirIndices);
+
+ int numArchiveItems = archiveItems.Size();
+ for(i = 0; i < numArchiveItems; i++)
+ archiveNames.Add(archiveItems[i].Name);
+ SortFileNames(archiveNames, archiveIndices);
+ TestDuplicateString(archiveNames, archiveIndices);
+
+ int dirItemIndex = 0, archiveItemIndex = 0;
+ CUpdatePair pair;
+ while(dirItemIndex < numDirItems && archiveItemIndex < numArchiveItems)
+ {
+ int dirItemIndex2 = dirIndices[dirItemIndex],
+ archiveItemIndex2 = archiveIndices[archiveItemIndex];
+ const CDirItem &dirItem = dirItems[dirItemIndex2];
+ const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2];
+ int compareResult = CompareFileNames(dirItem.Name, archiveItem.Name);
+ if (compareResult < 0)
+ {
+ pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
+ pair.DirItemIndex = dirItemIndex2;
+ dirItemIndex++;
+ }
+ else if (compareResult > 0)
+ {
+ pair.State = archiveItem.Censored ?
+ NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked;
+ pair.ArchiveItemIndex = archiveItemIndex2;
+ archiveItemIndex++;
+ }
+ else
+ {
+ if (!archiveItem.Censored)
+ throw 1082022;; // TTString(kNotCensoredCollisionMessaged + dirItem.Name);
+ pair.DirItemIndex = dirItemIndex2;
+ pair.ArchiveItemIndex = archiveItemIndex2;
+ switch (MyCompareTime(fileTimeType, dirItem.LastWriteTime, archiveItem.LastWriteTime))
+ {
+ case -1:
+ pair.State = NUpdateArchive::NPairState::kNewInArchive;
+ break;
+ case 1:
+ pair.State = NUpdateArchive::NPairState::kOldInArchive;
+ break;
+ default:
+ if (archiveItem.SizeIsDefined)
+ if (dirItem.Size != archiveItem.Size)
+ // throw 1082034; // kSameTimeChangedSizeCollisionMessaged;
+ pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles;
+ else
+ pair.State = NUpdateArchive::NPairState::kSameFiles;
+ else
+ pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles;
+ }
+ dirItemIndex++;
+ archiveItemIndex++;
+ }
+ updatePairs.Add(pair);
+ }
+ for(;dirItemIndex < numDirItems; dirItemIndex++)
+ {
+ pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
+ pair.DirItemIndex = dirIndices[dirItemIndex];
+ updatePairs.Add(pair);
+ }
+ for(;archiveItemIndex < numArchiveItems; archiveItemIndex++)
+ {
+ int archiveItemIndex2 = archiveIndices[archiveItemIndex];
+ const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2];
+ pair.State = archiveItem.Censored ?
+ NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked;
+ pair.ArchiveItemIndex = archiveItemIndex2;
+ updatePairs.Add(pair);
+ }
+}
Added: trunk/lzma/CPP/7zip/UI/Common/UpdatePair.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/UpdatePair.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/UpdatePair.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// UpdatePair.h
+
+#ifndef __UPDATE_PAIR_H
+#define __UPDATE_PAIR_H
+
+#include "DirItem.h"
+#include "UpdateAction.h"
+
+#include "../../Archive/IArchive.h"
+
+struct CUpdatePair
+{
+ NUpdateArchive::NPairState::EEnum State;
+ int ArchiveItemIndex;
+ int DirItemIndex;
+};
+
+void GetUpdatePairInfoList(
+ const CObjectVector<CDirItem> &dirItems,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ NFileTimeType::EEnum fileTimeType,
+ CObjectVector<CUpdatePair> &updatePairs);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,63 @@
+// UpdateProduce.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateProduce.h"
+
+using namespace NUpdateArchive;
+
+static const char *kUpdateActionSetCollision =
+ "Internal collision in update action set";
+
+void UpdateProduce(
+ const CObjectVector<CUpdatePair> &updatePairs,
+ const NUpdateArchive::CActionSet &actionSet,
+ CObjectVector<CUpdatePair2> &operationChain)
+{
+ for(int i = 0; i < updatePairs.Size(); i++)
+ {
+ // CUpdateArchiveRange aRange;
+ const CUpdatePair &pair = updatePairs[i];
+
+ CUpdatePair2 pair2;
+ pair2.IsAnti = false;
+ pair2.ArchiveItemIndex = pair.ArchiveItemIndex;
+ pair2.DirItemIndex = pair.DirItemIndex;
+ pair2.ExistInArchive = (pair.State != NPairState::kOnlyOnDisk);
+ pair2.ExistOnDisk = (pair.State != NPairState::kOnlyInArchive && pair.State != NPairState::kNotMasked);
+ switch(actionSet.StateActions[pair.State])
+ {
+ case NPairAction::kIgnore:
+ /*
+ if (pair.State != NPairState::kOnlyOnDisk)
+ IgnoreArchiveItem(m_ArchiveItems[pair.ArchiveItemIndex]);
+ // cout << "deleting";
+ */
+ break;
+ case NPairAction::kCopy:
+ {
+ if (pair.State == NPairState::kOnlyOnDisk)
+ throw kUpdateActionSetCollision;
+ pair2.NewData = pair2.NewProperties = false;
+ operationChain.Add(pair2);
+ break;
+ }
+ case NPairAction::kCompress:
+ {
+ if (pair.State == NPairState::kOnlyInArchive ||
+ pair.State == NPairState::kNotMasked)
+ throw kUpdateActionSetCollision;
+ pair2.NewData = pair2.NewProperties = true;
+ operationChain.Add(pair2);
+ break;
+ }
+ case NPairAction::kCompressAsAnti:
+ {
+ pair2.IsAnti = true;
+ pair2.NewData = pair2.NewProperties = true;
+ operationChain.Add(pair2);
+ break;
+ }
+ }
+ }
+}
Added: trunk/lzma/CPP/7zip/UI/Common/UpdateProduce.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/UpdateProduce.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/UpdateProduce.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,31 @@
+// UpdateProduce.h
+
+#ifndef __UPDATE_PRODUCE_H
+#define __UPDATE_PRODUCE_H
+
+#include "UpdatePair.h"
+
+struct CUpdatePair2
+{
+ // bool OperationIsCompress;
+ bool NewData;
+ bool NewProperties;
+
+ bool ExistInArchive;
+ bool ExistOnDisk;
+ bool IsAnti;
+ int ArchiveItemIndex;
+ int DirItemIndex;
+
+ bool NewNameIsDefined;
+ UString NewName;
+
+ CUpdatePair2(): NewNameIsDefined(false) {}
+};
+
+void UpdateProduce(
+ const CObjectVector<CUpdatePair> &updatePairs,
+ const NUpdateArchive::CActionSet &actionSet,
+ CObjectVector<CUpdatePair2> &operationChain);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/WorkDir.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/WorkDir.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/WorkDir.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,64 @@
+// WorkDir.cpp
+
+#include "StdAfx.h"
+
+#include "WorkDir.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path)
+{
+ NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
+ if (workDirInfo.ForRemovableOnly)
+ {
+ mode = NWorkDir::NMode::kCurrent;
+ UString prefix = path.Left(3);
+ if (prefix[1] == L':' && prefix[2] == L'\\')
+ {
+ UINT driveType = GetDriveType(GetSystemString(prefix, GetCurrentCodePage()));
+ if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE)
+ mode = workDirInfo.Mode;
+ }
+ /*
+ CParsedPath parsedPath;
+ parsedPath.ParsePath(archiveName);
+ UINT driveType = GetDriveType(parsedPath.Prefix);
+ if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE))
+ mode = NZipSettings::NWorkDir::NMode::kCurrent;
+ */
+ }
+ switch(mode)
+ {
+ case NWorkDir::NMode::kCurrent:
+ {
+ return ExtractDirPrefixFromPath(path);
+ }
+ case NWorkDir::NMode::kSpecified:
+ {
+ UString tempDir = workDirInfo.Path;
+ NormalizeDirPathPrefix(tempDir);
+ return tempDir;
+ }
+ default:
+ {
+ UString tempDir;
+ if(!NFile::NDirectory::MyGetTempPath(tempDir))
+ throw 141717;
+ return tempDir;
+ }
+ }
+}
+
+
+
Added: trunk/lzma/CPP/7zip/UI/Common/WorkDir.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/WorkDir.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/WorkDir.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// WorkDir.h
+
+#ifndef __WORKDIR_H
+#define __WORKDIR_H
+
+#include "ZipRegistry.h"
+
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Common/ZipRegistry.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Common/ZipRegistry.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Common/ZipRegistry.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,98 @@
+// ZipRegistry.h
+
+#ifndef __ZIPREGISTRY_H
+#define __ZIPREGISTRY_H
+
+#include "Common/MyString.h"
+#include "Common/Types.h"
+#include "ExtractMode.h"
+
+namespace NExtract
+{
+ struct CInfo
+ {
+ NPathMode::EEnum PathMode;
+ NOverwriteMode::EEnum OverwriteMode;
+ UStringVector Paths;
+ bool ShowPassword;
+ };
+}
+
+namespace NCompression {
+
+ struct CFormatOptions
+ {
+ CSysString FormatID;
+ UString Options;
+ UString Method;
+ UString EncryptionMethod;
+ UInt32 Level;
+ UInt32 Dictionary;
+ UInt32 Order;
+ UInt32 BlockLogSize;
+ UInt32 NumThreads;
+ void ResetForLevelChange()
+ {
+ BlockLogSize = NumThreads = Level = Dictionary = Order = UInt32(-1);
+ Method.Empty();
+ // EncryptionMethod.Empty();
+ // Options.Empty();
+ }
+ CFormatOptions() { ResetForLevelChange(); }
+ };
+
+ struct CInfo
+ {
+ UStringVector HistoryArchives;
+ UInt32 Level;
+ UString ArchiveType;
+
+ CObjectVector<CFormatOptions> FormatOptionsVector;
+
+ bool ShowPassword;
+ bool EncryptHeaders;
+ };
+}
+
+namespace NWorkDir{
+
+ namespace NMode
+ {
+ enum EEnum
+ {
+ kSystem,
+ kCurrent,
+ kSpecified
+ };
+ }
+ struct CInfo
+ {
+ NMode::EEnum Mode;
+ UString Path;
+ bool ForRemovableOnly;
+ void SetForRemovableOnlyDefault() { ForRemovableOnly = true; }
+ void SetDefault()
+ {
+ Mode = NMode::kSystem;
+ Path.Empty();
+ SetForRemovableOnlyDefault();
+ }
+ };
+}
+
+void SaveExtractionInfo(const NExtract::CInfo &info);
+void ReadExtractionInfo(NExtract::CInfo &info);
+
+void SaveCompressionInfo(const NCompression::CInfo &info);
+void ReadCompressionInfo(NCompression::CInfo &info);
+
+void SaveWorkDirInfo(const NWorkDir::CInfo &info);
+void ReadWorkDirInfo(NWorkDir::CInfo &info);
+
+void SaveCascadedMenu(bool enabled);
+bool ReadCascadedMenu();
+
+void SaveContextMenuStatus(UInt32 value);
+bool ReadContextMenuStatus(UInt32 &value);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,63 @@
+// ConsoleClose.cpp
+
+#include "StdAfx.h"
+
+#include "ConsoleClose.h"
+
+static int g_BreakCounter = 0;
+static const int kBreakAbortThreshold = 2;
+
+namespace NConsoleClose {
+
+static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
+{
+ if (ctrlType == CTRL_LOGOFF_EVENT)
+ {
+ // printf("\nCTRL_LOGOFF_EVENT\n");
+ return TRUE;
+ }
+
+ g_BreakCounter++;
+ if (g_BreakCounter < kBreakAbortThreshold)
+ return TRUE;
+ return FALSE;
+ /*
+ switch(ctrlType)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ if (g_BreakCounter < kBreakAbortThreshold)
+ return TRUE;
+ }
+ return FALSE;
+ */
+}
+
+bool TestBreakSignal()
+{
+ /*
+ if (g_BreakCounter > 0)
+ return true;
+ */
+ return (g_BreakCounter > 0);
+}
+
+void CheckCtrlBreak()
+{
+ if (TestBreakSignal())
+ throw CCtrlBreakException();
+}
+
+CCtrlHandlerSetter::CCtrlHandlerSetter()
+{
+ if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
+ throw "SetConsoleCtrlHandler fails";
+}
+
+CCtrlHandlerSetter::~CCtrlHandlerSetter()
+{
+ if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
+ throw "SetConsoleCtrlHandler fails";
+}
+
+}
Added: trunk/lzma/CPP/7zip/UI/Console/ConsoleClose.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/ConsoleClose.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/ConsoleClose.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// ConsoleCloseUtils.h
+
+#ifndef __CONSOLECLOSEUTILS_H
+#define __CONSOLECLOSEUTILS_H
+
+namespace NConsoleClose {
+
+bool TestBreakSignal();
+
+class CCtrlHandlerSetter
+{
+public:
+ CCtrlHandlerSetter();
+ virtual ~CCtrlHandlerSetter();
+};
+
+class CCtrlBreakException
+{};
+
+void CheckCtrlBreak();
+
+}
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,235 @@
+// ExtractCallbackConsole.h
+
+#include "StdAfx.h"
+
+#include "ExtractCallbackConsole.h"
+#include "UserInputUtils.h"
+#include "ConsoleClose.h"
+
+#include "Common/Wildcard.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Time.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Error.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "../../Common/FilePathAutoRename.h"
+
+#include "../Common/ExtractingFilePath.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static const char *kTestingString = "Testing ";
+static const char *kExtractingString = "Extracting ";
+static const char *kSkippingString = "Skipping ";
+
+// static const char *kCantAutoRename = "can not create file with auto name\n";
+// static const char *kCantRenameFile = "can not rename existing file\n";
+// static const char *kCantDeleteOutputFile = "can not delete output file ";
+static const char *kError = "ERROR: ";
+static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
+
+static const char *kProcessing = "Processing archive: ";
+static const char *kEverythingIsOk = "Everything is Ok";
+static const char *kNoFiles = "No files to process";
+
+static const char *kUnsupportedMethod = "Unsupported Method";
+static const char *kCrcFailed = "CRC Failed";
+static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
+static const char *kDataError = "Data Error";
+static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
+static const char *kUnknownError = "Unknown Error";
+
+STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
+ const wchar_t *existName, const FILETIME *, const UInt64 *,
+ const wchar_t *newName, const FILETIME *, const UInt64 *,
+ Int32 *answer)
+{
+ (*OutStream) << "file " << existName <<
+ "\nalready exists. Overwrite with " << endl;
+ (*OutStream) << newName;
+
+ NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
+
+ switch(overwriteAnswer)
+ {
+ case NUserAnswerMode::kQuit:
+ return E_ABORT;
+ case NUserAnswerMode::kNo:
+ *answer = NOverwriteAnswer::kNo;
+ break;
+ case NUserAnswerMode::kNoAll:
+ *answer = NOverwriteAnswer::kNoToAll;
+ break;
+ case NUserAnswerMode::kYesAll:
+ *answer = NOverwriteAnswer::kYesToAll;
+ break;
+ case NUserAnswerMode::kYes:
+ *answer = NOverwriteAnswer::kYes;
+ break;
+ case NUserAnswerMode::kAutoRename:
+ *answer = NOverwriteAnswer::kAutoRename;
+ break;
+ default:
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position)
+{
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ (*OutStream) << kExtractingString;
+ break;
+ case NArchive::NExtract::NAskMode::kTest:
+ (*OutStream) << kTestingString;
+ break;
+ case NArchive::NExtract::NAskMode::kSkip:
+ (*OutStream) << kSkippingString;
+ break;
+ };
+ (*OutStream) << name;
+ if (position != 0)
+ (*OutStream) << " <" << *position << ">";
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
+{
+ (*OutStream) << message << endl;
+ NumFileErrorsInCurrentArchive++;
+ NumFileErrors++;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
+{
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+ default:
+ {
+ NumFileErrorsInCurrentArchive++;
+ NumFileErrors++;
+ (*OutStream) << " ";
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ (*OutStream) << kUnsupportedMethod;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed);
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError);
+ break;
+ default:
+ (*OutStream) << kUnknownError;
+ }
+ }
+ }
+ (*OutStream) << endl;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ Password = GetPassword(OutStream);
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
+{
+ NumArchives++;
+ NumFileErrorsInCurrentArchive = 0;
+ (*OutStream) << endl << kProcessing << name << endl;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)
+{
+ (*OutStream) << endl;
+ if (result != S_OK)
+ {
+ (*OutStream) << "Error: ";
+ if (encrypted)
+ (*OutStream) << "Can not open encrypted archive. Wrong password?";
+ else
+ (*OutStream) << "Can not open file as archive";
+ (*OutStream) << endl;
+ NumArchiveErrors++;
+ }
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::ThereAreNoFiles()
+{
+ (*OutStream) << endl << kNoFiles << endl;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
+{
+ if (result == S_OK)
+ {
+ (*OutStream) << endl;
+ if (NumFileErrorsInCurrentArchive == 0)
+ (*OutStream) << kEverythingIsOk << endl;
+ else
+ {
+ NumArchiveErrors++;
+ (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
+ }
+ }
+ if (result == S_OK)
+ return result;
+ NumArchiveErrors++;
+ if (result == E_ABORT || result == ERROR_DISK_FULL)
+ return result;
+ (*OutStream) << endl << kError;
+ if (result == E_OUTOFMEMORY)
+ (*OutStream) << kMemoryExceptionMessage;
+ else
+ {
+ UString message;
+ NError::MyFormatMessage(result, message);
+ (*OutStream) << message;
+ }
+ (*OutStream) << endl;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
+{
+ PasswordIsDefined = true;
+ Password = password;
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,65 @@
+// ExtractCallbackConsole.h
+
+#ifndef __EXTRACTCALLBACKCONSOLE_H
+#define __EXTRACTCALLBACKCONSOLE_H
+
+#include "Common/MyString.h"
+#include "Common/StdOutStream.h"
+#include "../../Common/FileStreams.h"
+#include "../../IPassword.h"
+#include "../../Archive/IArchive.h"
+#include "../Common/ArchiveExtractCallback.h"
+
+class CExtractCallbackConsole:
+ public IExtractCallbackUI,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(IFolderArchiveExtractCallback, ICryptoGetTextPassword)
+
+ STDMETHOD(SetTotal)(UInt64 total);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IFolderArchiveExtractCallback
+ STDMETHOD(AskOverwrite)(
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+ Int32 *answer);
+ STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position);
+
+ STDMETHOD(MessageError)(const wchar_t *message);
+ STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+ HRESULT BeforeOpen(const wchar_t *name);
+ HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
+ HRESULT ThereAreNoFiles();
+ HRESULT ExtractResult(HRESULT result);
+
+ HRESULT SetPassword(const UString &password);
+
+public:
+ bool PasswordIsDefined;
+ UString Password;
+
+ UInt64 NumArchives;
+ UInt64 NumArchiveErrors;
+ UInt64 NumFileErrors;
+ UInt64 NumFileErrorsInCurrentArchive;
+
+ CStdOutStream *OutStream;
+
+ void Init()
+ {
+ NumArchives = 0;
+ NumArchiveErrors = 0;
+ NumFileErrors = 0;
+ NumFileErrorsInCurrentArchive = 0;
+ }
+
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Console/List.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/List.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/List.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,579 @@
+// List.cpp
+
+#include "StdAfx.h"
+
+#include "List.h"
+#include "ConsoleClose.h"
+
+#include "Common/StringConvert.h"
+#include "Common/StdOutStream.h"
+#include "Common/IntToString.h"
+#include "Common/MyCom.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/FileDir.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "../Common/PropIDUtils.h"
+#include "../Common/OpenArchive.h"
+
+#include "OpenCallbackConsole.h"
+
+using namespace NWindows;
+
+struct CPropIdToName
+{
+ PROPID PropID;
+ const wchar_t *Name;
+};
+
+static CPropIdToName kPropIdToName[] =
+{
+ { kpidPath, L"Path" },
+ { kpidName, L"Name" },
+ { kpidIsFolder, L"Folder" },
+ { kpidSize, L"Size" },
+ { kpidPackedSize, L"Packed Size" },
+ { kpidAttributes, L"Attributes" },
+ { kpidCreationTime, L"Created" },
+ { kpidLastAccessTime, L"Accessed" },
+ { kpidLastWriteTime, L"Modified" },
+ { kpidSolid, L"Solid" },
+ { kpidCommented, L"Commented" },
+ { kpidEncrypted, L"Encrypted" },
+ { kpidSplitBefore, L"Split Before" },
+ { kpidSplitAfter, L"Split After" },
+ { kpidDictionarySize, L"Dictionary Size" },
+ { kpidCRC, L"CRC" },
+ { kpidType, L"Type" },
+ { kpidIsAnti, L"Anti" },
+ { kpidMethod, L"Method" },
+ { kpidHostOS, L"Host OS" },
+ { kpidFileSystem, L"File System" },
+ { kpidUser, L"User" },
+ { kpidGroup, L"Group" },
+ { kpidBlock, L"Block" },
+ { kpidComment, L"Comment" },
+ { kpidPosition, L"Position" },
+ { kpidPrefix, L"Prefix" },
+ { kpidNumSubFolders, L"Folders" },
+ { kpidNumSubFiles, L"Files" },
+ { kpidUnpackVer, L"Version" },
+ { kpidVolume, L"Volume" },
+ { kpidIsVolume, L"Multivolume" },
+ { kpidOffset, L"Offset" },
+ { kpidLinks, L"Links" },
+ { kpidNumBlocks, L"Blocks" },
+ { kpidNumVolumes, L"Volumes" }
+};
+
+static const char kEmptyAttributeChar = '.';
+static const char kDirectoryAttributeChar = 'D';
+static const char kReadonlyAttributeChar = 'R';
+static const char kHiddenAttributeChar = 'H';
+static const char kSystemAttributeChar = 'S';
+static const char kArchiveAttributeChar = 'A';
+
+static const char *kListing = "Listing archive: ";
+static const wchar_t *kFilesMessage = L"files";
+static const wchar_t *kDirsMessage = L"folders";
+
+static void GetAttributesString(DWORD wa, bool directory, char *s)
+{
+ s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ?
+ kDirectoryAttributeChar: kEmptyAttributeChar;
+ s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)?
+ kReadonlyAttributeChar: kEmptyAttributeChar;
+ s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ?
+ kHiddenAttributeChar: kEmptyAttributeChar;
+ s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ?
+ kSystemAttributeChar: kEmptyAttributeChar;
+ s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ?
+ kArchiveAttributeChar: kEmptyAttributeChar;
+ s[5] = '\0';
+}
+
+enum EAdjustment
+{
+ kLeft,
+ kCenter,
+ kRight
+};
+
+struct CFieldInfo
+{
+ PROPID PropID;
+ UString Name;
+ EAdjustment TitleAdjustment;
+ EAdjustment TextAdjustment;
+ int PrefixSpacesWidth;
+ int Width;
+};
+
+struct CFieldInfoInit
+{
+ PROPID PropID;
+ const wchar_t *Name;
+ EAdjustment TitleAdjustment;
+ EAdjustment TextAdjustment;
+ int PrefixSpacesWidth;
+ int Width;
+};
+
+CFieldInfoInit kStandardFieldTable[] =
+{
+ { kpidLastWriteTime, L" Date Time", kLeft, kLeft, 0, 19 },
+ { kpidAttributes, L"Attr", kRight, kCenter, 1, 5 },
+ { kpidSize, L"Size", kRight, kRight, 1, 12 },
+ { kpidPackedSize, L"Compressed", kRight, kRight, 1, 12 },
+ { kpidPath, L"Name", kLeft, kLeft, 2, 24 }
+};
+
+void PrintSpaces(int numSpaces)
+{
+ for (int i = 0; i < numSpaces; i++)
+ g_StdOut << ' ';
+}
+
+void PrintString(EAdjustment adjustment, int width, const UString &textString)
+{
+ const int numSpaces = width - textString.Length();
+ int numLeftSpaces = 0;
+ switch (adjustment)
+ {
+ case kLeft:
+ numLeftSpaces = 0;
+ break;
+ case kCenter:
+ numLeftSpaces = numSpaces / 2;
+ break;
+ case kRight:
+ numLeftSpaces = numSpaces;
+ break;
+ }
+ PrintSpaces(numLeftSpaces);
+ g_StdOut << textString;
+ PrintSpaces(numSpaces - numLeftSpaces);
+}
+
+class CFieldPrinter
+{
+ CObjectVector<CFieldInfo> _fields;
+public:
+ void Clear() { _fields.Clear(); }
+ void Init(const CFieldInfoInit *standardFieldTable, int numItems);
+ HRESULT Init(IInArchive *archive);
+ void PrintTitle();
+ void PrintTitleLines();
+ HRESULT PrintItemInfo(IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ UInt32 index,
+ bool techMode);
+ HRESULT PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,
+ const UInt64 *size, const UInt64 *compressedSize);
+};
+
+void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
+{
+ Clear();
+ for (int i = 0; i < numItems; i++)
+ {
+ CFieldInfo fieldInfo;
+ const CFieldInfoInit &fieldInfoInit = standardFieldTable[i];
+ fieldInfo.PropID = fieldInfoInit.PropID;
+ fieldInfo.Name = fieldInfoInit.Name;
+ fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment;
+ fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment;
+ fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth;
+ fieldInfo.Width = fieldInfoInit.Width;
+ _fields.Add(fieldInfo);
+ }
+}
+
+static UString GetPropName(PROPID propID, BSTR name)
+{
+ for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)
+ {
+ const CPropIdToName &propIdToName = kPropIdToName[i];
+ if (propIdToName.PropID == propID)
+ return propIdToName.Name;
+ }
+ if (name)
+ return name;
+ return L"?";
+}
+
+HRESULT CFieldPrinter::Init(IInArchive *archive)
+{
+ Clear();
+ UInt32 numProps;
+ RINOK(archive->GetNumberOfProperties(&numProps));
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ CMyComBSTR name;
+ PROPID propID;
+ VARTYPE vt;
+ RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));
+ CFieldInfo fieldInfo;
+ fieldInfo.PropID = propID;
+ fieldInfo.Name = GetPropName(propID, name);
+ _fields.Add(fieldInfo);
+ }
+ return S_OK;
+}
+
+void CFieldPrinter::PrintTitle()
+{
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+ PrintString(fieldInfo.TitleAdjustment,
+ ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);
+ }
+}
+
+void CFieldPrinter::PrintTitleLines()
+{
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+ for (int i = 0; i < fieldInfo.Width; i++)
+ g_StdOut << '-';
+ }
+}
+
+
+BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)
+{
+ return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
+}
+
+static const char *kEmptyTimeString = " ";
+void PrintTime(const NCOM::CPropVariant &propVariant)
+{
+ if (propVariant.vt != VT_FILETIME)
+ throw "incorrect item";
+ if (IsFileTimeZero(&propVariant.filetime))
+ g_StdOut << kEmptyTimeString;
+ else
+ {
+ FILETIME localFileTime;
+ if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
+ throw "FileTimeToLocalFileTime error";
+ char s[32];
+ if (ConvertFileTimeToString(localFileTime, s, true, true))
+ g_StdOut << s;
+ else
+ g_StdOut << kEmptyTimeString;
+ }
+}
+
+HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ UInt32 index,
+ bool techMode)
+{
+ /*
+ if (techMode)
+ {
+ g_StdOut << "Index = ";
+ g_StdOut << (UInt64)index;
+ g_StdOut << endl;
+ }
+ */
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ if (!techMode)
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+
+ NCOM::CPropVariant propVariant;
+ RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant));
+ if (techMode)
+ {
+ g_StdOut << fieldInfo.Name << " = ";
+ }
+ int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;
+ if (propVariant.vt == VT_EMPTY)
+ {
+ switch(fieldInfo.PropID)
+ {
+ case kpidPath:
+ propVariant = defaultItemName;
+ break;
+ case kpidLastWriteTime:
+ propVariant = archiveFileInfo.LastWriteTime;
+ break;
+ default:
+ if (techMode)
+ g_StdOut << endl;
+ else
+ PrintSpaces(width);
+ continue;
+ }
+ }
+ if (fieldInfo.PropID == kpidLastWriteTime)
+ {
+ PrintTime(propVariant);
+ }
+ else if (fieldInfo.PropID == kpidAttributes)
+ {
+ if (propVariant.vt != VT_UI4)
+ throw "incorrect item";
+ UInt32 attributes = propVariant.ulVal;
+ bool isFolder;
+ RINOK(IsArchiveItemFolder(archive, index, isFolder));
+ char s[8];
+ GetAttributesString(attributes, isFolder, s);
+ g_StdOut << s;
+ }
+ else if (propVariant.vt == VT_BSTR)
+ {
+ if (techMode)
+ g_StdOut << propVariant.bstrVal;
+ else
+ PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal);
+ }
+ else
+ {
+ UString s = ConvertPropertyToString(propVariant, fieldInfo.PropID);
+ s.Replace(wchar_t(0xA), L' ');
+ s.Replace(wchar_t(0xD), L' ');
+
+ if (techMode)
+ g_StdOut << s;
+ else
+ PrintString(fieldInfo.TextAdjustment, width, s);
+ }
+ if (techMode)
+ g_StdOut << endl;
+ }
+ return S_OK;
+}
+
+void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value)
+{
+ wchar_t textString[32] = { 0 };
+ if (value != NULL)
+ ConvertUInt64ToString(*value, textString);
+ PrintString(adjustment, width, textString);
+}
+
+
+HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,
+ const UInt64 *size, const UInt64 *compressedSize)
+{
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+ NCOM::CPropVariant propVariant;
+ if (fieldInfo.PropID == kpidSize)
+ PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size);
+ else if (fieldInfo.PropID == kpidPackedSize)
+ PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize);
+ else if (fieldInfo.PropID == kpidPath)
+ {
+ wchar_t textString[32];
+ ConvertUInt64ToString(numFiles, textString);
+ UString temp = textString;
+ temp += L" ";
+ temp += kFilesMessage;
+ temp += L", ";
+ ConvertUInt64ToString(numDirs, textString);
+ temp += textString;
+ temp += L" ";
+ temp += kDirsMessage;
+ PrintString(fieldInfo.TextAdjustment, 0, temp);
+ }
+ else
+ PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");
+ }
+ return S_OK;
+}
+
+bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value)
+{
+ NCOM::CPropVariant propVariant;
+ if (archive->GetProperty(index, propID, &propVariant) != S_OK)
+ throw "GetPropertyValue error";
+ if (propVariant.vt == VT_EMPTY)
+ return false;
+ value = ConvertPropVariantToUInt64(propVariant);
+ return true;
+}
+
+HRESULT ListArchives(
+ CCodecs *codecs,
+ UStringVector &archivePaths, UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &numErrors)
+{
+ numErrors = 0;
+ CFieldPrinter fieldPrinter;
+ if (!techMode)
+ fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));
+
+ UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
+ UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
+ for (int i = 0; i < archivePaths.Size(); i++)
+ {
+ const UString &archiveName = archivePaths[i];
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
+ {
+ g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl;
+ numErrors++;
+ continue;
+ }
+ if (archiveFileInfo.IsDirectory())
+ {
+ g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
+ numErrors++;
+ continue;
+ }
+
+ CArchiveLink archiveLink;
+
+ COpenCallbackConsole openCallback;
+ openCallback.OutStream = &g_StdOut;
+ openCallback.PasswordIsDefined = passwordEnabled;
+ openCallback.Password = password;
+
+ HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, &openCallback);
+ if (result != S_OK)
+ {
+ g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl;
+ numErrors++;
+ continue;
+ }
+
+ for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
+ {
+ int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
+ if (index >= 0 && index > i)
+ {
+ archivePaths.Delete(index);
+ archivePathsFull.Delete(index);
+ }
+ }
+
+ IInArchive *archive = archiveLink.GetArchive();
+ const UString defaultItemName = archiveLink.GetDefaultItemName();
+
+ if (enableHeaders)
+ {
+ g_StdOut << endl << kListing << archiveName << endl << endl;
+
+ UInt32 numProps;
+ if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
+ {
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ CMyComBSTR name;
+ PROPID propID;
+ VARTYPE vt;
+ if (archive->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK)
+ continue;
+ NCOM::CPropVariant prop;
+ if (archive->GetArchiveProperty(propID, &prop) != S_OK)
+ continue;
+ UString s = ConvertPropertyToString(prop, propID);
+ if (!s.IsEmpty())
+ g_StdOut << GetPropName(propID, name) << " = " << s << endl;
+ }
+ }
+ if (techMode)
+ g_StdOut << "----------\n";
+ if (numProps > 0)
+ g_StdOut << endl;
+ }
+
+ if (enableHeaders && !techMode)
+ {
+ fieldPrinter.PrintTitle();
+ g_StdOut << endl;
+ fieldPrinter.PrintTitleLines();
+ g_StdOut << endl;
+ }
+
+ if (techMode)
+ {
+ RINOK(fieldPrinter.Init(archive));
+ }
+ UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
+ UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+
+ UString filePath;
+ RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath));
+
+ bool isFolder;
+ RINOK(IsArchiveItemFolder(archive, i, isFolder));
+ if (!wildcardCensor.CheckPath(filePath, !isFolder))
+ continue;
+
+ fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode);
+
+ UInt64 packSize, unpackSize;
+ if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
+ unpackSize = 0;
+ else
+ totalUnPackSizePointer = &totalUnPackSize;
+ if (!GetUInt64Value(archive, i, kpidPackedSize, packSize))
+ packSize = 0;
+ else
+ totalPackSizePointer = &totalPackSize;
+
+ g_StdOut << endl;
+
+ if (isFolder)
+ numDirs++;
+ else
+ numFiles++;
+ totalPackSize += packSize;
+ totalUnPackSize += unpackSize;
+ }
+ if (enableHeaders && !techMode)
+ {
+ fieldPrinter.PrintTitleLines();
+ g_StdOut << endl;
+ fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
+ g_StdOut << endl;
+ }
+ if (totalPackSizePointer != 0)
+ {
+ totalPackSizePointer2 = &totalPackSize2;
+ totalPackSize2 += totalPackSize;
+ }
+ if (totalUnPackSizePointer != 0)
+ {
+ totalUnPackSizePointer2 = &totalUnPackSize2;
+ totalUnPackSize2 += totalUnPackSize;
+ }
+ numFiles2 += numFiles;
+ numDirs2 += numDirs;
+ }
+ if (enableHeaders && !techMode && archivePaths.Size() > 1)
+ {
+ g_StdOut << endl;
+ fieldPrinter.PrintTitleLines();
+ g_StdOut << endl;
+ fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
+ g_StdOut << endl;
+ g_StdOut << "Archives: " << archivePaths.Size() << endl;
+ }
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/UI/Console/List.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/List.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/List.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,16 @@
+// List.h
+
+#ifndef __LIST_H
+#define __LIST_H
+
+#include "Common/Wildcard.h"
+#include "../Common/LoadCodecs.h"
+
+HRESULT ListArchives(
+ CCodecs *codecs,
+ UStringVector &archivePaths, UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &errors);
+
+#endif
+
Added: trunk/lzma/CPP/7zip/UI/Console/Main.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/Main.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/Main.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,563 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+
+#include "Common/CommandLineParser.h"
+#include "Common/MyException.h"
+#include "Common/IntToString.h"
+#include "Common/StdOutStream.h"
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/Defs.h"
+#include "Windows/Error.h"
+#ifdef _WIN32
+#include "Windows/MemoryLock.h"
+#endif
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+#include "../Common/UpdateAction.h"
+#include "../Common/Update.h"
+#include "../Common/Extract.h"
+#include "../Common/ArchiveCommandLine.h"
+#include "../Common/ExitCode.h"
+#ifdef EXTERNAL_CODECS
+#include "../Common/LoadCodecs.h"
+#endif
+
+#include "../../Compress/LZMA_Alone/LzmaBenchCon.h"
+
+#include "List.h"
+#include "OpenCallbackConsole.h"
+#include "ExtractCallbackConsole.h"
+#include "UpdateCallbackConsole.h"
+
+#include "../../MyVersion.h"
+
+#if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES)
+extern "C"
+{
+#include "../../../../C/Alloc.h"
+}
+#endif
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NCommandLineParser;
+
+HINSTANCE g_hInstance = 0;
+extern CStdOutStream *g_StdStream;
+
+static const char *kCopyrightString = "\n7-Zip"
+#ifndef EXTERNAL_CODECS
+" (A)"
+#endif
+
+#ifdef _WIN64
+" [64]"
+#endif
+
+" " MY_VERSION_COPYRIGHT_DATE "\n";
+
+static const char *kHelpString =
+ "\nUsage: 7z"
+#ifdef _NO_CRYPTO
+ "r"
+#else
+#ifndef EXTERNAL_CODECS
+ "a"
+#endif
+#endif
+ " <command> [<switches>...] <archive_name> [<file_names>...]\n"
+ " [<@listfiles...>]\n"
+ "\n"
+ "<Commands>\n"
+ " a: Add files to archive\n"
+ " b: Benchmark\n"
+ " d: Delete files from archive\n"
+ " e: Extract files from archive (without using directory names)\n"
+ " l: List contents of archive\n"
+// " l[a|t][f]: List contents of archive\n"
+// " a - with Additional fields\n"
+// " t - with all fields\n"
+// " f - with Full pathnames\n"
+ " t: Test integrity of archive\n"
+ " u: Update files to archive\n"
+ " x: eXtract files with full paths\n"
+ "<Switches>\n"
+ " -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n"
+ " -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n"
+ " -bd: Disable percentage indicator\n"
+ " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n"
+ " -m{Parameters}: set compression Method\n"
+ " -o{Directory}: set Output directory\n"
+ " -p{Password}: set Password\n"
+ " -r[-|0]: Recurse subdirectories\n"
+ " -scs{UTF-8 | WIN | DOS}: set charset for list files\n"
+ " -sfx[{name}]: Create SFX archive\n"
+ " -si[{name}]: read data from stdin\n"
+ " -slt: show technical information for l (List) command\n"
+ " -so: write data to stdout\n"
+ " -ssc[-]: set sensitive case mode\n"
+ " -ssw: compress shared files\n"
+ " -t{Type}: Set type of archive\n"
+ " -v{Size}[b|k|m|g]: Create volumes\n"
+ " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n"
+ " -w[{path}]: assign Work directory. Empty path means a temporary directory\n"
+ " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n"
+ " -y: assume Yes on all queries\n";
+
+// ---------------------------
+// exception messages
+
+static const char *kEverythingIsOk = "Everything is Ok";
+static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
+
+static const wchar_t *kDefaultSfxModule = L"7zCon.sfx";
+
+static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
+{
+ s << message << endl;
+ throw code;
+}
+
+static void PrintHelpAndExit(CStdOutStream &s) // yyy
+{
+ s << kHelpString;
+ ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError);
+}
+
+#ifndef _WIN32
+static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts)
+{
+ parts.Clear();
+ for(int i = 0; i < numArguments; i++)
+ {
+ UString s = MultiByteToUnicodeString(arguments[i]);
+ parts.Add(s);
+ }
+}
+#endif
+
+static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)
+{
+ s << kCopyrightString;
+ // s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\n";
+ if (needHelp)
+ s << kHelpString;
+}
+
+#ifdef EXTERNAL_CODECS
+static void PrintString(CStdOutStream &stdStream, const AString &s, int size)
+{
+ int len = s.Length();
+ stdStream << s;
+ for (int i = len; i < size; i++)
+ stdStream << ' ';
+}
+#endif
+
+static void PrintString(CStdOutStream &stdStream, const UString &s, int size)
+{
+ int len = s.Length();
+ stdStream << s;
+ for (int i = len; i < size; i++)
+ stdStream << ' ';
+}
+
+static inline char GetHex(Byte value)
+{
+ return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+int Main2(
+ #ifndef _WIN32
+ int numArguments, const char *arguments[]
+ #endif
+)
+{
+ #ifdef _WIN32
+ SetFileApisToOEM();
+ #endif
+
+ UStringVector commandStrings;
+ #ifdef _WIN32
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+ #else
+ GetArguments(numArguments, arguments, commandStrings);
+ #endif
+
+ if(commandStrings.Size() == 1)
+ {
+ ShowCopyrightAndHelp(g_StdOut, true);
+ return 0;
+ }
+ commandStrings.Delete(0);
+
+ CArchiveCommandLineOptions options;
+
+ CArchiveCommandLineParser parser;
+
+ parser.Parse1(commandStrings, options);
+
+ if(options.HelpMode)
+ {
+ ShowCopyrightAndHelp(g_StdOut, true);
+ return 0;
+ }
+
+ #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+ if (options.LargePages)
+ {
+ SetLargePageSize();
+ NSecurity::EnableLockMemoryPrivilege();
+ }
+ #endif
+
+ CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;
+ g_StdStream = &stdStream;
+
+ if (options.EnableHeaders)
+ ShowCopyrightAndHelp(stdStream, false);
+
+ parser.Parse2(options);
+
+ CCodecs *codecs = new CCodecs;
+ CMyComPtr<
+ #ifdef EXTERNAL_CODECS
+ ICompressCodecsInfo
+ #else
+ IUnknown
+ #endif
+ > compressCodecsInfo = codecs;
+ HRESULT result = codecs->Load();
+ if (result != S_OK)
+ throw CSystemException(result);
+
+ bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
+ if (options.Command.CommandType == NCommandType::kInfo)
+ {
+ stdStream << endl << "Formats:" << endl;
+ int i;
+ for (i = 0; i < codecs->Formats.Size(); i++)
+ {
+ const CArcInfoEx &arc = codecs->Formats[i];
+ #ifdef EXTERNAL_CODECS
+ if (arc.LibIndex >= 0)
+ {
+ char s[32];
+ ConvertUInt64ToString(arc.LibIndex, s);
+ PrintString(stdStream, s, 2);
+ }
+ else
+ #endif
+ stdStream << " ";
+ stdStream << ' ';
+ stdStream << (char)(arc.UpdateEnabled ? 'C' : ' ');
+ stdStream << (char)(arc.KeepName ? 'K' : ' ');
+ stdStream << " ";
+ PrintString(stdStream, arc.Name, 6);
+ stdStream << " ";
+ UString s;
+ for (int t = 0; t < arc.Exts.Size(); t++)
+ {
+ const CArcExtInfo &ext = arc.Exts[t];
+ s += ext.Ext;
+ if (!ext.AddExt.IsEmpty())
+ {
+ s += L" (";
+ s += ext.AddExt;
+ s += L')';
+ }
+ s += L' ';
+ }
+ PrintString(stdStream, s, 14);
+ stdStream << " ";
+ const CByteBuffer &sig = arc.StartSignature;
+ for (size_t j = 0; j < sig.GetCapacity(); j++)
+ {
+ Byte b = sig[j];
+ if (b > 0x20 && b < 0x80)
+ {
+ stdStream << (char)b;
+ }
+ else
+ {
+ stdStream << GetHex((Byte)((b >> 4) & 0xF));
+ stdStream << GetHex((Byte)(b & 0xF));
+ }
+ stdStream << ' ';
+ }
+ stdStream << endl;
+ }
+ stdStream << endl << "Codecs:" << endl;
+
+ #ifdef EXTERNAL_CODECS
+ UINT32 numMethods;
+ if (codecs->GetNumberOfMethods(&numMethods) == S_OK)
+ for (UInt32 j = 0; j < numMethods; j++)
+ {
+ int libIndex = codecs->GetCodecLibIndex(j);
+ if (libIndex >= 0)
+ {
+ char s[32];
+ ConvertUInt64ToString(libIndex, s);
+ PrintString(stdStream, s, 2);
+ }
+ else
+ stdStream << " ";
+ stdStream << ' ';
+ stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' ');
+ UInt64 id;
+ stdStream << " ";
+ HRESULT res = codecs->GetCodecId(j, id);
+ if (res != S_OK)
+ id = (UInt64)(Int64)-1;
+ char s[32];
+ ConvertUInt64ToString(id, s, 16);
+ PrintString(stdStream, s, 8);
+ stdStream << " ";
+ PrintString(stdStream, codecs->GetCodecName(j), 11);
+ stdStream << endl;
+ /*
+ if (res != S_OK)
+ throw "incorrect Codec ID";
+ */
+ }
+ #endif
+ return S_OK;
+ }
+ else if (options.Command.CommandType == NCommandType::kBenchmark)
+ {
+ if (options.Method.CompareNoCase(L"CRC") == 0)
+ {
+ HRESULT res = CrcBenchCon((FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
+ if (res != S_OK)
+ {
+ if (res == S_FALSE)
+ {
+ stdStream << "\nCRC Error\n";
+ return NExitCode::kFatalError;
+ }
+ throw CSystemException(res);
+ }
+ }
+ else
+ {
+ HRESULT res = LzmaBenchCon(
+ #ifdef EXTERNAL_LZMA
+ codecs,
+ #endif
+ (FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
+ if (res != S_OK)
+ {
+ if (res == S_FALSE)
+ {
+ stdStream << "\nDecoding Error\n";
+ return NExitCode::kFatalError;
+ }
+ throw CSystemException(res);
+ }
+ }
+ }
+ else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
+ {
+ if(isExtractGroupCommand)
+ {
+ CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+
+ ecs->OutStream = &stdStream;
+ ecs->PasswordIsDefined = options.PasswordEnabled;
+ ecs->Password = options.Password;
+ ecs->Init();
+
+ COpenCallbackConsole openCallback;
+ openCallback.OutStream = &stdStream;
+ openCallback.PasswordIsDefined = options.PasswordEnabled;
+ openCallback.Password = options.Password;
+
+ CExtractOptions eo;
+ eo.StdOutMode = options.StdOutMode;
+ eo.PathMode = options.Command.GetPathMode();
+ eo.TestMode = options.Command.IsTestMode();
+ eo.OverwriteMode = options.OverwriteMode;
+ eo.OutputDir = options.OutputDir;
+ eo.YesToAll = options.YesToAll;
+ #ifdef COMPRESS_MT
+ eo.Properties = options.ExtractProperties;
+ #endif
+ UString errorMessage;
+ CDecompressStat stat;
+ HRESULT result = DecompressArchives(
+ codecs,
+ options.ArchivePathsSorted,
+ options.ArchivePathsFullSorted,
+ options.WildcardCensor.Pairs.Front().Head,
+ eo, &openCallback, ecs, errorMessage, stat);
+ if (!errorMessage.IsEmpty())
+ {
+ stdStream << endl << "Error: " << errorMessage;
+ if (result == S_OK)
+ result = E_FAIL;
+ }
+
+ stdStream << endl;
+ if (ecs->NumArchives > 1)
+ stdStream << "Archives: " << ecs->NumArchives << endl;
+ if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
+ {
+ if (ecs->NumArchives > 1)
+ {
+ stdStream << endl;
+ if (ecs->NumArchiveErrors != 0)
+ stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl;
+ if (ecs->NumFileErrors != 0)
+ stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl;
+ }
+ if (result != S_OK)
+ throw CSystemException(result);
+ return NExitCode::kFatalError;
+ }
+ if (result != S_OK)
+ throw CSystemException(result);
+ if (stat.NumFolders != 0)
+ stdStream << "Folders: " << stat.NumFolders << endl;
+ if (stat.NumFiles != 1 || stat.NumFolders != 0)
+ stdStream << "Files: " << stat.NumFiles << endl;
+ stdStream
+ << "Size: " << stat.UnpackSize << endl
+ << "Compressed: " << stat.PackSize << endl;
+ }
+ else
+ {
+ UInt64 numErrors = 0;
+ HRESULT result = ListArchives(
+ codecs,
+ options.ArchivePathsSorted,
+ options.ArchivePathsFullSorted,
+ options.WildcardCensor.Pairs.Front().Head,
+ options.EnableHeaders,
+ options.TechMode,
+ options.PasswordEnabled,
+ options.Password, numErrors);
+ if (numErrors > 0)
+ {
+ g_StdOut << endl << "Errors: " << numErrors;
+ return NExitCode::kFatalError;
+ }
+ if (result != S_OK)
+ throw CSystemException(result);
+ }
+ }
+ else if(options.Command.IsFromUpdateGroup())
+ {
+ UString workingDir;
+
+ CUpdateOptions &uo = options.UpdateOptions;
+ if (uo.SfxMode && uo.SfxModule.IsEmpty())
+ uo.SfxModule = kDefaultSfxModule;
+
+ bool passwordIsDefined =
+ options.PasswordEnabled && !options.Password.IsEmpty();
+
+ COpenCallbackConsole openCallback;
+ openCallback.OutStream = &stdStream;
+ openCallback.PasswordIsDefined = passwordIsDefined;
+ openCallback.Password = options.Password;
+
+ CUpdateCallbackConsole callback;
+ callback.EnablePercents = options.EnablePercents;
+ callback.PasswordIsDefined = passwordIsDefined;
+ callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
+ callback.Password = options.Password;
+ callback.StdOutMode = uo.StdOutMode;
+ callback.Init(&stdStream);
+
+ CUpdateErrorInfo errorInfo;
+
+ if (!uo.Init(codecs, options.ArchiveName, options.ArcType))
+ throw "Unsupported archive type";
+ HRESULT result = UpdateArchive(codecs,
+ options.WildcardCensor, uo,
+ errorInfo, &openCallback, &callback);
+
+ int exitCode = NExitCode::kSuccess;
+ if (callback.CantFindFiles.Size() > 0)
+ {
+ stdStream << endl;
+ stdStream << "WARNINGS for files:" << endl << endl;
+ int numErrors = callback.CantFindFiles.Size();
+ for (int i = 0; i < numErrors; i++)
+ {
+ stdStream << callback.CantFindFiles[i] << " : ";
+ stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl;
+ }
+ stdStream << "----------------" << endl;
+ stdStream << "WARNING: Cannot find " << numErrors << " file";
+ if (numErrors > 1)
+ stdStream << "s";
+ stdStream << endl;
+ exitCode = NExitCode::kWarning;
+ }
+
+ if (result != S_OK)
+ {
+ UString message;
+ if (!errorInfo.Message.IsEmpty())
+ {
+ message += errorInfo.Message;
+ message += L"\n";
+ }
+ if (!errorInfo.FileName.IsEmpty())
+ {
+ message += errorInfo.FileName;
+ message += L"\n";
+ }
+ if (!errorInfo.FileName2.IsEmpty())
+ {
+ message += errorInfo.FileName2;
+ message += L"\n";
+ }
+ if (errorInfo.SystemError != 0)
+ {
+ message += NError::MyFormatMessageW(errorInfo.SystemError);
+ message += L"\n";
+ }
+ if (!message.IsEmpty())
+ stdStream << L"\nError:\n" << message;
+ throw CSystemException(result);
+ }
+ int numErrors = callback.FailedFiles.Size();
+ if (numErrors == 0)
+ {
+ if (callback.CantFindFiles.Size() == 0)
+ stdStream << kEverythingIsOk << endl;
+ }
+ else
+ {
+ stdStream << endl;
+ stdStream << "WARNINGS for files:" << endl << endl;
+ for (int i = 0; i < numErrors; i++)
+ {
+ stdStream << callback.FailedFiles[i] << " : ";
+ stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl;
+ }
+ stdStream << "----------------" << endl;
+ stdStream << "WARNING: Cannot open " << numErrors << " file";
+ if (numErrors > 1)
+ stdStream << "s";
+ stdStream << endl;
+ exitCode = NExitCode::kWarning;
+ }
+ return exitCode;
+ }
+ else
+ PrintHelpAndExit(stdStream);
+ return 0;
+}
Added: trunk/lzma/CPP/7zip/UI/Console/MainAr.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/MainAr.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/MainAr.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,161 @@
+// MainAr.cpp
+
+#include "StdAfx.h"
+
+// #include <locale.h>
+
+#include "Windows/Error.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/NewHandler.h"
+#include "Common/MyException.h"
+#include "Common/StringConvert.h"
+
+#include "../Common/ExitCode.h"
+#include "../Common/ArchiveCommandLine.h"
+#include "ConsoleClose.h"
+
+using namespace NWindows;
+
+CStdOutStream *g_StdStream = 0;
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool g_IsNT = false;
+#endif
+#if !defined(_UNICODE) || !defined(_WIN64)
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+#endif
+
+extern int Main2(
+ #ifndef _WIN32
+ int numArguments, const char *arguments[]
+ #endif
+);
+
+static const char *kExceptionErrorMessage = "\n\nError:\n";
+static const char *kUserBreak = "\nBreak signaled\n";
+
+static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n";
+static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n";
+static const char *kInternalExceptionMessage = "\n\nInternal Error #";
+
+int
+#ifdef _MSC_VER
+__cdecl
+#endif
+main
+(
+#ifndef _WIN32
+int numArguments, const char *arguments[]
+#endif
+)
+{
+ g_StdStream = &g_StdOut;
+ #ifdef _WIN32
+
+ #ifdef _UNICODE
+ #ifndef _WIN64
+ if (!IsItWindowsNT())
+ {
+ (*g_StdStream) << "This program requires Windows NT/2000/XP/2003/Vista";
+ return NExitCode::kFatalError;
+ }
+ #endif
+ #else
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ #endif
+
+ // setlocale(LC_COLLATE, ".OCP");
+ NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
+ int res = 0;
+ try
+ {
+ res = Main2(
+#ifndef _WIN32
+ numArguments, arguments
+#endif
+ );
+ }
+ catch(const CNewException &)
+ {
+ (*g_StdStream) << kMemoryExceptionMessage;
+ return (NExitCode::kMemoryError);
+ }
+ catch(const NConsoleClose::CCtrlBreakException &)
+ {
+ (*g_StdStream) << endl << kUserBreak;
+ return (NExitCode::kUserBreak);
+ }
+ catch(const CArchiveCommandLineException &e)
+ {
+ (*g_StdStream) << kExceptionErrorMessage << e << endl;
+ return (NExitCode::kUserError);
+ }
+ catch(const CSystemException &systemError)
+ {
+ if (systemError.ErrorCode == E_OUTOFMEMORY)
+ {
+ (*g_StdStream) << kMemoryExceptionMessage;
+ return (NExitCode::kMemoryError);
+ }
+ if (systemError.ErrorCode == E_ABORT)
+ {
+ (*g_StdStream) << endl << kUserBreak;
+ return (NExitCode::kUserBreak);
+ }
+ UString message;
+ NError::MyFormatMessage(systemError.ErrorCode, message);
+ (*g_StdStream) << endl << endl << "System error:" << endl <<
+ message << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(NExitCode::EEnum &exitCode)
+ {
+ (*g_StdStream) << kInternalExceptionMessage << exitCode << endl;
+ return (exitCode);
+ }
+ /*
+ catch(const NExitCode::CMultipleErrors &multipleErrors)
+ {
+ (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl;
+ return (NExitCode::kFatalError);
+ }
+ */
+ catch(const UString &s)
+ {
+ (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(const AString &s)
+ {
+ (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(const char *s)
+ {
+ (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(int t)
+ {
+ (*g_StdStream) << kInternalExceptionMessage << t << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(...)
+ {
+ (*g_StdStream) << kUnknownExceptionMessage;
+ return (NExitCode::kFatalError);
+ }
+ return res;
+}
Added: trunk/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,58 @@
+// OpenCallbackConsole.cpp
+
+#include "StdAfx.h"
+
+#include "OpenCallbackConsole.h"
+
+#include "ConsoleClose.h"
+#include "UserInputUtils.h"
+
+HRESULT COpenCallbackConsole::CheckBreak()
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+HRESULT COpenCallbackConsole::SetTotal(const UInt64 *, const UInt64 *)
+{
+ return CheckBreak();
+}
+
+HRESULT COpenCallbackConsole::SetCompleted(const UInt64 *, const UInt64 *)
+{
+ return CheckBreak();
+}
+
+HRESULT COpenCallbackConsole::CryptoGetTextPassword(BSTR *password)
+{
+ PasswordWasAsked = true;
+ RINOK(CheckBreak());
+ if (!PasswordIsDefined)
+ {
+ Password = GetPassword(OutStream);
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR temp(Password);
+ *password = temp.Detach();
+ return S_OK;
+}
+
+HRESULT COpenCallbackConsole::GetPasswordIfAny(UString &password)
+{
+ if (PasswordIsDefined)
+ password = Password;
+ return S_OK;
+}
+
+bool COpenCallbackConsole::WasPasswordAsked()
+{
+ return PasswordWasAsked;
+}
+
+void COpenCallbackConsole::ClearPasswordWasAskedFlag()
+{
+ PasswordWasAsked = false;
+}
+
+
Added: trunk/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,27 @@
+// OpenCallbackConsole.h
+
+#ifndef __OPENCALLBACKCONSOLE_H
+#define __OPENCALLBACKCONSOLE_H
+
+#include "Common/StdOutStream.h"
+#include "../Common/ArchiveOpenCallback.h"
+
+class COpenCallbackConsole: public IOpenCallbackUI
+{
+public:
+ HRESULT CheckBreak();
+ HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes);
+ HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes);
+ HRESULT CryptoGetTextPassword(BSTR *password);
+ HRESULT GetPasswordIfAny(UString &password);
+ bool WasPasswordAsked();
+ void ClearPasswordWasAskedFlag();
+
+ CStdOutStream *OutStream;
+ bool PasswordIsDefined;
+ UString Password;
+ bool PasswordWasAsked;
+ COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {}
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,90 @@
+// PercentPrinter.cpp
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.h"
+#include "Common/MyString.h"
+
+#include "PercentPrinter.h"
+
+const int kPaddingSize = 2;
+const int kPercentsSize = 4;
+const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
+
+static void ClearPrev(char *p, int num)
+{
+ int i;
+ for (i = 0; i < num; i++) *p++ = '\b';
+ for (i = 0; i < num; i++) *p++ = ' ';
+ for (i = 0; i < num; i++) *p++ = '\b';
+ *p = '\0';
+}
+
+void CPercentPrinter::ClosePrint()
+{
+ if (m_NumExtraChars == 0)
+ return;
+ char s[kMaxExtraSize * 3 + 1];
+ ClearPrev(s, m_NumExtraChars);
+ (*OutStream) << s;
+ m_NumExtraChars = 0;
+}
+
+void CPercentPrinter::PrintString(const char *s)
+{
+ ClosePrint();
+ (*OutStream) << s;
+}
+
+void CPercentPrinter::PrintString(const wchar_t *s)
+{
+ ClosePrint();
+ (*OutStream) << s;
+}
+
+void CPercentPrinter::PrintNewLine()
+{
+ ClosePrint();
+ (*OutStream) << "\n";
+}
+
+void CPercentPrinter::RePrintRatio()
+{
+ char s[32];
+ ConvertUInt64ToString(((m_Total == 0) ? 0 : (m_CurValue * 100 / m_Total)), s);
+ int size = (int)strlen(s);
+ s[size++] = '%';
+ s[size] = '\0';
+
+ int extraSize = kPaddingSize + MyMax(size, kPercentsSize);
+ if (extraSize < m_NumExtraChars)
+ extraSize = m_NumExtraChars;
+
+ char fullString[kMaxExtraSize * 3];
+ char *p = fullString;
+ int i;
+ if (m_NumExtraChars == 0)
+ {
+ for (i = 0; i < extraSize; i++)
+ *p++ = ' ';
+ m_NumExtraChars = extraSize;
+ }
+
+ for (i = 0; i < m_NumExtraChars; i++)
+ *p++ = '\b';
+ m_NumExtraChars = extraSize;
+ for (; size < m_NumExtraChars; size++)
+ *p++ = ' ';
+ MyStringCopy(p, s);
+ (*OutStream) << fullString;
+ OutStream->Flush();
+ m_PrevValue = m_CurValue;
+}
+
+void CPercentPrinter::PrintRatio()
+{
+ if (m_CurValue < m_PrevValue + m_MinStepSize &&
+ m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0)
+ return;
+ RePrintRatio();
+}
Added: trunk/lzma/CPP/7zip/UI/Console/PercentPrinter.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/PercentPrinter.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/PercentPrinter.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,31 @@
+// PercentPrinter.h
+
+#ifndef __PERCENTPRINTER_H
+#define __PERCENTPRINTER_H
+
+#include "Common/Types.h"
+#include "Common/StdOutStream.h"
+
+class CPercentPrinter
+{
+ UInt64 m_MinStepSize;
+ UInt64 m_PrevValue;
+ UInt64 m_CurValue;
+ UInt64 m_Total;
+ int m_NumExtraChars;
+public:
+ CStdOutStream *OutStream;
+
+ CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize),
+ m_PrevValue(0), m_CurValue(0), m_Total(1), m_NumExtraChars(0) {}
+ void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; }
+ void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; }
+ void PrintString(const char *s);
+ void PrintString(const wchar_t *s);
+ void PrintNewLine();
+ void ClosePrint();
+ void RePrintRatio();
+ void PrintRatio();
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Console/StdAfx.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/StdAfx.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/StdAfx.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
Added: trunk/lzma/CPP/7zip/UI/Console/StdAfx.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,208 @@
+// UpdateCallbackConsole.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateCallbackConsole.h"
+
+#include "Windows/Error.h"
+#ifdef COMPRESS_MT
+#include "Windows/Synchronization.h"
+#endif
+
+#include "ConsoleClose.h"
+#include "UserInputUtils.h"
+
+using namespace NWindows;
+
+#ifdef COMPRESS_MT
+static NSynchronization::CCriticalSection g_CriticalSection;
+#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+#else
+#define MT_LOCK
+#endif
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+static const char *kCreatingArchiveMessage = "Creating archive ";
+static const char *kUpdatingArchiveMessage = "Updating archive ";
+static const char *kScanningMessage = "Scanning";
+
+
+HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
+{
+ (*OutStream) << endl;
+ if (result != S_OK)
+ (*OutStream) << "Error: " << name << " is not supported archive" << endl;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::StartScanning()
+{
+ (*OutStream) << kScanningMessage;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
+{
+ CantFindFiles.Add(name);
+ CantFindCodes.Add(systemError);
+ // m_PercentPrinter.ClosePrint();
+ if (!m_WarningsMode)
+ {
+ (*OutStream) << endl << endl;
+ m_PercentPrinter.PrintNewLine();
+ m_WarningsMode = true;
+ }
+ m_PercentPrinter.PrintString(name);
+ m_PercentPrinter.PrintString(": WARNING: ");
+ m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
+ m_PercentPrinter.PrintNewLine();
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::FinishScanning()
+{
+ (*OutStream) << endl << endl;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
+{
+ if(updating)
+ (*OutStream) << kUpdatingArchiveMessage;
+ else
+ (*OutStream) << kCreatingArchiveMessage;
+ if (name != 0)
+ (*OutStream) << name;
+ else
+ (*OutStream) << "StdOut";
+ (*OutStream) << endl << endl;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::FinishArchive()
+{
+ (*OutStream) << endl;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::CheckBreak()
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::Finilize()
+{
+ MT_LOCK
+ if (m_NeedBeClosed)
+ {
+ if (EnablePercents)
+ {
+ m_PercentPrinter.ClosePrint();
+ }
+ if (!StdOutMode && m_NeedNewLine)
+ {
+ m_PercentPrinter.PrintNewLine();
+ m_NeedNewLine = false;
+ }
+ m_NeedBeClosed = false;
+ }
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
+{
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
+{
+ MT_LOCK
+ if (EnablePercents)
+ m_PercentPrinter.SetTotal(size);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
+{
+ MT_LOCK
+ if (completeValue != NULL)
+ {
+ if (EnablePercents)
+ {
+ m_PercentPrinter.SetRatio(*completeValue);
+ m_PercentPrinter.PrintRatio();
+ m_NeedBeClosed = true;
+ }
+ }
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)
+{
+ /*
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ */
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)
+{
+ MT_LOCK
+ if (StdOutMode)
+ return S_OK;
+ if(isAnti)
+ m_PercentPrinter.PrintString("Anti item ");
+ else
+ m_PercentPrinter.PrintString("Compressing ");
+ if (name[0] == 0)
+ name = kEmptyFileAlias;
+ m_PercentPrinter.PrintString(name);
+ if (EnablePercents)
+ m_PercentPrinter.RePrintRatio();
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
+{
+ MT_LOCK
+ FailedCodes.Add(systemError);
+ FailedFiles.Add(name);
+ // if (systemError == ERROR_SHARING_VIOLATION)
+ {
+ m_PercentPrinter.ClosePrint();
+ m_PercentPrinter.PrintNewLine();
+ m_PercentPrinter.PrintString("WARNING: ");
+ m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
+ return S_FALSE;
+ }
+ // return systemError;
+}
+
+HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 )
+{
+ m_NeedBeClosed = true;
+ m_NeedNewLine = true;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ if (AskPassword)
+ {
+ Password = GetPassword(OutStream);
+ PasswordIsDefined = true;
+ }
+ }
+ *passwordIsDefined = BoolToInt(PasswordIsDefined);
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
Added: trunk/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,58 @@
+// UpdateCallbackConsole.h
+
+#ifndef __UPDATECALLBACKCONSOLE_H
+#define __UPDATECALLBACKCONSOLE_H
+
+#include "Common/MyString.h"
+#include "Common/StdOutStream.h"
+#include "PercentPrinter.h"
+#include "../Common/Update.h"
+
+class CUpdateCallbackConsole: public IUpdateCallbackUI2
+{
+ CPercentPrinter m_PercentPrinter;
+ bool m_NeedBeClosed;
+ bool m_NeedNewLine;
+
+ bool m_WarningsMode;
+
+ CStdOutStream *OutStream;
+public:
+ bool EnablePercents;
+ bool StdOutMode;
+
+ bool PasswordIsDefined;
+ UString Password;
+ bool AskPassword;
+
+
+ CUpdateCallbackConsole():
+ m_PercentPrinter(1 << 16),
+ PasswordIsDefined(false),
+ AskPassword(false),
+ StdOutMode(false),
+ EnablePercents(true),
+ m_WarningsMode(false)
+ {}
+
+ ~CUpdateCallbackConsole() { Finilize(); }
+ void Init(CStdOutStream *outStream)
+ {
+ m_NeedBeClosed = false;
+ m_NeedNewLine = false;
+ FailedFiles.Clear();
+ FailedCodes.Clear();
+ OutStream = outStream;
+ m_PercentPrinter.OutStream = outStream;
+ }
+
+ INTERFACE_IUpdateCallbackUI2(;)
+
+ UStringVector FailedFiles;
+ CRecordVector<HRESULT> FailedCodes;
+
+ UStringVector CantFindFiles;
+ CRecordVector<HRESULT> CantFindCodes;
+};
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,58 @@
+// UserInputUtils.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StdInStream.h"
+#include "Common/StringConvert.h"
+
+#include "UserInputUtils.h"
+
+static const char kYes = 'Y';
+static const char kNo = 'N';
+static const char kYesAll = 'A';
+static const char kNoAll = 'S';
+static const char kAutoRename = 'U';
+static const char kQuit = 'Q';
+
+static const char *kFirstQuestionMessage = "?\n";
+static const char *kHelpQuestionMessage =
+ "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename / (Q)uit? ";
+
+// return true if pressed Quite;
+// in: anAll
+// out: anAll, anYes;
+
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
+{
+ (*outStream) << kFirstQuestionMessage;
+ for(;;)
+ {
+ (*outStream) << kHelpQuestionMessage;
+ AString scannedString = g_StdIn.ScanStringUntilNewLine();
+ scannedString.Trim();
+ if(!scannedString.IsEmpty())
+ switch(::MyCharUpper(scannedString[0]))
+ {
+ case kYes:
+ return NUserAnswerMode::kYes;
+ case kNo:
+ return NUserAnswerMode::kNo;
+ case kYesAll:
+ return NUserAnswerMode::kYesAll;
+ case kNoAll:
+ return NUserAnswerMode::kNoAll;
+ case kAutoRename:
+ return NUserAnswerMode::kAutoRename;
+ case kQuit:
+ return NUserAnswerMode::kQuit;
+ }
+ }
+}
+
+UString GetPassword(CStdOutStream *outStream)
+{
+ (*outStream) << "\nEnter password:";
+ outStream->Flush();
+ AString oemPassword = g_StdIn.ScanStringUntilNewLine();
+ return MultiByteToUnicodeString(oemPassword, CP_OEMCP);
+}
Added: trunk/lzma/CPP/7zip/UI/Console/UserInputUtils.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/UserInputUtils.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/UserInputUtils.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// UserInputUtils.h
+
+#ifndef __USERINPUTUTILS_H
+#define __USERINPUTUTILS_H
+
+#include "Common/StdOutStream.h"
+
+namespace NUserAnswerMode {
+
+enum EEnum
+{
+ kYes,
+ kNo,
+ kYesAll,
+ kNoAll,
+ kAutoRename,
+ kQuit
+};
+}
+
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);
+UString GetPassword(CStdOutStream *outStream);
+
+#endif
Added: trunk/lzma/CPP/7zip/UI/Console/afxres.h
===================================================================
--- trunk/lzma/CPP/7zip/UI/Console/afxres.h (rev 0)
+++ trunk/lzma/CPP/7zip/UI/Console/afxres.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1 @@
+#include <winresrc.h>
Added: trunk/lzma/CPP/Build.mak
===================================================================
--- trunk/lzma/CPP/Build.mak (rev 0)
+++ trunk/lzma/CPP/Build.mak 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,68 @@
+!IFDEF CPU
+LIBS = $(LIBS) bufferoverflowU.lib
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope
+!ENDIF
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+!IF "$(CPU)" != "IA64"
+!IF "$(CPU)" != "AMD64"
+MY_ML = ml
+!ELSE
+MY_ML = ml64
+!ENDIF
+!ENDIF
+
+COMPL_ASM = $(MY_ML) -c -Fo$O/ $**
+
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -EHsc -Gz -WX -Gy
+
+!IFDEF MY_STATIC_LINK
+!IFNDEF MY_SINGLE_THREAD
+CFLAGS = $(CFLAGS) -MT
+!ENDIF
+!ELSE
+CFLAGS = $(CFLAGS) -MD
+!ENDIF
+
+!IFDEF NEW_COMPILER
+CFLAGS_O1 = $(CFLAGS) -O1 -W4 -Wp64
+CFLAGS_O2 = $(CFLAGS) -O2 -W4 -Wp64
+!ELSE
+CFLAGS_O1 = $(CFLAGS) -O1 -W3
+CFLAGS_O2 = $(CFLAGS) -O2 -W3
+!ENDIF
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 -OPT:REF
+
+!IFDEF DEF_FILE
+LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE)
+!ENDIF
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
+COMPL_PCH = $(CPP) $(CFLAGS_O1) -Yc"StdAfx.h" -Fp$O/a.pch $**
+COMPL = $(CPP) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $**
+
+all: $(PROGPATH)
+
+clean:
+ -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
+
+$O:
+ if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS) $(DEF_FILE)
+ link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+$O\resource.res: $(*B).rc
+ rc -fo$@ $**
+$O\StdAfx.obj: $(*B).cpp
+ $(COMPL_PCH)
Added: trunk/lzma/CPP/Common/AutoPtr.h
===================================================================
--- trunk/lzma/CPP/Common/AutoPtr.h (rev 0)
+++ trunk/lzma/CPP/Common/AutoPtr.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,35 @@
+// Common/AutoPtr.h
+
+#ifndef __COMMON_AUTOPTR_H
+#define __COMMON_AUTOPTR_H
+
+template<class T> class CMyAutoPtr
+{
+ T *_p;
+public:
+ CMyAutoPtr(T *p = 0) : _p(p) {}
+ CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {}
+ CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p)
+ {
+ reset(p.release());
+ return (*this);
+ }
+ ~CMyAutoPtr() { delete _p; }
+ T& operator*() const { return *_p; }
+ // T* operator->() const { return (&**this); }
+ T* get() const { return _p; }
+ T* release()
+ {
+ T *tmp = _p;
+ _p = 0;
+ return tmp;
+ }
+ void reset(T* p = 0)
+ {
+ if (p != _p)
+ delete _p;
+ _p = p;
+ }
+};
+
+#endif
Added: trunk/lzma/CPP/Common/Buffer.h
===================================================================
--- trunk/lzma/CPP/Common/Buffer.h (rev 0)
+++ trunk/lzma/CPP/Common/Buffer.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,77 @@
+// Common/Buffer.h
+
+#ifndef __COMMON_BUFFER_H
+#define __COMMON_BUFFER_H
+
+#include "Defs.h"
+
+template <class T> class CBuffer
+{
+protected:
+ size_t _capacity;
+ T *_items;
+public:
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ _capacity = 0;
+ }
+ CBuffer(): _capacity(0), _items(0) {};
+ CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; }
+ CBuffer(size_t size): _items(0), _capacity(0) { SetCapacity(size); }
+ virtual ~CBuffer() { delete []_items; }
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+ size_t GetCapacity() const { return _capacity; }
+ void SetCapacity(size_t newCapacity)
+ {
+ if (newCapacity == _capacity)
+ return;
+ T *newBuffer;
+ if (newCapacity > 0)
+ {
+ newBuffer = new T[newCapacity];
+ if(_capacity > 0)
+ memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T));
+ }
+ else
+ newBuffer = 0;
+ delete []_items;
+ _items = newBuffer;
+ _capacity = newCapacity;
+ }
+ CBuffer& operator=(const CBuffer &buffer)
+ {
+ Free();
+ if(buffer._capacity > 0)
+ {
+ SetCapacity(buffer._capacity);
+ memmove(_items, buffer._items, buffer._capacity * sizeof(T));
+ }
+ return *this;
+ }
+};
+
+template <class T>
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ if (b1.GetCapacity() != b2.GetCapacity())
+ return false;
+ for (size_t i = 0; i < b1.GetCapacity(); i++)
+ if (b1[i] != b2[i])
+ return false;
+ return true;
+}
+
+template <class T>
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ return !(b1 == b2);
+}
+
+typedef CBuffer<char> CCharBuffer;
+typedef CBuffer<wchar_t> CWCharBuffer;
+typedef CBuffer<unsigned char> CByteBuffer;
+
+#endif
Added: trunk/lzma/CPP/Common/CRC.cpp
===================================================================
--- trunk/lzma/CPP/Common/CRC.cpp (rev 0)
+++ trunk/lzma/CPP/Common/CRC.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,14 @@
+// Common/CRC.cpp
+
+#include "StdAfx.h"
+
+extern "C"
+{
+#include "../../C/7zCrc.h"
+}
+
+class CCRCTableInit
+{
+public:
+ CCRCTableInit() { CrcGenerateTable(); }
+} g_CRCTableInit;
Added: trunk/lzma/CPP/Common/C_FileIO.cpp
===================================================================
--- trunk/lzma/CPP/Common/C_FileIO.cpp (rev 0)
+++ trunk/lzma/CPP/Common/C_FileIO.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,88 @@
+// Common/C_FileIO.h
+
+#include "C_FileIO.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+
+namespace NC {
+namespace NFile {
+namespace NIO {
+
+bool CFileBase::OpenBinary(const char *name, int flags)
+{
+ #ifdef O_BINARY
+ flags |= O_BINARY;
+ #endif
+ Close();
+ _handle = ::open(name, flags, 0666);
+ return _handle != -1;
+}
+
+bool CFileBase::Close()
+{
+ if(_handle == -1)
+ return true;
+ if (close(_handle) != 0)
+ return false;
+ _handle = -1;
+ return true;
+}
+
+bool CFileBase::GetLength(UInt64 &length) const
+{
+ off_t curPos = Seek(0, SEEK_CUR);
+ off_t lengthTemp = Seek(0, SEEK_END);
+ Seek(curPos, SEEK_SET);
+ length = (UInt64)lengthTemp;
+ return true;
+}
+
+off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const
+{
+ return ::lseek(_handle, distanceToMove, moveMethod);
+}
+
+/////////////////////////
+// CInFile
+
+bool CInFile::Open(const char *name)
+{
+ return CFileBase::OpenBinary(name, O_RDONLY);
+}
+
+bool CInFile::OpenShared(const char *name, bool)
+{
+ return Open(name);
+}
+
+ssize_t CInFile::Read(void *data, size_t size)
+{
+ return read(_handle, data, size);
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Create(const char *name, bool createAlways)
+{
+ if (createAlways)
+ {
+ Close();
+ _handle = ::creat(name, 0666);
+ return _handle != -1;
+ }
+ return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY);
+}
+
+bool COutFile::Open(const char *name, DWORD creationDisposition)
+{
+ return Create(name, false);
+}
+
+ssize_t COutFile::Write(const void *data, size_t size)
+{
+ return write(_handle, data, size);
+}
+
+}}}
Added: trunk/lzma/CPP/Common/C_FileIO.h
===================================================================
--- trunk/lzma/CPP/Common/C_FileIO.h (rev 0)
+++ trunk/lzma/CPP/Common/C_FileIO.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,47 @@
+// Common/C_FileIO.h
+
+#ifndef __COMMON_C_FILEIO_H
+#define __COMMON_C_FILEIO_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "Types.h"
+#include "MyWindows.h"
+
+namespace NC {
+namespace NFile {
+namespace NIO {
+
+class CFileBase
+{
+protected:
+ int _handle;
+ bool OpenBinary(const char *name, int flags);
+public:
+ CFileBase(): _handle(-1) {};
+ ~CFileBase() { Close(); }
+ bool Close();
+ bool GetLength(UInt64 &length) const;
+ off_t Seek(off_t distanceToMove, int moveMethod) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+ bool Open(const char *name);
+ bool OpenShared(const char *name, bool shareForWrite);
+ ssize_t Read(void *data, size_t size);
+};
+
+class COutFile: public CFileBase
+{
+public:
+ bool Create(const char *name, bool createAlways);
+ bool Open(const char *name, DWORD creationDisposition);
+ ssize_t Write(const void *data, size_t size);
+};
+
+}}}
+
+#endif
Added: trunk/lzma/CPP/Common/ComTry.h
===================================================================
--- trunk/lzma/CPP/Common/ComTry.h (rev 0)
+++ trunk/lzma/CPP/Common/ComTry.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,17 @@
+// ComTry.h
+
+#ifndef __COM_TRY_H
+#define __COM_TRY_H
+
+#include "MyWindows.h"
+// #include "Exception.h"
+// #include "NewHandler.h"
+
+#define COM_TRY_BEGIN try {
+#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; }
+
+ // catch(const CNewException &) { return E_OUTOFMEMORY; }\
+ // catch(const CSystemException &e) { return e.ErrorCode; }\
+ // catch(...) { return E_FAIL; }
+
+#endif
Added: trunk/lzma/CPP/Common/CommandLineParser.cpp
===================================================================
--- trunk/lzma/CPP/Common/CommandLineParser.cpp (rev 0)
+++ trunk/lzma/CPP/Common/CommandLineParser.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,232 @@
+// CommandLineParser.cpp
+
+#include "StdAfx.h"
+
+#include "CommandLineParser.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
+{
+ dest1.Empty();
+ dest2.Empty();
+ bool quoteMode = false;
+ int i;
+ for (i = 0; i < src.Length(); i++)
+ {
+ wchar_t c = src[i];
+ if (c == L'\"')
+ quoteMode = !quoteMode;
+ else if (c == L' ' && !quoteMode)
+ {
+ i++;
+ break;
+ }
+ else
+ dest1 += c;
+ }
+ dest2 = src.Mid(i);
+}
+
+void SplitCommandLine(const UString &s, UStringVector &parts)
+{
+ UString sTemp = s;
+ sTemp.Trim();
+ parts.Clear();
+ for (;;)
+ {
+ UString s1, s2;
+ SplitCommandLine(sTemp, s1, s2);
+ // s1.Trim();
+ // s2.Trim();
+ if (!s1.IsEmpty())
+ parts.Add(s1);
+ if (s2.IsEmpty())
+ break;
+ sTemp = s2;
+ }
+}
+
+
+static const wchar_t kSwitchID1 = '-';
+// static const wchar_t kSwitchID2 = '/';
+
+static const wchar_t kSwitchMinus = '-';
+static const wchar_t *kStopSwitchParsing = L"--";
+
+static bool IsItSwitchChar(wchar_t c)
+{
+ return (c == kSwitchID1 /*|| c == kSwitchID2 */);
+}
+
+CParser::CParser(int numSwitches):
+ _numSwitches(numSwitches)
+{
+ _switches = new CSwitchResult[_numSwitches];
+}
+
+CParser::~CParser()
+{
+ delete []_switches;
+}
+
+void CParser::ParseStrings(const CSwitchForm *switchForms,
+ const UStringVector &commandStrings)
+{
+ int numCommandStrings = commandStrings.Size();
+ bool stopSwitch = false;
+ for (int i = 0; i < numCommandStrings; i++)
+ {
+ const UString &s = commandStrings[i];
+ if (stopSwitch)
+ NonSwitchStrings.Add(s);
+ else
+ if (s == kStopSwitchParsing)
+ stopSwitch = true;
+ else
+ if (!ParseString(s, switchForms))
+ NonSwitchStrings.Add(s);
+ }
+}
+
+// if string contains switch then function updates switch structures
+// out: (string is a switch)
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
+{
+ int len = s.Length();
+ if (len == 0)
+ return false;
+ int pos = 0;
+ if (!IsItSwitchChar(s[pos]))
+ return false;
+ while(pos < len)
+ {
+ if (IsItSwitchChar(s[pos]))
+ pos++;
+ const int kNoLen = -1;
+ int matchedSwitchIndex = 0; // GCC Warning
+ int maxLen = kNoLen;
+ for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
+ {
+ int switchLen = MyStringLen(switchForms[switchIndex].IDString);
+ if (switchLen <= maxLen || pos + switchLen > len)
+ continue;
+
+ UString temp = s + pos;
+ temp = temp.Left(switchLen);
+ if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
+ // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
+ {
+ matchedSwitchIndex = switchIndex;
+ maxLen = switchLen;
+ }
+ }
+ if (maxLen == kNoLen)
+ throw "maxLen == kNoLen";
+ CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
+ const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
+ if ((!switchForm.Multi) && matchedSwitch.ThereIs)
+ throw "switch must be single";
+ matchedSwitch.ThereIs = true;
+ pos += maxLen;
+ int tailSize = len - pos;
+ NSwitchType::EEnum type = switchForm.Type;
+ switch(type)
+ {
+ case NSwitchType::kPostMinus:
+ {
+ if (tailSize == 0)
+ matchedSwitch.WithMinus = false;
+ else
+ {
+ matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
+ if (matchedSwitch.WithMinus)
+ pos++;
+ }
+ break;
+ }
+ case NSwitchType::kPostChar:
+ {
+ if (tailSize < switchForm.MinLen)
+ throw "switch is not full";
+ UString set = switchForm.PostCharSet;
+ const int kEmptyCharValue = -1;
+ if (tailSize == 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ int index = set.Find(s[pos]);
+ if (index < 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ matchedSwitch.PostCharIndex = index;
+ pos++;
+ }
+ }
+ break;
+ }
+ case NSwitchType::kLimitedPostString:
+ case NSwitchType::kUnLimitedPostString:
+ {
+ int minLen = switchForm.MinLen;
+ if (tailSize < minLen)
+ throw "switch is not full";
+ if (type == NSwitchType::kUnLimitedPostString)
+ {
+ matchedSwitch.PostStrings.Add(s.Mid(pos));
+ return true;
+ }
+ int maxLen = switchForm.MaxLen;
+ UString stringSwitch = s.Mid(pos, minLen);
+ pos += minLen;
+ for(int i = minLen; i < maxLen && pos < len; i++, pos++)
+ {
+ wchar_t c = s[pos];
+ if (IsItSwitchChar(c))
+ break;
+ stringSwitch += c;
+ }
+ matchedSwitch.PostStrings.Add(stringSwitch);
+ break;
+ }
+ case NSwitchType::kSimple:
+ break;
+ }
+ }
+ return true;
+}
+
+const CSwitchResult& CParser::operator[](size_t index) const
+{
+ return _switches[index];
+}
+
+/////////////////////////////////
+// Command parsing procedures
+
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
+ const UString &commandString, UString &postString)
+{
+ for(int i = 0; i < numCommandForms; i++)
+ {
+ const UString id = commandForms[i].IDString;
+ if (commandForms[i].PostStringMode)
+ {
+ if(commandString.Find(id) == 0)
+ {
+ postString = commandString.Mid(id.Length());
+ return i;
+ }
+ }
+ else
+ if (commandString == id)
+ {
+ postString.Empty();
+ return i;
+ }
+ }
+ return -1;
+}
+
+}
Added: trunk/lzma/CPP/Common/CommandLineParser.h
===================================================================
--- trunk/lzma/CPP/Common/CommandLineParser.h (rev 0)
+++ trunk/lzma/CPP/Common/CommandLineParser.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,72 @@
+// Common/CommandLineParser.h
+
+#ifndef __COMMON_COMMANDLINEPARSER_H
+#define __COMMON_COMMANDLINEPARSER_H
+
+#include "MyString.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
+void SplitCommandLine(const UString &s, UStringVector &parts);
+
+namespace NSwitchType {
+ enum EEnum
+ {
+ kSimple,
+ kPostMinus,
+ kLimitedPostString,
+ kUnLimitedPostString,
+ kPostChar
+ };
+}
+
+struct CSwitchForm
+{
+ const wchar_t *IDString;
+ NSwitchType::EEnum Type;
+ bool Multi;
+ int MinLen;
+ int MaxLen;
+ const wchar_t *PostCharSet;
+};
+
+struct CSwitchResult
+{
+ bool ThereIs;
+ bool WithMinus;
+ UStringVector PostStrings;
+ int PostCharIndex;
+ CSwitchResult(): ThereIs(false) {};
+};
+
+class CParser
+{
+ int _numSwitches;
+ CSwitchResult *_switches;
+ bool ParseString(const UString &s, const CSwitchForm *switchForms);
+public:
+ UStringVector NonSwitchStrings;
+ CParser(int numSwitches);
+ ~CParser();
+ void ParseStrings(const CSwitchForm *switchForms,
+ const UStringVector &commandStrings);
+ const CSwitchResult& operator[](size_t index) const;
+};
+
+/////////////////////////////////
+// Command parsing procedures
+
+struct CCommandForm
+{
+ wchar_t *IDString;
+ bool PostStringMode;
+};
+
+// Returns: Index of form and postString; -1, if there is no match
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
+ const UString &commandString, UString &postString);
+
+}
+
+#endif
Added: trunk/lzma/CPP/Common/Defs.h
===================================================================
--- trunk/lzma/CPP/Common/Defs.h (rev 0)
+++ trunk/lzma/CPP/Common/Defs.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,20 @@
+// Common/Defs.h
+
+#ifndef __COMMON_DEFS_H
+#define __COMMON_DEFS_H
+
+template <class T> inline T MyMin(T a, T b)
+ { return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b)
+ { return a > b ? a : b; }
+
+template <class T> inline int MyCompare(T a, T b)
+ { return a < b ? -1 : (a == b ? 0 : 1); }
+
+inline int BoolToInt(bool value)
+ { return (value ? 1: 0); }
+
+inline bool IntToBool(int value)
+ { return (value != 0); }
+
+#endif
Added: trunk/lzma/CPP/Common/DynamicBuffer.h
===================================================================
--- trunk/lzma/CPP/Common/DynamicBuffer.h (rev 0)
+++ trunk/lzma/CPP/Common/DynamicBuffer.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,47 @@
+// Common/DynamicBuffer.h
+
+#ifndef __COMMON_DYNAMICBUFFER_H
+#define __COMMON_DYNAMICBUFFER_H
+
+#include "Buffer.h"
+
+template <class T> class CDynamicBuffer: public CBuffer<T>
+{
+ void GrowLength(size_t size)
+ {
+ size_t delta;
+ if (this->_capacity > 64)
+ delta = this->_capacity / 4;
+ else if (this->_capacity > 8)
+ delta = 16;
+ else
+ delta = 4;
+ delta = MyMax(delta, size);
+ SetCapacity(this->_capacity + delta);
+ }
+public:
+ CDynamicBuffer(): CBuffer<T>() {};
+ CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer<T>(buffer) {};
+ CDynamicBuffer(size_t size): CBuffer<T>(size) {};
+ CDynamicBuffer& operator=(const CDynamicBuffer &buffer)
+ {
+ this->Free();
+ if(buffer._capacity > 0)
+ {
+ SetCapacity(buffer._capacity);
+ memmove(this->_items, buffer._items, buffer._capacity * sizeof(T));
+ }
+ return *this;
+ }
+ void EnsureCapacity(size_t capacity)
+ {
+ if (this->_capacity < capacity)
+ GrowLength(capacity - this->_capacity);
+ }
+};
+
+typedef CDynamicBuffer<char> CCharDynamicBuffer;
+typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer;
+typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
+
+#endif
Added: trunk/lzma/CPP/Common/IntToString.cpp
===================================================================
--- trunk/lzma/CPP/Common/IntToString.cpp (rev 0)
+++ trunk/lzma/CPP/Common/IntToString.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,63 @@
+// Common/IntToString.cpp
+
+#include "StdAfx.h"
+
+#include "IntToString.h"
+
+void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base)
+{
+ if (base < 2 || base > 36)
+ {
+ *s = '\0';
+ return;
+ }
+ char temp[72];
+ int pos = 0;
+ do
+ {
+ int delta = (int)(value % base);
+ temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10)));
+ value /= base;
+ }
+ while (value != 0);
+ do
+ *s++ = temp[--pos];
+ while(pos > 0);
+ *s = '\0';
+}
+
+void ConvertUInt64ToString(UInt64 value, wchar_t *s)
+{
+ wchar_t temp[32];
+ int pos = 0;
+ do
+ {
+ temp[pos++] = (wchar_t)(L'0' + (int)(value % 10));
+ value /= 10;
+ }
+ while (value != 0);
+ do
+ *s++ = temp[--pos];
+ while(pos > 0);
+ *s = L'\0';
+}
+
+void ConvertInt64ToString(Int64 value, char *s)
+{
+ if (value < 0)
+ {
+ *s++ = '-';
+ value = -value;
+ }
+ ConvertUInt64ToString(value, s);
+}
+
+void ConvertInt64ToString(Int64 value, wchar_t *s)
+{
+ if (value < 0)
+ {
+ *s++ = L'-';
+ value = -value;
+ }
+ ConvertUInt64ToString(value, s);
+}
Added: trunk/lzma/CPP/Common/IntToString.h
===================================================================
--- trunk/lzma/CPP/Common/IntToString.h (rev 0)
+++ trunk/lzma/CPP/Common/IntToString.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,15 @@
+// Common/IntToString.h
+
+#ifndef __COMMON_INTTOSTRING_H
+#define __COMMON_INTTOSTRING_H
+
+#include <stddef.h>
+#include "Types.h"
+
+void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10);
+void ConvertUInt64ToString(UInt64 value, wchar_t *s);
+
+void ConvertInt64ToString(Int64 value, char *s);
+void ConvertInt64ToString(Int64 value, wchar_t *s);
+
+#endif
Added: trunk/lzma/CPP/Common/ListFileUtils.cpp
===================================================================
--- trunk/lzma/CPP/Common/ListFileUtils.cpp (rev 0)
+++ trunk/lzma/CPP/Common/ListFileUtils.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,74 @@
+// Common/ListFileUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../Windows/FileIO.h"
+
+#include "ListFileUtils.h"
+#include "StringConvert.h"
+#include "UTFConvert.h"
+
+static const char kQuoteChar = '\"';
+static void RemoveQuote(UString &s)
+{
+ if (s.Length() >= 2)
+ if (s[0] == kQuoteChar && s[s.Length() - 1] == kQuoteChar)
+ s = s.Mid(1, s.Length() - 2);
+}
+
+bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &resultStrings, UINT codePage)
+{
+ NWindows::NFile::NIO::CInFile file;
+ if (!file.Open(fileName))
+ return false;
+ UInt64 length;
+ if (!file.GetLength(length))
+ return false;
+ if (length > ((UInt32)1 << 31))
+ return false;
+ AString s;
+ char *p = s.GetBuffer((int)length + 1);
+ UInt32 processed;
+ if (!file.Read(p, (UInt32)length, processed))
+ return false;
+ p[(UInt32)length] = 0;
+ s.ReleaseBuffer();
+ file.Close();
+
+ UString u;
+ #ifdef CP_UTF8
+ if (codePage == CP_UTF8)
+ {
+ if (!ConvertUTF8ToUnicode(s, u))
+ return false;
+ }
+ else
+ #endif
+ u = MultiByteToUnicodeString(s, codePage);
+ if (!u.IsEmpty())
+ {
+ if (u[0] == 0xFEFF)
+ u.Delete(0);
+ }
+
+ UString t;
+ for(int i = 0; i < u.Length(); i++)
+ {
+ wchar_t c = u[i];
+ if (c == L'\n' || c == 0xD)
+ {
+ t.Trim();
+ RemoveQuote(t);
+ if (!t.IsEmpty())
+ resultStrings.Add(t);
+ t.Empty();
+ }
+ else
+ t += c;
+ }
+ t.Trim();
+ RemoveQuote(t);
+ if (!t.IsEmpty())
+ resultStrings.Add(t);
+ return true;
+}
Added: trunk/lzma/CPP/Common/ListFileUtils.h
===================================================================
--- trunk/lzma/CPP/Common/ListFileUtils.h (rev 0)
+++ trunk/lzma/CPP/Common/ListFileUtils.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,11 @@
+// Common/ListFileUtils.h
+
+#ifndef __COMMON_LISTFILEUTILS_H
+#define __COMMON_LISTFILEUTILS_H
+
+#include "MyString.h"
+#include "Types.h"
+
+bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
+
+#endif
Added: trunk/lzma/CPP/Common/MyCom.h
===================================================================
--- trunk/lzma/CPP/Common/MyCom.h (rev 0)
+++ trunk/lzma/CPP/Common/MyCom.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,218 @@
+// MyCom.h
+
+#ifndef __MYCOM_H
+#define __MYCOM_H
+
+#include "MyWindows.h"
+
+#ifndef RINOK
+#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+#endif
+
+template <class T>
+class CMyComPtr
+{
+ T* _p;
+public:
+ // typedef T _PtrClass;
+ CMyComPtr() { _p = NULL;}
+ CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp)
+ {
+ if ((_p = lp._p) != NULL)
+ _p->AddRef();
+ }
+ ~CMyComPtr() { if (_p) _p->Release(); }
+ void Release() { if (_p) { _p->Release(); _p = NULL; } }
+ operator T*() const { return (T*)_p; }
+ // T& operator*() const { return *_p; }
+ T** operator&() { return &_p; }
+ T* operator->() const { return _p; }
+ T* operator=(T* p)
+ {
+ if (p != 0)
+ p->AddRef();
+ if (_p)
+ _p->Release();
+ _p = p;
+ return p;
+ }
+ T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
+ bool operator!() const { return (_p == NULL); }
+ // bool operator==(T* pT) const { return _p == pT; }
+ // Compare two objects for equivalence
+ void Attach(T* p2)
+ {
+ Release();
+ _p = p2;
+ }
+ T* Detach()
+ {
+ T* pt = _p;
+ _p = NULL;
+ return pt;
+ }
+ #ifdef _WIN32
+ HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
+ }
+ #endif
+ /*
+ HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ CLSID clsid;
+ HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
+ ATLASSERT(_p == NULL);
+ if (SUCCEEDED(hr))
+ hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
+ return hr;
+ }
+ */
+ template <class Q>
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const
+ {
+ return _p->QueryInterface(iid, (void**)pp);
+ }
+};
+
+//////////////////////////////////////////////////////////
+
+class CMyComBSTR
+{
+public:
+ BSTR m_str;
+ CMyComBSTR() { m_str = NULL; }
+ CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); }
+ // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
+ // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
+ CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+ /*
+ CMyComBSTR(REFGUID src)
+ {
+ LPOLESTR szGuid;
+ StringFromCLSID(src, &szGuid);
+ m_str = ::SysAllocString(szGuid);
+ CoTaskMemFree(szGuid);
+ }
+ */
+ ~CMyComBSTR() { ::SysFreeString(m_str); }
+ CMyComBSTR& operator=(const CMyComBSTR& src)
+ {
+ if (m_str != src.m_str)
+ {
+ if (m_str)
+ ::SysFreeString(m_str);
+ m_str = src.MyCopy();
+ }
+ return *this;
+ }
+ CMyComBSTR& operator=(LPCOLESTR pSrc)
+ {
+ ::SysFreeString(m_str);
+ m_str = ::SysAllocString(pSrc);
+ return *this;
+ }
+ unsigned int Length() const { return ::SysStringLen(m_str); }
+ operator BSTR() const { return m_str; }
+ BSTR* operator&() { return &m_str; }
+ BSTR MyCopy() const
+ {
+ int byteLen = ::SysStringByteLen(m_str);
+ BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
+ memmove(res, m_str, byteLen);
+ return res;
+ }
+ void Attach(BSTR src) { m_str = src; }
+ BSTR Detach()
+ {
+ BSTR s = m_str;
+ m_str = NULL;
+ return s;
+ }
+ void Empty()
+ {
+ ::SysFreeString(m_str);
+ m_str = NULL;
+ }
+ bool operator!() const { return (m_str == NULL); }
+};
+
+
+//////////////////////////////////////////////////////////
+
+class CMyUnknownImp
+{
+public:
+ ULONG __m_RefCount;
+ CMyUnknownImp(): __m_RefCount(0) {}
+};
+
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
+ (REFGUID iid, void **outObject) {
+
+#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
+ { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; }
+
+#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
+ MY_QUERYINTERFACE_ENTRY(i)
+
+#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+
+#define MY_ADDREF_RELEASE \
+STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
+ return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC(i) \
+ MY_QUERYINTERFACE_BEGIN \
+ i \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+
+#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
+ MY_QUERYINTERFACE_ENTRY(i) \
+ )
+
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ )
+
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ )
+
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ )
+
+#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ )
+
+#endif
Added: trunk/lzma/CPP/Common/MyException.h
===================================================================
--- trunk/lzma/CPP/Common/MyException.h (rev 0)
+++ trunk/lzma/CPP/Common/MyException.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,14 @@
+// Common/Exception.h
+
+#ifndef __COMMON_EXCEPTION_H
+#define __COMMON_EXCEPTION_H
+
+#include "MyWindows.h"
+
+struct CSystemException
+{
+ HRESULT ErrorCode;
+ CSystemException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+
+#endif
Added: trunk/lzma/CPP/Common/MyGuidDef.h
===================================================================
--- trunk/lzma/CPP/Common/MyGuidDef.h (rev 0)
+++ trunk/lzma/CPP/Common/MyGuidDef.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,54 @@
+// Common/MyGuidDef.h
+
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+
+#include "Types.h"
+
+typedef struct {
+ UInt32 Data1;
+ UInt16 Data2;
+ UInt16 Data3;
+ unsigned char Data4[8];
+} GUID;
+
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID *
+#endif
+
+#define REFCLSID REFGUID
+#define REFIID REFGUID
+
+#ifdef __cplusplus
+inline int operator==(REFGUID g1, REFGUID g2)
+{
+ for (int i = 0; i < (int)sizeof(g1); i++)
+ if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
+ return 0;
+ return 1;
+}
+inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
+#endif
+
+#ifdef __cplusplus
+ #define MY_EXTERN_C extern "C"
+#else
+ #define MY_EXTERN_C extern
+#endif
+
+#endif // GUID_DEFINED
+
+
+#ifdef DEFINE_GUID
+#undef DEFINE_GUID
+#endif
+
+#ifdef INITGUID
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+#else
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name
+#endif
Added: trunk/lzma/CPP/Common/MyInitGuid.h
===================================================================
--- trunk/lzma/CPP/Common/MyInitGuid.h (rev 0)
+++ trunk/lzma/CPP/Common/MyInitGuid.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,15 @@
+// Common/MyInitGuid.h
+
+#ifndef __COMMON_MYINITGUID_H
+#define __COMMON_MYINITGUID_H
+
+#ifdef _WIN32
+#include <initguid.h>
+#else
+#define INITGUID
+#include "MyGuidDef.h"
+DEFINE_GUID(IID_IUnknown,
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+#endif
+
+#endif
Added: trunk/lzma/CPP/Common/MyString.cpp
===================================================================
--- trunk/lzma/CPP/Common/MyString.cpp (rev 0)
+++ trunk/lzma/CPP/Common/MyString.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,198 @@
+// Common/MyString.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include "StringConvert.h"
+#else
+#include <ctype.h>
+#endif
+
+#include "MyString.h"
+
+
+#ifdef _WIN32
+
+#ifndef _UNICODE
+
+wchar_t MyCharUpper(wchar_t c)
+{
+ if (c == 0)
+ return 0;
+ wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)(unsigned int)(UINT_PTR)res;
+ const int kBufferSize = 4;
+ char s[kBufferSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
+ if (numChars == 0 || numChars > kBufferSize)
+ return c;
+ s[numChars] = 0;
+ ::CharUpperA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
+}
+
+wchar_t MyCharLower(wchar_t c)
+{
+ if (c == 0)
+ return 0;
+ wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)(unsigned int)(UINT_PTR)res;
+ const int kBufferSize = 4;
+ char s[kBufferSize + 1];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
+ if (numChars == 0 || numChars > kBufferSize)
+ return c;
+ s[numChars] = 0;
+ ::CharLowerA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
+}
+
+wchar_t * MyStringUpper(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ wchar_t *res = CharUpperW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeUpper();
+ return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+}
+
+wchar_t * MyStringLower(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ wchar_t *res = CharLowerW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeLower();
+ return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+}
+
+#endif
+
+/*
+inline int ConvertCompareResult(int r) { return r - 2; }
+
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
+{
+ int res = CompareStringW(
+ LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1);
+ #ifdef _UNICODE
+ return ConvertCompareResult(res);
+ #else
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return ConvertCompareResult(res);
+ return MyStringCollate(UnicodeStringToMultiByte(s1),
+ UnicodeStringToMultiByte(s2));
+ #endif
+}
+
+#ifndef _WIN32_WCE
+int MyStringCollate(const char *s1, const char *s2)
+{
+ return ConvertCompareResult(CompareStringA(
+ LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1));
+}
+
+int MyStringCollateNoCase(const char *s1, const char *s2)
+{
+ return ConvertCompareResult(CompareStringA(
+ LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1));
+}
+#endif
+
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+{
+ int res = CompareStringW(
+ LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1);
+ #ifdef _UNICODE
+ return ConvertCompareResult(res);
+ #else
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return ConvertCompareResult(res);
+ return MyStringCollateNoCase(UnicodeStringToMultiByte(s1),
+ UnicodeStringToMultiByte(s2));
+ #endif
+}
+*/
+
+#else
+
+wchar_t MyCharUpper(wchar_t c)
+{
+ return toupper(c);
+}
+
+/*
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ if (u1 == 0) return 0;
+ }
+}
+*/
+
+#endif
+
+int MyStringCompare(const char *s1, const char *s2)
+{
+ for (;;)
+ {
+ unsigned char c1 = (unsigned char)*s1++;
+ unsigned char c2 = (unsigned char)*s2++;
+ if (c1 < c2) return -1;
+ if (c1 > c2) return 1;
+ if (c1 == 0) return 0;
+ }
+}
+
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2)
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 < c2) return -1;
+ if (c1 > c2) return 1;
+ if (c1 == 0) return 0;
+ }
+}
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
+{
+ for (;;)
+ {
+ wchar_t c1 = *s1++;
+ wchar_t c2 = *s2++;
+ if (c1 != c2)
+ {
+ wchar_t u1 = MyCharUpper(c1);
+ wchar_t u2 = MyCharUpper(c2);
+ if (u1 < u2) return -1;
+ if (u1 > u2) return 1;
+ }
+ if (c1 == 0) return 0;
+ }
+}
+
+#ifdef _WIN32
+int MyStringCompareNoCase(const char *s1, const char *s2)
+{
+ return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
+}
+#endif
Added: trunk/lzma/CPP/Common/MyString.h
===================================================================
--- trunk/lzma/CPP/Common/MyString.h (rev 0)
+++ trunk/lzma/CPP/Common/MyString.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,636 @@
+// Common/String.h
+
+#ifndef __COMMON_STRING_H
+#define __COMMON_STRING_H
+
+#include <string.h>
+// #include <wchar.h>
+
+#include "MyVector.h"
+
+#ifdef _WIN32
+#include "MyWindows.h"
+#endif
+
+template <class T>
+inline int MyStringLen(const T *s)
+{
+ int i;
+ for (i = 0; s[i] != '\0'; i++);
+ return i;
+}
+
+template <class T>
+inline T * MyStringCopy(T *dest, const T *src)
+{
+ T *destStart = dest;
+ while((*dest++ = *src++) != 0);
+ return destStart;
+}
+
+inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
+ { return (p + 1); }
+inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
+ { return (p + 1); }
+inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
+ { return (p - 1); }
+inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
+ { return (p - 1); }
+
+#ifdef _WIN32
+
+inline char* MyStringGetNextCharPointer(char *p)
+ { return CharNextA(p); }
+inline const char* MyStringGetNextCharPointer(const char *p)
+ { return CharNextA(p); }
+
+inline char* MyStringGetPrevCharPointer(char *base, char *p)
+ { return CharPrevA(base, p); }
+inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
+ { return CharPrevA(base, p); }
+
+inline char MyCharUpper(char c)
+ { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharUpper(wchar_t c)
+ { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }
+#else
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+inline char MyCharLower(char c)
+ { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharLower(wchar_t c)
+ { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }
+#else
+wchar_t MyCharLower(wchar_t c);
+#endif
+
+inline char * MyStringUpper(char *s) { return CharUpperA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+#else
+wchar_t * MyStringUpper(wchar_t *s);
+#endif
+
+inline char * MyStringLower(char *s) { return CharLowerA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+#else
+wchar_t * MyStringLower(wchar_t *s);
+#endif
+
+#else // Standard-C
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+//////////////////////////////////////
+// Compare
+
+/*
+#ifndef _WIN32_WCE
+int MyStringCollate(const char *s1, const char *s2);
+int MyStringCollateNoCase(const char *s1, const char *s2);
+#endif
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
+*/
+
+int MyStringCompare(const char *s1, const char *s2);
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
+
+#ifdef _WIN32
+int MyStringCompareNoCase(const char *s1, const char *s2);
+#endif
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
+
+template <class T>
+class CStringBase
+{
+ void TrimLeftWithCharSet(const CStringBase &charSet)
+ {
+ const T *p = _chars;
+ while (charSet.Find(*p) >= 0 && (*p != 0))
+ p = GetNextCharPointer(p);
+ Delete(0, (int)(p - _chars));
+ }
+ void TrimRightWithCharSet(const CStringBase &charSet)
+ {
+ const T *p = _chars;
+ const T *pLast = NULL;
+ while (*p != 0)
+ {
+ if (charSet.Find(*p) >= 0)
+ {
+ if (pLast == NULL)
+ pLast = p;
+ }
+ else
+ pLast = NULL;
+ p = GetNextCharPointer(p);
+ }
+ if(pLast != NULL)
+ {
+ int i = (int)(pLast - _chars);
+ Delete(i, _length - i);
+ }
+
+ }
+ void MoveItems(int destIndex, int srcIndex)
+ {
+ memmove(_chars + destIndex, _chars + srcIndex,
+ sizeof(T) * (_length - srcIndex + 1));
+ }
+
+ void InsertSpace(int &index, int size)
+ {
+ CorrectIndex(index);
+ GrowLength(size);
+ MoveItems(index + size, index);
+ }
+
+ static T *GetNextCharPointer(T *p)
+ { return MyStringGetNextCharPointer(p); }
+ static const T *GetNextCharPointer(const T *p)
+ { return MyStringGetNextCharPointer(p); }
+ static T *GetPrevCharPointer(T *base, T *p)
+ { return MyStringGetPrevCharPointer(base, p); }
+ static const T *GetPrevCharPointer(const T *base, const T *p)
+ { return MyStringGetPrevCharPointer(base, p); }
+protected:
+ T *_chars;
+ int _length;
+ int _capacity;
+
+ void SetCapacity(int newCapacity)
+ {
+ int realCapacity = newCapacity + 1;
+ if(realCapacity == _capacity)
+ return;
+ /*
+ const int kMaxStringSize = 0x20000000;
+ #ifndef _WIN32_WCE
+ if(newCapacity > kMaxStringSize || newCapacity < _length)
+ throw 1052337;
+ #endif
+ */
+ T *newBuffer = new T[realCapacity];
+ if(_capacity > 0)
+ {
+ for (int i = 0; i < (_length + 1); i++)
+ newBuffer[i] = _chars[i];
+ delete []_chars;
+ _chars = newBuffer;
+ }
+ else
+ {
+ _chars = newBuffer;
+ _chars[0] = 0;
+ }
+ _capacity = realCapacity;
+ }
+
+ void GrowLength(int n)
+ {
+ int freeSize = _capacity - _length - 1;
+ if (n <= freeSize)
+ return;
+ int delta;
+ if (_capacity > 64)
+ delta = _capacity / 2;
+ else if (_capacity > 8)
+ delta = 16;
+ else
+ delta = 4;
+ if (freeSize + delta < n)
+ delta = n - freeSize;
+ SetCapacity(_capacity + delta);
+ }
+
+ void CorrectIndex(int &index) const
+ {
+ if (index > _length)
+ index = _length;
+ }
+
+public:
+ CStringBase(): _chars(0), _length(0), _capacity(0)
+ { SetCapacity(16 - 1); }
+ CStringBase(T c): _chars(0), _length(0), _capacity(0)
+ {
+ SetCapacity(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+ _length = 1;
+ }
+ CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
+ {
+ int length = MyStringLen(chars);
+ SetCapacity(length);
+ MyStringCopy(_chars, chars); // can be optimized by memove()
+ _length = length;
+ }
+ CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)
+ {
+ SetCapacity(s._length);
+ MyStringCopy(_chars, s._chars);
+ _length = s._length;
+ }
+ ~CStringBase() { delete []_chars; }
+
+ operator const T*() const { return _chars;}
+
+ // The minimum size of the character buffer in characters.
+ // This value does not include space for a null terminator.
+ T* GetBuffer(int minBufLength)
+ {
+ if(minBufLength >= _capacity)
+ SetCapacity(minBufLength + 1);
+ return _chars;
+ }
+ void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
+ void ReleaseBuffer(int newLength)
+ {
+ /*
+ #ifndef _WIN32_WCE
+ if(newLength >= _capacity)
+ throw 282217;
+ #endif
+ */
+ _chars[newLength] = 0;
+ _length = newLength;
+ }
+
+ CStringBase& operator=(T c)
+ {
+ Empty();
+ SetCapacity(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+ _length = 1;
+ return *this;
+ }
+ CStringBase& operator=(const T *chars)
+ {
+ Empty();
+ int length = MyStringLen(chars);
+ SetCapacity(length);
+ MyStringCopy(_chars, chars);
+ _length = length;
+ return *this;
+ }
+ CStringBase& operator=(const CStringBase& s)
+ {
+ if(&s == this)
+ return *this;
+ Empty();
+ SetCapacity(s._length);
+ MyStringCopy(_chars, s._chars);
+ _length = s._length;
+ return *this;
+ }
+
+ CStringBase& operator+=(T c)
+ {
+ GrowLength(1);
+ _chars[_length] = c;
+ _chars[++_length] = 0;
+ return *this;
+ }
+ CStringBase& operator+=(const T *s)
+ {
+ int len = MyStringLen(s);
+ GrowLength(len);
+ MyStringCopy(_chars + _length, s);
+ _length += len;
+ return *this;
+ }
+ CStringBase& operator+=(const CStringBase &s)
+ {
+ GrowLength(s._length);
+ MyStringCopy(_chars + _length, s._chars);
+ _length += s._length;
+ return *this;
+ }
+ void Empty()
+ {
+ _length = 0;
+ _chars[0] = 0;
+ }
+ int Length() const { return _length; }
+ bool IsEmpty() const { return (_length == 0); }
+
+ CStringBase Mid(int startIndex) const
+ { return Mid(startIndex, _length - startIndex); }
+ CStringBase Mid(int startIndex, int count ) const
+ {
+ if (startIndex + count > _length)
+ count = _length - startIndex;
+
+ if (startIndex == 0 && startIndex + count == _length)
+ return *this;
+
+ CStringBase<T> result;
+ result.SetCapacity(count);
+ // MyStringNCopy(result._chars, _chars + startIndex, count);
+ for (int i = 0; i < count; i++)
+ result._chars[i] = _chars[startIndex + i];
+ result._chars[count] = 0;
+ result._length = count;
+ return result;
+ }
+ CStringBase Left(int count) const
+ { return Mid(0, count); }
+ CStringBase Right(int count) const
+ {
+ if (count > _length)
+ count = _length;
+ return Mid(_length - count, count);
+ }
+
+ void MakeUpper()
+ { MyStringUpper(_chars); }
+ void MakeLower()
+ { MyStringLower(_chars); }
+
+ int Compare(const CStringBase& s) const
+ { return MyStringCompare(_chars, s._chars); }
+
+ int Compare(const T *s) const
+ { return MyStringCompare(_chars, s); }
+
+ int CompareNoCase(const CStringBase& s) const
+ { return MyStringCompareNoCase(_chars, s._chars); }
+
+ int CompareNoCase(const T *s) const
+ { return MyStringCompareNoCase(_chars, s); }
+
+ /*
+ int Collate(const CStringBase& s) const
+ { return MyStringCollate(_chars, s._chars); }
+ int CollateNoCase(const CStringBase& s) const
+ { return MyStringCollateNoCase(_chars, s._chars); }
+ */
+
+ int Find(T c) const { return Find(c, 0); }
+ int Find(T c, int startIndex) const
+ {
+ T *p = _chars + startIndex;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (*p == 0)
+ return -1;
+ p = GetNextCharPointer(p);
+ }
+ }
+ int Find(const CStringBase &s) const { return Find(s, 0); }
+ int Find(const CStringBase &s, int startIndex) const
+ {
+ if (s.IsEmpty())
+ return startIndex;
+ for (; startIndex < _length; startIndex++)
+ {
+ int j;
+ for (j = 0; j < s._length && startIndex + j < _length; j++)
+ if (_chars[startIndex+j] != s._chars[j])
+ break;
+ if (j == s._length)
+ return startIndex;
+ }
+ return -1;
+ }
+ int ReverseFind(T c) const
+ {
+ if (_length == 0)
+ return -1;
+ T *p = _chars + _length - 1;
+ for (;;)
+ {
+ if (*p == c)
+ return (int)(p - _chars);
+ if (p == _chars)
+ return -1;
+ p = GetPrevCharPointer(_chars, p);
+ }
+ }
+ int FindOneOf(const CStringBase &s) const
+ {
+ for(int i = 0; i < _length; i++)
+ if (s.Find(_chars[i]) >= 0)
+ return i;
+ return -1;
+ }
+
+ void TrimLeft(T c)
+ {
+ const T *p = _chars;
+ while (c == *p)
+ p = GetNextCharPointer(p);
+ Delete(0, p - _chars);
+ }
+ private:
+ CStringBase GetTrimDefaultCharSet()
+ {
+ CStringBase<T> charSet;
+ charSet += (T)' ';
+ charSet += (T)'\n';
+ charSet += (T)'\t';
+ return charSet;
+ }
+ public:
+
+ void TrimLeft()
+ {
+ TrimLeftWithCharSet(GetTrimDefaultCharSet());
+ }
+ void TrimRight()
+ {
+ TrimRightWithCharSet(GetTrimDefaultCharSet());
+ }
+ void TrimRight(T c)
+ {
+ const T *p = _chars;
+ const T *pLast = NULL;
+ while (*p != 0)
+ {
+ if (*p == c)
+ {
+ if (pLast == NULL)
+ pLast = p;
+ }
+ else
+ pLast = NULL;
+ p = GetNextCharPointer(p);
+ }
+ if(pLast != NULL)
+ {
+ int i = pLast - _chars;
+ Delete(i, _length - i);
+ }
+ }
+ void Trim()
+ {
+ TrimRight();
+ TrimLeft();
+ }
+
+ int Insert(int index, T c)
+ {
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _length++;
+ return _length;
+ }
+ int Insert(int index, const CStringBase &s)
+ {
+ CorrectIndex(index);
+ if (s.IsEmpty())
+ return _length;
+ int numInsertChars = s.Length();
+ InsertSpace(index, numInsertChars);
+ for(int i = 0; i < numInsertChars; i++)
+ _chars[index + i] = s[i];
+ _length += numInsertChars;
+ return _length;
+ }
+
+ // !!!!!!!!!!!!!!! test it if newChar = '\0'
+ int Replace(T oldChar, T newChar)
+ {
+ if (oldChar == newChar)
+ return 0;
+ int number = 0;
+ int pos = 0;
+ while (pos < Length())
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[pos] = newChar;
+ pos++;
+ number++;
+ }
+ return number;
+ }
+ int Replace(const CStringBase &oldString, const CStringBase &newString)
+ {
+ if (oldString.IsEmpty())
+ return 0;
+ if (oldString == newString)
+ return 0;
+ int oldStringLength = oldString.Length();
+ int newStringLength = newString.Length();
+ int number = 0;
+ int pos = 0;
+ while (pos < _length)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldStringLength);
+ Insert(pos, newString);
+ pos += newStringLength;
+ number++;
+ }
+ return number;
+ }
+ int Delete(int index, int count = 1 )
+ {
+ if (index + count > _length)
+ count = _length - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _length -= count;
+ }
+ return _length;
+ }
+};
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
+{
+ CStringBase<T> result(s1);
+ result += s2;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, T c)
+{
+ CStringBase<T> result(s);
+ result += c;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(T c, const CStringBase<T>& s)
+{
+ CStringBase<T> result(c);
+ result += s;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
+{
+ CStringBase<T> result(s);
+ result += chars;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
+{
+ CStringBase<T> result(chars);
+ result += s;
+ return result;
+}
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) < 0); }
+
+template <class T>
+bool operator==(const T *s1, const CStringBase<T>& s2)
+ { return (s2.Compare(s1) == 0); }
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const T *s2)
+ { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) != 0); }
+
+template <class T>
+bool operator!=(const T *s1, const CStringBase<T>& s2)
+ { return (s2.Compare(s1) != 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const T *s2)
+ { return (s1.Compare(s2) != 0); }
+
+typedef CStringBase<char> AString;
+typedef CStringBase<wchar_t> UString;
+
+typedef CObjectVector<AString> AStringVector;
+typedef CObjectVector<UString> UStringVector;
+
+#ifdef _UNICODE
+ typedef UString CSysString;
+#else
+ typedef AString CSysString;
+#endif
+
+typedef CObjectVector<CSysString> CSysStringVector;
+
+#endif
Added: trunk/lzma/CPP/Common/MyUnknown.h
===================================================================
--- trunk/lzma/CPP/Common/MyUnknown.h (rev 0)
+++ trunk/lzma/CPP/Common/MyUnknown.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// MyUnknown.h
+
+#ifndef __MYUNKNOWN_H
+#define __MYUNKNOWN_H
+
+#ifdef _WIN32
+
+#ifdef _WIN32_WCE
+#if (_WIN32_WCE > 300)
+#include <basetyps.h>
+#else
+#define MIDL_INTERFACE(x) struct
+#endif
+#else
+#include <basetyps.h>
+#endif
+
+#include <unknwn.h>
+
+#else
+#include "MyWindows.h"
+#endif
+
+#endif
Added: trunk/lzma/CPP/Common/MyVector.cpp
===================================================================
--- trunk/lzma/CPP/Common/MyVector.cpp (rev 0)
+++ trunk/lzma/CPP/Common/MyVector.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,78 @@
+// Common/MyVector.cpp
+
+#include "StdAfx.h"
+
+#include <string.h>
+
+#include "MyVector.h"
+
+CBaseRecordVector::~CBaseRecordVector() { Free(); }
+
+void CBaseRecordVector::Free()
+{
+ delete []((unsigned char *)_items);
+ _capacity = 0;
+ _size = 0;
+ _items = 0;
+}
+
+void CBaseRecordVector::Clear() { DeleteFrom(0); }
+void CBaseRecordVector::DeleteBack() { Delete(_size - 1); }
+void CBaseRecordVector::DeleteFrom(int index) { Delete(index, _size - index); }
+
+void CBaseRecordVector::ReserveOnePosition()
+{
+ if (_size != _capacity)
+ return;
+ int delta;
+ if (_capacity > 64)
+ delta = _capacity / 2;
+ else if (_capacity > 8)
+ delta = 8;
+ else
+ delta = 4;
+ Reserve(_capacity + delta);
+}
+
+void CBaseRecordVector::Reserve(int newCapacity)
+{
+ if (newCapacity <= _capacity)
+ return;
+ if ((unsigned)newCapacity >= ((unsigned)1 << (sizeof(unsigned) * 8 - 1)))
+ throw 1052353;
+ size_t newSize = (size_t)(unsigned)newCapacity * _itemSize;
+ if (newSize / _itemSize != (size_t)(unsigned)newCapacity)
+ throw 1052354;
+ unsigned char *p = new unsigned char[newSize];
+ if (p == 0)
+ throw 1052355;
+ int numRecordsToMove = _capacity;
+ memmove(p, _items, _itemSize * numRecordsToMove);
+ delete [](unsigned char *)_items;
+ _items = p;
+ _capacity = newCapacity;
+}
+
+void CBaseRecordVector::MoveItems(int destIndex, int srcIndex)
+{
+ memmove(((unsigned char *)_items) + destIndex * _itemSize,
+ ((unsigned char *)_items) + srcIndex * _itemSize,
+ _itemSize * (_size - srcIndex));
+}
+
+void CBaseRecordVector::InsertOneItem(int index)
+{
+ ReserveOnePosition();
+ MoveItems(index + 1, index);
+ _size++;
+}
+
+void CBaseRecordVector::Delete(int index, int num)
+{
+ TestIndexAndCorrectNum(index, num);
+ if (num > 0)
+ {
+ MoveItems(index, index + num);
+ _size -= num;
+ }
+}
Added: trunk/lzma/CPP/Common/MyVector.h
===================================================================
--- trunk/lzma/CPP/Common/MyVector.h (rev 0)
+++ trunk/lzma/CPP/Common/MyVector.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,254 @@
+// Common/Vector.h
+
+#ifndef __COMMON_VECTOR_H
+#define __COMMON_VECTOR_H
+
+#include "Defs.h"
+
+class CBaseRecordVector
+{
+ void MoveItems(int destIndex, int srcIndex);
+protected:
+ int _capacity;
+ int _size;
+ void *_items;
+ size_t _itemSize;
+
+ void ReserveOnePosition();
+ void InsertOneItem(int index);
+ void TestIndexAndCorrectNum(int index, int &num) const
+ { if (index + num > _size) num = _size - index; }
+public:
+ CBaseRecordVector(size_t itemSize):
+ _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}
+ virtual ~CBaseRecordVector();
+ void Free();
+ int Size() const { return _size; }
+ bool IsEmpty() const { return (_size == 0); }
+ void Reserve(int newCapacity);
+ virtual void Delete(int index, int num = 1);
+ void Clear();
+ void DeleteFrom(int index);
+ void DeleteBack();
+};
+
+template <class T>
+class CRecordVector: public CBaseRecordVector
+{
+public:
+ CRecordVector():CBaseRecordVector(sizeof(T)){};
+ CRecordVector(const CRecordVector &v):
+ CBaseRecordVector(sizeof(T)) { *this = v;}
+ CRecordVector& operator=(const CRecordVector &v)
+ {
+ Clear();
+ return (*this += v);
+ }
+ CRecordVector& operator+=(const CRecordVector &v)
+ {
+ int size = v.Size();
+ Reserve(Size() + size);
+ for(int i = 0; i < size; i++)
+ Add(v[i]);
+ return *this;
+ }
+ int Add(T item)
+ {
+ ReserveOnePosition();
+ ((T *)_items)[_size] = item;
+ return _size++;
+ }
+ void Insert(int index, T item)
+ {
+ InsertOneItem(index);
+ ((T *)_items)[index] = item;
+ }
+ // T* GetPointer() const { return (T*)_items; }
+ // operator const T *() const { return _items; };
+ const T& operator[](int index) const { return ((T *)_items)[index]; }
+ T& operator[](int index) { return ((T *)_items)[index]; }
+ const T& Front() const { return operator[](0); }
+ T& Front() { return operator[](0); }
+ const T& Back() const { return operator[](_size - 1); }
+ T& Back() { return operator[](_size - 1); }
+
+ void Swap(int i, int j)
+ {
+ T temp = operator[](i);
+ operator[](i) = operator[](j);
+ operator[](j) = temp;
+ }
+
+ int FindInSorted(const T& item) const
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ return mid;
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+
+ int AddToUniqueSorted(const T& item)
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ return mid;
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param)
+ {
+ T temp = p[k];
+ for (;;)
+ {
+ int s = (k << 1);
+ if (s > size)
+ break;
+ if (s < size && compare(p + s + 1, p + s, param) > 0)
+ s++;
+ if (compare(&temp, p + s, param) >= 0)
+ break;
+ p[k] = p[s];
+ k = s;
+ }
+ p[k] = temp;
+ }
+
+ void Sort(int (*compare)(const T*, const T*, void *), void *param)
+ {
+ int size = _size;
+ if (size <= 1)
+ return;
+ T* p = (&Front()) - 1;
+ {
+ int i = size / 2;
+ do
+ SortRefDown(p, i, size, compare, param);
+ while(--i != 0);
+ }
+ do
+ {
+ T temp = p[size];
+ p[size--] = p[1];
+ p[1] = temp;
+ SortRefDown(p, 1, size, compare, param);
+ }
+ while (size > 1);
+ }
+};
+
+typedef CRecordVector<int> CIntVector;
+typedef CRecordVector<unsigned int> CUIntVector;
+typedef CRecordVector<bool> CBoolVector;
+typedef CRecordVector<unsigned char> CByteVector;
+typedef CRecordVector<void *> CPointerVector;
+
+template <class T>
+class CObjectVector: public CPointerVector
+{
+public:
+ CObjectVector(){};
+ ~CObjectVector() { Clear(); }
+ CObjectVector(const CObjectVector &objectVector)
+ { *this = objectVector; }
+ CObjectVector& operator=(const CObjectVector &objectVector)
+ {
+ Clear();
+ return (*this += objectVector);
+ }
+ CObjectVector& operator+=(const CObjectVector &objectVector)
+ {
+ int size = objectVector.Size();
+ Reserve(Size() + size);
+ for(int i = 0; i < size; i++)
+ Add(objectVector[i]);
+ return *this;
+ }
+ const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
+ T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
+ T& Front() { return operator[](0); }
+ const T& Front() const { return operator[](0); }
+ T& Back() { return operator[](_size - 1); }
+ const T& Back() const { return operator[](_size - 1); }
+ int Add(const T& item)
+ { return CPointerVector::Add(new T(item)); }
+ void Insert(int index, const T& item)
+ { CPointerVector::Insert(index, new T(item)); }
+ virtual void Delete(int index, int num = 1)
+ {
+ TestIndexAndCorrectNum(index, num);
+ for(int i = 0; i < num; i++)
+ delete (T *)(((void **)_items)[index + i]);
+ CPointerVector::Delete(index, num);
+ }
+ int Find(const T& item) const
+ {
+ for(int i = 0; i < Size(); i++)
+ if (item == (*this)[i])
+ return i;
+ return -1;
+ }
+ int FindInSorted(const T& item) const
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ return mid;
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+ int AddToSorted(const T& item)
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ {
+ right = mid + 1;
+ break;
+ }
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+
+ void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
+ { CPointerVector::Sort(compare, param); }
+
+ static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
+ { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
+ void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
+};
+
+#endif
Added: trunk/lzma/CPP/Common/MyWindows.h
===================================================================
--- trunk/lzma/CPP/Common/MyWindows.h (rev 0)
+++ trunk/lzma/CPP/Common/MyWindows.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,214 @@
+// MyWindows.h
+
+#ifndef __MYWINDOWS_H
+#define __MYWINDOWS_H
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+#define CHAR_PATH_SEPARATOR '\\'
+#define WCHAR_PATH_SEPARATOR L'\\'
+#define STRING_PATH_SEPARATOR "\\"
+#define WSTRING_PATH_SEPARATOR L"\\"
+
+#else
+
+#define CHAR_PATH_SEPARATOR '/'
+#define WCHAR_PATH_SEPARATOR L'/'
+#define STRING_PATH_SEPARATOR "/"
+#define WSTRING_PATH_SEPARATOR L"/"
+
+#include <stddef.h> // for wchar_t
+#include <string.h>
+
+#include "MyGuidDef.h"
+
+typedef char CHAR;
+typedef unsigned char UCHAR;
+
+#undef BYTE
+typedef unsigned char BYTE;
+
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+#undef WORD
+typedef unsigned short WORD;
+typedef short VARIANT_BOOL;
+
+typedef int INT;
+typedef Int32 INT32;
+typedef unsigned int UINT;
+typedef UInt32 UINT32;
+typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
+typedef UINT32 ULONG;
+
+#undef DWORD
+typedef UINT32 DWORD;
+
+typedef Int64 LONGLONG;
+typedef UInt64 ULONGLONG;
+
+typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
+
+typedef const CHAR *LPCSTR;
+typedef CHAR TCHAR;
+typedef const TCHAR *LPCTSTR;
+typedef wchar_t WCHAR;
+typedef WCHAR OLECHAR;
+typedef const WCHAR *LPCWSTR;
+typedef OLECHAR *BSTR;
+typedef const OLECHAR *LPCOLESTR;
+typedef OLECHAR *LPOLESTR;
+
+typedef struct _FILETIME
+{
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+}FILETIME;
+
+#define HRESULT LONG
+#define FAILED(Status) ((HRESULT)(Status)<0)
+typedef ULONG PROPID;
+typedef LONG SCODE;
+
+#define S_OK ((HRESULT)0x00000000L)
+#define S_FALSE ((HRESULT)0x00000001L)
+#define E_NOTIMPL ((HRESULT)0x80004001L)
+#define E_NOINTERFACE ((HRESULT)0x80004002L)
+#define E_ABORT ((HRESULT)0x80004004L)
+#define E_FAIL ((HRESULT)0x80004005L)
+#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
+#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
+#define E_INVALIDARG ((HRESULT)0x80070057L)
+
+#ifdef _MSC_VER
+#define STDMETHODCALLTYPE __stdcall
+#else
+#define STDMETHODCALLTYPE
+#endif
+
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)
+
+#define PURE = 0
+
+#define MIDL_INTERFACE(x) struct
+
+#ifdef __cplusplus
+
+DEFINE_GUID(IID_IUnknown,
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+struct IUnknown
+{
+ STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
+ STDMETHOD_(ULONG, AddRef)() PURE;
+ STDMETHOD_(ULONG, Release)() PURE;
+ #ifndef _WIN32
+ virtual ~IUnknown() {}
+ #endif
+};
+
+typedef IUnknown *LPUNKNOWN;
+
+#endif
+
+#define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#define VARIANT_FALSE ((VARIANT_BOOL)0)
+
+enum VARENUM
+{
+ VT_EMPTY = 0,
+ VT_NULL = 1,
+ VT_I2 = 2,
+ VT_I4 = 3,
+ VT_R4 = 4,
+ VT_R8 = 5,
+ VT_CY = 6,
+ VT_DATE = 7,
+ VT_BSTR = 8,
+ VT_DISPATCH = 9,
+ VT_ERROR = 10,
+ VT_BOOL = 11,
+ VT_VARIANT = 12,
+ VT_UNKNOWN = 13,
+ VT_DECIMAL = 14,
+ VT_I1 = 16,
+ VT_UI1 = 17,
+ VT_UI2 = 18,
+ VT_UI4 = 19,
+ VT_I8 = 20,
+ VT_UI8 = 21,
+ VT_INT = 22,
+ VT_UINT = 23,
+ VT_VOID = 24,
+ VT_HRESULT = 25,
+ VT_FILETIME = 64
+};
+
+typedef unsigned short VARTYPE;
+typedef WORD PROPVAR_PAD1;
+typedef WORD PROPVAR_PAD2;
+typedef WORD PROPVAR_PAD3;
+
+#ifdef __cplusplus
+
+typedef struct tagPROPVARIANT
+{
+ VARTYPE vt;
+ PROPVAR_PAD1 wReserved1;
+ PROPVAR_PAD2 wReserved2;
+ PROPVAR_PAD3 wReserved3;
+ union
+ {
+ CHAR cVal;
+ UCHAR bVal;
+ SHORT iVal;
+ USHORT uiVal;
+ LONG lVal;
+ ULONG ulVal;
+ INT intVal;
+ UINT uintVal;
+ LARGE_INTEGER hVal;
+ ULARGE_INTEGER uhVal;
+ VARIANT_BOOL boolVal;
+ SCODE scode;
+ FILETIME filetime;
+ BSTR bstrVal;
+ };
+} PROPVARIANT;
+
+typedef PROPVARIANT tagVARIANT;
+typedef tagVARIANT VARIANT;
+typedef VARIANT VARIANTARG;
+
+MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+
+#endif
+
+MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
+MY_EXTERN_C void SysFreeString(BSTR bstr);
+MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
+MY_EXTERN_C UINT SysStringLen(BSTR bstr);
+
+MY_EXTERN_C DWORD GetLastError();
+MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
+
+#define CP_ACP 0
+#define CP_OEMCP 1
+
+typedef enum tagSTREAM_SEEK
+{
+ STREAM_SEEK_SET = 0,
+ STREAM_SEEK_CUR = 1,
+ STREAM_SEEK_END = 2
+} STREAM_SEEK;
+
+#endif
+#endif
Added: trunk/lzma/CPP/Common/NewHandler.cpp
===================================================================
--- trunk/lzma/CPP/Common/NewHandler.cpp (rev 0)
+++ trunk/lzma/CPP/Common/NewHandler.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,116 @@
+// NewHandler.cpp
+
+#include "StdAfx.h"
+
+#include <stdlib.h>
+
+#include "NewHandler.h"
+
+// #define DEBUG_MEMORY_LEAK
+
+#ifndef DEBUG_MEMORY_LEAK
+
+#ifdef _WIN32
+void *
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete(void *p) throw()
+{
+ /*
+ if (p == 0)
+ return;
+ ::HeapFree(::GetProcessHeap(), 0, p);
+ */
+ ::free(p);
+}
+#endif
+
+#else
+
+#pragma init_seg(lib)
+const int kDebugSize = 1000000;
+static void *a[kDebugSize];
+static int index = 0;
+
+static int numAllocs = 0;
+void * __cdecl operator new(size_t size)
+{
+ numAllocs++;
+ void *p = HeapAlloc(GetProcessHeap(), 0, size);
+ if (index == 40)
+ {
+ int t = 1;
+ }
+ if (index < kDebugSize)
+ {
+ a[index] = p;
+ index++;
+ }
+ if (p == 0)
+ throw CNewException();
+ printf("Alloc %6d, size = %8d\n", numAllocs, size);
+ return p;
+}
+
+class CC
+{
+public:
+ CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ a[i] = 0;
+ }
+ ~CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ if (a[i] != 0)
+ return;
+ }
+} g_CC;
+
+
+void __cdecl operator delete(void *p)
+{
+ if (p == 0)
+ return;
+ /*
+ for (int i = 0; i < index; i++)
+ if (a[i] == p)
+ a[i] = 0;
+ */
+ HeapFree(GetProcessHeap(), 0, p);
+ numAllocs--;
+ printf("Free %d\n", numAllocs);
+}
+
+#endif
+
+/*
+int MemErrorVC(size_t)
+{
+ throw CNewException();
+ // return 1;
+}
+CNewHandlerSetter::CNewHandlerSetter()
+{
+ // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
+}
+CNewHandlerSetter::~CNewHandlerSetter()
+{
+ // _set_new_handler(MemErrorOldVCFunction);
+}
+*/
Added: trunk/lzma/CPP/Common/NewHandler.h
===================================================================
--- trunk/lzma/CPP/Common/NewHandler.h (rev 0)
+++ trunk/lzma/CPP/Common/NewHandler.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,16 @@
+// Common/NewHandler.h
+
+#ifndef __COMMON_NEWHANDLER_H
+#define __COMMON_NEWHANDLER_H
+
+class CNewException {};
+
+#ifdef _WIN32
+void
+#ifdef _MSC_VER
+__cdecl
+#endif
+operator delete(void *p) throw();
+#endif
+
+#endif
Added: trunk/lzma/CPP/Common/StdAfx.h
===================================================================
--- trunk/lzma/CPP/Common/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/Common/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+// #include "MyWindows.h"
+#include "NewHandler.h"
+
+#endif
Added: trunk/lzma/CPP/Common/StdInStream.cpp
===================================================================
--- trunk/lzma/CPP/Common/StdInStream.cpp (rev 0)
+++ trunk/lzma/CPP/Common/StdInStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,84 @@
+// Common/StdInStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+#include "StdInStream.h"
+
+#ifdef _MSC_VER
+// "was declared deprecated" disabling
+#pragma warning(disable : 4996 )
+#endif
+
+static const char kIllegalChar = '\0';
+static const char kNewLineChar = '\n';
+
+static const char *kEOFMessage = "Unexpected end of input stream";
+static const char *kReadErrorMessage ="Error reading input stream";
+static const char *kIllegalCharMessage = "Illegal character in input stream";
+
+static LPCTSTR kFileOpenMode = TEXT("r");
+
+CStdInStream g_StdIn(stdin);
+
+bool CStdInStream::Open(LPCTSTR fileName)
+{
+ Close();
+ _stream = _tfopen(fileName, kFileOpenMode);
+ _streamIsOpen = (_stream != 0);
+ return _streamIsOpen;
+}
+
+bool CStdInStream::Close()
+{
+ if(!_streamIsOpen)
+ return true;
+ _streamIsOpen = (fclose(_stream) != 0);
+ return !_streamIsOpen;
+}
+
+CStdInStream::~CStdInStream()
+{
+ Close();
+}
+
+AString CStdInStream::ScanStringUntilNewLine()
+{
+ AString s;
+ for (;;)
+ {
+ int intChar = GetChar();
+ if(intChar == EOF)
+ throw kEOFMessage;
+ char c = char(intChar);
+ if (c == kIllegalChar)
+ throw kIllegalCharMessage;
+ if(c == kNewLineChar)
+ break;
+ s += c;
+ }
+ return s;
+}
+
+void CStdInStream::ReadToString(AString &resultString)
+{
+ resultString.Empty();
+ int c;
+ while((c = GetChar()) != EOF)
+ resultString += char(c);
+}
+
+bool CStdInStream::Eof()
+{
+ return (feof(_stream) != 0);
+}
+
+int CStdInStream::GetChar()
+{
+ int c = fgetc(_stream); // getc() doesn't work in BeOS?
+ if(c == EOF && !Eof())
+ throw kReadErrorMessage;
+ return c;
+}
+
+
Added: trunk/lzma/CPP/Common/StdInStream.h
===================================================================
--- trunk/lzma/CPP/Common/StdInStream.h (rev 0)
+++ trunk/lzma/CPP/Common/StdInStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,31 @@
+// Common/StdInStream.h
+
+#ifndef __COMMON_STDINSTREAM_H
+#define __COMMON_STDINSTREAM_H
+
+#include <stdio.h>
+
+#include "MyString.h"
+#include "Types.h"
+
+class CStdInStream
+{
+ bool _streamIsOpen;
+ FILE *_stream;
+public:
+ CStdInStream(): _streamIsOpen(false) {};
+ CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {};
+ ~CStdInStream();
+ bool Open(LPCTSTR fileName);
+ bool Close();
+
+ AString ScanStringUntilNewLine();
+ void ReadToString(AString &resultString);
+
+ bool Eof();
+ int GetChar();
+};
+
+extern CStdInStream g_StdIn;
+
+#endif
Added: trunk/lzma/CPP/Common/StdOutStream.cpp
===================================================================
--- trunk/lzma/CPP/Common/StdOutStream.cpp (rev 0)
+++ trunk/lzma/CPP/Common/StdOutStream.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,93 @@
+// Common/StdOutStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+
+#include "StdOutStream.h"
+#include "IntToString.h"
+#include "StringConvert.h"
+
+#ifdef _MSC_VER
+// "was declared deprecated" disabling
+#pragma warning(disable : 4996 )
+#endif
+
+static const char kNewLineChar = '\n';
+
+static const char *kFileOpenMode = "wt";
+
+CStdOutStream g_StdOut(stdout);
+CStdOutStream g_StdErr(stderr);
+
+bool CStdOutStream::Open(const char *fileName)
+{
+ Close();
+ _stream = fopen(fileName, kFileOpenMode);
+ _streamIsOpen = (_stream != 0);
+ return _streamIsOpen;
+}
+
+bool CStdOutStream::Close()
+{
+ if(!_streamIsOpen)
+ return true;
+ if (fclose(_stream) != 0)
+ return false;
+ _stream = 0;
+ _streamIsOpen = false;
+ return true;
+}
+
+bool CStdOutStream::Flush()
+{
+ return (fflush(_stream) == 0);
+}
+
+CStdOutStream::~CStdOutStream ()
+{
+ Close();
+}
+
+CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &))
+{
+ (*aFunction)(*this);
+ return *this;
+}
+
+CStdOutStream & endl(CStdOutStream & outStream)
+{
+ return outStream << kNewLineChar;
+}
+
+CStdOutStream & CStdOutStream::operator<<(const char *string)
+{
+ fputs(string, _stream);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(const wchar_t *string)
+{
+ *this << (const char *)UnicodeStringToMultiByte(string, CP_OEMCP);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(char c)
+{
+ fputc(c, _stream);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(int number)
+{
+ char textString[32];
+ ConvertInt64ToString(number, textString);
+ return operator<<(textString);
+}
+
+CStdOutStream & CStdOutStream::operator<<(UInt64 number)
+{
+ char textString[32];
+ ConvertUInt64ToString(number, textString);
+ return operator<<(textString);
+}
Added: trunk/lzma/CPP/Common/StdOutStream.h
===================================================================
--- trunk/lzma/CPP/Common/StdOutStream.h (rev 0)
+++ trunk/lzma/CPP/Common/StdOutStream.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,35 @@
+// Common/StdOutStream.h
+
+#ifndef __COMMON_STDOUTSTREAM_H
+#define __COMMON_STDOUTSTREAM_H
+
+#include <stdio.h>
+
+#include "Types.h"
+
+class CStdOutStream
+{
+ bool _streamIsOpen;
+ FILE *_stream;
+public:
+ CStdOutStream (): _streamIsOpen(false), _stream(0) {};
+ CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {};
+ ~CStdOutStream ();
+ operator FILE *() { return _stream; }
+ bool Open(const char *fileName);
+ bool Close();
+ bool Flush();
+ CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream &));
+ CStdOutStream & operator<<(const char *string);
+ CStdOutStream & operator<<(const wchar_t *string);
+ CStdOutStream & operator<<(char c);
+ CStdOutStream & operator<<(int number);
+ CStdOutStream & operator<<(UInt64 number);
+};
+
+CStdOutStream & endl(CStdOutStream & outStream);
+
+extern CStdOutStream g_StdOut;
+extern CStdOutStream g_StdErr;
+
+#endif
Added: trunk/lzma/CPP/Common/StringConvert.cpp
===================================================================
--- trunk/lzma/CPP/Common/StringConvert.cpp (rev 0)
+++ trunk/lzma/CPP/Common/StringConvert.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,94 @@
+// Common/StringConvert.cpp
+
+#include "StdAfx.h"
+
+#include "StringConvert.h"
+
+#ifndef _WIN32
+#include <stdlib.h>
+#endif
+
+#ifdef _WIN32
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+ UString resultString;
+ if(!srcString.IsEmpty())
+ {
+ int numChars = MultiByteToWideChar(codePage, 0, srcString,
+ srcString.Length(), resultString.GetBuffer(srcString.Length()),
+ srcString.Length() + 1);
+ #ifndef _WIN32_WCE
+ if(numChars == 0)
+ throw 282228;
+ #endif
+ resultString.ReleaseBuffer(numChars);
+ }
+ return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+ AString resultString;
+ if(!srcString.IsEmpty())
+ {
+ int numRequiredBytes = srcString.Length() * 2;
+ char defaultChar = '_';
+ int numChars = WideCharToMultiByte(codePage, 0, srcString,
+ srcString.Length(), resultString.GetBuffer(numRequiredBytes),
+ numRequiredBytes + 1, &defaultChar, NULL);
+ #ifndef _WIN32_WCE
+ if(numChars == 0)
+ throw 282229;
+ #endif
+ resultString.ReleaseBuffer(numChars);
+ }
+ return resultString;
+}
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString)
+{
+ AString result;
+ CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
+ result.ReleaseBuffer();
+ return result;
+}
+#endif
+
+#else
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+ UString resultString;
+ for (int i = 0; i < srcString.Length(); i++)
+ resultString += wchar_t(srcString[i]);
+ /*
+ if(!srcString.IsEmpty())
+ {
+ int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1);
+ if (numChars < 0) throw "Your environment does not support UNICODE";
+ resultString.ReleaseBuffer(numChars);
+ }
+ */
+ return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+ AString resultString;
+ for (int i = 0; i < srcString.Length(); i++)
+ resultString += char(srcString[i]);
+ /*
+ if(!srcString.IsEmpty())
+ {
+ int numRequiredBytes = srcString.Length() * 6 + 1;
+ int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
+ if (numChars < 0) throw "Your environment does not support UNICODE";
+ resultString.ReleaseBuffer(numChars);
+ }
+ */
+ return resultString;
+}
+
+#endif
+
Added: trunk/lzma/CPP/Common/StringConvert.h
===================================================================
--- trunk/lzma/CPP/Common/StringConvert.h (rev 0)
+++ trunk/lzma/CPP/Common/StringConvert.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,71 @@
+// Common/StringConvert.h
+
+#ifndef __COMMON_STRINGCONVERT_H
+#define __COMMON_STRINGCONVERT_H
+
+#include "MyWindows.h"
+#include "MyString.h"
+#include "Types.h"
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
+
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
+ { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString)
+ { return unicodeString; }
+inline UString GetUnicodeString(const AString &ansiString)
+ { return MultiByteToUnicodeString(ansiString); }
+inline UString GetUnicodeString(const AString &multiByteString, UINT codePage)
+ { return MultiByteToUnicodeString(multiByteString, codePage); }
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT)
+ { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString, UINT)
+ { return unicodeString; }
+
+inline const char* GetAnsiString(const char* ansiString)
+ { return ansiString; }
+inline const AString& GetAnsiString(const AString &ansiString)
+ { return ansiString; }
+inline AString GetAnsiString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString); }
+
+inline const char* GetOemString(const char* oemString)
+ { return oemString; }
+inline const AString& GetOemString(const AString &oemString)
+ { return oemString; }
+inline AString GetOemString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); }
+
+
+#ifdef _UNICODE
+ inline const wchar_t* GetSystemString(const wchar_t* unicodeString)
+ { return unicodeString;}
+ inline const UString& GetSystemString(const UString &unicodeString)
+ { return unicodeString;}
+ inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */)
+ { return unicodeString;}
+ inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */)
+ { return unicodeString;}
+ inline UString GetSystemString(const AString &multiByteString, UINT codePage)
+ { return MultiByteToUnicodeString(multiByteString, codePage);}
+ inline UString GetSystemString(const AString &multiByteString)
+ { return MultiByteToUnicodeString(multiByteString);}
+#else
+ inline const char* GetSystemString(const char *ansiString)
+ { return ansiString; }
+ inline const AString& GetSystemString(const AString &multiByteString, UINT)
+ { return multiByteString; }
+ inline const char * GetSystemString(const char *multiByteString, UINT)
+ { return multiByteString; }
+ inline AString GetSystemString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString); }
+ inline AString GetSystemString(const UString &unicodeString, UINT codePage)
+ { return UnicodeStringToMultiByte(unicodeString, codePage); }
+#endif
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString);
+#endif
+
+#endif
Added: trunk/lzma/CPP/Common/StringToInt.cpp
===================================================================
--- trunk/lzma/CPP/Common/StringToInt.cpp (rev 0)
+++ trunk/lzma/CPP/Common/StringToInt.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,68 @@
+// Common/StringToInt.cpp
+
+#include "StdAfx.h"
+
+#include "StringToInt.h"
+
+UInt64 ConvertStringToUInt64(const char *s, const char **end)
+{
+ UInt64 result = 0;
+ for (;;)
+ {
+ char c = *s;
+ if (c < '0' || c > '9')
+ {
+ if (end != NULL)
+ *end = s;
+ return result;
+ }
+ result *= 10;
+ result += (c - '0');
+ s++;
+ }
+}
+
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end)
+{
+ UInt64 result = 0;
+ for (;;)
+ {
+ char c = *s;
+ if (c < '0' || c > '7')
+ {
+ if (end != NULL)
+ *end = s;
+ return result;
+ }
+ result <<= 3;
+ result += (c - '0');
+ s++;
+ }
+}
+
+
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end)
+{
+ UInt64 result = 0;
+ for (;;)
+ {
+ wchar_t c = *s;
+ if (c < '0' || c > '9')
+ {
+ if (end != NULL)
+ *end = s;
+ return result;
+ }
+ result *= 10;
+ result += (c - '0');
+ s++;
+ }
+}
+
+
+Int64 ConvertStringToInt64(const char *s, const char **end)
+{
+ if (*s == '-')
+ return -(Int64)ConvertStringToUInt64(s + 1, end);
+ return ConvertStringToUInt64(s, end);
+}
Added: trunk/lzma/CPP/Common/StringToInt.h
===================================================================
--- trunk/lzma/CPP/Common/StringToInt.h (rev 0)
+++ trunk/lzma/CPP/Common/StringToInt.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,17 @@
+// Common/StringToInt.h
+
+#ifndef __COMMON_STRINGTOINT_H
+#define __COMMON_STRINGTOINT_H
+
+#include <string.h>
+#include "Types.h"
+
+UInt64 ConvertStringToUInt64(const char *s, const char **end);
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end);
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end);
+
+Int64 ConvertStringToInt64(const char *s, const char **end);
+
+#endif
+
+
Added: trunk/lzma/CPP/Common/Types.h
===================================================================
--- trunk/lzma/CPP/Common/Types.h (rev 0)
+++ trunk/lzma/CPP/Common/Types.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,57 @@
+// Common/Types.h
+
+#ifndef __COMMON_TYPES_H
+#define __COMMON_TYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif
+
+#ifndef _7ZIP_INT16_DEFINED
+#define _7ZIP_INT16_DEFINED
+typedef short Int16;
+#endif
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif
+
+#ifndef _7ZIP_INT32_DEFINED
+#define _7ZIP_INT32_DEFINED
+typedef int Int32;
+#endif
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _MSC_VER
+
+#ifndef _7ZIP_INT64_DEFINED
+#define _7ZIP_INT64_DEFINED
+typedef __int64 Int64;
+#endif
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+typedef unsigned __int64 UInt64;
+#endif
+
+#else
+
+#ifndef _7ZIP_INT64_DEFINED
+#define _7ZIP_INT64_DEFINED
+typedef long long int Int64;
+#endif
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#endif
Added: trunk/lzma/CPP/Common/UTFConvert.cpp
===================================================================
--- trunk/lzma/CPP/Common/UTFConvert.cpp (rev 0)
+++ trunk/lzma/CPP/Common/UTFConvert.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,91 @@
+// UTFConvert.cpp
+
+#include "StdAfx.h"
+
+#include "UTFConvert.h"
+#include "Types.h"
+
+static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+// These functions are for UTF8 <-> UTF16 conversion.
+
+bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
+{
+ dest.Empty();
+ for(int i = 0; i < src.Length();)
+ {
+ Byte c = (Byte)src[i++];
+ if (c < 0x80)
+ {
+ dest += (wchar_t)c;
+ continue;
+ }
+ if(c < 0xC0)
+ return false;
+ int numAdds;
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (c < kUtf8Limits[numAdds])
+ break;
+ UInt32 value = (c - kUtf8Limits[numAdds - 1]);
+ do
+ {
+ if (i >= src.Length())
+ return false;
+ Byte c2 = (Byte)src[i++];
+ if (c2 < 0x80 || c2 >= 0xC0)
+ return false;
+ value <<= 6;
+ value |= (c2 - 0x80);
+ numAdds--;
+ }
+ while(numAdds > 0);
+ if (value < 0x10000)
+ dest += (wchar_t)(value);
+ else
+ {
+ value -= 0x10000;
+ if (value >= 0x100000)
+ return false;
+ dest += (wchar_t)(0xD800 + (value >> 10));
+ dest += (wchar_t)(0xDC00 + (value & 0x3FF));
+ }
+ }
+ return true;
+}
+
+bool ConvertUnicodeToUTF8(const UString &src, AString &dest)
+{
+ dest.Empty();
+ for(int i = 0; i < src.Length();)
+ {
+ UInt32 value = (UInt32)src[i++];
+ if (value < 0x80)
+ {
+ dest += (char)value;
+ continue;
+ }
+ if (value >= 0xD800 && value < 0xE000)
+ {
+ if (value >= 0xDC00)
+ return false;
+ if (i >= src.Length())
+ return false;
+ UInt32 c2 = (UInt32)src[i++];
+ if (c2 < 0xDC00 || c2 >= 0xE000)
+ return false;
+ value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+ }
+ int numAdds;
+ for (numAdds = 1; numAdds < 5; numAdds++)
+ if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+ break;
+ dest += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+ do
+ {
+ numAdds--;
+ dest += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+ }
+ while(numAdds > 0);
+ }
+ return true;
+}
Added: trunk/lzma/CPP/Common/UTFConvert.h
===================================================================
--- trunk/lzma/CPP/Common/UTFConvert.h (rev 0)
+++ trunk/lzma/CPP/Common/UTFConvert.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,11 @@
+// Common/UTFConvert.h
+
+#ifndef __COMMON_UTFCONVERT_H
+#define __COMMON_UTFCONVERT_H
+
+#include "MyString.h"
+
+bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
+bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
+
+#endif
Added: trunk/lzma/CPP/Common/Wildcard.cpp
===================================================================
--- trunk/lzma/CPP/Common/Wildcard.cpp (rev 0)
+++ trunk/lzma/CPP/Common/Wildcard.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,458 @@
+// Common/Wildcard.cpp
+
+#include "StdAfx.h"
+
+#include "Wildcard.h"
+
+bool g_CaseSensitive =
+ #ifdef _WIN32
+ false;
+ #else
+ true;
+ #endif
+
+static const wchar_t kAnyCharsChar = L'*';
+static const wchar_t kAnyCharChar = L'?';
+
+#ifdef _WIN32
+static const wchar_t kDirDelimiter1 = L'\\';
+#endif
+static const wchar_t kDirDelimiter2 = L'/';
+
+static const UString kWildCardCharSet = L"?*";
+
+static const UString kIllegalWildCardFileNameChars=
+ L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"
+ L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+ L"\"/:<>\\|";
+
+
+static inline bool IsCharDirLimiter(wchar_t c)
+{
+ return (
+ #ifdef _WIN32
+ c == kDirDelimiter1 ||
+ #endif
+ c == kDirDelimiter2);
+}
+
+int CompareFileNames(const UString &s1, const UString &s2)
+{
+ if (g_CaseSensitive)
+ return s1.Compare(s2);
+ return s1.CompareNoCase(s2);
+}
+
+// -----------------------------------------
+// this function compares name with mask
+// ? - any char
+// * - any char or empty
+
+static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
+{
+ for (;;)
+ {
+ wchar_t m = *mask;
+ wchar_t c = *name;
+ if (m == 0)
+ return (c == 0);
+ if (m == kAnyCharsChar)
+ {
+ if (EnhancedMaskTest(mask + 1, name))
+ return true;
+ if (c == 0)
+ return false;
+ }
+ else
+ {
+ if (m == kAnyCharChar)
+ {
+ if (c == 0)
+ return false;
+ }
+ else if (m != c)
+ if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c))
+ return false;
+ mask++;
+ }
+ name++;
+ }
+}
+
+// --------------------------------------------------
+// Splits path to strings
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts)
+{
+ pathParts.Clear();
+ UString name;
+ int len = path.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = path[i];
+ if (IsCharDirLimiter(c))
+ {
+ pathParts.Add(name);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ pathParts.Add(name);
+}
+
+void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name)
+{
+ int i;
+ for(i = path.Length() - 1; i >= 0; i--)
+ if(IsCharDirLimiter(path[i]))
+ break;
+ dirPrefix = path.Left(i + 1);
+ name = path.Mid(i + 1);
+}
+
+UString ExtractDirPrefixFromPath(const UString &path)
+{
+ int i;
+ for(i = path.Length() - 1; i >= 0; i--)
+ if(IsCharDirLimiter(path[i]))
+ break;
+ return path.Left(i + 1);
+}
+
+UString ExtractFileNameFromPath(const UString &path)
+{
+ int i;
+ for(i = path.Length() - 1; i >= 0; i--)
+ if(IsCharDirLimiter(path[i]))
+ break;
+ return path.Mid(i + 1);
+}
+
+
+bool CompareWildCardWithName(const UString &mask, const UString &name)
+{
+ return EnhancedMaskTest(mask, name);
+}
+
+bool DoesNameContainWildCard(const UString &path)
+{
+ return (path.FindOneOf(kWildCardCharSet) >= 0);
+}
+
+
+// ----------------------------------------------------------'
+// NWildcard
+
+namespace NWildcard {
+
+
+/*
+M = MaskParts.Size();
+N = TestNameParts.Size();
+
+ File Dir
+ForFile req M<=N [N-M, N) -
+ nonreq M=N [0, M) -
+
+ForDir req M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File
+ nonreq [0, M) same as ForBoth-File
+
+ForBoth req m<=N [0, M) ... [N-M, N) same as ForBoth-File
+ nonreq [0, M) same as ForBoth-File
+
+*/
+
+bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
+{
+ if (!isFile && !ForDir)
+ return false;
+ int delta = (int)pathParts.Size() - (int)PathParts.Size();
+ if (delta < 0)
+ return false;
+ int start = 0;
+ int finish = 0;
+ if (isFile)
+ {
+ if (!ForDir && !Recursive && delta !=0)
+ return false;
+ if (!ForFile && delta == 0)
+ return false;
+ if (!ForDir && Recursive)
+ start = delta;
+ }
+ if (Recursive)
+ {
+ finish = delta;
+ if (isFile && !ForFile)
+ finish = delta - 1;
+ }
+ for (int d = start; d <= finish; d++)
+ {
+ int i;
+ for (i = 0; i < PathParts.Size(); i++)
+ if (!CompareWildCardWithName(PathParts[i], pathParts[i + d]))
+ break;
+ if (i == PathParts.Size())
+ return true;
+ }
+ return false;
+}
+
+int CCensorNode::FindSubNode(const UString &name) const
+{
+ for (int i = 0; i < SubNodes.Size(); i++)
+ if (CompareFileNames(SubNodes[i].Name, name) == 0)
+ return i;
+ return -1;
+}
+
+void CCensorNode::AddItemSimple(bool include, CItem &item)
+{
+ if (include)
+ IncludeItems.Add(item);
+ else
+ ExcludeItems.Add(item);
+}
+
+void CCensorNode::AddItem(bool include, CItem &item)
+{
+ if (item.PathParts.Size() <= 1)
+ {
+ AddItemSimple(include, item);
+ return;
+ }
+ const UString &front = item.PathParts.Front();
+ if (DoesNameContainWildCard(front))
+ {
+ AddItemSimple(include, item);
+ return;
+ }
+ int index = FindSubNode(front);
+ if (index < 0)
+ index = SubNodes.Add(CCensorNode(front, this));
+ item.PathParts.Delete(0);
+ SubNodes[index].AddItem(include, item);
+}
+
+void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir)
+{
+ CItem item;
+ SplitPathToParts(path, item.PathParts);
+ item.Recursive = recursive;
+ item.ForFile = forFile;
+ item.ForDir = forDir;
+ AddItem(include, item);
+}
+
+bool CCensorNode::NeedCheckSubDirs() const
+{
+ for (int i = 0; i < IncludeItems.Size(); i++)
+ {
+ const CItem &item = IncludeItems[i];
+ if (item.Recursive || item.PathParts.Size() > 1)
+ return true;
+ }
+ return false;
+}
+
+bool CCensorNode::AreThereIncludeItems() const
+{
+ if (IncludeItems.Size() > 0)
+ return true;
+ for (int i = 0; i < SubNodes.Size(); i++)
+ if (SubNodes[i].AreThereIncludeItems())
+ return true;
+ return false;
+}
+
+bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
+{
+ const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
+ for (int i = 0; i < items.Size(); i++)
+ if (items[i].CheckPath(pathParts, isFile))
+ return true;
+ return false;
+}
+
+bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const
+{
+ if (CheckPathCurrent(false, pathParts, isFile))
+ {
+ include = false;
+ return true;
+ }
+ include = true;
+ bool finded = CheckPathCurrent(true, pathParts, isFile);
+ if (pathParts.Size() == 1)
+ return finded;
+ int index = FindSubNode(pathParts.Front());
+ if (index >= 0)
+ {
+ UStringVector pathParts2 = pathParts;
+ pathParts2.Delete(0);
+ if (SubNodes[index].CheckPath(pathParts2, isFile, include))
+ return true;
+ }
+ return finded;
+}
+
+bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ return CheckPath(pathParts, isFile, include);
+}
+
+bool CCensorNode::CheckPath(const UString &path, bool isFile) const
+{
+ bool include;
+ if(CheckPath(path, isFile, include))
+ return include;
+ return false;
+}
+
+bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
+{
+ if (CheckPathCurrent(include, pathParts, isFile))
+ return true;
+ if (Parent == 0)
+ return false;
+ pathParts.Insert(0, Name);
+ return Parent->CheckPathToRoot(include, pathParts, isFile);
+}
+
+/*
+bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ return CheckPathToRoot(include, pathParts, isFile);
+}
+*/
+
+void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
+{
+ if (path.IsEmpty())
+ return;
+ bool forFile = true;
+ bool forFolder = true;
+ UString path2 = path;
+ if (IsCharDirLimiter(path[path.Length() - 1]))
+ {
+ path2.Delete(path.Length() - 1);
+ forFile = false;
+ }
+ AddItem(include, path2, recursive, forFile, forFolder);
+}
+
+void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
+{
+ ExcludeItems += fromNodes.ExcludeItems;
+ for (int i = 0; i < fromNodes.SubNodes.Size(); i++)
+ {
+ const CCensorNode &node = fromNodes.SubNodes[i];
+ int subNodeIndex = FindSubNode(node.Name);
+ if (subNodeIndex < 0)
+ subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this));
+ SubNodes[subNodeIndex].ExtendExclude(node);
+ }
+}
+
+int CCensor::FindPrefix(const UString &prefix) const
+{
+ for (int i = 0; i < Pairs.Size(); i++)
+ if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
+ return i;
+ return -1;
+}
+
+void CCensor::AddItem(bool include, const UString &path, bool recursive)
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ bool forFile = true;
+ if (pathParts.Back().IsEmpty())
+ {
+ forFile = false;
+ pathParts.DeleteBack();
+ }
+ const UString &front = pathParts.Front();
+ bool isAbs = false;
+ if (front.IsEmpty())
+ isAbs = true;
+ else if (front.Length() == 2 && front[1] == L':')
+ isAbs = true;
+ else
+ {
+ for (int i = 0; i < pathParts.Size(); i++)
+ {
+ const UString &part = pathParts[i];
+ if (part == L".." || part == L".")
+ {
+ isAbs = true;
+ break;
+ }
+ }
+ }
+ int numAbsParts = 0;
+ if (isAbs)
+ if (pathParts.Size() > 1)
+ numAbsParts = pathParts.Size() - 1;
+ else
+ numAbsParts = 1;
+ UString prefix;
+ for (int i = 0; i < numAbsParts; i++)
+ {
+ const UString &front = pathParts.Front();
+ if (DoesNameContainWildCard(front))
+ break;
+ prefix += front;
+ prefix += WCHAR_PATH_SEPARATOR;
+ pathParts.Delete(0);
+ }
+ int index = FindPrefix(prefix);
+ if (index < 0)
+ index = Pairs.Add(CPair(prefix));
+
+ CItem item;
+ item.PathParts = pathParts;
+ item.ForDir = true;
+ item.ForFile = forFile;
+ item.Recursive = recursive;
+ Pairs[index].Head.AddItem(include, item);
+}
+
+bool CCensor::CheckPath(const UString &path, bool isFile) const
+{
+ bool finded = false;
+ for (int i = 0; i < Pairs.Size(); i++)
+ {
+ bool include;
+ if (Pairs[i].Head.CheckPath(path, isFile, include))
+ {
+ if (!include)
+ return false;
+ finded = true;
+ }
+ }
+ return finded;
+}
+
+void CCensor::ExtendExclude()
+{
+ int i;
+ for (i = 0; i < Pairs.Size(); i++)
+ if (Pairs[i].Prefix.IsEmpty())
+ break;
+ if (i == Pairs.Size())
+ return;
+ int index = i;
+ for (i = 0; i < Pairs.Size(); i++)
+ if (index != i)
+ Pairs[i].Head.ExtendExclude(Pairs[index].Head);
+}
+
+}
Added: trunk/lzma/CPP/Common/Wildcard.h
===================================================================
--- trunk/lzma/CPP/Common/Wildcard.h (rev 0)
+++ trunk/lzma/CPP/Common/Wildcard.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,80 @@
+// Common/Wildcard.h
+
+#ifndef __COMMON_WILDCARD_H
+#define __COMMON_WILDCARD_H
+
+#include "MyString.h"
+
+int CompareFileNames(const UString &s1, const UString &s2);
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts);
+void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name);
+UString ExtractDirPrefixFromPath(const UString &path);
+UString ExtractFileNameFromPath(const UString &path);
+bool DoesNameContainWildCard(const UString &path);
+bool CompareWildCardWithName(const UString &mask, const UString &name);
+
+namespace NWildcard {
+
+struct CItem
+{
+ UStringVector PathParts;
+ bool Recursive;
+ bool ForFile;
+ bool ForDir;
+ bool CheckPath(const UStringVector &pathParts, bool isFile) const;
+};
+
+class CCensorNode
+{
+ CCensorNode *Parent;
+ bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;
+ void AddItemSimple(bool include, CItem &item);
+ bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const;
+public:
+ CCensorNode(): Parent(0) { };
+ CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { };
+ UString Name;
+ CObjectVector<CCensorNode> SubNodes;
+ CObjectVector<CItem> IncludeItems;
+ CObjectVector<CItem> ExcludeItems;
+
+ int FindSubNode(const UString &path) const;
+
+ void AddItem(bool include, CItem &item);
+ void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir);
+ void AddItem2(bool include, const UString &path, bool recursive);
+
+ bool NeedCheckSubDirs() const;
+ bool AreThereIncludeItems() const;
+
+ bool CheckPath(const UString &path, bool isFile, bool &include) const;
+ bool CheckPath(const UString &path, bool isFile) const;
+
+ bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const;
+ // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const;
+ void ExtendExclude(const CCensorNode &fromNodes);
+};
+
+struct CPair
+{
+ UString Prefix;
+ CCensorNode Head;
+ CPair(const UString &prefix): Prefix(prefix) { };
+};
+
+class CCensor
+{
+ int FindPrefix(const UString &prefix) const;
+public:
+ CObjectVector<CPair> Pairs;
+ bool AllAreRelative() const
+ { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }
+ void AddItem(bool include, const UString &path, bool recursive);
+ bool CheckPath(const UString &path, bool isFile) const;
+ void ExtendExclude();
+};
+
+}
+
+#endif
Added: trunk/lzma/CPP/Windows/DLL.cpp
===================================================================
--- trunk/lzma/CPP/Windows/DLL.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/DLL.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,115 @@
+// Windows/DLL.cpp
+
+#include "StdAfx.h"
+
+#include "DLL.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NDLL {
+
+CLibrary::~CLibrary()
+{
+ Free();
+}
+
+bool CLibrary::Free()
+{
+ if (_module == 0)
+ return true;
+ // MessageBox(0, TEXT(""), TEXT("Free"), 0);
+ // Sleep(5000);
+ if (!::FreeLibrary(_module))
+ return false;
+ _module = 0;
+ return true;
+}
+
+bool CLibrary::LoadOperations(HMODULE newModule)
+{
+ if (newModule == NULL)
+ return false;
+ if(!Free())
+ return false;
+ _module = newModule;
+ return true;
+}
+
+bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)
+{
+ // MessageBox(0, fileName, TEXT("LoadEx"), 0);
+ return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));
+}
+
+bool CLibrary::Load(LPCTSTR fileName)
+{
+ // MessageBox(0, fileName, TEXT("Load"), 0);
+ // Sleep(5000);
+ // OutputDebugString(fileName);
+ // OutputDebugString(TEXT("\n"));
+ return LoadOperations(::LoadLibrary(fileName));
+}
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+CSysString GetSysPath(LPCWSTR sysPath)
+ { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
+
+bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)
+{
+ if (g_IsNT)
+ return LoadOperations(::LoadLibraryExW(fileName, NULL, flags));
+ return LoadEx(GetSysPath(fileName), flags);
+}
+bool CLibrary::Load(LPCWSTR fileName)
+{
+ if (g_IsNT)
+ return LoadOperations(::LoadLibraryW(fileName));
+ return Load(GetSysPath(fileName));
+}
+#endif
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
+{
+ result.Empty();
+ TCHAR fullPath[MAX_PATH + 2];
+ DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ result = fullPath;
+ return true;
+ }
+ return false;
+}
+
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result)
+{
+ result.Empty();
+ if (g_IsNT)
+ {
+ wchar_t fullPath[MAX_PATH + 2];
+ DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ result = fullPath;
+ return true;
+ }
+ return false;
+ }
+ CSysString resultSys;
+ if (!MyGetModuleFileName(hModule, resultSys))
+ return false;
+ result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
+ return true;
+}
+#endif
+
+}}
Added: trunk/lzma/CPP/Windows/DLL.h
===================================================================
--- trunk/lzma/CPP/Windows/DLL.h (rev 0)
+++ trunk/lzma/CPP/Windows/DLL.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,54 @@
+// Windows/DLL.h
+
+#ifndef __WINDOWS_DLL_H
+#define __WINDOWS_DLL_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+namespace NDLL {
+
+class CLibrary
+{
+ bool LoadOperations(HMODULE newModule);
+protected:
+ HMODULE _module;
+public:
+ operator HMODULE() const { return _module; }
+ HMODULE* operator&() { return &_module; }
+
+ CLibrary():_module(NULL) {};
+ ~CLibrary();
+ void Attach(HMODULE m)
+ {
+ Free();
+ _module = m;
+ }
+ HMODULE Detach()
+ {
+ HMODULE m = _module;
+ _module = NULL;
+ return m;
+ }
+
+ // operator HMODULE() const { return _module; };
+ bool IsLoaded() const { return (_module != NULL); };
+ bool Free();
+ bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+ bool Load(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+ bool Load(LPCWSTR fileName);
+ #endif
+ FARPROC GetProcAddress(LPCSTR procName) const
+ { return ::GetProcAddress(_module, procName); }
+};
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result);
+#endif
+
+}}
+
+#endif
Added: trunk/lzma/CPP/Windows/Defs.h
===================================================================
--- trunk/lzma/CPP/Windows/Defs.h (rev 0)
+++ trunk/lzma/CPP/Windows/Defs.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,23 @@
+// Windows/Defs.h
+
+#ifndef __WINDOWS_DEFS_H
+#define __WINDOWS_DEFS_H
+
+inline bool BOOLToBool(BOOL value)
+ { return (value != FALSE); }
+
+#ifdef _WIN32
+inline bool LRESULTToBool(LRESULT value)
+ { return (value != FALSE); }
+#endif
+
+inline BOOL BoolToBOOL(bool value)
+ { return (value ? TRUE: FALSE); }
+
+inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value)
+ { return (value ? VARIANT_TRUE: VARIANT_FALSE); }
+
+inline bool VARIANT_BOOLToBool(VARIANT_BOOL value)
+ { return (value != VARIANT_FALSE); }
+
+#endif
Added: trunk/lzma/CPP/Windows/Error.cpp
===================================================================
--- trunk/lzma/CPP/Windows/Error.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/Error.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,50 @@
+// Windows/Error.h
+
+#include "StdAfx.h"
+
+#include "Windows/Error.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NError {
+
+bool MyFormatMessage(DWORD messageID, CSysString &message)
+{
+ LPVOID msgBuf;
+ if(::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,messageID, 0, (LPTSTR) &msgBuf,0, NULL) == 0)
+ return false;
+ message = (LPCTSTR)msgBuf;
+ ::LocalFree(msgBuf);
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyFormatMessage(DWORD messageID, UString &message)
+{
+ if (g_IsNT)
+ {
+ LPVOID msgBuf;
+ if(::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)
+ return false;
+ message = (LPCWSTR)msgBuf;
+ ::LocalFree(msgBuf);
+ return true;
+ }
+ CSysString messageSys;
+ bool result = MyFormatMessage(messageID, messageSys);
+ message = GetUnicodeString(messageSys);
+ return result;
+}
+#endif
+
+}}
Added: trunk/lzma/CPP/Windows/Error.h
===================================================================
--- trunk/lzma/CPP/Windows/Error.h (rev 0)
+++ trunk/lzma/CPP/Windows/Error.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,33 @@
+// Windows/Error.h
+
+#ifndef __WINDOWS_ERROR_H
+#define __WINDOWS_ERROR_H
+
+#include "Common/MyString.h"
+
+namespace NWindows {
+namespace NError {
+
+bool MyFormatMessage(DWORD messageID, CSysString &message);
+inline CSysString MyFormatMessage(DWORD messageID)
+{
+ CSysString message;
+ MyFormatMessage(messageID, message);
+ return message;
+}
+#ifdef _UNICODE
+inline UString MyFormatMessageW(DWORD messageID)
+ { return MyFormatMessage(messageID); }
+#else
+bool MyFormatMessage(DWORD messageID, UString &message);
+inline UString MyFormatMessageW(DWORD messageID)
+{
+ UString message;
+ MyFormatMessage(messageID, message);
+ return message;
+}
+#endif
+
+}}
+
+#endif
Added: trunk/lzma/CPP/Windows/FileDir.cpp
===================================================================
--- trunk/lzma/CPP/Windows/FileDir.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/FileDir.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,841 @@
+// Windows/FileDir.cpp
+
+#include "StdAfx.h"
+
+#include "FileDir.h"
+#include "FileName.h"
+#include "FileFind.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)
+#define WIN_LONG_PATH2
+#endif
+
+// SetCurrentDirectory doesn't support \\?\ prefix
+
+#ifdef WIN_LONG_PATH
+bool GetLongPathBase(LPCWSTR fileName, UString &res);
+bool GetLongPath(LPCWSTR fileName, UString &res);
+#endif
+
+namespace NDirectory {
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+static UString GetUnicodePath(const CSysString &sysPath)
+ { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
+static CSysString GetSysPath(LPCWSTR sysPath)
+ { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
+#endif
+
+bool MyGetWindowsDirectory(CSysString &path)
+{
+ UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+bool MyGetSystemDirectory(CSysString &path)
+{
+ UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetWindowsDirectory(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+
+bool MyGetSystemDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetSystemDirectory(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+#endif
+
+bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return false;
+ }
+ #endif
+ HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ #ifdef WIN_LONG_PATH
+ if (hDir == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ hDir = ::CreateFileW(longPath, GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ }
+ #endif
+
+ bool res = false;
+ if (hDir != INVALID_HANDLE_VALUE)
+ {
+ res = BOOLToBool(::SetFileTime(hDir, creationTime, lastAccessTime, lastWriteTime));
+ ::CloseHandle(hDir);
+ }
+ return res;
+}
+
+bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
+{
+ if (::SetFileAttributes(fileName, fileAttributes))
+ return true;
+ #ifdef WIN_LONG_PATH2
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
+ #endif
+ return false;
+}
+
+bool MyRemoveDirectory(LPCTSTR pathName)
+{
+ if (::RemoveDirectory(pathName))
+ return true;
+ #ifdef WIN_LONG_PATH2
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ return BOOLToBool(::RemoveDirectoryW(longPath));
+ #endif
+ return false;
+}
+
+#ifdef WIN_LONG_PATH
+bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2)
+{
+ if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2))
+ return false;
+ if (d1.IsEmpty() && d2.IsEmpty()) return false;
+ if (d1.IsEmpty()) d1 = s1;
+ if (d2.IsEmpty()) d2 = s2;
+ return true;
+}
+#endif
+
+bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
+{
+ if (::MoveFile(existFileName, newFileName))
+ return true;
+ #ifdef WIN_LONG_PATH2
+ UString d1, d2;
+ if (GetLongPaths(existFileName, newFileName, d1, d2))
+ return BOOLToBool(::MoveFileW(d1, d2));
+ #endif
+ return false;
+}
+
+#ifndef _UNICODE
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
+{
+ if (!g_IsNT)
+ return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
+ if (::SetFileAttributesW(fileName, fileAttributes))
+ return true;
+ #ifdef WIN_LONG_PATH
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
+ #endif
+ return false;
+}
+
+
+bool MyRemoveDirectory(LPCWSTR pathName)
+{
+ if (!g_IsNT)
+ return MyRemoveDirectory(GetSysPath(pathName));
+ if (::RemoveDirectoryW(pathName))
+ return true;
+ #ifdef WIN_LONG_PATH
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ return BOOLToBool(::RemoveDirectoryW(longPath));
+ #endif
+ return false;
+}
+
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
+{
+ if (!g_IsNT)
+ return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
+ if (::MoveFileW(existFileName, newFileName))
+ return true;
+ #ifdef WIN_LONG_PATH
+ UString d1, d2;
+ if (GetLongPaths(existFileName, newFileName, d1, d2))
+ return BOOLToBool(::MoveFileW(d1, d2));
+ #endif
+ return false;
+}
+#endif
+
+bool MyCreateDirectory(LPCTSTR pathName)
+{
+ if (::CreateDirectory(pathName, NULL))
+ return true;
+ #ifdef WIN_LONG_PATH2
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ }
+ #endif
+ return false;
+}
+
+#ifndef _UNICODE
+bool MyCreateDirectory(LPCWSTR pathName)
+{
+ if (!g_IsNT)
+ return MyCreateDirectory(GetSysPath(pathName));
+ if (::CreateDirectoryW(pathName, NULL))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ }
+ #endif
+ return false;
+}
+#endif
+
+/*
+bool CreateComplexDirectory(LPCTSTR pathName)
+{
+ NName::CParsedPath path;
+ path.ParsePath(pathName);
+ CSysString fullPath = path.Prefix;
+ DWORD errorCode = ERROR_SUCCESS;
+ for(int i = 0; i < path.PathParts.Size(); i++)
+ {
+ const CSysString &string = path.PathParts[i];
+ if(string.IsEmpty())
+ {
+ if(i != path.PathParts.Size() - 1)
+ return false;
+ return true;
+ }
+ fullPath += path.PathParts[i];
+ if (!MyCreateDirectory(fullPath))
+ {
+ DWORD errorCode = GetLastError();
+ if(errorCode != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+ fullPath += NName::kDirDelimiter;
+ }
+ return true;
+}
+*/
+
+bool CreateComplexDirectory(LPCTSTR _aPathName)
+{
+ CSysString pathName = _aPathName;
+ int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+ if (pos > 0 && pos == pathName.Length() - 1)
+ {
+ if (pathName.Length() == 3 && pathName[1] == ':')
+ return true; // Disk folder;
+ pathName.Delete(pos);
+ }
+ CSysString pathName2 = pathName;
+ pos = pathName.Length();
+ for (;;)
+ {
+ if(MyCreateDirectory(pathName))
+ break;
+ if (::GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ NFind::CFileInfo fileInfo;
+ if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ return true;
+ if (!fileInfo.IsDirectory())
+ return false;
+ break;
+ }
+ pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+ if (pos < 0 || pos == 0)
+ return false;
+ if (pathName[pos - 1] == ':')
+ return false;
+ pathName = pathName.Left(pos);
+ }
+ pathName = pathName2;
+ while(pos < pathName.Length())
+ {
+ pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
+ if (pos < 0)
+ pos = pathName.Length();
+ if (!MyCreateDirectory(pathName.Left(pos)))
+ return false;
+ }
+ return true;
+}
+
+#ifndef _UNICODE
+
+bool CreateComplexDirectory(LPCWSTR _aPathName)
+{
+ UString pathName = _aPathName;
+ int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos > 0 && pos == pathName.Length() - 1)
+ {
+ if (pathName.Length() == 3 && pathName[1] == L':')
+ return true; // Disk folder;
+ pathName.Delete(pos);
+ }
+ UString pathName2 = pathName;
+ pos = pathName.Length();
+ for (;;)
+ {
+ if(MyCreateDirectory(pathName))
+ break;
+ if (::GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ return true;
+ if (!fileInfo.IsDirectory())
+ return false;
+ break;
+ }
+ pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos < 0 || pos == 0)
+ return false;
+ if (pathName[pos - 1] == L':')
+ return false;
+ pathName = pathName.Left(pos);
+ }
+ pathName = pathName2;
+ while(pos < pathName.Length())
+ {
+ pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+ if (pos < 0)
+ pos = pathName.Length();
+ if (!MyCreateDirectory(pathName.Left(pos)))
+ return false;
+ }
+ return true;
+}
+
+#endif
+
+bool DeleteFileAlways(LPCTSTR name)
+{
+ if (!MySetFileAttributes(name, 0))
+ return false;
+ if (::DeleteFile(name))
+ return true;
+ #ifdef WIN_LONG_PATH2
+ UString longPath;
+ if (GetLongPath(name, longPath))
+ return BOOLToBool(::DeleteFileW(longPath));
+ #endif
+ return false;
+}
+
+#ifndef _UNICODE
+bool DeleteFileAlways(LPCWSTR name)
+{
+ if (!g_IsNT)
+ return DeleteFileAlways(GetSysPath(name));
+ if (!MySetFileAttributes(name, 0))
+ return false;
+ if (::DeleteFileW(name))
+ return true;
+ #ifdef WIN_LONG_PATH
+ UString longPath;
+ if (GetLongPath(name, longPath))
+ return BOOLToBool(::DeleteFileW(longPath));
+ #endif
+ return false;
+}
+#endif
+
+static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
+{
+ if(fileInfo.IsDirectory())
+ return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
+ return DeleteFileAlways(pathPrefix + fileInfo.Name);
+}
+
+bool RemoveDirectoryWithSubItems(const CSysString &path)
+{
+ NFind::CFileInfo fileInfo;
+ CSysString pathPrefix = path + NName::kDirDelimiter;
+ {
+ NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
+ while(enumerator.Next(fileInfo))
+ if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ return false;
+ }
+ if (!MySetFileAttributes(path, 0))
+ return false;
+ return MyRemoveDirectory(path);
+}
+
+#ifndef _UNICODE
+static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
+{
+ if(fileInfo.IsDirectory())
+ return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
+ return DeleteFileAlways(pathPrefix + fileInfo.Name);
+}
+bool RemoveDirectoryWithSubItems(const UString &path)
+{
+ NFind::CFileInfoW fileInfo;
+ UString pathPrefix = path + UString(NName::kDirDelimiter);
+ {
+ NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
+ while(enumerator.Next(fileInfo))
+ if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ return false;
+ }
+ if (!MySetFileAttributes(path, 0))
+ return false;
+ return MyRemoveDirectory(path);
+}
+#endif
+
+#ifndef _WIN32_WCE
+
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
+{
+ DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ shortPath.ReleaseBuffer();
+ return (needLength > 0 && needLength < MAX_PATH);
+}
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
+{
+ resultPath.Empty();
+ LPTSTR fileNamePointer = 0;
+ LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
+ DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
+ resultPath.ReleaseBuffer();
+ if (needLength == 0)
+ return false;
+ if (needLength >= MAX_PATH)
+ {
+ #ifdef WIN_LONG_PATH2
+ needLength++;
+ buffer = resultPath.GetBuffer(needLength + 1);
+ DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
+ resultPath.ReleaseBuffer();
+ if (needLength2 == 0 || needLength2 > needLength)
+ #endif
+ return false;
+ }
+ if (fileNamePointer == 0)
+ fileNamePartStartIndex = lstrlen(fileName);
+ else
+ fileNamePartStartIndex = (int)(fileNamePointer - buffer);
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+{
+ resultPath.Empty();
+ if (g_IsNT)
+ {
+ LPWSTR fileNamePointer = 0;
+ LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
+ DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
+ resultPath.ReleaseBuffer();
+ if (needLength == 0)
+ return false;
+ if (needLength >= MAX_PATH)
+ {
+ #ifdef WIN_LONG_PATH
+ needLength++;
+ buffer = resultPath.GetBuffer(needLength + 1);
+ DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
+ resultPath.ReleaseBuffer();
+ if (needLength2 == 0 || needLength2 > needLength)
+ #endif
+ return false;
+ }
+ if (fileNamePointer == 0)
+ fileNamePartStartIndex = MyStringLen(fileName);
+ else
+ fileNamePartStartIndex = (int)(fileNamePointer - buffer);
+ }
+ else
+ {
+ CSysString sysPath;
+ if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
+ return false;
+ UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
+ UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
+ fileNamePartStartIndex = resultPath1.Length();
+ resultPath = resultPath1 + resultPath2;
+ }
+ return true;
+}
+#endif
+
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
+{
+ int index;
+ return MyGetFullPathName(fileName, path, index);
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &path)
+{
+ int index;
+ return MyGetFullPathName(fileName, path, index);
+}
+#endif
+
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Mid(index);
+ return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Mid(index);
+ return true;
+}
+#endif
+
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Left(index);
+ return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Left(index);
+ return true;
+}
+#endif
+
+bool MyGetCurrentDirectory(CSysString &path)
+{
+ DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path)
+{
+ if (g_IsNT)
+ return BOOLToBool(::SetCurrentDirectoryW(path));
+ return MySetCurrentDirectory(GetSysPath(path));
+}
+bool MyGetCurrentDirectory(UString &path)
+{
+ if (g_IsNT)
+ {
+ DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetCurrentDirectory(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+#endif
+#endif
+
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath, UINT32 &filePart)
+{
+ LPTSTR filePartPointer;
+ DWORD value = ::SearchPath(path, fileName, extension,
+ MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
+ filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
+ resultPath.ReleaseBuffer();
+ return (value > 0 && value <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath, UINT32 &filePart)
+{
+ if (g_IsNT)
+ {
+ LPWSTR filePartPointer = 0;
+ DWORD value = ::SearchPathW(path, fileName, extension,
+ MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
+ filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
+ resultPath.ReleaseBuffer();
+ return (value > 0 && value <= MAX_PATH);
+ }
+
+ CSysString sysPath;
+ if (!MySearchPath(
+ path != 0 ? (LPCTSTR)GetSysPath(path): 0,
+ fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
+ extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
+ sysPath, filePart))
+ return false;
+ UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
+ UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
+ filePart = resultPath1.Length();
+ resultPath = resultPath1 + resultPath2;
+ return true;
+}
+#endif
+
+bool MyGetTempPath(CSysString &path)
+{
+ DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MyGetTempPath(UString &path)
+{
+ path.Empty();
+ if (g_IsNT)
+ {
+ DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+ }
+ CSysString sysPath;
+ if (!MyGetTempPath(sysPath))
+ return false;
+ path = GetUnicodePath(sysPath);
+ return true;
+}
+#endif
+
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
+{
+ UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return number;
+}
+
+#ifndef _UNICODE
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
+{
+ if (g_IsNT)
+ {
+ UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
+ path.ReleaseBuffer();
+ return number;
+ }
+ CSysString sysPath;
+ UINT number = MyGetTempFileName(
+ dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
+ prefix ? (LPCTSTR)GetSysPath(prefix): 0,
+ sysPath);
+ path = GetUnicodePath(sysPath);
+ return number;
+}
+#endif
+
+UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+{
+ Remove();
+ UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+ if(number != 0)
+ {
+ _fileName = resultPath;
+ _mustBeDeleted = true;
+ }
+ return number;
+}
+
+bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+{
+ CSysString tempPath;
+ if (!MyGetTempPath(tempPath))
+ return false;
+ if (Create(tempPath, prefix, resultPath) != 0)
+ return true;
+ if (!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFile::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !DeleteFileAlways(_fileName);
+ return !_mustBeDeleted;
+}
+
+#ifndef _UNICODE
+
+UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
+{
+ Remove();
+ UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+ if(number != 0)
+ {
+ _fileName = resultPath;
+ _mustBeDeleted = true;
+ }
+ return number;
+}
+
+bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
+{
+ UString tempPath;
+ if (!MyGetTempPath(tempPath))
+ return false;
+ if (Create(tempPath, prefix, resultPath) != 0)
+ return true;
+ if (!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFileW::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !DeleteFileAlways(_fileName);
+ return !_mustBeDeleted;
+}
+
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
+{
+ /*
+ CSysString prefix = tempPath + prefixChars;
+ CRandom random;
+ random.Init();
+ */
+ for (;;)
+ {
+ CTempFile tempFile;
+ if (!tempFile.Create(prefix, dirName))
+ return false;
+ if (!::DeleteFile(dirName))
+ return false;
+ /*
+ UINT32 randomNumber = random.Generate();
+ TCHAR randomNumberString[32];
+ _stprintf(randomNumberString, _T("%04X"), randomNumber);
+ dirName = prefix + randomNumberString;
+ */
+ if(NFind::DoesFileExist(dirName))
+ continue;
+ if (MyCreateDirectory(dirName))
+ return true;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+}
+
+bool CTempDirectory::Create(LPCTSTR prefix)
+{
+ Remove();
+ return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
+}
+
+#ifndef _UNICODE
+
+bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
+{
+ /*
+ CSysString prefix = tempPath + prefixChars;
+ CRandom random;
+ random.Init();
+ */
+ for (;;)
+ {
+ CTempFileW tempFile;
+ if (!tempFile.Create(prefix, dirName))
+ return false;
+ if (!DeleteFileAlways(dirName))
+ return false;
+ /*
+ UINT32 randomNumber = random.Generate();
+ TCHAR randomNumberString[32];
+ _stprintf(randomNumberString, _T("%04X"), randomNumber);
+ dirName = prefix + randomNumberString;
+ */
+ if(NFind::DoesFileExist(dirName))
+ continue;
+ if (MyCreateDirectory(dirName))
+ return true;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+}
+
+bool CTempDirectoryW::Create(LPCWSTR prefix)
+{
+ Remove();
+ return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
+}
+
+#endif
+
+}}}
Added: trunk/lzma/CPP/Windows/FileDir.h
===================================================================
--- trunk/lzma/CPP/Windows/FileDir.h (rev 0)
+++ trunk/lzma/CPP/Windows/FileDir.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,178 @@
+// Windows/FileDir.h
+
+#ifndef __WINDOWS_FILEDIR_H
+#define __WINDOWS_FILEDIR_H
+
+#include "../Common/MyString.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NDirectory {
+
+#ifdef WIN_LONG_PATH
+bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2);
+#endif
+
+bool MyGetWindowsDirectory(CSysString &path);
+bool MyGetSystemDirectory(CSysString &path);
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path);
+bool MyGetSystemDirectory(UString &path);
+#endif
+
+bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+
+bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);
+bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);
+bool MyRemoveDirectory(LPCTSTR pathName);
+bool MyCreateDirectory(LPCTSTR pathName);
+bool CreateComplexDirectory(LPCTSTR pathName);
+bool DeleteFileAlways(LPCTSTR name);
+bool RemoveDirectoryWithSubItems(const CSysString &path);
+
+#ifndef _UNICODE
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
+bool MyRemoveDirectory(LPCWSTR pathName);
+bool MyCreateDirectory(LPCWSTR pathName);
+bool CreateComplexDirectory(LPCWSTR pathName);
+bool DeleteFileAlways(LPCWSTR name);
+bool RemoveDirectoryWithSubItems(const UString &path);
+#endif
+
+#ifndef _WIN32_WCE
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
+ int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
+ int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
+bool GetOnlyName(LPCWSTR fileName, UString &resultName);
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);
+#endif
+
+inline bool MySetCurrentDirectory(LPCTSTR path)
+ { return BOOLToBool(::SetCurrentDirectory(path)); }
+bool MyGetCurrentDirectory(CSysString &resultPath);
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path);
+bool MyGetCurrentDirectory(UString &resultPath);
+#endif
+#endif
+
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath, UINT32 &filePart);
+#ifndef _UNICODE
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath, UINT32 &filePart);
+#endif
+
+inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath)
+{
+ UINT32 value;
+ return MySearchPath(path, fileName, extension, resultPath, value);
+}
+
+#ifndef _UNICODE
+inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath)
+{
+ UINT32 value;
+ return MySearchPath(path, fileName, extension, resultPath, value);
+}
+#endif
+
+bool MyGetTempPath(CSysString &resultPath);
+#ifndef _UNICODE
+bool MyGetTempPath(UString &resultPath);
+#endif
+
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+#ifndef _UNICODE
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+#endif
+
+class CTempFile
+{
+ bool _mustBeDeleted;
+ CSysString _fileName;
+public:
+ CTempFile(): _mustBeDeleted(false) {}
+ ~CTempFile() { Remove(); }
+ void DisableDeleting() { _mustBeDeleted = false; }
+ UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+ bool Create(LPCTSTR prefix, CSysString &resultPath);
+ bool Remove();
+};
+
+#ifdef _UNICODE
+typedef CTempFile CTempFileW;
+#else
+class CTempFileW
+{
+ bool _mustBeDeleted;
+ UString _fileName;
+public:
+ CTempFileW(): _mustBeDeleted(false) {}
+ ~CTempFileW() { Remove(); }
+ void DisableDeleting() { _mustBeDeleted = false; }
+ UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+ bool Create(LPCWSTR prefix, UString &resultPath);
+ bool Remove();
+};
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
+
+class CTempDirectory
+{
+ bool _mustBeDeleted;
+ CSysString _tempDir;
+public:
+ const CSysString &GetPath() const { return _tempDir; }
+ CTempDirectory(): _mustBeDeleted(false) {}
+ ~CTempDirectory() { Remove(); }
+ bool Create(LPCTSTR prefix) ;
+ bool Remove()
+ {
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+ return (!_mustBeDeleted);
+ }
+ void DisableDeleting() { _mustBeDeleted = false; }
+};
+
+#ifdef _UNICODE
+typedef CTempDirectory CTempDirectoryW;
+#else
+class CTempDirectoryW
+{
+ bool _mustBeDeleted;
+ UString _tempDir;
+public:
+ const UString &GetPath() const { return _tempDir; }
+ CTempDirectoryW(): _mustBeDeleted(false) {}
+ ~CTempDirectoryW() { Remove(); }
+ bool Create(LPCWSTR prefix) ;
+ bool Remove()
+ {
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+ return (!_mustBeDeleted);
+ }
+ void DisableDeleting() { _mustBeDeleted = false; }
+};
+#endif
+
+}}}
+
+#endif
Added: trunk/lzma/CPP/Windows/FileFind.cpp
===================================================================
--- trunk/lzma/CPP/Windows/FileFind.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/FileFind.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,408 @@
+// Windows/FileFind.cpp
+
+#include "StdAfx.h"
+
+#include "FileFind.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)
+#define WIN_LONG_PATH2
+#endif
+
+bool GetLongPath(LPCWSTR fileName, UString &res);
+
+namespace NFind {
+
+static const TCHAR kDot = TEXT('.');
+
+bool CFileInfo::IsDots() const
+{
+ if (!IsDirectory() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+
+#ifndef _UNICODE
+bool CFileInfoW::IsDots() const
+{
+ if (!IsDirectory() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+#endif
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATA &findData,
+ CFileInfo &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = findData.cFileName;
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+
+#ifndef _UNICODE
+
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATAW &findData,
+ CFileInfoW &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = findData.cFileName;
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATA &findData,
+ CFileInfoW &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow;
+ fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+#endif
+
+////////////////////////////////
+// CFindFile
+
+bool CFindFile::Close()
+{
+ if (_handle == INVALID_HANDLE_VALUE)
+ return true;
+ if (!::FindClose(_handle))
+ return false;
+ _handle = INVALID_HANDLE_VALUE;
+ return true;
+}
+
+
+bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+ if (!Close())
+ return false;
+ WIN32_FIND_DATA findData;
+ _handle = ::FindFirstFile(wildcard, &findData);
+ #ifdef WIN_LONG_PATH2
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(wildcard, longPath))
+ _handle = ::FindFirstFileW(longPath, &findData);
+ }
+ #endif
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return true;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ if (!Close())
+ return false;
+ if (g_IsNT)
+ {
+ WIN32_FIND_DATAW findData;
+ _handle = ::FindFirstFileW(wildcard, &findData);
+ #ifdef WIN_LONG_PATH
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(wildcard, longPath))
+ _handle = ::FindFirstFileW(longPath, &findData);
+ }
+ #endif
+ if (_handle != INVALID_HANDLE_VALUE)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ else
+ {
+ WIN32_FIND_DATAA findData;
+ _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
+ GetCurrentCodePage()), &findData);
+ if (_handle != INVALID_HANDLE_VALUE)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ return (_handle != INVALID_HANDLE_VALUE);
+}
+#endif
+
+bool CFindFile::FindNext(CFileInfo &fileInfo)
+{
+ WIN32_FIND_DATA findData;
+ bool result = BOOLToBool(::FindNextFile(_handle, &findData));
+ if (result)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return result;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindNext(CFileInfoW &fileInfo)
+{
+ if (g_IsNT)
+ {
+ WIN32_FIND_DATAW findData;
+ if (!::FindNextFileW(_handle, &findData))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ else
+ {
+ WIN32_FIND_DATAA findData;
+ if (!::FindNextFileA(_handle, &findData))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ return true;
+}
+#endif
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+ CFindFile finder;
+ return finder.FindFirst(wildcard, fileInfo);
+}
+
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ CFindFile finder;
+ return finder.FindFirst(wildcard, fileInfo);
+}
+#endif
+
+bool DoesFileExist(LPCTSTR name)
+{
+ CFileInfo fileInfo;
+ return FindFile(name, fileInfo);
+}
+
+#ifndef _UNICODE
+bool DoesFileExist(LPCWSTR name)
+{
+ CFileInfoW fileInfo;
+ return FindFile(name, fileInfo);
+}
+#endif
+
+/////////////////////////////////////
+// CEnumerator
+
+bool CEnumerator::NextAny(CFileInfo &fileInfo)
+{
+ if (_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fileInfo);
+ else
+ return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo)
+{
+ for (;;)
+ {
+ if (!NextAny(fileInfo))
+ return false;
+ if (!fileInfo.IsDots())
+ return true;
+ }
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
+{
+ if (Next(fileInfo))
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_NO_MORE_FILES);
+}
+
+#ifndef _UNICODE
+bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
+{
+ if (_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fileInfo);
+ else
+ return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo)
+{
+ for (;;)
+ {
+ if (!NextAny(fileInfo))
+ return false;
+ if (!fileInfo.IsDots())
+ return true;
+ }
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
+{
+ if (Next(fileInfo))
+ {
+ found = true;
+ return true;
+ }
+ found = false;
+ return (::GetLastError() == ERROR_NO_MORE_FILES);
+}
+
+#endif
+
+////////////////////////////////
+// CFindChangeNotification
+// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
+
+bool CFindChangeNotification::Close()
+{
+ if (!IsHandleAllocated())
+ return true;
+ if (!::FindCloseChangeNotification(_handle))
+ return false;
+ _handle = INVALID_HANDLE_VALUE;
+ return true;
+}
+
+HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter)
+{
+ _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter);
+ #ifdef WIN_LONG_PATH2
+ if (!IsHandleAllocated())
+ {
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ }
+ #endif
+ return _handle;
+}
+
+#ifndef _UNICODE
+HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter)
+{
+ if (!g_IsNT)
+ return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
+ _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
+ #ifdef WIN_LONG_PATH
+ if (!IsHandleAllocated())
+ {
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ }
+ #endif
+ return _handle;
+}
+#endif
+
+#ifndef _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
+{
+ driveStrings.Clear();
+ UINT32 size = GetLogicalDriveStrings(0, NULL);
+ if (size == 0)
+ return false;
+ CSysString buffer;
+ UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
+ if (newSize == 0)
+ return false;
+ if (newSize > size)
+ return false;
+ CSysString string;
+ for(UINT32 i = 0; i < newSize; i++)
+ {
+ TCHAR c = buffer[i];
+ if (c == TEXT('\0'))
+ {
+ driveStrings.Add(string);
+ string.Empty();
+ }
+ else
+ string += c;
+ }
+ if (!string.IsEmpty())
+ return false;
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
+{
+ driveStrings.Clear();
+ if (g_IsNT)
+ {
+ UINT32 size = GetLogicalDriveStringsW(0, NULL);
+ if (size == 0)
+ return false;
+ UString buffer;
+ UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
+ if (newSize == 0)
+ return false;
+ if (newSize > size)
+ return false;
+ UString string;
+ for(UINT32 i = 0; i < newSize; i++)
+ {
+ WCHAR c = buffer[i];
+ if (c == L'\0')
+ {
+ driveStrings.Add(string);
+ string.Empty();
+ }
+ else
+ string += c;
+ }
+ return string.IsEmpty();
+ }
+ CSysStringVector driveStringsA;
+ bool res = MyGetLogicalDriveStrings(driveStringsA);
+ for (int i = 0; i < driveStringsA.Size(); i++)
+ driveStrings.Add(GetUnicodeString(driveStringsA[i]));
+ return res;
+}
+#endif
+
+#endif
+
+}}}
Added: trunk/lzma/CPP/Windows/FileFind.h
===================================================================
--- trunk/lzma/CPP/Windows/FileFind.h (rev 0)
+++ trunk/lzma/CPP/Windows/FileFind.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,153 @@
+// Windows/FileFind.h
+
+#ifndef __WINDOWS_FILEFIND_H
+#define __WINDOWS_FILEFIND_H
+
+#include "../Common/MyString.h"
+#include "../Common/Types.h"
+#include "FileName.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NFind {
+
+namespace NAttributes
+{
+ inline bool IsReadOnly(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_READONLY) != 0; }
+ inline bool IsHidden(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_HIDDEN) != 0; }
+ inline bool IsSystem(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_SYSTEM) != 0; }
+ inline bool IsDirectory(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
+ inline bool IsArchived(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ARCHIVE) != 0; }
+ inline bool IsCompressed(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_COMPRESSED) != 0; }
+ inline bool IsEncrypted(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
+}
+
+class CFileInfoBase
+{
+ bool MatchesMask(UINT32 mask) const { return ((Attributes & mask) != 0); }
+public:
+ DWORD Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ UInt64 Size;
+
+ #ifndef _WIN32_WCE
+ UINT32 ReparseTag;
+ #else
+ DWORD ObjectID;
+ #endif
+
+ bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
+ bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
+ bool IsDirectory() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
+ bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); }
+ bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); }
+ bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); }
+ bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); }
+ bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); }
+ bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); }
+ bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); }
+ bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
+ bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
+};
+
+class CFileInfo: public CFileInfoBase
+{
+public:
+ CSysString Name;
+ bool IsDots() const;
+};
+
+#ifdef _UNICODE
+typedef CFileInfo CFileInfoW;
+#else
+class CFileInfoW: public CFileInfoBase
+{
+public:
+ UString Name;
+ bool IsDots() const;
+};
+#endif
+
+class CFindFile
+{
+ friend class CEnumerator;
+ HANDLE _handle;
+public:
+ bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
+ CFindFile(): _handle(INVALID_HANDLE_VALUE) {}
+ ~CFindFile() { Close(); }
+ bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
+ bool FindNext(CFileInfo &fileInfo);
+ #ifndef _UNICODE
+ bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
+ bool FindNext(CFileInfoW &fileInfo);
+ #endif
+ bool Close();
+};
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo);
+
+bool DoesFileExist(LPCTSTR name);
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo);
+bool DoesFileExist(LPCWSTR name);
+#endif
+
+class CEnumerator
+{
+ CFindFile _findFile;
+ CSysString _wildcard;
+ bool NextAny(CFileInfo &fileInfo);
+public:
+ CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
+ CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
+ bool Next(CFileInfo &fileInfo);
+ bool Next(CFileInfo &fileInfo, bool &found);
+};
+
+#ifdef _UNICODE
+typedef CEnumerator CEnumeratorW;
+#else
+class CEnumeratorW
+{
+ CFindFile _findFile;
+ UString _wildcard;
+ bool NextAny(CFileInfoW &fileInfo);
+public:
+ CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
+ CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
+ bool Next(CFileInfoW &fileInfo);
+ bool Next(CFileInfoW &fileInfo, bool &found);
+};
+#endif
+
+class CFindChangeNotification
+{
+ HANDLE _handle;
+public:
+ operator HANDLE () { return _handle; }
+ bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }
+ CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
+ ~CFindChangeNotification() { Close(); }
+ bool Close();
+ HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);
+ #ifndef _UNICODE
+ HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);
+ #endif
+ bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
+};
+
+#ifndef _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
+#endif
+#endif
+
+}}}
+
+#endif
+
Added: trunk/lzma/CPP/Windows/FileIO.cpp
===================================================================
--- trunk/lzma/CPP/Windows/FileIO.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/FileIO.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,318 @@
+// Windows/FileIO.cpp
+
+#include "StdAfx.h"
+
+#include "FileIO.h"
+#include "Defs.h"
+#ifdef WIN_LONG_PATH
+#include "../Common/MyString.h"
+#endif
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)
+#define WIN_LONG_PATH2
+#endif
+
+#ifdef WIN_LONG_PATH
+bool GetLongPathBase(LPCWSTR s, UString &res)
+{
+ res.Empty();
+ int len = MyStringLen(s);
+ wchar_t c = s[0];
+ if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.'))
+ return true;
+ UString curDir;
+ bool isAbs = false;
+ if (len > 3)
+ isAbs = (s[1] == L':' && s[2] == L'\\' && (c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z'));
+
+ if (!isAbs)
+ {
+ DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1));
+ curDir.ReleaseBuffer();
+ if (needLength == 0 || needLength > MAX_PATH)
+ return false;
+ if (curDir[curDir.Length() - 1] != L'\\')
+ curDir += L'\\';
+ }
+ res = UString(L"\\\\?\\") + curDir + s;
+ return true;
+}
+
+bool GetLongPath(LPCWSTR path, UString &longPath)
+{
+ if (GetLongPathBase(path, longPath))
+ return !longPath.IsEmpty();
+ return false;
+}
+#endif
+
+namespace NIO {
+
+CFileBase::~CFileBase() { Close(); }
+
+bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ if (!Close())
+ return false;
+ _handle = ::CreateFile(fileName, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
+ flagsAndAttributes, (HANDLE)NULL);
+ #ifdef WIN_LONG_PATH2
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
+ flagsAndAttributes, (HANDLE)NULL);
+ }
+ #endif
+ return (_handle != INVALID_HANDLE_VALUE);
+}
+
+#ifndef _UNICODE
+bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ if (!g_IsNT)
+ return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
+ desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
+ if (!Close())
+ return false;
+ _handle = ::CreateFileW(fileName, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
+ flagsAndAttributes, (HANDLE)NULL);
+ #ifdef WIN_LONG_PATH
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
+ flagsAndAttributes, (HANDLE)NULL);
+ }
+ #endif
+ return (_handle != INVALID_HANDLE_VALUE);
+}
+#endif
+
+bool CFileBase::Close()
+{
+ if (_handle == INVALID_HANDLE_VALUE)
+ return true;
+ if (!::CloseHandle(_handle))
+ return false;
+ _handle = INVALID_HANDLE_VALUE;
+ return true;
+}
+
+bool CFileBase::GetPosition(UInt64 &position) const
+{
+ return Seek(0, FILE_CURRENT, position);
+}
+
+bool CFileBase::GetLength(UInt64 &length) const
+{
+ DWORD sizeHigh;
+ DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
+ if(sizeLow == 0xFFFFFFFF)
+ if(::GetLastError() != NO_ERROR)
+ return false;
+ length = (((UInt64)sizeHigh) << 32) + sizeLow;
+ return true;
+}
+
+bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
+{
+ LARGE_INTEGER value;
+ value.QuadPart = distanceToMove;
+ value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
+ if (value.LowPart == 0xFFFFFFFF)
+ if(::GetLastError() != NO_ERROR)
+ return false;
+ newPosition = value.QuadPart;
+ return true;
+}
+
+bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
+{
+ return Seek(position, FILE_BEGIN, newPosition);
+}
+
+bool CFileBase::SeekToBegin()
+{
+ UInt64 newPosition;
+ return Seek(0, newPosition);
+}
+
+bool CFileBase::SeekToEnd(UInt64 &newPosition)
+{
+ return Seek(0, FILE_END, newPosition);
+}
+
+bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
+{
+ BY_HANDLE_FILE_INFORMATION winFileInfo;
+ if(!::GetFileInformationByHandle(_handle, &winFileInfo))
+ return false;
+ fileInfo.Attributes = winFileInfo.dwFileAttributes;
+ fileInfo.CreationTime = winFileInfo.ftCreationTime;
+ fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime;
+ fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime;
+ fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
+ fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow;
+ fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
+ fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
+ return true;
+}
+
+/////////////////////////
+// CInFile
+
+bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::OpenShared(LPCTSTR fileName, bool shareForWrite)
+{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+
+bool CInFile::Open(LPCTSTR fileName)
+ { return OpenShared(fileName, false); }
+
+#ifndef _UNICODE
+bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite)
+{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+
+bool CInFile::Open(LPCWSTR fileName)
+ { return OpenShared(fileName, false); }
+#endif
+
+// ReadFile and WriteFile functions in Windows have BUG:
+// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
+// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+// (Insufficient system resources exist to complete the requested service).
+
+// Probably in some version of Windows there are problems with other sizes:
+// for 32 MB (maybe also for 16 MB).
+// And message can be "Network connection was lost"
+
+static UInt32 kChunkSizeMax = (1 << 22);
+
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
+{
+ if (size > kChunkSizeMax)
+ size = kChunkSizeMax;
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UInt32)processedLoc;
+ return res;
+}
+
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
+{
+ processedSize = 0;
+ do
+ {
+ UInt32 processedLoc = 0;
+ bool res = ReadPart(data, size, processedLoc);
+ processedSize += processedLoc;
+ if (!res)
+ return false;
+ if (processedLoc == 0)
+ return true;
+ data = (void *)((unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size > 0);
+ return true;
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+
+static inline DWORD GetCreationDisposition(bool createAlways)
+ { return createAlways? CREATE_ALWAYS: CREATE_NEW; }
+
+bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
+ { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
+
+bool COutFile::Create(LPCTSTR fileName, bool createAlways)
+ { return Open(fileName, GetCreationDisposition(createAlways)); }
+
+#ifndef _UNICODE
+
+bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+ { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
+ { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
+
+bool COutFile::Create(LPCWSTR fileName, bool createAlways)
+ { return Open(fileName, GetCreationDisposition(createAlways)); }
+
+#endif
+
+bool COutFile::SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+ { return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); }
+
+bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
+ { return SetTime(NULL, NULL, lastWriteTime); }
+
+bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
+{
+ if (size > kChunkSizeMax)
+ size = kChunkSizeMax;
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UInt32)processedLoc;
+ return res;
+}
+
+bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
+{
+ processedSize = 0;
+ do
+ {
+ UInt32 processedLoc = 0;
+ bool res = WritePart(data, size, processedLoc);
+ processedSize += processedLoc;
+ if (!res)
+ return false;
+ if (processedLoc == 0)
+ return true;
+ data = (const void *)((const unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size > 0);
+ return true;
+}
+
+bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
+
+bool COutFile::SetLength(UInt64 length)
+{
+ UInt64 newPosition;
+ if(!Seek(length, newPosition))
+ return false;
+ if(newPosition != length)
+ return false;
+ return SetEndOfFile();
+}
+
+}}}
Added: trunk/lzma/CPP/Windows/FileIO.h
===================================================================
--- trunk/lzma/CPP/Windows/FileIO.h (rev 0)
+++ trunk/lzma/CPP/Windows/FileIO.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,99 @@
+// Windows/FileIO.h
+
+#ifndef __WINDOWS_FILEIO_H
+#define __WINDOWS_FILEIO_H
+
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+struct CByHandleFileInfo
+{
+ DWORD Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ DWORD VolumeSerialNumber;
+ UInt64 Size;
+ DWORD NumberOfLinks;
+ UInt64 FileIndex;
+};
+
+class CFileBase
+{
+protected:
+ HANDLE _handle;
+ bool Create(LPCTSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ #ifndef _UNICODE
+ bool Create(LPCWSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ #endif
+
+public:
+ CFileBase(): _handle(INVALID_HANDLE_VALUE){};
+ ~CFileBase();
+
+ bool Close();
+
+ bool GetPosition(UInt64 &position) const;
+ bool GetLength(UInt64 &length) const;
+
+ bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;
+ bool Seek(UInt64 position, UInt64 &newPosition);
+ bool SeekToBegin();
+ bool SeekToEnd(UInt64 &newPosition);
+
+ bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+ bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool OpenShared(LPCTSTR fileName, bool shareForWrite);
+ bool Open(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool OpenShared(LPCWSTR fileName, bool shareForWrite);
+ bool Open(LPCWSTR fileName);
+ #endif
+ bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
+ bool Read(void *data, UInt32 size, UInt32 &processedSize);
+};
+
+class COutFile: public CFileBase
+{
+ // DWORD m_CreationDisposition;
+public:
+ // COutFile(): m_CreationDisposition(CREATE_NEW){};
+ bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCTSTR fileName, DWORD creationDisposition);
+ bool Create(LPCTSTR fileName, bool createAlways);
+
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCWSTR fileName, DWORD creationDisposition);
+ bool Create(LPCWSTR fileName, bool createAlways);
+ #endif
+
+ /*
+ void SetOpenCreationDisposition(DWORD creationDisposition)
+ { m_CreationDisposition = creationDisposition; }
+ void SetOpenCreationDispositionCreateAlways()
+ { m_CreationDisposition = CREATE_ALWAYS; }
+ */
+
+ bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+ bool SetLastWriteTime(const FILETIME *lastWriteTime);
+ bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);
+ bool Write(const void *data, UInt32 size, UInt32 &processedSize);
+ bool SetEndOfFile();
+ bool SetLength(UInt64 length);
+};
+
+}}}
+
+#endif
Added: trunk/lzma/CPP/Windows/FileMapping.cpp
===================================================================
--- trunk/lzma/CPP/Windows/FileMapping.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/FileMapping.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,14 @@
+// Windows/FileMapping.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileMapping.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NMapping {
+
+
+
+
+}}}
\ No newline at end of file
Added: trunk/lzma/CPP/Windows/FileMapping.h
===================================================================
--- trunk/lzma/CPP/Windows/FileMapping.h (rev 0)
+++ trunk/lzma/CPP/Windows/FileMapping.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,50 @@
+// Windows/FileMapping.h
+
+#ifndef __WINDOWS_FILEMAPPING_H
+#define __WINDOWS_FILEMAPPING_H
+
+#include "Windows/Handle.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+// namespace NFile {
+// namespace NMapping {
+
+class CFileMapping: public CHandle
+{
+public:
+ bool Create(HANDLE file, LPSECURITY_ATTRIBUTES attributes,
+ DWORD protect, UINT64 maximumSize, LPCTSTR name)
+ {
+ _handle = ::CreateFileMapping(file, attributes,
+ protect, DWORD(maximumSize >> 32), DWORD(maximumSize), name);
+ return (_handle != NULL);
+ }
+
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenFileMapping(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != NULL);
+ }
+
+ LPVOID MapViewOfFile(DWORD desiredAccess, UINT64 fileOffset,
+ SIZE_T numberOfBytesToMap)
+ {
+ return ::MapViewOfFile(_handle, desiredAccess,
+ DWORD(fileOffset >> 32), DWORD(fileOffset), numberOfBytesToMap);
+ }
+
+ LPVOID MapViewOfFileEx(DWORD desiredAccess, UINT64 fileOffset,
+ SIZE_T numberOfBytesToMap, LPVOID baseAddress)
+ {
+ return ::MapViewOfFileEx(_handle, desiredAccess,
+ DWORD(fileOffset >> 32), DWORD(fileOffset),
+ numberOfBytesToMap, baseAddress);
+ }
+
+
+};
+
+}
+
+#endif
Added: trunk/lzma/CPP/Windows/FileName.cpp
===================================================================
--- trunk/lzma/CPP/Windows/FileName.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/FileName.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,54 @@
+// Windows/FileName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileName.h"
+#include "Common/Wildcard.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+void NormalizeDirPathPrefix(CSysString &dirPath)
+{
+ if (dirPath.IsEmpty())
+ return;
+ if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
+ dirPath += kDirDelimiter;
+}
+
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath)
+{
+ if (dirPath.IsEmpty())
+ return;
+ if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
+ dirPath += wchar_t(kDirDelimiter);
+}
+#endif
+
+#ifdef _WIN32
+
+const wchar_t kExtensionDelimiter = L'.';
+
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension)
+{
+ int index = fullName.ReverseFind(kExtensionDelimiter);
+ if (index < 0)
+ {
+ pureName = fullName;
+ extensionDelimiter.Empty();
+ extension.Empty();
+ }
+ else
+ {
+ pureName = fullName.Left(index);
+ extensionDelimiter = kExtensionDelimiter;
+ extension = fullName.Mid(index + 1);
+ }
+}
+
+#endif
+
+}}}
Added: trunk/lzma/CPP/Windows/FileName.h
===================================================================
--- trunk/lzma/CPP/Windows/FileName.h (rev 0)
+++ trunk/lzma/CPP/Windows/FileName.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,27 @@
+// Windows/FileName.h
+
+#ifndef __WINDOWS_FILENAME_H
+#define __WINDOWS_FILENAME_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;
+const TCHAR kAnyStringWildcard = '*';
+
+void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
+#endif
+
+#ifdef _WIN32
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension);
+#endif
+
+}}}
+
+#endif
Added: trunk/lzma/CPP/Windows/Handle.h
===================================================================
--- trunk/lzma/CPP/Windows/Handle.h (rev 0)
+++ trunk/lzma/CPP/Windows/Handle.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,37 @@
+// Windows/Handle.h
+
+#ifndef __WINDOWS_HANDLE_H
+#define __WINDOWS_HANDLE_H
+
+namespace NWindows {
+
+class CHandle
+{
+protected:
+ HANDLE _handle;
+public:
+ operator HANDLE() { return _handle; }
+ CHandle(): _handle(NULL) {}
+ ~CHandle() { Close(); }
+ bool Close()
+ {
+ if (_handle == NULL)
+ return true;
+ if (!::CloseHandle(_handle))
+ return false;
+ _handle = NULL;
+ return true;
+ }
+ void Attach(HANDLE handle)
+ { _handle = handle; }
+ HANDLE Detach()
+ {
+ HANDLE handle = _handle;
+ _handle = NULL;
+ return handle;
+ }
+};
+
+}
+
+#endif
Added: trunk/lzma/CPP/Windows/MemoryLock.cpp
===================================================================
--- trunk/lzma/CPP/Windows/MemoryLock.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/MemoryLock.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,78 @@
+// Common/MemoryLock.cpp
+
+#include "StdAfx.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+#ifndef _UNICODE
+typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
+typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
+typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
+ PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);
+#endif
+
+#ifdef _UNICODE
+bool EnableLockMemoryPrivilege(
+#else
+static bool EnableLockMemoryPrivilege2(HMODULE hModule,
+#endif
+bool enable)
+{
+ #ifndef _UNICODE
+ if (hModule == NULL)
+ return false;
+ OpenProcessTokenP openProcessToken = (OpenProcessTokenP)GetProcAddress(hModule, "OpenProcessToken");
+ LookupPrivilegeValueP lookupPrivilegeValue = (LookupPrivilegeValueP)GetProcAddress(hModule, "LookupPrivilegeValueA" );
+ AdjustTokenPrivilegesP adjustTokenPrivileges = (AdjustTokenPrivilegesP)GetProcAddress(hModule, "AdjustTokenPrivileges");
+ if (openProcessToken == NULL || adjustTokenPrivileges == NULL || lookupPrivilegeValue == NULL)
+ return false;
+ #endif
+
+ HANDLE token;
+ if (!
+ #ifdef _UNICODE
+ ::OpenProcessToken
+ #else
+ openProcessToken
+ #endif
+ (::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
+ return false;
+ TOKEN_PRIVILEGES tp;
+ bool res = false;
+ if (
+ #ifdef _UNICODE
+ ::LookupPrivilegeValue
+ #else
+ lookupPrivilegeValue
+ #endif
+ (NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)))
+ {
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED: 0;
+ if (
+ #ifdef _UNICODE
+ ::AdjustTokenPrivileges
+ #else
+ adjustTokenPrivileges
+ #endif
+ (token, FALSE, &tp, 0, NULL, NULL))
+ res = (GetLastError() == ERROR_SUCCESS);
+ }
+ ::CloseHandle(token);
+ return res;
+}
+
+#ifndef _UNICODE
+bool EnableLockMemoryPrivilege(bool enable)
+{
+ HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll"));
+ if(hModule == NULL)
+ return false;
+ bool res = EnableLockMemoryPrivilege2(hModule, enable);
+ ::FreeLibrary(hModule);
+ return res;
+}
+#endif
+
+}}
Added: trunk/lzma/CPP/Windows/MemoryLock.h
===================================================================
--- trunk/lzma/CPP/Windows/MemoryLock.h (rev 0)
+++ trunk/lzma/CPP/Windows/MemoryLock.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,13 @@
+// Windows/MemoryLock.h
+
+#ifndef __WINDOWS_MEMORYLOCK_H
+#define __WINDOWS_MEMORYLOCK_H
+
+namespace NWindows {
+namespace NSecurity {
+
+bool EnableLockMemoryPrivilege(bool enable = true);
+
+}}
+
+#endif
Added: trunk/lzma/CPP/Windows/PropVariant.cpp
===================================================================
--- trunk/lzma/CPP/Windows/PropVariant.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/PropVariant.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,312 @@
+// Windows/PropVariant.cpp
+
+#include "StdAfx.h"
+
+#include "PropVariant.h"
+
+#include "../Common/Defs.h"
+
+namespace NWindows {
+namespace NCOM {
+
+CPropVariant::CPropVariant(const PROPVARIANT& varSrc)
+{
+ vt = VT_EMPTY;
+ InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(const CPropVariant& varSrc)
+{
+ vt = VT_EMPTY;
+ InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(BSTR bstrSrc)
+{
+ vt = VT_EMPTY;
+ *this = bstrSrc;
+}
+
+CPropVariant::CPropVariant(LPCOLESTR lpszSrc)
+{
+ vt = VT_EMPTY;
+ *this = lpszSrc;
+}
+
+CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc)
+{
+ InternalCopy(&varSrc);
+ return *this;
+}
+CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc)
+{
+ InternalCopy(&varSrc);
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
+{
+ *this = (LPCOLESTR)bstrSrc;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
+{
+ InternalClear();
+ vt = VT_BSTR;
+ wReserved1 = 0;
+ bstrVal = ::SysAllocString(lpszSrc);
+ if (bstrVal == NULL && lpszSrc != NULL)
+ {
+ vt = VT_ERROR;
+ scode = E_OUTOFMEMORY;
+ }
+ return *this;
+}
+
+
+CPropVariant& CPropVariant::operator=(bool bSrc)
+{
+ if (vt != VT_BOOL)
+ {
+ InternalClear();
+ vt = VT_BOOL;
+ }
+ boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UInt32 value)
+{
+ if (vt != VT_UI4)
+ {
+ InternalClear();
+ vt = VT_UI4;
+ }
+ ulVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UInt64 value)
+{
+ if (vt != VT_UI8)
+ {
+ InternalClear();
+ vt = VT_UI8;
+ }
+ uhVal.QuadPart = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(const FILETIME &value)
+{
+ if (vt != VT_FILETIME)
+ {
+ InternalClear();
+ vt = VT_FILETIME;
+ }
+ filetime = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Int32 value)
+{
+ if (vt != VT_I4)
+ {
+ InternalClear();
+ vt = VT_I4;
+ }
+ lVal = value;
+
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Byte value)
+{
+ if (vt != VT_UI1)
+ {
+ InternalClear();
+ vt = VT_UI1;
+ }
+ bVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Int16 value)
+{
+ if (vt != VT_I2)
+ {
+ InternalClear();
+ vt = VT_I2;
+ }
+ iVal = value;
+ return *this;
+}
+
+/*
+CPropVariant& CPropVariant::operator=(LONG value)
+{
+ if (vt != VT_I4)
+ {
+ InternalClear();
+ vt = VT_I4;
+ }
+ lVal = value;
+ return *this;
+}
+*/
+
+static HRESULT MyPropVariantClear(PROPVARIANT *propVariant)
+{
+ switch(propVariant->vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ propVariant->vt = VT_EMPTY;
+ propVariant->wReserved1 = 0;
+ return S_OK;
+ }
+ return ::VariantClear((VARIANTARG *)propVariant);
+}
+
+HRESULT CPropVariant::Clear()
+{
+ return MyPropVariantClear(this);
+}
+
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
+{
+ ::VariantClear((tagVARIANT *)this);
+ switch(pSrc->vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
+ return S_OK;
+ }
+ return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc));
+}
+
+
+HRESULT CPropVariant::Attach(PROPVARIANT* pSrc)
+{
+ HRESULT hr = Clear();
+ if (FAILED(hr))
+ return hr;
+ memcpy(this, pSrc, sizeof(PROPVARIANT));
+ pSrc->vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT CPropVariant::Detach(PROPVARIANT* pDest)
+{
+ HRESULT hr = MyPropVariantClear(pDest);
+ if (FAILED(hr))
+ return hr;
+ memcpy(pDest, this, sizeof(PROPVARIANT));
+ vt = VT_EMPTY;
+ return S_OK;
+}
+
+HRESULT CPropVariant::InternalClear()
+{
+ HRESULT hr = Clear();
+ if (FAILED(hr))
+ {
+ vt = VT_ERROR;
+ scode = hr;
+ }
+ return hr;
+}
+
+void CPropVariant::InternalCopy(const PROPVARIANT* pSrc)
+{
+ HRESULT hr = Copy(pSrc);
+ if (FAILED(hr))
+ {
+ vt = VT_ERROR;
+ scode = hr;
+ }
+}
+
+int CPropVariant::Compare(const CPropVariant &a)
+{
+ if(vt != a.vt)
+ return 0; // it's mean some bug
+ switch (vt)
+ {
+ case VT_EMPTY:
+ return 0;
+
+ /*
+ case VT_I1:
+ return MyCompare(cVal, a.cVal);
+ */
+ case VT_UI1:
+ return MyCompare(bVal, a.bVal);
+
+ case VT_I2:
+ return MyCompare(iVal, a.iVal);
+ case VT_UI2:
+ return MyCompare(uiVal, a.uiVal);
+
+ case VT_I4:
+ return MyCompare(lVal, a.lVal);
+ /*
+ case VT_INT:
+ return MyCompare(intVal, a.intVal);
+ */
+ case VT_UI4:
+ return MyCompare(ulVal, a.ulVal);
+ /*
+ case VT_UINT:
+ return MyCompare(uintVal, a.uintVal);
+ */
+ case VT_I8:
+ return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
+ case VT_UI8:
+ return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
+
+ case VT_BOOL:
+ return -MyCompare(boolVal, a.boolVal);
+
+ case VT_FILETIME:
+ return ::CompareFileTime(&filetime, &a.filetime);
+ case VT_BSTR:
+ return 0; // Not implemented
+ // return MyCompare(aPropVarint.cVal);
+
+ default:
+ return 0;
+ }
+}
+
+}}
Added: trunk/lzma/CPP/Windows/PropVariant.h
===================================================================
--- trunk/lzma/CPP/Windows/PropVariant.h (rev 0)
+++ trunk/lzma/CPP/Windows/PropVariant.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,57 @@
+// Windows/PropVariant.h
+
+#ifndef __WINDOWS_PROPVARIANT_H
+#define __WINDOWS_PROPVARIANT_H
+
+#include "../Common/MyWindows.h"
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NCOM {
+
+class CPropVariant : public tagPROPVARIANT
+{
+public:
+ CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
+ ~CPropVariant() { Clear(); }
+ CPropVariant(const PROPVARIANT& varSrc);
+ CPropVariant(const CPropVariant& varSrc);
+ CPropVariant(BSTR bstrSrc);
+ CPropVariant(LPCOLESTR lpszSrc);
+ CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
+ CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
+ CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal = *(ULARGE_INTEGER*)&value; }
+ CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
+ CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
+ CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
+ CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
+ // CPropVariant(LONG value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
+
+ CPropVariant& operator=(const CPropVariant& varSrc);
+ CPropVariant& operator=(const PROPVARIANT& varSrc);
+ CPropVariant& operator=(BSTR bstrSrc);
+ CPropVariant& operator=(LPCOLESTR lpszSrc);
+ CPropVariant& operator=(bool bSrc);
+ CPropVariant& operator=(UInt32 value);
+ CPropVariant& operator=(UInt64 value);
+ CPropVariant& operator=(const FILETIME &value);
+
+ CPropVariant& operator=(Int32 value);
+ CPropVariant& operator=(Byte value);
+ CPropVariant& operator=(Int16 value);
+ // CPropVariant& operator=(LONG value);
+
+ HRESULT Clear();
+ HRESULT Copy(const PROPVARIANT* pSrc);
+ HRESULT Attach(PROPVARIANT* pSrc);
+ HRESULT Detach(PROPVARIANT* pDest);
+
+ HRESULT InternalClear();
+ void InternalCopy(const PROPVARIANT* pSrc);
+
+ int Compare(const CPropVariant &a1);
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/Windows/PropVariantConversions.cpp
===================================================================
--- trunk/lzma/CPP/Windows/PropVariantConversions.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/PropVariantConversions.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,150 @@
+// PropVariantConversions.cpp
+
+#include "StdAfx.h"
+
+// #include <stdio.h>
+
+#include "PropVariantConversions.h"
+
+#include "Windows/Defs.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+static UString ConvertUInt64ToString(UInt64 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static UString ConvertInt64ToString(Int64 value)
+{
+ wchar_t buffer[32];
+ ConvertInt64ToString(value, buffer);
+ return buffer;
+}
+
+static char *UIntToStringSpec(UInt32 value, char *s, int numPos)
+{
+ char temp[16];
+ int pos = 0;
+ do
+ {
+ temp[pos++] = (char)('0' + value % 10);
+ value /= 10;
+ }
+ while (value != 0);
+ int i;
+ for (i = 0; i < numPos - pos; i++)
+ *s++ = '0';
+ do
+ *s++ = temp[--pos];
+ while (pos > 0);
+ *s = '\0';
+ return s;
+}
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
+{
+ s[0] = '\0';
+ SYSTEMTIME st;
+ if(!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
+ return false;
+ s = UIntToStringSpec(st.wYear, s, 4);
+ *s++ = '-';
+ s = UIntToStringSpec(st.wMonth, s, 2);
+ *s++ = '-';
+ s = UIntToStringSpec(st.wDay, s, 2);
+ if (includeTime)
+ {
+ *s++ = ' ';
+ s = UIntToStringSpec(st.wHour, s, 2);
+ *s++ = ':';
+ s = UIntToStringSpec(st.wMinute, s, 2);
+ if (includeSeconds)
+ {
+ *s++ = ':';
+ UIntToStringSpec(st.wSecond, s, 2);
+ }
+ }
+ /*
+ sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
+ if (includeTime)
+ {
+ sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute);
+ if (includeSeconds)
+ sprintf(s + strlen(s), ":%02d", st.wSecond);
+ }
+ */
+ return true;
+}
+
+UString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime, bool includeSeconds)
+{
+ char s[32];
+ ConvertFileTimeToString(fileTime, s, includeTime, includeSeconds);
+ return GetUnicodeString(s);
+}
+
+
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant)
+{
+ switch (propVariant.vt)
+ {
+ case VT_EMPTY:
+ return UString();
+ case VT_BSTR:
+ return propVariant.bstrVal;
+ case VT_UI1:
+ return ConvertUInt64ToString(propVariant.bVal);
+ case VT_UI2:
+ return ConvertUInt64ToString(propVariant.uiVal);
+ case VT_UI4:
+ return ConvertUInt64ToString(propVariant.ulVal);
+ case VT_UI8:
+ return ConvertUInt64ToString(propVariant.uhVal.QuadPart);
+ case VT_FILETIME:
+ return ConvertFileTimeToString(propVariant.filetime, true, true);
+ /*
+ case VT_I1:
+ return ConvertInt64ToString(propVariant.cVal);
+ */
+ case VT_I2:
+ return ConvertInt64ToString(propVariant.iVal);
+ case VT_I4:
+ return ConvertInt64ToString(propVariant.lVal);
+ case VT_I8:
+ return ConvertInt64ToString(propVariant.hVal.QuadPart);
+
+ case VT_BOOL:
+ return VARIANT_BOOLToBool(propVariant.boolVal) ? L"+" : L"-";
+ default:
+ #ifndef _WIN32_WCE
+ throw 150245;
+ #else
+ return UString();
+ #endif
+ }
+}
+
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant)
+{
+ switch (propVariant.vt)
+ {
+ case VT_UI1:
+ return propVariant.bVal;
+ case VT_UI2:
+ return propVariant.uiVal;
+ case VT_UI4:
+ return propVariant.ulVal;
+ case VT_UI8:
+ return (UInt64)propVariant.uhVal.QuadPart;
+ default:
+ #ifndef _WIN32_WCE
+ throw 151199;
+ #else
+ return 0;
+ #endif
+ }
+}
Added: trunk/lzma/CPP/Windows/PropVariantConversions.h
===================================================================
--- trunk/lzma/CPP/Windows/PropVariantConversions.h (rev 0)
+++ trunk/lzma/CPP/Windows/PropVariantConversions.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,14 @@
+// Windows/PropVariantConversions.h
+
+#ifndef __PROPVARIANTCONVERSIONS_H
+#define __PROPVARIANTCONVERSIONS_H
+
+#include "Common/Types.h"
+#include "Common/MyString.h"
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);
+UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant);
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant);
+
+#endif
Added: trunk/lzma/CPP/Windows/StdAfx.h
===================================================================
--- trunk/lzma/CPP/Windows/StdAfx.h (rev 0)
+++ trunk/lzma/CPP/Windows/StdAfx.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../Common/MyWindows.h"
+#include "../Common/NewHandler.h"
+
+#endif
Added: trunk/lzma/CPP/Windows/Synchronization.cpp
===================================================================
--- trunk/lzma/CPP/Windows/Synchronization.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/Synchronization.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,10 @@
+// Windows/Synchronization.cpp
+
+#include "StdAfx.h"
+
+#include "Synchronization.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+}}
Added: trunk/lzma/CPP/Windows/Synchronization.h
===================================================================
--- trunk/lzma/CPP/Windows/Synchronization.h (rev 0)
+++ trunk/lzma/CPP/Windows/Synchronization.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,168 @@
+// Windows/Synchronization.h
+
+#ifndef __WINDOWS_SYNCHRONIZATION_H
+#define __WINDOWS_SYNCHRONIZATION_H
+
+#include "Defs.h"
+
+extern "C"
+{
+#include "../../C/Threads.h"
+}
+
+#ifdef _WIN32
+#include "Handle.h"
+#endif
+
+namespace NWindows {
+namespace NSynchronization {
+
+class CBaseEvent
+{
+protected:
+ ::CEvent _object;
+public:
+ bool IsCreated() { return Event_IsCreated(&_object) != 0; }
+ operator HANDLE() { return _object.handle; }
+ CBaseEvent() { Event_Construct(&_object); }
+ ~CBaseEvent() { Close(); }
+ HRes Close() { return Event_Close(&_object); }
+ #ifdef _WIN32
+ HRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _object.handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset),
+ BoolToBOOL(initiallyOwn), name);
+ if (_object.handle != 0)
+ return 0;
+ return ::GetLastError();
+ }
+ HRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _object.handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
+ if (_object.handle != 0)
+ return 0;
+ return ::GetLastError();
+ }
+ #endif
+
+ HRes Set() { return Event_Set(&_object); }
+ // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
+ HRes Reset() { return Event_Reset(&_object); }
+ HRes Lock() { return Event_Wait(&_object); }
+};
+
+class CManualResetEvent: public CBaseEvent
+{
+public:
+ HRes Create(bool initiallyOwn = false)
+ {
+ return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0);
+ }
+ HRes CreateIfNotCreated()
+ {
+ if (IsCreated())
+ return 0;
+ return ManualResetEvent_CreateNotSignaled(&_object);
+ }
+ #ifdef _WIN32
+ HRes CreateWithName(bool initiallyOwn, LPCTSTR name)
+ {
+ return CBaseEvent::Create(true, initiallyOwn, name);
+ }
+ #endif
+};
+
+class CAutoResetEvent: public CBaseEvent
+{
+public:
+ HRes Create()
+ {
+ return AutoResetEvent_CreateNotSignaled(&_object);
+ }
+ HRes CreateIfNotCreated()
+ {
+ if (IsCreated())
+ return 0;
+ return AutoResetEvent_CreateNotSignaled(&_object);
+ }
+};
+
+#ifdef _WIN32
+class CObject: public CHandle
+{
+public:
+ HRes Lock(DWORD timeoutInterval = INFINITE)
+ { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); }
+};
+class CMutex: public CObject
+{
+public:
+ HRes Create(bool initiallyOwn, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name);
+ if (_handle != 0)
+ return 0;
+ return ::GetLastError();
+ }
+ HRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
+ if (_handle != 0)
+ return 0;
+ return ::GetLastError();
+ }
+ HRes Release()
+ {
+ return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();
+ }
+};
+class CMutexLock
+{
+ CMutex *_object;
+public:
+ CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
+ ~CMutexLock() { _object->Release(); }
+};
+#endif
+
+class CSemaphore
+{
+ ::CSemaphore _object;
+public:
+ CSemaphore() { Semaphore_Construct(&_object); }
+ ~CSemaphore() { Close(); }
+ HRes Close() { return Semaphore_Close(&_object); }
+ operator HANDLE() { return _object.handle; }
+ HRes Create(UInt32 initiallyCount, UInt32 maxCount)
+ {
+ return Semaphore_Create(&_object, initiallyCount, maxCount);
+ }
+ HRes Release() { return Semaphore_Release1(&_object); }
+ HRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }
+ HRes Lock() { return Semaphore_Wait(&_object); }
+};
+
+class CCriticalSection
+{
+ ::CCriticalSection _object;
+public:
+ CCriticalSection() { CriticalSection_Init(&_object); }
+ ~CCriticalSection() { CriticalSection_Delete(&_object); }
+ void Enter() { CriticalSection_Enter(&_object); }
+ void Leave() { CriticalSection_Leave(&_object); }
+};
+
+class CCriticalSectionLock
+{
+ CCriticalSection *_object;
+ void Unlock() { _object->Leave(); }
+public:
+ CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
+ ~CCriticalSectionLock() { Unlock(); }
+};
+
+}}
+
+#endif
Added: trunk/lzma/CPP/Windows/System.cpp
===================================================================
--- trunk/lzma/CPP/Windows/System.cpp (rev 0)
+++ trunk/lzma/CPP/Windows/System.cpp 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,64 @@
+// Windows/System.cpp
+
+#include "StdAfx.h"
+
+#include "System.h"
+
+namespace NWindows {
+namespace NSystem {
+
+UInt32 GetNumberOfProcessors()
+{
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ return (UInt32)systemInfo.dwNumberOfProcessors;
+}
+
+#if !defined(_WIN64) && defined(__GNUC__)
+
+typedef struct _MY_MEMORYSTATUSEX {
+ DWORD dwLength;
+ DWORD dwMemoryLoad;
+ DWORDLONG ullTotalPhys;
+ DWORDLONG ullAvailPhys;
+ DWORDLONG ullTotalPageFile;
+ DWORDLONG ullAvailPageFile;
+ DWORDLONG ullTotalVirtual;
+ DWORDLONG ullAvailVirtual;
+ DWORDLONG ullAvailExtendedVirtual;
+} MY_MEMORYSTATUSEX, *MY_LPMEMORYSTATUSEX;
+
+#else
+
+#define MY_MEMORYSTATUSEX MEMORYSTATUSEX
+#define MY_LPMEMORYSTATUSEX LPMEMORYSTATUSEX
+
+#endif
+
+typedef BOOL (WINAPI *GlobalMemoryStatusExP)(MY_LPMEMORYSTATUSEX lpBuffer);
+
+UInt64 GetRamSize()
+{
+ MY_MEMORYSTATUSEX stat;
+ stat.dwLength = sizeof(stat);
+ #ifdef _WIN64
+ if (!::GlobalMemoryStatusEx(&stat))
+ return 0;
+ return stat.ullTotalPhys;
+ #else
+ GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
+ "GlobalMemoryStatusEx");
+ if (globalMemoryStatusEx != 0)
+ if (globalMemoryStatusEx(&stat))
+ return stat.ullTotalPhys;
+ {
+ MEMORYSTATUS stat;
+ stat.dwLength = sizeof(stat);
+ GlobalMemoryStatus(&stat);
+ return stat.dwTotalPhys;
+ }
+ #endif
+}
+
+}}
Added: trunk/lzma/CPP/Windows/System.h
===================================================================
--- trunk/lzma/CPP/Windows/System.h (rev 0)
+++ trunk/lzma/CPP/Windows/System.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,16 @@
+// Windows/System.h
+
+#ifndef __WINDOWS_SYSTEM_H
+#define __WINDOWS_SYSTEM_H
+
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NSystem {
+
+UInt32 GetNumberOfProcessors();
+UInt64 GetRamSize();
+
+}}
+
+#endif
Added: trunk/lzma/CPP/Windows/Thread.h
===================================================================
--- trunk/lzma/CPP/Windows/Thread.h (rev 0)
+++ trunk/lzma/CPP/Windows/Thread.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,38 @@
+// Windows/Thread.h
+
+#ifndef __WINDOWS_THREAD_H
+#define __WINDOWS_THREAD_H
+
+#include "Defs.h"
+
+extern "C"
+{
+#include "../../C/Threads.h"
+}
+
+namespace NWindows {
+
+class CThread
+{
+ ::CThread thread;
+public:
+ CThread() { Thread_Construct(&thread); }
+ ~CThread() { Close(); }
+ bool IsCreated() { return Thread_WasCreated(&thread) != 0; }
+ HRes Close() { return Thread_Close(&thread); }
+ HRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
+ { return Thread_Create(&thread, startAddress, parameter); }
+ HRes Wait() { return Thread_Wait(&thread); }
+
+ #ifdef _WIN32
+ DWORD Resume() { return ::ResumeThread(thread.handle); }
+ DWORD Suspend() { return ::SuspendThread(thread.handle); }
+ bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread.handle, exitCode)); }
+ int GetPriority() { return ::GetThreadPriority(thread.handle); }
+ bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread.handle, priority)); }
+ #endif
+};
+
+}
+
+#endif
Added: trunk/lzma/CPP/Windows/Time.h
===================================================================
--- trunk/lzma/CPP/Windows/Time.h (rev 0)
+++ trunk/lzma/CPP/Windows/Time.h 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,66 @@
+// Windows/Time.h
+
+#ifndef __WINDOWS_TIME_H
+#define __WINDOWS_TIME_H
+
+#include "Common/Types.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NTime {
+
+inline bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime)
+{
+ return BOOLToBool(::DosDateTimeToFileTime(UInt16(dosTime >> 16),
+ UInt16(dosTime & 0xFFFF), &fileTime));
+}
+
+const UInt32 kHighDosTime = 0xFF9FBF7D;
+const UInt32 kLowDosTime = 0x210000;
+
+inline bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime)
+{
+ WORD datePart, timePart;
+ if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart))
+ {
+ if (fileTime.dwHighDateTime >= 0x01C00000) // 2000
+ dosTime = kHighDosTime;
+ else
+ dosTime = kLowDosTime;
+ return false;
+ }
+ dosTime = (((UInt32)datePart) << 16) + timePart;
+ return true;
+}
+
+const UInt32 kNumTimeQuantumsInSecond = 10000000;
+const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774;
+
+inline void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime)
+{
+ UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ fileTime.dwLowDateTime = (DWORD)v;
+ fileTime.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+inline bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime)
+{
+ UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
+ if (winTime < kUnixTimeStartValue)
+ {
+ unixTime = 0;
+ return false;
+ }
+ winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+ if (winTime > 0xFFFFFFFF)
+ {
+ unixTime = 0xFFFFFFFF;
+ return false;
+ }
+ unixTime = (UInt32)winTime;
+ return true;
+}
+
+}}
+
+#endif
Added: trunk/lzma/CS/7zip/Common/CRC.cs
===================================================================
--- trunk/lzma/CS/7zip/Common/CRC.cs (rev 0)
+++ trunk/lzma/CS/7zip/Common/CRC.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,55 @@
+// Common/CRC.cs
+
+namespace SevenZip
+{
+ class CRC
+ {
+ public static readonly uint[] Table;
+
+ static CRC()
+ {
+ Table = new uint[256];
+ const uint kPoly = 0xEDB88320;
+ for (uint i = 0; i < 256; i++)
+ {
+ uint r = i;
+ for (int j = 0; j < 8; j++)
+ if ((r & 1) != 0)
+ r = (r >> 1) ^ kPoly;
+ else
+ r >>= 1;
+ Table[i] = r;
+ }
+ }
+
+ uint _value = 0xFFFFFFFF;
+
+ public void Init() { _value = 0xFFFFFFFF; }
+
+ public void UpdateByte(byte b)
+ {
+ _value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);
+ }
+
+ public void Update(byte[] data, uint offset, uint size)
+ {
+ for (uint i = 0; i < size; i++)
+ _value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
+ }
+
+ public uint GetDigest() { return _value ^ 0xFFFFFFFF; }
+
+ static uint CalculateDigest(byte[] data, uint offset, uint size)
+ {
+ CRC crc = new CRC();
+ // crc.Init();
+ crc.Update(data, offset, size);
+ return crc.GetDigest();
+ }
+
+ static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
+ {
+ return (CalculateDigest(data, offset, size) == digest);
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Common/CommandLineParser.cs
===================================================================
--- trunk/lzma/CS/7zip/Common/CommandLineParser.cs (rev 0)
+++ trunk/lzma/CS/7zip/Common/CommandLineParser.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,274 @@
+// CommandLineParser.cs
+
+using System;
+using System.Collections;
+
+namespace SevenZip.CommandLineParser
+{
+ public enum SwitchType
+ {
+ Simple,
+ PostMinus,
+ LimitedPostString,
+ UnLimitedPostString,
+ PostChar
+ }
+
+ public class SwitchForm
+ {
+ public string IDString;
+ public SwitchType Type;
+ public bool Multi;
+ public int MinLen;
+ public int MaxLen;
+ public string PostCharSet;
+
+ public SwitchForm(string idString, SwitchType type, bool multi,
+ int minLen, int maxLen, string postCharSet)
+ {
+ IDString = idString;
+ Type = type;
+ Multi = multi;
+ MinLen = minLen;
+ MaxLen = maxLen;
+ PostCharSet = postCharSet;
+ }
+ public SwitchForm(string idString, SwitchType type, bool multi, int minLen):
+ this(idString, type, multi, minLen, 0, "")
+ {
+ }
+ public SwitchForm(string idString, SwitchType type, bool multi):
+ this(idString, type, multi, 0)
+ {
+ }
+ }
+
+ public class SwitchResult
+ {
+ public bool ThereIs;
+ public bool WithMinus;
+ public ArrayList PostStrings = new ArrayList();
+ public int PostCharIndex;
+ public SwitchResult()
+ {
+ ThereIs = false;
+ }
+ }
+
+ public class Parser
+ {
+ public ArrayList NonSwitchStrings = new ArrayList();
+ SwitchResult[] _switches;
+
+ public Parser(int numSwitches)
+ {
+ _switches = new SwitchResult[numSwitches];
+ for (int i = 0; i < numSwitches; i++)
+ _switches[i] = new SwitchResult();
+ }
+
+ bool ParseString(string srcString, SwitchForm[] switchForms)
+ {
+ int len = srcString.Length;
+ if (len == 0)
+ return false;
+ int pos = 0;
+ if (!IsItSwitchChar(srcString[pos]))
+ return false;
+ while (pos < len)
+ {
+ if (IsItSwitchChar(srcString[pos]))
+ pos++;
+ const int kNoLen = -1;
+ int matchedSwitchIndex = 0;
+ int maxLen = kNoLen;
+ for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++)
+ {
+ int switchLen = switchForms[switchIndex].IDString.Length;
+ if (switchLen <= maxLen || pos + switchLen > len)
+ continue;
+ if (String.Compare(switchForms[switchIndex].IDString, 0,
+ srcString, pos, switchLen, true) == 0)
+ {
+ matchedSwitchIndex = switchIndex;
+ maxLen = switchLen;
+ }
+ }
+ if (maxLen == kNoLen)
+ throw new Exception("maxLen == kNoLen");
+ SwitchResult matchedSwitch = _switches[matchedSwitchIndex];
+ SwitchForm switchForm = switchForms[matchedSwitchIndex];
+ if ((!switchForm.Multi) && matchedSwitch.ThereIs)
+ throw new Exception("switch must be single");
+ matchedSwitch.ThereIs = true;
+ pos += maxLen;
+ int tailSize = len - pos;
+ SwitchType type = switchForm.Type;
+ switch (type)
+ {
+ case SwitchType.PostMinus:
+ {
+ if (tailSize == 0)
+ matchedSwitch.WithMinus = false;
+ else
+ {
+ matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus);
+ if (matchedSwitch.WithMinus)
+ pos++;
+ }
+ break;
+ }
+ case SwitchType.PostChar:
+ {
+ if (tailSize < switchForm.MinLen)
+ throw new Exception("switch is not full");
+ string charSet = switchForm.PostCharSet;
+ const int kEmptyCharValue = -1;
+ if (tailSize == 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ int index = charSet.IndexOf(srcString[pos]);
+ if (index < 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ matchedSwitch.PostCharIndex = index;
+ pos++;
+ }
+ }
+ break;
+ }
+ case SwitchType.LimitedPostString:
+ case SwitchType.UnLimitedPostString:
+ {
+ int minLen = switchForm.MinLen;
+ if (tailSize < minLen)
+ throw new Exception("switch is not full");
+ if (type == SwitchType.UnLimitedPostString)
+ {
+ matchedSwitch.PostStrings.Add(srcString.Substring(pos));
+ return true;
+ }
+ String stringSwitch = srcString.Substring(pos, minLen);
+ pos += minLen;
+ for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++)
+ {
+ char c = srcString[pos];
+ if (IsItSwitchChar(c))
+ break;
+ stringSwitch += c;
+ }
+ matchedSwitch.PostStrings.Add(stringSwitch);
+ break;
+ }
+ }
+ }
+ return true;
+
+ }
+
+ public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings)
+ {
+ int numCommandStrings = commandStrings.Length;
+ bool stopSwitch = false;
+ for (int i = 0; i < numCommandStrings; i++)
+ {
+ string s = commandStrings[i];
+ if (stopSwitch)
+ NonSwitchStrings.Add(s);
+ else
+ if (s == kStopSwitchParsing)
+ stopSwitch = true;
+ else
+ if (!ParseString(s, switchForms))
+ NonSwitchStrings.Add(s);
+ }
+ }
+
+ public SwitchResult this[int index] { get { return _switches[index]; } }
+
+ public static int ParseCommand(CommandForm[] commandForms, string commandString,
+ out string postString)
+ {
+ for (int i = 0; i < commandForms.Length; i++)
+ {
+ string id = commandForms[i].IDString;
+ if (commandForms[i].PostStringMode)
+ {
+ if (commandString.IndexOf(id) == 0)
+ {
+ postString = commandString.Substring(id.Length);
+ return i;
+ }
+ }
+ else
+ if (commandString == id)
+ {
+ postString = "";
+ return i;
+ }
+ }
+ postString = "";
+ return -1;
+ }
+
+ static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms,
+ string commandString, ArrayList indices)
+ {
+ indices.Clear();
+ int numUsedChars = 0;
+ for (int i = 0; i < numForms; i++)
+ {
+ CommandSubCharsSet charsSet = forms[i];
+ int currentIndex = -1;
+ int len = charsSet.Chars.Length;
+ for (int j = 0; j < len; j++)
+ {
+ char c = charsSet.Chars[j];
+ int newIndex = commandString.IndexOf(c);
+ if (newIndex >= 0)
+ {
+ if (currentIndex >= 0)
+ return false;
+ if (commandString.IndexOf(c, newIndex + 1) >= 0)
+ return false;
+ currentIndex = j;
+ numUsedChars++;
+ }
+ }
+ if (currentIndex == -1 && !charsSet.EmptyAllowed)
+ return false;
+ indices.Add(currentIndex);
+ }
+ return (numUsedChars == commandString.Length);
+ }
+ const char kSwitchID1 = '-';
+ const char kSwitchID2 = '/';
+
+ const char kSwitchMinus = '-';
+ const string kStopSwitchParsing = "--";
+
+ static bool IsItSwitchChar(char c)
+ {
+ return (c == kSwitchID1 || c == kSwitchID2);
+ }
+ }
+
+ public class CommandForm
+ {
+ public string IDString = "";
+ public bool PostStringMode = false;
+ public CommandForm(string idString, bool postStringMode)
+ {
+ IDString = idString;
+ PostStringMode = postStringMode;
+ }
+ }
+
+ class CommandSubCharsSet
+ {
+ public string Chars = "";
+ public bool EmptyAllowed = false;
+ }
+}
Added: trunk/lzma/CS/7zip/Common/InBuffer.cs
===================================================================
--- trunk/lzma/CS/7zip/Common/InBuffer.cs (rev 0)
+++ trunk/lzma/CS/7zip/Common/InBuffer.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,72 @@
+// InBuffer.cs
+
+namespace SevenZip.Buffer
+{
+ public class InBuffer
+ {
+ byte[] m_Buffer;
+ uint m_Pos;
+ uint m_Limit;
+ uint m_BufferSize;
+ System.IO.Stream m_Stream;
+ bool m_StreamWasExhausted;
+ ulong m_ProcessedSize;
+
+ public InBuffer(uint bufferSize)
+ {
+ m_Buffer = new byte[bufferSize];
+ m_BufferSize = bufferSize;
+ }
+
+ public void Init(System.IO.Stream stream)
+ {
+ m_Stream = stream;
+ m_ProcessedSize = 0;
+ m_Limit = 0;
+ m_Pos = 0;
+ m_StreamWasExhausted = false;
+ }
+
+ public bool ReadBlock()
+ {
+ if (m_StreamWasExhausted)
+ return false;
+ m_ProcessedSize += m_Pos;
+ int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize);
+ m_Pos = 0;
+ m_Limit = (uint)aNumProcessedBytes;
+ m_StreamWasExhausted = (aNumProcessedBytes == 0);
+ return (!m_StreamWasExhausted);
+ }
+
+
+ public void ReleaseStream()
+ {
+ // m_Stream.Close();
+ m_Stream = null;
+ }
+
+ public bool ReadByte(byte b) // check it
+ {
+ if (m_Pos >= m_Limit)
+ if (!ReadBlock())
+ return false;
+ b = m_Buffer[m_Pos++];
+ return true;
+ }
+
+ public byte ReadByte()
+ {
+ // return (byte)m_Stream.ReadByte();
+ if (m_Pos >= m_Limit)
+ if (!ReadBlock())
+ return 0xFF;
+ return m_Buffer[m_Pos++];
+ }
+
+ public ulong GetProcessedSize()
+ {
+ return m_ProcessedSize + m_Pos;
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Common/OutBuffer.cs
===================================================================
--- trunk/lzma/CS/7zip/Common/OutBuffer.cs (rev 0)
+++ trunk/lzma/CS/7zip/Common/OutBuffer.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,47 @@
+// OutBuffer.cs
+
+namespace SevenZip.Buffer
+{
+ public class OutBuffer
+ {
+ byte[] m_Buffer;
+ uint m_Pos;
+ uint m_BufferSize;
+ System.IO.Stream m_Stream;
+ ulong m_ProcessedSize;
+
+ public OutBuffer(uint bufferSize)
+ {
+ m_Buffer = new byte[bufferSize];
+ m_BufferSize = bufferSize;
+ }
+
+ public void SetStream(System.IO.Stream stream) { m_Stream = stream; }
+ public void FlushStream() { m_Stream.Flush(); }
+ public void CloseStream() { m_Stream.Close(); }
+ public void ReleaseStream() { m_Stream = null; }
+
+ public void Init()
+ {
+ m_ProcessedSize = 0;
+ m_Pos = 0;
+ }
+
+ public void WriteByte(byte b)
+ {
+ m_Buffer[m_Pos++] = b;
+ if (m_Pos >= m_BufferSize)
+ FlushData();
+ }
+
+ public void FlushData()
+ {
+ if (m_Pos == 0)
+ return;
+ m_Stream.Write(m_Buffer, 0, (int)m_Pos);
+ m_Pos = 0;
+ }
+
+ public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LZ/IMatchFinder.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LZ/IMatchFinder.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LZ/IMatchFinder.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,24 @@
+// IMatchFinder.cs
+
+using System;
+
+namespace SevenZip.Compression.LZ
+{
+ interface IInWindowStream
+ {
+ void SetStream(System.IO.Stream inStream);
+ void Init();
+ void ReleaseStream();
+ Byte GetIndexByte(Int32 index);
+ UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit);
+ UInt32 GetNumAvailableBytes();
+ }
+
+ interface IMatchFinder : IInWindowStream
+ {
+ void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
+ UInt32 GetMatches(UInt32[] distances);
+ void Skip(UInt32 num);
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LZ/LzBinTree.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LZ/LzBinTree.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LZ/LzBinTree.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,367 @@
+// LzBinTree.cs
+
+using System;
+
+namespace SevenZip.Compression.LZ
+{
+ public class BinTree : InWindow, IMatchFinder
+ {
+ UInt32 _cyclicBufferPos;
+ UInt32 _cyclicBufferSize = 0;
+ UInt32 _matchMaxLen;
+
+ UInt32[] _son;
+ UInt32[] _hash;
+
+ UInt32 _cutValue = 0xFF;
+ UInt32 _hashMask;
+ UInt32 _hashSizeSum = 0;
+
+ bool HASH_ARRAY = true;
+
+ const UInt32 kHash2Size = 1 << 10;
+ const UInt32 kHash3Size = 1 << 16;
+ const UInt32 kBT2HashSize = 1 << 16;
+ const UInt32 kStartMaxLen = 1;
+ const UInt32 kHash3Offset = kHash2Size;
+ const UInt32 kEmptyHashValue = 0;
+ const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1;
+
+ UInt32 kNumHashDirectBytes = 0;
+ UInt32 kMinMatchCheck = 4;
+ UInt32 kFixHashSize = kHash2Size + kHash3Size;
+
+ public void SetType(int numHashBytes)
+ {
+ HASH_ARRAY = (numHashBytes > 2);
+ if (HASH_ARRAY)
+ {
+ kNumHashDirectBytes = 0;
+ kMinMatchCheck = 4;
+ kFixHashSize = kHash2Size + kHash3Size;
+ }
+ else
+ {
+ kNumHashDirectBytes = 2;
+ kMinMatchCheck = 2 + 1;
+ kFixHashSize = 0;
+ }
+ }
+
+ public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); }
+ public new void ReleaseStream() { base.ReleaseStream(); }
+
+ public new void Init()
+ {
+ base.Init();
+ for (UInt32 i = 0; i < _hashSizeSum; i++)
+ _hash[i] = kEmptyHashValue;
+ _cyclicBufferPos = 0;
+ ReduceOffsets(-1);
+ }
+
+ public new void MovePos()
+ {
+ if (++_cyclicBufferPos >= _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ base.MovePos();
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ }
+
+ public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); }
+
+ public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
+ { return base.GetMatchLen(index, distance, limit); }
+
+ public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); }
+
+ public void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
+ {
+ if (historySize > kMaxValForNormalize - 256)
+ throw new Exception();
+ _cutValue = 16 + (matchMaxLen >> 1);
+
+ UInt32 windowReservSize = (historySize + keepAddBufferBefore +
+ matchMaxLen + keepAddBufferAfter) / 2 + 256;
+
+ base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
+
+ _matchMaxLen = matchMaxLen;
+
+ UInt32 cyclicBufferSize = historySize + 1;
+ if (_cyclicBufferSize != cyclicBufferSize)
+ _son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2];
+
+ UInt32 hs = kBT2HashSize;
+
+ if (HASH_ARRAY)
+ {
+ hs = historySize - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ hs |= 0xFFFF;
+ if (hs > (1 << 24))
+ hs >>= 1;
+ _hashMask = hs;
+ hs++;
+ hs += kFixHashSize;
+ }
+ if (hs != _hashSizeSum)
+ _hash = new UInt32[_hashSizeSum = hs];
+ }
+
+ public UInt32 GetMatches(UInt32[] distances)
+ {
+ UInt32 lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if (lenLimit < kMinMatchCheck)
+ {
+ MovePos();
+ return 0;
+ }
+ }
+
+ UInt32 offset = 0;
+ UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ UInt32 cur = _bufferOffset + _pos;
+ UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
+ UInt32 hashValue, hash2Value = 0, hash3Value = 0;
+
+ if (HASH_ARRAY)
+ {
+ UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
+ hash2Value = temp & (kHash2Size - 1);
+ temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
+ hash3Value = temp & (kHash3Size - 1);
+ hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
+ }
+ else
+ hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
+
+ UInt32 curMatch = _hash[kFixHashSize + hashValue];
+ if (HASH_ARRAY)
+ {
+ UInt32 curMatch2 = _hash[hash2Value];
+ UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
+ _hash[hash2Value] = _pos;
+ _hash[kHash3Offset + hash3Value] = _pos;
+ if (curMatch2 > matchMinPos)
+ if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
+ {
+ distances[offset++] = maxLen = 2;
+ distances[offset++] = _pos - curMatch2 - 1;
+ }
+ if (curMatch3 > matchMinPos)
+ if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
+ {
+ if (curMatch3 == curMatch2)
+ offset -= 2;
+ distances[offset++] = maxLen = 3;
+ distances[offset++] = _pos - curMatch3 - 1;
+ curMatch2 = curMatch3;
+ }
+ if (offset != 0 && curMatch2 == curMatch)
+ {
+ offset -= 2;
+ maxLen = kStartMaxLen;
+ }
+ }
+
+ _hash[kFixHashSize + hashValue] = _pos;
+
+ UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
+ UInt32 ptr1 = (_cyclicBufferPos << 1);
+
+ UInt32 len0, len1;
+ len0 = len1 = kNumHashDirectBytes;
+
+ if (kNumHashDirectBytes != 0)
+ {
+ if (curMatch > matchMinPos)
+ {
+ if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
+ _bufferBase[cur + kNumHashDirectBytes])
+ {
+ distances[offset++] = maxLen = kNumHashDirectBytes;
+ distances[offset++] = _pos - curMatch - 1;
+ }
+ }
+ }
+
+ UInt32 count = _cutValue;
+
+ while(true)
+ {
+ if(curMatch <= matchMinPos || count-- == 0)
+ {
+ _son[ptr0] = _son[ptr1] = kEmptyHashValue;
+ break;
+ }
+ UInt32 delta = _pos - curMatch;
+ UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta) :
+ (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
+
+ UInt32 pby1 = _bufferOffset + curMatch;
+ UInt32 len = Math.Min(len0, len1);
+ if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
+ {
+ while(++len != lenLimit)
+ if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
+ break;
+ if (maxLen < len)
+ {
+ distances[offset++] = maxLen = len;
+ distances[offset++] = delta - 1;
+ if (len == lenLimit)
+ {
+ _son[ptr1] = _son[cyclicPos];
+ _son[ptr0] = _son[cyclicPos + 1];
+ break;
+ }
+ }
+ }
+ if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
+ {
+ _son[ptr1] = curMatch;
+ ptr1 = cyclicPos + 1;
+ curMatch = _son[ptr1];
+ len1 = len;
+ }
+ else
+ {
+ _son[ptr0] = curMatch;
+ ptr0 = cyclicPos;
+ curMatch = _son[ptr0];
+ len0 = len;
+ }
+ }
+ MovePos();
+ return offset;
+ }
+
+ public void Skip(UInt32 num)
+ {
+ do
+ {
+ UInt32 lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if (lenLimit < kMinMatchCheck)
+ {
+ MovePos();
+ continue;
+ }
+ }
+
+ UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ UInt32 cur = _bufferOffset + _pos;
+
+ UInt32 hashValue;
+
+ if (HASH_ARRAY)
+ {
+ UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
+ UInt32 hash2Value = temp & (kHash2Size - 1);
+ _hash[hash2Value] = _pos;
+ temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
+ UInt32 hash3Value = temp & (kHash3Size - 1);
+ _hash[kHash3Offset + hash3Value] = _pos;
+ hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
+ }
+ else
+ hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
+
+ UInt32 curMatch = _hash[kFixHashSize + hashValue];
+ _hash[kFixHashSize + hashValue] = _pos;
+
+ UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
+ UInt32 ptr1 = (_cyclicBufferPos << 1);
+
+ UInt32 len0, len1;
+ len0 = len1 = kNumHashDirectBytes;
+
+ UInt32 count = _cutValue;
+ while (true)
+ {
+ if (curMatch <= matchMinPos || count-- == 0)
+ {
+ _son[ptr0] = _son[ptr1] = kEmptyHashValue;
+ break;
+ }
+
+ UInt32 delta = _pos - curMatch;
+ UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta) :
+ (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
+
+ UInt32 pby1 = _bufferOffset + curMatch;
+ UInt32 len = Math.Min(len0, len1);
+ if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
+ {
+ while (++len != lenLimit)
+ if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
+ break;
+ if (len == lenLimit)
+ {
+ _son[ptr1] = _son[cyclicPos];
+ _son[ptr0] = _son[cyclicPos + 1];
+ break;
+ }
+ }
+ if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
+ {
+ _son[ptr1] = curMatch;
+ ptr1 = cyclicPos + 1;
+ curMatch = _son[ptr1];
+ len1 = len;
+ }
+ else
+ {
+ _son[ptr0] = curMatch;
+ ptr0 = cyclicPos;
+ curMatch = _son[ptr0];
+ len0 = len;
+ }
+ }
+ MovePos();
+ }
+ while (--num != 0);
+ }
+
+ void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue)
+ {
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt32 value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+ }
+
+ void Normalize()
+ {
+ UInt32 subValue = _pos - _cyclicBufferSize;
+ NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
+ NormalizeLinks(_hash, _hashSizeSum, subValue);
+ ReduceOffsets((Int32)subValue);
+ }
+
+ public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LZ/LzInWindow.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LZ/LzInWindow.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LZ/LzInWindow.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,132 @@
+// LzInWindow.cs
+
+using System;
+
+namespace SevenZip.Compression.LZ
+{
+ public class InWindow
+ {
+ public Byte[] _bufferBase = null; // pointer to buffer with data
+ System.IO.Stream _stream;
+ UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
+ bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
+
+ UInt32 _pointerToLastSafePosition;
+
+ public UInt32 _bufferOffset;
+
+ public UInt32 _blockSize; // Size of Allocated memory block
+ public UInt32 _pos; // offset (from _buffer) of curent byte
+ UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
+ UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
+ public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
+
+ public void MoveBlock()
+ {
+ UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore;
+ // we need one additional byte, since MovePos moves on 1 byte.
+ if (offset > 0)
+ offset--;
+
+ UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset;
+
+ // check negative offset ????
+ for (UInt32 i = 0; i < numBytes; i++)
+ _bufferBase[i] = _bufferBase[offset + i];
+ _bufferOffset -= offset;
+ }
+
+ public virtual void ReadBlock()
+ {
+ if (_streamEndWasReached)
+ return;
+ while (true)
+ {
+ int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos);
+ if (size == 0)
+ return;
+ int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size);
+ if (numReadBytes == 0)
+ {
+ _posLimit = _streamPos;
+ UInt32 pointerToPostion = _bufferOffset + _posLimit;
+ if (pointerToPostion > _pointerToLastSafePosition)
+ _posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset);
+
+ _streamEndWasReached = true;
+ return;
+ }
+ _streamPos += (UInt32)numReadBytes;
+ if (_streamPos >= _pos + _keepSizeAfter)
+ _posLimit = _streamPos - _keepSizeAfter;
+ }
+ }
+
+ void Free() { _bufferBase = null; }
+
+ public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
+ {
+ _keepSizeBefore = keepSizeBefore;
+ _keepSizeAfter = keepSizeAfter;
+ UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
+ if (_bufferBase == null || _blockSize != blockSize)
+ {
+ Free();
+ _blockSize = blockSize;
+ _bufferBase = new Byte[_blockSize];
+ }
+ _pointerToLastSafePosition = _blockSize - keepSizeAfter;
+ }
+
+ public void SetStream(System.IO.Stream stream) { _stream = stream; }
+ public void ReleaseStream() { _stream = null; }
+
+ public void Init()
+ {
+ _bufferOffset = 0;
+ _pos = 0;
+ _streamPos = 0;
+ _streamEndWasReached = false;
+ ReadBlock();
+ }
+
+ public void MovePos()
+ {
+ _pos++;
+ if (_pos > _posLimit)
+ {
+ UInt32 pointerToPostion = _bufferOffset + _pos;
+ if (pointerToPostion > _pointerToLastSafePosition)
+ MoveBlock();
+ ReadBlock();
+ }
+ }
+
+ public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; }
+
+ // index + limit have not to exceed _keepSizeAfter;
+ public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
+ {
+ if (_streamEndWasReached)
+ if ((_pos + index) + limit > _streamPos)
+ limit = _streamPos - (UInt32)(_pos + index);
+ distance++;
+ // Byte *pby = _buffer + (size_t)_pos + index;
+ UInt32 pby = _bufferOffset + _pos + (UInt32)index;
+
+ UInt32 i;
+ for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
+ return i;
+ }
+
+ public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; }
+
+ public void ReduceOffsets(Int32 subValue)
+ {
+ _bufferOffset += (UInt32)subValue;
+ _posLimit -= (UInt32)subValue;
+ _pos -= (UInt32)subValue;
+ _streamPos -= (UInt32)subValue;
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LZ/LzOutWindow.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LZ/LzOutWindow.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LZ/LzOutWindow.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,110 @@
+// LzOutWindow.cs
+
+namespace SevenZip.Compression.LZ
+{
+ public class OutWindow
+ {
+ byte[] _buffer = null;
+ uint _pos;
+ uint _windowSize = 0;
+ uint _streamPos;
+ System.IO.Stream _stream;
+
+ public uint TrainSize = 0;
+
+ public void Create(uint windowSize)
+ {
+ if (_windowSize != windowSize)
+ {
+ // System.GC.Collect();
+ _buffer = new byte[windowSize];
+ }
+ _windowSize = windowSize;
+ _pos = 0;
+ _streamPos = 0;
+ }
+
+ public void Init(System.IO.Stream stream, bool solid)
+ {
+ ReleaseStream();
+ _stream = stream;
+ if (!solid)
+ {
+ _streamPos = 0;
+ _pos = 0;
+ TrainSize = 0;
+ }
+ }
+
+ public bool Train(System.IO.Stream stream)
+ {
+ long len = stream.Length;
+ uint size = (len < _windowSize) ? (uint)len : _windowSize;
+ TrainSize = size;
+ stream.Position = len - size;
+ _streamPos = _pos = 0;
+ while (size > 0)
+ {
+ uint curSize = _windowSize - _pos;
+ if (size < curSize)
+ curSize = size;
+ int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize);
+ if (numReadBytes == 0)
+ return false;
+ size -= (uint)numReadBytes;
+ _pos += (uint)numReadBytes;
+ _streamPos += (uint)numReadBytes;
+ if (_pos == _windowSize)
+ _streamPos = _pos = 0;
+ }
+ return true;
+ }
+
+ public void ReleaseStream()
+ {
+ Flush();
+ _stream = null;
+ }
+
+ public void Flush()
+ {
+ uint size = _pos - _streamPos;
+ if (size == 0)
+ return;
+ _stream.Write(_buffer, (int)_streamPos, (int)size);
+ if (_pos >= _windowSize)
+ _pos = 0;
+ _streamPos = _pos;
+ }
+
+ public void CopyBlock(uint distance, uint len)
+ {
+ uint pos = _pos - distance - 1;
+ if (pos >= _windowSize)
+ pos += _windowSize;
+ for (; len > 0; len--)
+ {
+ if (pos >= _windowSize)
+ pos = 0;
+ _buffer[_pos++] = _buffer[pos++];
+ if (_pos >= _windowSize)
+ Flush();
+ }
+ }
+
+ public void PutByte(byte b)
+ {
+ _buffer[_pos++] = b;
+ if (_pos >= _windowSize)
+ Flush();
+ }
+
+ public byte GetByte(uint distance)
+ {
+ uint pos = _pos - distance - 1;
+ if (pos >= _windowSize)
+ pos += _windowSize;
+ return _buffer[pos];
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LZMA/LzmaBase.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LZMA/LzmaBase.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LZMA/LzmaBase.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,76 @@
+// LzmaBase.cs
+
+namespace SevenZip.Compression.LZMA
+{
+ internal abstract class Base
+ {
+ public const uint kNumRepDistances = 4;
+ public const uint kNumStates = 12;
+
+ // static byte []kLiteralNextStates = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+ // static byte []kMatchNextStates = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+ // static byte []kRepNextStates = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+ // static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+ public struct State
+ {
+ public uint Index;
+ public void Init() { Index = 0; }
+ public void UpdateChar()
+ {
+ if (Index < 4) Index = 0;
+ else if (Index < 10) Index -= 3;
+ else Index -= 6;
+ }
+ public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); }
+ public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); }
+ public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); }
+ public bool IsCharState() { return Index < 7; }
+ }
+
+ public const int kNumPosSlotBits = 6;
+ public const int kDicLogSizeMin = 0;
+ // public const int kDicLogSizeMax = 30;
+ // public const uint kDistTableSizeMax = kDicLogSizeMax * 2;
+
+ public const int kNumLenToPosStatesBits = 2; // it's for speed optimization
+ public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
+
+ public const uint kMatchMinLen = 2;
+
+ public static uint GetLenToPosState(uint len)
+ {
+ len -= kMatchMinLen;
+ if (len < kNumLenToPosStates)
+ return len;
+ return (uint)(kNumLenToPosStates - 1);
+ }
+
+ public const int kNumAlignBits = 4;
+ public const uint kAlignTableSize = 1 << kNumAlignBits;
+ public const uint kAlignMask = (kAlignTableSize - 1);
+
+ public const uint kStartPosModelIndex = 4;
+ public const uint kEndPosModelIndex = 14;
+ public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+ public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2);
+
+ public const uint kNumLitPosStatesBitsEncodingMax = 4;
+ public const uint kNumLitContextBitsMax = 8;
+
+ public const int kNumPosStatesBitsMax = 4;
+ public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+ public const int kNumPosStatesBitsEncodingMax = 4;
+ public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+ public const int kNumLowLenBits = 3;
+ public const int kNumMidLenBits = 3;
+ public const int kNumHighLenBits = 8;
+ public const uint kNumLowLenSymbols = 1 << kNumLowLenBits;
+ public const uint kNumMidLenSymbols = 1 << kNumMidLenBits;
+ public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
+ (1 << kNumHighLenBits);
+ public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LZMA/LzmaDecoder.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LZMA/LzmaDecoder.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LZMA/LzmaDecoder.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,398 @@
+// LzmaDecoder.cs
+
+using System;
+
+namespace SevenZip.Compression.LZMA
+{
+ using RangeCoder;
+
+ public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
+ {
+ class LenDecoder
+ {
+ BitDecoder m_Choice = new BitDecoder();
+ BitDecoder m_Choice2 = new BitDecoder();
+ BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
+ BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
+ BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
+ uint m_NumPosStates = 0;
+
+ public void Create(uint numPosStates)
+ {
+ for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
+ {
+ m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
+ m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
+ }
+ m_NumPosStates = numPosStates;
+ }
+
+ public void Init()
+ {
+ m_Choice.Init();
+ for (uint posState = 0; posState < m_NumPosStates; posState++)
+ {
+ m_LowCoder[posState].Init();
+ m_MidCoder[posState].Init();
+ }
+ m_Choice2.Init();
+ m_HighCoder.Init();
+ }
+
+ public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
+ {
+ if (m_Choice.Decode(rangeDecoder) == 0)
+ return m_LowCoder[posState].Decode(rangeDecoder);
+ else
+ {
+ uint symbol = Base.kNumLowLenSymbols;
+ if (m_Choice2.Decode(rangeDecoder) == 0)
+ symbol += m_MidCoder[posState].Decode(rangeDecoder);
+ else
+ {
+ symbol += Base.kNumMidLenSymbols;
+ symbol += m_HighCoder.Decode(rangeDecoder);
+ }
+ return symbol;
+ }
+ }
+ }
+
+ class LiteralDecoder
+ {
+ struct Decoder2
+ {
+ BitDecoder[] m_Decoders;
+ public void Create() { m_Decoders = new BitDecoder[0x300]; }
+ public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
+
+ public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
+ {
+ uint symbol = 1;
+ do
+ symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
+ while (symbol < 0x100);
+ return (byte)symbol;
+ }
+
+ public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
+ {
+ uint symbol = 1;
+ do
+ {
+ uint matchBit = (uint)(matchByte >> 7) & 1;
+ matchByte <<= 1;
+ uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
+ symbol = (symbol << 1) | bit;
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ return (byte)symbol;
+ }
+ }
+
+ Decoder2[] m_Coders;
+ int m_NumPrevBits;
+ int m_NumPosBits;
+ uint m_PosMask;
+
+ public void Create(int numPosBits, int numPrevBits)
+ {
+ if (m_Coders != null && m_NumPrevBits == numPrevBits &&
+ m_NumPosBits == numPosBits)
+ return;
+ m_NumPosBits = numPosBits;
+ m_PosMask = ((uint)1 << numPosBits) - 1;
+ m_NumPrevBits = numPrevBits;
+ uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
+ m_Coders = new Decoder2[numStates];
+ for (uint i = 0; i < numStates; i++)
+ m_Coders[i].Create();
+ }
+
+ public void Init()
+ {
+ uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
+ for (uint i = 0; i < numStates; i++)
+ m_Coders[i].Init();
+ }
+
+ uint GetState(uint pos, byte prevByte)
+ { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
+
+ public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
+ { return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+
+ public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
+ { return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+ };
+
+ LZ.OutWindow m_OutWindow = new LZ.OutWindow();
+ RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
+
+ BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
+ BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
+ BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
+ BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
+ BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
+ BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
+
+ BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
+ BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
+
+ BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
+
+ LenDecoder m_LenDecoder = new LenDecoder();
+ LenDecoder m_RepLenDecoder = new LenDecoder();
+
+ LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
+
+ uint m_DictionarySize;
+ uint m_DictionarySizeCheck;
+
+ uint m_PosStateMask;
+
+ public Decoder()
+ {
+ m_DictionarySize = 0xFFFFFFFF;
+ for (int i = 0; i < Base.kNumLenToPosStates; i++)
+ m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
+ }
+
+ void SetDictionarySize(uint dictionarySize)
+ {
+ if (m_DictionarySize != dictionarySize)
+ {
+ m_DictionarySize = dictionarySize;
+ m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
+ uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
+ m_OutWindow.Create(blockSize);
+ }
+ }
+
+ void SetLiteralProperties(int lp, int lc)
+ {
+ if (lp > 8)
+ throw new InvalidParamException();
+ if (lc > 8)
+ throw new InvalidParamException();
+ m_LiteralDecoder.Create(lp, lc);
+ }
+
+ void SetPosBitsProperties(int pb)
+ {
+ if (pb > Base.kNumPosStatesBitsMax)
+ throw new InvalidParamException();
+ uint numPosStates = (uint)1 << pb;
+ m_LenDecoder.Create(numPosStates);
+ m_RepLenDecoder.Create(numPosStates);
+ m_PosStateMask = numPosStates - 1;
+ }
+
+ bool _solid = false;
+ void Init(System.IO.Stream inStream, System.IO.Stream outStream)
+ {
+ m_RangeDecoder.Init(inStream);
+ m_OutWindow.Init(outStream, _solid);
+
+ uint i;
+ for (i = 0; i < Base.kNumStates; i++)
+ {
+ for (uint j = 0; j <= m_PosStateMask; j++)
+ {
+ uint index = (i << Base.kNumPosStatesBitsMax) + j;
+ m_IsMatchDecoders[index].Init();
+ m_IsRep0LongDecoders[index].Init();
+ }
+ m_IsRepDecoders[i].Init();
+ m_IsRepG0Decoders[i].Init();
+ m_IsRepG1Decoders[i].Init();
+ m_IsRepG2Decoders[i].Init();
+ }
+
+ m_LiteralDecoder.Init();
+ for (i = 0; i < Base.kNumLenToPosStates; i++)
+ m_PosSlotDecoder[i].Init();
+ // m_PosSpecDecoder.Init();
+ for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
+ m_PosDecoders[i].Init();
+
+ m_LenDecoder.Init();
+ m_RepLenDecoder.Init();
+ m_PosAlignDecoder.Init();
+ }
+
+ public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
+ Int64 inSize, Int64 outSize, ICodeProgress progress)
+ {
+ Init(inStream, outStream);
+
+ Base.State state = new Base.State();
+ state.Init();
+ uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
+
+ UInt64 nowPos64 = 0;
+ UInt64 outSize64 = (UInt64)outSize;
+ if (nowPos64 < outSize64)
+ {
+ if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
+ throw new DataErrorException();
+ state.UpdateChar();
+ byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
+ m_OutWindow.PutByte(b);
+ nowPos64++;
+ }
+ while (nowPos64 < outSize64)
+ {
+ // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
+ // while(nowPos64 < next)
+ {
+ uint posState = (uint)nowPos64 & m_PosStateMask;
+ if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
+ {
+ byte b;
+ byte prevByte = m_OutWindow.GetByte(0);
+ if (!state.IsCharState())
+ b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
+ (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));
+ else
+ b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);
+ m_OutWindow.PutByte(b);
+ state.UpdateChar();
+ nowPos64++;
+ }
+ else
+ {
+ uint len;
+ if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
+ {
+ if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
+ {
+ if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
+ {
+ state.UpdateShortRep();
+ m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
+ nowPos64++;
+ continue;
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
+ {
+ distance = rep1;
+ }
+ else
+ {
+ if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
+ state.UpdateRep();
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
+ state.UpdateMatch();
+ uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
+ if (posSlot >= Base.kStartPosModelIndex)
+ {
+ int numDirectBits = (int)((posSlot >> 1) - 1);
+ rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+ if (posSlot < Base.kEndPosModelIndex)
+ rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
+ rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
+ else
+ {
+ rep0 += (m_RangeDecoder.DecodeDirectBits(
+ numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
+ rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
+ }
+ }
+ else
+ rep0 = posSlot;
+ }
+ if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
+ {
+ if (rep0 == 0xFFFFFFFF)
+ break;
+ throw new DataErrorException();
+ }
+ m_OutWindow.CopyBlock(rep0, len);
+ nowPos64 += len;
+ }
+ }
+ }
+ m_OutWindow.Flush();
+ m_OutWindow.ReleaseStream();
+ m_RangeDecoder.ReleaseStream();
+ }
+
+ public void SetDecoderProperties(byte[] properties)
+ {
+ if (properties.Length < 5)
+ throw new InvalidParamException();
+ int lc = properties[0] % 9;
+ int remainder = properties[0] / 9;
+ int lp = remainder % 5;
+ int pb = remainder / 5;
+ if (pb > Base.kNumPosStatesBitsMax)
+ throw new InvalidParamException();
+ UInt32 dictionarySize = 0;
+ for (int i = 0; i < 4; i++)
+ dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
+ SetDictionarySize(dictionarySize);
+ SetLiteralProperties(lp, lc);
+ SetPosBitsProperties(pb);
+ }
+
+ public bool Train(System.IO.Stream stream)
+ {
+ _solid = true;
+ return m_OutWindow.Train(stream);
+ }
+
+ /*
+ public override bool CanRead { get { return true; }}
+ public override bool CanWrite { get { return true; }}
+ public override bool CanSeek { get { return true; }}
+ public override long Length { get { return 0; }}
+ public override long Position
+ {
+ get { return 0; }
+ set { }
+ }
+ public override void Flush() { }
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ return 0;
+ }
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ }
+ public override long Seek(long offset, System.IO.SeekOrigin origin)
+ {
+ return 0;
+ }
+ public override void SetLength(long value) {}
+ */
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LZMA/LzmaEncoder.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LZMA/LzmaEncoder.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LZMA/LzmaEncoder.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1480 @@
+// LzmaEncoder.cs
+
+using System;
+
+namespace SevenZip.Compression.LZMA
+{
+ using RangeCoder;
+
+ public class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
+ {
+ enum EMatchFinderType
+ {
+ BT2,
+ BT4,
+ };
+
+ const UInt32 kIfinityPrice = 0xFFFFFFF;
+
+ static Byte[] g_FastPos = new Byte[1 << 11];
+
+ static Encoder()
+ {
+ const Byte kFastSlots = 22;
+ int c = 2;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+ for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)
+ {
+ UInt32 k = ((UInt32)1 << ((slotFast >> 1) - 1));
+ for (UInt32 j = 0; j < k; j++, c++)
+ g_FastPos[c] = slotFast;
+ }
+ }
+
+ static UInt32 GetPosSlot(UInt32 pos)
+ {
+ if (pos < (1 << 11))
+ return g_FastPos[pos];
+ if (pos < (1 << 21))
+ return (UInt32)(g_FastPos[pos >> 10] + 20);
+ return (UInt32)(g_FastPos[pos >> 20] + 40);
+ }
+
+ static UInt32 GetPosSlot2(UInt32 pos)
+ {
+ if (pos < (1 << 17))
+ return (UInt32)(g_FastPos[pos >> 6] + 12);
+ if (pos < (1 << 27))
+ return (UInt32)(g_FastPos[pos >> 16] + 32);
+ return (UInt32)(g_FastPos[pos >> 26] + 52);
+ }
+
+ Base.State _state = new Base.State();
+ Byte _previousByte;
+ UInt32[] _repDistances = new UInt32[Base.kNumRepDistances];
+
+ void BaseInit()
+ {
+ _state.Init();
+ _previousByte = 0;
+ for (UInt32 i = 0; i < Base.kNumRepDistances; i++)
+ _repDistances[i] = 0;
+ }
+
+ const int kDefaultDictionaryLogSize = 22;
+ const UInt32 kNumFastBytesDefault = 0x20;
+
+ class LiteralEncoder
+ {
+ public struct Encoder2
+ {
+ BitEncoder[] m_Encoders;
+
+ public void Create() { m_Encoders = new BitEncoder[0x300]; }
+
+ public void Init() { for (int i = 0; i < 0x300; i++) m_Encoders[i].Init(); }
+
+ public void Encode(RangeCoder.Encoder rangeEncoder, byte symbol)
+ {
+ uint context = 1;
+ for (int i = 7; i >= 0; i--)
+ {
+ uint bit = (uint)((symbol >> i) & 1);
+ m_Encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ }
+
+ public void EncodeMatched(RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol)
+ {
+ uint context = 1;
+ bool same = true;
+ for (int i = 7; i >= 0; i--)
+ {
+ uint bit = (uint)((symbol >> i) & 1);
+ uint state = context;
+ if (same)
+ {
+ uint matchBit = (uint)((matchByte >> i) & 1);
+ state += ((1 + matchBit) << 8);
+ same = (matchBit == bit);
+ }
+ m_Encoders[state].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ }
+
+ public uint GetPrice(bool matchMode, byte matchByte, byte symbol)
+ {
+ uint price = 0;
+ uint context = 1;
+ int i = 7;
+ if (matchMode)
+ {
+ for (; i >= 0; i--)
+ {
+ uint matchBit = (uint)(matchByte >> i) & 1;
+ uint bit = (uint)(symbol >> i) & 1;
+ price += m_Encoders[((1 + matchBit) << 8) + context].GetPrice(bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ {
+ i--;
+ break;
+ }
+ }
+ }
+ for (; i >= 0; i--)
+ {
+ uint bit = (uint)(symbol >> i) & 1;
+ price += m_Encoders[context].GetPrice(bit);
+ context = (context << 1) | bit;
+ }
+ return price;
+ }
+ }
+
+ Encoder2[] m_Coders;
+ int m_NumPrevBits;
+ int m_NumPosBits;
+ uint m_PosMask;
+
+ public void Create(int numPosBits, int numPrevBits)
+ {
+ if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
+ return;
+ m_NumPosBits = numPosBits;
+ m_PosMask = ((uint)1 << numPosBits) - 1;
+ m_NumPrevBits = numPrevBits;
+ uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
+ m_Coders = new Encoder2[numStates];
+ for (uint i = 0; i < numStates; i++)
+ m_Coders[i].Create();
+ }
+
+ public void Init()
+ {
+ uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
+ for (uint i = 0; i < numStates; i++)
+ m_Coders[i].Init();
+ }
+
+ public Encoder2 GetSubCoder(UInt32 pos, Byte prevByte)
+ { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits))]; }
+ }
+
+ class LenEncoder
+ {
+ RangeCoder.BitEncoder _choice = new RangeCoder.BitEncoder();
+ RangeCoder.BitEncoder _choice2 = new RangeCoder.BitEncoder();
+ RangeCoder.BitTreeEncoder[] _lowCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax];
+ RangeCoder.BitTreeEncoder[] _midCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax];
+ RangeCoder.BitTreeEncoder _highCoder = new RangeCoder.BitTreeEncoder(Base.kNumHighLenBits);
+
+ public LenEncoder()
+ {
+ for (UInt32 posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)
+ {
+ _lowCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumLowLenBits);
+ _midCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumMidLenBits);
+ }
+ }
+
+ public void Init(UInt32 numPosStates)
+ {
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+ }
+
+ public void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)
+ {
+ if (symbol < Base.kNumLowLenSymbols)
+ {
+ _choice.Encode(rangeEncoder, 0);
+ _lowCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ symbol -= Base.kNumLowLenSymbols;
+ _choice.Encode(rangeEncoder, 1);
+ if (symbol < Base.kNumMidLenSymbols)
+ {
+ _choice2.Encode(rangeEncoder, 0);
+ _midCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ _choice2.Encode(rangeEncoder, 1);
+ _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);
+ }
+ }
+ }
+
+ public void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32[] prices, UInt32 st)
+ {
+ UInt32 a0 = _choice.GetPrice0();
+ UInt32 a1 = _choice.GetPrice1();
+ UInt32 b0 = a1 + _choice2.GetPrice0();
+ UInt32 b1 = a1 + _choice2.GetPrice1();
+ UInt32 i = 0;
+ for (i = 0; i < Base.kNumLowLenSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);
+ }
+ for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);
+ }
+ for (; i < numSymbols; i++)
+ prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);
+ }
+ };
+
+ const UInt32 kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;
+
+ class LenPriceTableEncoder : LenEncoder
+ {
+ UInt32[] _prices = new UInt32[Base.kNumLenSymbols << Base.kNumPosStatesBitsEncodingMax];
+ UInt32 _tableSize;
+ UInt32[] _counters = new UInt32[Base.kNumPosStatesEncodingMax];
+
+ public void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
+
+ public UInt32 GetPrice(UInt32 symbol, UInt32 posState)
+ {
+ return _prices[posState * Base.kNumLenSymbols + symbol];
+ }
+
+ void UpdateTable(UInt32 posState)
+ {
+ SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);
+ _counters[posState] = _tableSize;
+ }
+
+ public void UpdateTables(UInt32 numPosStates)
+ {
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ UpdateTable(posState);
+ }
+
+ public new void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)
+ {
+ base.Encode(rangeEncoder, symbol, posState);
+ if (--_counters[posState] == 0)
+ UpdateTable(posState);
+ }
+ }
+
+ const UInt32 kNumOpts = 1 << 12;
+ class Optimal
+ {
+ public Base.State State;
+
+ public bool Prev1IsChar;
+ public bool Prev2;
+
+ public UInt32 PosPrev2;
+ public UInt32 BackPrev2;
+
+ public UInt32 Price;
+ public UInt32 PosPrev;
+ public UInt32 BackPrev;
+
+ public UInt32 Backs0;
+ public UInt32 Backs1;
+ public UInt32 Backs2;
+ public UInt32 Backs3;
+
+ public void MakeAsChar() { BackPrev = 0xFFFFFFFF; Prev1IsChar = false; }
+ public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+ public bool IsShortRep() { return (BackPrev == 0); }
+ };
+ Optimal[] _optimum = new Optimal[kNumOpts];
+ LZ.IMatchFinder _matchFinder = null;
+ RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder();
+
+ RangeCoder.BitEncoder[] _isMatch = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
+ RangeCoder.BitEncoder[] _isRep = new RangeCoder.BitEncoder[Base.kNumStates];
+ RangeCoder.BitEncoder[] _isRepG0 = new RangeCoder.BitEncoder[Base.kNumStates];
+ RangeCoder.BitEncoder[] _isRepG1 = new RangeCoder.BitEncoder[Base.kNumStates];
+ RangeCoder.BitEncoder[] _isRepG2 = new RangeCoder.BitEncoder[Base.kNumStates];
+ RangeCoder.BitEncoder[] _isRep0Long = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
+
+ RangeCoder.BitTreeEncoder[] _posSlotEncoder = new RangeCoder.BitTreeEncoder[Base.kNumLenToPosStates];
+
+ RangeCoder.BitEncoder[] _posEncoders = new RangeCoder.BitEncoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
+ RangeCoder.BitTreeEncoder _posAlignEncoder = new RangeCoder.BitTreeEncoder(Base.kNumAlignBits);
+
+ LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
+ LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();
+
+ LiteralEncoder _literalEncoder = new LiteralEncoder();
+
+ UInt32[] _matchDistances = new UInt32[Base.kMatchMaxLen * 2 + 2];
+
+ UInt32 _numFastBytes = kNumFastBytesDefault;
+ UInt32 _longestMatchLength;
+ UInt32 _numDistancePairs;
+
+ UInt32 _additionalOffset;
+
+ UInt32 _optimumEndIndex;
+ UInt32 _optimumCurrentIndex;
+
+ bool _longestMatchWasFound;
+
+ UInt32[] _posSlotPrices = new UInt32[1 << (Base.kNumPosSlotBits + Base.kNumLenToPosStatesBits)];
+ UInt32[] _distancesPrices = new UInt32[Base.kNumFullDistances << Base.kNumLenToPosStatesBits];
+ UInt32[] _alignPrices = new UInt32[Base.kAlignTableSize];
+ UInt32 _alignPriceCount;
+
+ UInt32 _distTableSize = (kDefaultDictionaryLogSize * 2);
+
+ int _posStateBits = 2;
+ UInt32 _posStateMask = (4 - 1);
+ int _numLiteralPosStateBits = 0;
+ int _numLiteralContextBits = 3;
+
+ UInt32 _dictionarySize = (1 << kDefaultDictionaryLogSize);
+ UInt32 _dictionarySizePrev = 0xFFFFFFFF;
+ UInt32 _numFastBytesPrev = 0xFFFFFFFF;
+
+ Int64 nowPos64;
+ bool _finished;
+ System.IO.Stream _inStream;
+
+ EMatchFinderType _matchFinderType = EMatchFinderType.BT4;
+ bool _writeEndMark = false;
+
+ bool _needReleaseMFStream;
+
+ void Create()
+ {
+ if (_matchFinder == null)
+ {
+ LZ.BinTree bt = new LZ.BinTree();
+ int numHashBytes = 4;
+ if (_matchFinderType == EMatchFinderType.BT2)
+ numHashBytes = 2;
+ bt.SetType(numHashBytes);
+ _matchFinder = bt;
+ }
+ _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);
+
+ if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
+ return;
+ _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);
+ _dictionarySizePrev = _dictionarySize;
+ _numFastBytesPrev = _numFastBytes;
+ }
+
+ public Encoder()
+ {
+ for (int i = 0; i < kNumOpts; i++)
+ _optimum[i] = new Optimal();
+ for (int i = 0; i < Base.kNumLenToPosStates; i++)
+ _posSlotEncoder[i] = new RangeCoder.BitTreeEncoder(Base.kNumPosSlotBits);
+ }
+
+ void SetWriteEndMarkerMode(bool writeEndMarker)
+ {
+ _writeEndMark = writeEndMarker;
+ }
+
+ void Init()
+ {
+ BaseInit();
+ _rangeEncoder.Init();
+
+ uint i;
+ for (i = 0; i < Base.kNumStates; i++)
+ {
+ for (uint j = 0; j <= _posStateMask; j++)
+ {
+ uint complexState = (i << Base.kNumPosStatesBitsMax) + j;
+ _isMatch[complexState].Init();
+ _isRep0Long[complexState].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+ _literalEncoder.Init();
+ for (i = 0; i < Base.kNumLenToPosStates; i++)
+ _posSlotEncoder[i].Init();
+ for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
+ _posEncoders[i].Init();
+
+ _lenEncoder.Init((UInt32)1 << _posStateBits);
+ _repMatchLenEncoder.Init((UInt32)1 << _posStateBits);
+
+ _posAlignEncoder.Init();
+
+ _longestMatchWasFound = false;
+ _optimumEndIndex = 0;
+ _optimumCurrentIndex = 0;
+ _additionalOffset = 0;
+ }
+
+ void ReadMatchDistances(out UInt32 lenRes, out UInt32 numDistancePairs)
+ {
+ lenRes = 0;
+ numDistancePairs = _matchFinder.GetMatches(_matchDistances);
+ if (numDistancePairs > 0)
+ {
+ lenRes = _matchDistances[numDistancePairs - 2];
+ if (lenRes == _numFastBytes)
+ lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[numDistancePairs - 1],
+ Base.kMatchMaxLen - lenRes);
+ }
+ _additionalOffset++;
+ }
+
+
+ void MovePos(UInt32 num)
+ {
+ if (num > 0)
+ {
+ _matchFinder.Skip(num);
+ _additionalOffset += num;
+ }
+ }
+
+ UInt32 GetRepLen1Price(Base.State state, UInt32 posState)
+ {
+ return _isRepG0[state.Index].GetPrice0() +
+ _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0();
+ }
+
+ UInt32 GetPureRepPrice(UInt32 repIndex, Base.State state, UInt32 posState)
+ {
+ UInt32 price;
+ if (repIndex == 0)
+ {
+ price = _isRepG0[state.Index].GetPrice0();
+ price += _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();
+ }
+ else
+ {
+ price = _isRepG0[state.Index].GetPrice1();
+ if (repIndex == 1)
+ price += _isRepG1[state.Index].GetPrice0();
+ else
+ {
+ price += _isRepG1[state.Index].GetPrice1();
+ price += _isRepG2[state.Index].GetPrice(repIndex - 2);
+ }
+ }
+ return price;
+ }
+
+ UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, Base.State state, UInt32 posState)
+ {
+ UInt32 price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
+ return price + GetPureRepPrice(repIndex, state, posState);
+ }
+
+ UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState)
+ {
+ UInt32 price;
+ UInt32 lenToPosState = Base.GetLenToPosState(len);
+ if (pos < Base.kNumFullDistances)
+ price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];
+ else
+ price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] +
+ _alignPrices[pos & Base.kAlignMask];
+ return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
+ }
+
+ UInt32 Backward(out UInt32 backRes, UInt32 cur)
+ {
+ _optimumEndIndex = cur;
+ UInt32 posMem = _optimum[cur].PosPrev;
+ UInt32 backMem = _optimum[cur].BackPrev;
+ do
+ {
+ if (_optimum[cur].Prev1IsChar)
+ {
+ _optimum[posMem].MakeAsChar();
+ _optimum[posMem].PosPrev = posMem - 1;
+ if (_optimum[cur].Prev2)
+ {
+ _optimum[posMem - 1].Prev1IsChar = false;
+ _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+ _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+ }
+ }
+ UInt32 posPrev = posMem;
+ UInt32 backCur = backMem;
+
+ backMem = _optimum[posPrev].BackPrev;
+ posMem = _optimum[posPrev].PosPrev;
+
+ _optimum[posPrev].BackPrev = backCur;
+ _optimum[posPrev].PosPrev = cur;
+ cur = posPrev;
+ }
+ while (cur > 0);
+ backRes = _optimum[0].BackPrev;
+ _optimumCurrentIndex = _optimum[0].PosPrev;
+ return _optimumCurrentIndex;
+ }
+
+ UInt32[] reps = new UInt32[Base.kNumRepDistances];
+ UInt32[] repLens = new UInt32[Base.kNumRepDistances];
+
+
+ UInt32 GetOptimum(UInt32 position, out UInt32 backRes)
+ {
+ if (_optimumEndIndex != _optimumCurrentIndex)
+ {
+ UInt32 lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;
+ backRes = _optimum[_optimumCurrentIndex].BackPrev;
+ _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;
+ return lenRes;
+ }
+ _optimumCurrentIndex = _optimumEndIndex = 0;
+
+ UInt32 lenMain, numDistancePairs;
+ if (!_longestMatchWasFound)
+ {
+ ReadMatchDistances(out lenMain, out numDistancePairs);
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ numDistancePairs = _numDistancePairs;
+ _longestMatchWasFound = false;
+ }
+
+ UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;
+ if (numAvailableBytes < 2)
+ {
+ backRes = 0xFFFFFFFF;
+ return 1;
+ }
+ if (numAvailableBytes > Base.kMatchMaxLen)
+ numAvailableBytes = Base.kMatchMaxLen;
+
+ UInt32 repMaxIndex = 0;
+ UInt32 i;
+ for (i = 0; i < Base.kNumRepDistances; i++)
+ {
+ reps[i] = _repDistances[i];
+ repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);
+ if (repLens[i] > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if (repLens[repMaxIndex] >= _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ UInt32 lenRes = repLens[repMaxIndex];
+ MovePos(lenRes - 1);
+ return lenRes;
+ }
+
+ if (lenMain >= _numFastBytes)
+ {
+ backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+
+ Byte currentByte = _matchFinder.GetIndexByte(0 - 1);
+ Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - 1));
+
+ if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+ {
+ backRes = (UInt32)0xFFFFFFFF;
+ return 1;
+ }
+
+ _optimum[0].State = _state;
+
+ UInt32 posState = (position & _posStateMask);
+
+ _optimum[1].Price = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() +
+ _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!_state.IsCharState(), matchByte, currentByte);
+ _optimum[1].MakeAsChar();
+
+ UInt32 matchPrice = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
+
+ if (matchByte == currentByte)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+ if (shortRepPrice < _optimum[1].Price)
+ {
+ _optimum[1].Price = shortRepPrice;
+ _optimum[1].MakeAsShortRep();
+ }
+ }
+
+ UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+ if(lenEnd < 2)
+ {
+ backRes = _optimum[1].BackPrev;
+ return 1;
+ }
+
+ _optimum[1].PosPrev = 0;
+
+ _optimum[0].Backs0 = reps[0];
+ _optimum[0].Backs1 = reps[1];
+ _optimum[0].Backs2 = reps[2];
+ _optimum[0].Backs3 = reps[3];
+
+ UInt32 len = lenEnd;
+ do
+ _optimum[len--].Price = kIfinityPrice;
+ while (len >= 2);
+
+ for (i = 0; i < Base.kNumRepDistances; i++)
+ {
+ UInt32 repLen = repLens[i];
+ if (repLen < 2)
+ continue;
+ UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
+ Optimal optimum = _optimum[repLen];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = i;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while (--repLen >= 2);
+ }
+
+ UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();
+
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= lenMain)
+ {
+ UInt32 offs = 0;
+ while (len > _matchDistances[offs])
+ offs += 2;
+ for (; ; len++)
+ {
+ UInt32 distance = _matchDistances[offs + 1];
+ UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
+ Optimal optimum = _optimum[len];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = distance + Base.kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+ if (len == _matchDistances[offs])
+ {
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ }
+ }
+ }
+
+ UInt32 cur = 0;
+
+ while (true)
+ {
+ cur++;
+ if (cur == lenEnd)
+ return Backward(out backRes, cur);
+ UInt32 newLen;
+ ReadMatchDistances(out newLen, out numDistancePairs);
+ if (newLen >= _numFastBytes)
+ {
+ _numDistancePairs = numDistancePairs;
+ _longestMatchLength = newLen;
+ _longestMatchWasFound = true;
+ return Backward(out backRes, cur);
+ }
+ position++;
+ UInt32 posPrev = _optimum[cur].PosPrev;
+ Base.State state;
+ if (_optimum[cur].Prev1IsChar)
+ {
+ posPrev--;
+ if (_optimum[cur].Prev2)
+ {
+ state = _optimum[_optimum[cur].PosPrev2].State;
+ if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ else
+ state = _optimum[posPrev].State;
+ state.UpdateChar();
+ }
+ else
+ state = _optimum[posPrev].State;
+ if (posPrev == cur - 1)
+ {
+ if (_optimum[cur].IsShortRep())
+ state.UpdateShortRep();
+ else
+ state.UpdateChar();
+ }
+ else
+ {
+ UInt32 pos;
+ if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)
+ {
+ posPrev = _optimum[cur].PosPrev2;
+ pos = _optimum[cur].BackPrev2;
+ state.UpdateRep();
+ }
+ else
+ {
+ pos = _optimum[cur].BackPrev;
+ if (pos < Base.kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ Optimal opt = _optimum[posPrev];
+ if (pos < Base.kNumRepDistances)
+ {
+ if (pos == 0)
+ {
+ reps[0] = opt.Backs0;
+ reps[1] = opt.Backs1;
+ reps[2] = opt.Backs2;
+ reps[3] = opt.Backs3;
+ }
+ else if (pos == 1)
+ {
+ reps[0] = opt.Backs1;
+ reps[1] = opt.Backs0;
+ reps[2] = opt.Backs2;
+ reps[3] = opt.Backs3;
+ }
+ else if (pos == 2)
+ {
+ reps[0] = opt.Backs2;
+ reps[1] = opt.Backs0;
+ reps[2] = opt.Backs1;
+ reps[3] = opt.Backs3;
+ }
+ else
+ {
+ reps[0] = opt.Backs3;
+ reps[1] = opt.Backs0;
+ reps[2] = opt.Backs1;
+ reps[3] = opt.Backs2;
+ }
+ }
+ else
+ {
+ reps[0] = (pos - Base.kNumRepDistances);
+ reps[1] = opt.Backs0;
+ reps[2] = opt.Backs1;
+ reps[3] = opt.Backs2;
+ }
+ }
+ _optimum[cur].State = state;
+ _optimum[cur].Backs0 = reps[0];
+ _optimum[cur].Backs1 = reps[1];
+ _optimum[cur].Backs2 = reps[2];
+ _optimum[cur].Backs3 = reps[3];
+ UInt32 curPrice = _optimum[cur].Price;
+
+ currentByte = _matchFinder.GetIndexByte(0 - 1);
+ matchByte = _matchFinder.GetIndexByte((Int32)(0 - reps[0] - 1 - 1));
+
+ posState = (position & _posStateMask);
+
+ UInt32 curAnd1Price = curPrice +
+ _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() +
+ _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)).
+ GetPrice(!state.IsCharState(), matchByte, currentByte);
+
+ Optimal nextOptimum = _optimum[cur + 1];
+
+ bool nextIsChar = false;
+ if (curAnd1Price < nextOptimum.Price)
+ {
+ nextOptimum.Price = curAnd1Price;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsChar();
+ nextIsChar = true;
+ }
+
+ matchPrice = curPrice + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();
+ repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
+
+ if (matchByte == currentByte &&
+ !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+ if (shortRepPrice <= nextOptimum.Price)
+ {
+ nextOptimum.Price = shortRepPrice;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsShortRep();
+ nextIsChar = true;
+ }
+ }
+
+ UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;
+ numAvailableBytesFull = Math.Min(kNumOpts - 1 - cur, numAvailableBytesFull);
+ numAvailableBytes = numAvailableBytesFull;
+
+ if (numAvailableBytes < 2)
+ continue;
+ if (numAvailableBytes > _numFastBytes)
+ numAvailableBytes = _numFastBytes;
+ if (!nextIsChar && matchByte != currentByte)
+ {
+ // try Literal + rep0
+ UInt32 t = Math.Min(numAvailableBytesFull - 1, _numFastBytes);
+ UInt32 lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);
+ if (lenTest2 >= 2)
+ {
+ Base.State state2 = state;
+ state2.UpdateChar();
+ UInt32 posStateNext = (position + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAnd1Price +
+ _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+ {
+ UInt32 offset = cur + 1 + lenTest2;
+ while (lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ Optimal optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = false;
+ }
+ }
+ }
+ }
+
+ UInt32 startLen = 2; // speed optimization
+
+ for (UInt32 repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)
+ {
+ UInt32 lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes);
+ if (lenTest < 2)
+ continue;
+ UInt32 lenTestTemp = lenTest;
+ do
+ {
+ while (lenEnd < cur + lenTest)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
+ Optimal optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = repIndex;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while(--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (repIndex == 0)
+ startLen = lenTest + 1;
+
+ // if (_maxMode)
+ if (lenTest < numAvailableBytesFull)
+ {
+ UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
+ UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, reps[repIndex], t);
+ if (lenTest2 >= 2)
+ {
+ Base.State state2 = state;
+ state2.UpdateRep();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice =
+ repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) +
+ _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() +
+ _literalEncoder.GetSubCoder(position + lenTest,
+ _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).GetPrice(true,
+ _matchFinder.GetIndexByte((Int32)((Int32)lenTest - 1 - (Int32)(reps[repIndex] + 1))),
+ _matchFinder.GetIndexByte((Int32)lenTest - 1));
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1();
+ UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = lenTest + 1 + lenTest2;
+ while(lenEnd < cur + offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+ Optimal optimum = _optimum[cur + offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+
+ if (newLen > numAvailableBytes)
+ {
+ newLen = numAvailableBytes;
+ for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ;
+ _matchDistances[numDistancePairs] = newLen;
+ numDistancePairs += 2;
+ }
+ if (newLen >= startLen)
+ {
+ normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();
+ while (lenEnd < cur + newLen)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+
+ UInt32 offs = 0;
+ while (startLen > _matchDistances[offs])
+ offs += 2;
+
+ for (UInt32 lenTest = startLen; ; lenTest++)
+ {
+ UInt32 curBack = _matchDistances[offs + 1];
+ UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
+ Optimal optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = curBack + Base.kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+
+ if (lenTest == _matchDistances[offs])
+ {
+ if (lenTest < numAvailableBytesFull)
+ {
+ UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
+ UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, curBack, t);
+ if (lenTest2 >= 2)
+ {
+ Base.State state2 = state;
+ state2.UpdateMatch();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice = curAndLenPrice +
+ _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() +
+ _literalEncoder.GetSubCoder(position + lenTest,
+ _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).
+ GetPrice(true,
+ _matchFinder.GetIndexByte((Int32)lenTest - (Int32)(curBack + 1) - 1),
+ _matchFinder.GetIndexByte((Int32)lenTest - 1));
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1();
+ UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();
+
+ UInt32 offset = lenTest + 1 + lenTest2;
+ while (lenEnd < cur + offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+ optimum = _optimum[cur + offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = curBack + Base.kNumRepDistances;
+ }
+ }
+ }
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ bool ChangePair(UInt32 smallDist, UInt32 bigDist)
+ {
+ const int kDif = 7;
+ return (smallDist < ((UInt32)(1) << (32 - kDif)) && bigDist >= (smallDist << kDif));
+ }
+
+ void WriteEndMarker(UInt32 posState)
+ {
+ if (!_writeEndMark)
+ return;
+
+ _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 1);
+ _isRep[_state.Index].Encode(_rangeEncoder, 0);
+ _state.UpdateMatch();
+ UInt32 len = Base.kMatchMinLen;
+ _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+ UInt32 posSlot = (1 << Base.kNumPosSlotBits) - 1;
+ UInt32 lenToPosState = Base.GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
+ int footerBits = 30;
+ UInt32 posReduced = (((UInt32)1) << footerBits) - 1;
+ _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
+ }
+
+ void Flush(UInt32 nowPos)
+ {
+ ReleaseMFStream();
+ WriteEndMarker(nowPos & _posStateMask);
+ _rangeEncoder.FlushData();
+ _rangeEncoder.FlushStream();
+ }
+
+ public void CodeOneBlock(out Int64 inSize, out Int64 outSize, out bool finished)
+ {
+ inSize = 0;
+ outSize = 0;
+ finished = true;
+
+ if (_inStream != null)
+ {
+ _matchFinder.SetStream(_inStream);
+ _matchFinder.Init();
+ _needReleaseMFStream = true;
+ _inStream = null;
+ if (_trainSize > 0)
+ _matchFinder.Skip(_trainSize);
+ }
+
+ if (_finished)
+ return;
+ _finished = true;
+
+
+ Int64 progressPosValuePrev = nowPos64;
+ if (nowPos64 == 0)
+ {
+ if (_matchFinder.GetNumAvailableBytes() == 0)
+ {
+ Flush((UInt32)nowPos64);
+ return;
+ }
+ UInt32 len, numDistancePairs; // it's not used
+ ReadMatchDistances(out len, out numDistancePairs);
+ UInt32 posState = (UInt32)(nowPos64) & _posStateMask;
+ _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 0);
+ _state.UpdateChar();
+ Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset));
+ _literalEncoder.GetSubCoder((UInt32)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);
+ _previousByte = curByte;
+ _additionalOffset--;
+ nowPos64++;
+ }
+ if (_matchFinder.GetNumAvailableBytes() == 0)
+ {
+ Flush((UInt32)nowPos64);
+ return;
+ }
+ while (true)
+ {
+ UInt32 pos;
+ UInt32 len = GetOptimum((UInt32)nowPos64, out pos);
+
+ UInt32 posState = ((UInt32)nowPos64) & _posStateMask;
+ UInt32 complexState = (_state.Index << Base.kNumPosStatesBitsMax) + posState;
+ if (len == 1 && pos == 0xFFFFFFFF)
+ {
+ _isMatch[complexState].Encode(_rangeEncoder, 0);
+ Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset));
+ LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((UInt32)nowPos64, _previousByte);
+ if (!_state.IsCharState())
+ {
+ Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - _additionalOffset));
+ subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);
+ }
+ else
+ subCoder.Encode(_rangeEncoder, curByte);
+ _previousByte = curByte;
+ _state.UpdateChar();
+ }
+ else
+ {
+ _isMatch[complexState].Encode(_rangeEncoder, 1);
+ if (pos < Base.kNumRepDistances)
+ {
+ _isRep[_state.Index].Encode(_rangeEncoder, 1);
+ if (pos == 0)
+ {
+ _isRepG0[_state.Index].Encode(_rangeEncoder, 0);
+ if (len == 1)
+ _isRep0Long[complexState].Encode(_rangeEncoder, 0);
+ else
+ _isRep0Long[complexState].Encode(_rangeEncoder, 1);
+ }
+ else
+ {
+ _isRepG0[_state.Index].Encode(_rangeEncoder, 1);
+ if (pos == 1)
+ _isRepG1[_state.Index].Encode(_rangeEncoder, 0);
+ else
+ {
+ _isRepG1[_state.Index].Encode(_rangeEncoder, 1);
+ _isRepG2[_state.Index].Encode(_rangeEncoder, pos - 2);
+ }
+ }
+ if (len == 1)
+ _state.UpdateShortRep();
+ else
+ {
+ _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+ _state.UpdateRep();
+ }
+ UInt32 distance = _repDistances[pos];
+ if (pos != 0)
+ {
+ for (UInt32 i = pos; i >= 1; i--)
+ _repDistances[i] = _repDistances[i - 1];
+ _repDistances[0] = distance;
+ }
+ }
+ else
+ {
+ _isRep[_state.Index].Encode(_rangeEncoder, 0);
+ _state.UpdateMatch();
+ _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+ pos -= Base.kNumRepDistances;
+ UInt32 posSlot = GetPosSlot(pos);
+ UInt32 lenToPosState = Base.GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
+
+ if (posSlot >= Base.kStartPosModelIndex)
+ {
+ int footerBits = (int)((posSlot >> 1) - 1);
+ UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits);
+ UInt32 posReduced = pos - baseVal;
+
+ if (posSlot < Base.kEndPosModelIndex)
+ RangeCoder.BitTreeEncoder.ReverseEncode(_posEncoders,
+ baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);
+ else
+ {
+ _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
+ _alignPriceCount++;
+ }
+ }
+ UInt32 distance = pos;
+ for (UInt32 i = Base.kNumRepDistances - 1; i >= 1; i--)
+ _repDistances[i] = _repDistances[i - 1];
+ _repDistances[0] = distance;
+ _matchPriceCount++;
+ }
+ _previousByte = _matchFinder.GetIndexByte((Int32)(len - 1 - _additionalOffset));
+ }
+ _additionalOffset -= len;
+ nowPos64 += len;
+ if (_additionalOffset == 0)
+ {
+ // if (!_fastMode)
+ if (_matchPriceCount >= (1 << 7))
+ FillDistancesPrices();
+ if (_alignPriceCount >= Base.kAlignTableSize)
+ FillAlignPrices();
+ inSize = nowPos64;
+ outSize = _rangeEncoder.GetProcessedSizeAdd();
+ if (_matchFinder.GetNumAvailableBytes() == 0)
+ {
+ Flush((UInt32)nowPos64);
+ return;
+ }
+
+ if (nowPos64 - progressPosValuePrev >= (1 << 12))
+ {
+ _finished = false;
+ finished = false;
+ return;
+ }
+ }
+ }
+ }
+
+ void ReleaseMFStream()
+ {
+ if (_matchFinder != null && _needReleaseMFStream)
+ {
+ _matchFinder.ReleaseStream();
+ _needReleaseMFStream = false;
+ }
+ }
+
+ void SetOutStream(System.IO.Stream outStream) { _rangeEncoder.SetStream(outStream); }
+ void ReleaseOutStream() { _rangeEncoder.ReleaseStream(); }
+
+ void ReleaseStreams()
+ {
+ ReleaseMFStream();
+ ReleaseOutStream();
+ }
+
+ void SetStreams(System.IO.Stream inStream, System.IO.Stream outStream,
+ Int64 inSize, Int64 outSize)
+ {
+ _inStream = inStream;
+ _finished = false;
+ Create();
+ SetOutStream(outStream);
+ Init();
+
+ // if (!_fastMode)
+ {
+ FillDistancesPrices();
+ FillAlignPrices();
+ }
+
+ _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
+ _lenEncoder.UpdateTables((UInt32)1 << _posStateBits);
+ _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
+ _repMatchLenEncoder.UpdateTables((UInt32)1 << _posStateBits);
+
+ nowPos64 = 0;
+ }
+
+
+ public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
+ Int64 inSize, Int64 outSize, ICodeProgress progress)
+ {
+ _needReleaseMFStream = false;
+ try
+ {
+ SetStreams(inStream, outStream, inSize, outSize);
+ while (true)
+ {
+ Int64 processedInSize;
+ Int64 processedOutSize;
+ bool finished;
+ CodeOneBlock(out processedInSize, out processedOutSize, out finished);
+ if (finished)
+ return;
+ if (progress != null)
+ {
+ progress.SetProgress(processedInSize, processedOutSize);
+ }
+ }
+ }
+ finally
+ {
+ ReleaseStreams();
+ }
+ }
+
+ const int kPropSize = 5;
+ Byte[] properties = new Byte[kPropSize];
+
+ public void WriteCoderProperties(System.IO.Stream outStream)
+ {
+ properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
+ for (int i = 0; i < 4; i++)
+ properties[1 + i] = (Byte)(_dictionarySize >> (8 * i));
+ outStream.Write(properties, 0, kPropSize);
+ }
+
+ UInt32[] tempPrices = new UInt32[Base.kNumFullDistances];
+ UInt32 _matchPriceCount;
+
+ void FillDistancesPrices()
+ {
+ for (UInt32 i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)
+ {
+ UInt32 posSlot = GetPosSlot(i);
+ int footerBits = (int)((posSlot >> 1) - 1);
+ UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits);
+ tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders,
+ baseVal - posSlot - 1, footerBits, i - baseVal);
+ }
+
+ for (UInt32 lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 posSlot;
+ RangeCoder.BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];
+
+ UInt32 st = (lenToPosState << Base.kNumPosSlotBits);
+ for (posSlot = 0; posSlot < _distTableSize; posSlot++)
+ _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);
+ for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
+ _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << RangeCoder.BitEncoder.kNumBitPriceShiftBits);
+
+ UInt32 st2 = lenToPosState * Base.kNumFullDistances;
+ UInt32 i;
+ for (i = 0; i < Base.kStartPosModelIndex; i++)
+ _distancesPrices[st2 + i] = _posSlotPrices[st + i];
+ for (; i < Base.kNumFullDistances; i++)
+ _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];
+ }
+ _matchPriceCount = 0;
+ }
+
+ void FillAlignPrices()
+ {
+ for (UInt32 i = 0; i < Base.kAlignTableSize; i++)
+ _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+ _alignPriceCount = 0;
+ }
+
+
+ static string[] kMatchFinderIDs =
+ {
+ "BT2",
+ "BT4",
+ };
+
+ static int FindMatchFinder(string s)
+ {
+ for (int m = 0; m < kMatchFinderIDs.Length; m++)
+ if (s == kMatchFinderIDs[m])
+ return m;
+ return -1;
+ }
+
+ public void SetCoderProperties(CoderPropID[] propIDs, object[] properties)
+ {
+ for (UInt32 i = 0; i < properties.Length; i++)
+ {
+ object prop = properties[i];
+ switch (propIDs[i])
+ {
+ case CoderPropID.NumFastBytes:
+ {
+ if (!(prop is Int32))
+ throw new InvalidParamException();
+ Int32 numFastBytes = (Int32)prop;
+ if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)
+ throw new InvalidParamException();
+ _numFastBytes = (UInt32)numFastBytes;
+ break;
+ }
+ case CoderPropID.Algorithm:
+ {
+ /*
+ if (!(prop is Int32))
+ throw new InvalidParamException();
+ Int32 maximize = (Int32)prop;
+ _fastMode = (maximize == 0);
+ _maxMode = (maximize >= 2);
+ */
+ break;
+ }
+ case CoderPropID.MatchFinder:
+ {
+ if (!(prop is String))
+ throw new InvalidParamException();
+ EMatchFinderType matchFinderIndexPrev = _matchFinderType;
+ int m = FindMatchFinder(((string)prop).ToUpper());
+ if (m < 0)
+ throw new InvalidParamException();
+ _matchFinderType = (EMatchFinderType)m;
+ if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
+ {
+ _dictionarySizePrev = 0xFFFFFFFF;
+ _matchFinder = null;
+ }
+ break;
+ }
+ case CoderPropID.DictionarySize:
+ {
+ const int kDicLogSizeMaxCompress = 30;
+ if (!(prop is Int32))
+ throw new InvalidParamException(); ;
+ Int32 dictionarySize = (Int32)prop;
+ if (dictionarySize < (UInt32)(1 << Base.kDicLogSizeMin) ||
+ dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress))
+ throw new InvalidParamException();
+ _dictionarySize = (UInt32)dictionarySize;
+ int dicLogSize;
+ for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
+ if (dictionarySize <= ((UInt32)(1) << dicLogSize))
+ break;
+ _distTableSize = (UInt32)dicLogSize * 2;
+ break;
+ }
+ case CoderPropID.PosStateBits:
+ {
+ if (!(prop is Int32))
+ throw new InvalidParamException();
+ Int32 v = (Int32)prop;
+ if (v < 0 || v > (UInt32)Base.kNumPosStatesBitsEncodingMax)
+ throw new InvalidParamException();
+ _posStateBits = (int)v;
+ _posStateMask = (((UInt32)1) << (int)_posStateBits) - 1;
+ break;
+ }
+ case CoderPropID.LitPosBits:
+ {
+ if (!(prop is Int32))
+ throw new InvalidParamException();
+ Int32 v = (Int32)prop;
+ if (v < 0 || v > (UInt32)Base.kNumLitPosStatesBitsEncodingMax)
+ throw new InvalidParamException();
+ _numLiteralPosStateBits = (int)v;
+ break;
+ }
+ case CoderPropID.LitContextBits:
+ {
+ if (!(prop is Int32))
+ throw new InvalidParamException();
+ Int32 v = (Int32)prop;
+ if (v < 0 || v > (UInt32)Base.kNumLitContextBitsMax)
+ throw new InvalidParamException(); ;
+ _numLiteralContextBits = (int)v;
+ break;
+ }
+ case CoderPropID.EndMarker:
+ {
+ if (!(prop is Boolean))
+ throw new InvalidParamException();
+ SetWriteEndMarkerMode((Boolean)prop);
+ break;
+ }
+ default:
+ throw new InvalidParamException();
+ }
+ }
+ }
+
+ uint _trainSize = 0;
+ public void SetTrainSize(uint trainSize)
+ {
+ _trainSize = trainSize;
+ }
+
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,364 @@
+using System;
+using System.IO;
+namespace SevenZip
+{
+ using CommandLineParser;
+
+ public class CDoubleStream: Stream
+ {
+ public System.IO.Stream s1;
+ public System.IO.Stream s2;
+ public int fileIndex;
+ public long skipSize;
+
+ public override bool CanRead { get { return true; }}
+ public override bool CanWrite { get { return false; }}
+ public override bool CanSeek { get { return false; }}
+ public override long Length { get { return s1.Length + s2.Length - skipSize; } }
+ public override long Position
+ {
+ get { return 0; }
+ set { }
+ }
+ public override void Flush() { }
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ int numTotal = 0;
+ while (count > 0)
+ {
+ if (fileIndex == 0)
+ {
+ int num = s1.Read(buffer, offset, count);
+ offset += num;
+ count -= num;
+ numTotal += num;
+ if (num == 0)
+ fileIndex++;
+ }
+ if (fileIndex == 1)
+ {
+ numTotal += s2.Read(buffer, offset, count);
+ return numTotal;
+ }
+ }
+ return numTotal;
+ }
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ throw (new Exception("can't Write"));
+ }
+ public override long Seek(long offset, System.IO.SeekOrigin origin)
+ {
+ throw (new Exception("can't Seek"));
+ }
+ public override void SetLength(long value)
+ {
+ throw (new Exception("can't SetLength"));
+ }
+ }
+
+ class LzmaAlone
+ {
+ enum Key
+ {
+ Help1 = 0,
+ Help2,
+ Mode,
+ Dictionary,
+ FastBytes,
+ LitContext,
+ LitPos,
+ PosBits,
+ MatchFinder,
+ EOS,
+ StdIn,
+ StdOut,
+ Train
+ };
+
+ static void PrintHelp()
+ {
+ System.Console.WriteLine("\nUsage: LZMA <e|d> [<switches>...] inputFile outputFile\n" +
+ " e: encode file\n" +
+ " d: decode file\n" +
+ " b: Benchmark\n" +
+ "<Switches>\n" +
+ // " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" +
+ " -d{N}: set dictionary - [0, 29], default: 23 (8MB)\n" +
+ " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +
+ " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +
+ " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +
+ " -pb{N}: set number of pos bits - [0, 4], default: 2\n" +
+ " -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +
+ " -eos: write End Of Stream marker\n"
+ // + " -si: read data from stdin\n"
+ // + " -so: write data to stdout\n"
+ );
+ }
+
+ static bool GetNumber(string s, out Int32 v)
+ {
+ v = 0;
+ for (int i = 0; i < s.Length; i++)
+ {
+ char c = s[i];
+ if (c < '0' || c > '9')
+ return false;
+ v *= 10;
+ v += (Int32)(c - '0');
+ }
+ return true;
+ }
+
+ static int IncorrectCommand()
+ {
+ throw (new Exception("Command line error"));
+ // System.Console.WriteLine("\nCommand line error\n");
+ // return 1;
+ }
+ static int Main2(string[] args)
+ {
+ System.Console.WriteLine("\nLZMA# 4.49 Copyright (c) 1999-2007 Igor Pavlov 2006-07-05\n");
+
+ if (args.Length == 0)
+ {
+ PrintHelp();
+ return 0;
+ }
+
+ SwitchForm[] kSwitchForms = new SwitchForm[13];
+ int sw = 0;
+ kSwitchForms[sw++] = new SwitchForm("?", SwitchType.Simple, false);
+ kSwitchForms[sw++] = new SwitchForm("H", SwitchType.Simple, false);
+ kSwitchForms[sw++] = new SwitchForm("A", SwitchType.UnLimitedPostString, false, 1);
+ kSwitchForms[sw++] = new SwitchForm("D", SwitchType.UnLimitedPostString, false, 1);
+ kSwitchForms[sw++] = new SwitchForm("FB", SwitchType.UnLimitedPostString, false, 1);
+ kSwitchForms[sw++] = new SwitchForm("LC", SwitchType.UnLimitedPostString, false, 1);
+ kSwitchForms[sw++] = new SwitchForm("LP", SwitchType.UnLimitedPostString, false, 1);
+ kSwitchForms[sw++] = new SwitchForm("PB", SwitchType.UnLimitedPostString, false, 1);
+ kSwitchForms[sw++] = new SwitchForm("MF", SwitchType.UnLimitedPostString, false, 1);
+ kSwitchForms[sw++] = new SwitchForm("EOS", SwitchType.Simple, false);
+ kSwitchForms[sw++] = new SwitchForm("SI", SwitchType.Simple, false);
+ kSwitchForms[sw++] = new SwitchForm("SO", SwitchType.Simple, false);
+ kSwitchForms[sw++] = new SwitchForm("T", SwitchType.UnLimitedPostString, false, 1);
+
+
+ Parser parser = new Parser(sw);
+ try
+ {
+ parser.ParseStrings(kSwitchForms, args);
+ }
+ catch
+ {
+ return IncorrectCommand();
+ }
+
+ if (parser[(int)Key.Help1].ThereIs || parser[(int)Key.Help2].ThereIs)
+ {
+ PrintHelp();
+ return 0;
+ }
+
+ System.Collections.ArrayList nonSwitchStrings = parser.NonSwitchStrings;
+
+ int paramIndex = 0;
+ if (paramIndex >= nonSwitchStrings.Count)
+ return IncorrectCommand();
+ string command = (string)nonSwitchStrings[paramIndex++];
+ command = command.ToLower();
+
+ bool dictionaryIsDefined = false;
+ Int32 dictionary = 1 << 21;
+ if (parser[(int)Key.Dictionary].ThereIs)
+ {
+ Int32 dicLog;
+ if (!GetNumber((string)parser[(int)Key.Dictionary].PostStrings[0], out dicLog))
+ IncorrectCommand();
+ dictionary = (Int32)1 << dicLog;
+ dictionaryIsDefined = true;
+ }
+ string mf = "bt4";
+ if (parser[(int)Key.MatchFinder].ThereIs)
+ mf = (string)parser[(int)Key.MatchFinder].PostStrings[0];
+ mf = mf.ToLower();
+
+ if (command == "b")
+ {
+ const Int32 kNumDefaultItereations = 10;
+ Int32 numIterations = kNumDefaultItereations;
+ if (paramIndex < nonSwitchStrings.Count)
+ if (!GetNumber((string)nonSwitchStrings[paramIndex++], out numIterations))
+ numIterations = kNumDefaultItereations;
+ return LzmaBench.LzmaBenchmark(numIterations, (UInt32)dictionary);
+ }
+
+ string train = "";
+ if (parser[(int)Key.Train].ThereIs)
+ train = (string)parser[(int)Key.Train].PostStrings[0];
+
+ bool encodeMode = false;
+ if (command == "e")
+ encodeMode = true;
+ else if (command == "d")
+ encodeMode = false;
+ else
+ IncorrectCommand();
+
+ bool stdInMode = parser[(int)Key.StdIn].ThereIs;
+ bool stdOutMode = parser[(int)Key.StdOut].ThereIs;
+
+ Stream inStream = null;
+ if (stdInMode)
+ {
+ throw (new Exception("Not implemeted"));
+ }
+ else
+ {
+ if (paramIndex >= nonSwitchStrings.Count)
+ IncorrectCommand();
+ string inputName = (string)nonSwitchStrings[paramIndex++];
+ inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read);
+ }
+
+ FileStream outStream = null;
+ if (stdOutMode)
+ {
+ throw (new Exception("Not implemeted"));
+ }
+ else
+ {
+ if (paramIndex >= nonSwitchStrings.Count)
+ IncorrectCommand();
+ string outputName = (string)nonSwitchStrings[paramIndex++];
+ outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write);
+ }
+
+ FileStream trainStream = null;
+ if (train.Length != 0)
+ trainStream = new FileStream(train, FileMode.Open, FileAccess.Read);
+
+ if (encodeMode)
+ {
+ if (!dictionaryIsDefined)
+ dictionary = 1 << 23;
+
+ Int32 posStateBits = 2;
+ Int32 litContextBits = 3; // for normal files
+ // UInt32 litContextBits = 0; // for 32-bit data
+ Int32 litPosBits = 0;
+ // UInt32 litPosBits = 2; // for 32-bit data
+ Int32 algorithm = 2;
+ Int32 numFastBytes = 128;
+
+ bool eos = parser[(int)Key.EOS].ThereIs || stdInMode;
+
+ if (parser[(int)Key.Mode].ThereIs)
+ if (!GetNumber((string)parser[(int)Key.Mode].PostStrings[0], out algorithm))
+ IncorrectCommand();
+
+ if (parser[(int)Key.FastBytes].ThereIs)
+ if (!GetNumber((string)parser[(int)Key.FastBytes].PostStrings[0], out numFastBytes))
+ IncorrectCommand();
+ if (parser[(int)Key.LitContext].ThereIs)
+ if (!GetNumber((string)parser[(int)Key.LitContext].PostStrings[0], out litContextBits))
+ IncorrectCommand();
+ if (parser[(int)Key.LitPos].ThereIs)
+ if (!GetNumber((string)parser[(int)Key.LitPos].PostStrings[0], out litPosBits))
+ IncorrectCommand();
+ if (parser[(int)Key.PosBits].ThereIs)
+ if (!GetNumber((string)parser[(int)Key.PosBits].PostStrings[0], out posStateBits))
+ IncorrectCommand();
+
+ CoderPropID[] propIDs =
+ {
+ CoderPropID.DictionarySize,
+ CoderPropID.PosStateBits,
+ CoderPropID.LitContextBits,
+ CoderPropID.LitPosBits,
+ CoderPropID.Algorithm,
+ CoderPropID.NumFastBytes,
+ CoderPropID.MatchFinder,
+ CoderPropID.EndMarker
+ };
+ object[] properties =
+ {
+ (Int32)(dictionary),
+ (Int32)(posStateBits),
+ (Int32)(litContextBits),
+ (Int32)(litPosBits),
+ (Int32)(algorithm),
+ (Int32)(numFastBytes),
+ mf,
+ eos
+ };
+
+ Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();
+ encoder.SetCoderProperties(propIDs, properties);
+ encoder.WriteCoderProperties(outStream);
+ Int64 fileSize;
+ if (eos || stdInMode)
+ fileSize = -1;
+ else
+ fileSize = inStream.Length;
+ for (int i = 0; i < 8; i++)
+ outStream.WriteByte((Byte)(fileSize >> (8 * i)));
+ if (trainStream != null)
+ {
+ CDoubleStream doubleStream = new CDoubleStream();
+ doubleStream.s1 = trainStream;
+ doubleStream.s2 = inStream;
+ doubleStream.fileIndex = 0;
+ inStream = doubleStream;
+ long trainFileSize = trainStream.Length;
+ doubleStream.skipSize = 0;
+ if (trainFileSize > dictionary)
+ doubleStream.skipSize = trainFileSize - dictionary;
+ trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin);
+ encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize));
+ }
+ encoder.Code(inStream, outStream, -1, -1, null);
+ }
+ else if (command == "d")
+ {
+ byte[] properties = new byte[5];
+ if (inStream.Read(properties, 0, 5) != 5)
+ throw (new Exception("input .lzma is too short"));
+ Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();
+ decoder.SetDecoderProperties(properties);
+ if (trainStream != null)
+ {
+ if (!decoder.Train(trainStream))
+ throw (new Exception("can't train"));
+ }
+ long outSize = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ int v = inStream.ReadByte();
+ if (v < 0)
+ throw (new Exception("Can't Read 1"));
+ outSize |= ((long)(byte)v) << (8 * i);
+ }
+ long compressedSize = inStream.Length - inStream.Position;
+ decoder.Code(inStream, outStream, compressedSize, outSize, null);
+ }
+ else
+ throw (new Exception("Command Error"));
+ return 0;
+ }
+
+ [STAThread]
+ static int Main(string[] args)
+ {
+ try
+ {
+ return Main2(args);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("{0} Caught exception #1.", e);
+ // throw e;
+ return 1;
+ }
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj
===================================================================
--- trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,90 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>LzmaAlone</RootNamespace>
+ <AssemblyName>Lzma#</AssemblyName>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.\bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugSymbols>false</DebugSymbols>
+ <Optimize>true</Optimize>
+ <OutputPath>.\bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\..\Common\CommandLineParser.cs">
+ <Link>Common\CommandLineParser.cs</Link>
+ </Compile>
+ <Compile Include="..\..\Common\CRC.cs">
+ <Link>Common\CRC.cs</Link>
+ </Compile>
+ <Compile Include="..\..\ICoder.cs">
+ <Link>ICoder.cs</Link>
+ </Compile>
+ <Compile Include="..\LZ\IMatchFinder.cs">
+ <Link>LZ\IMatchFinder.cs</Link>
+ </Compile>
+ <Compile Include="..\LZ\LzBinTree.cs">
+ <Link>LZ\LzBinTree.cs</Link>
+ </Compile>
+ <Compile Include="..\LZ\LzInWindow.cs">
+ <Link>LZ\LzInWindow.cs</Link>
+ </Compile>
+ <Compile Include="..\LZ\LzOutWindow.cs">
+ <Link>LZ\LzOutWindow.cs</Link>
+ </Compile>
+ <Compile Include="..\LZMA\LzmaBase.cs">
+ <Link>LZMA\LzmaBase.cs</Link>
+ </Compile>
+ <Compile Include="..\LZMA\LzmaDecoder.cs">
+ <Link>LZMA\LzmaDecoder.cs</Link>
+ </Compile>
+ <Compile Include="..\LZMA\LzmaEncoder.cs">
+ <Link>LZMA\LzmaEncoder.cs</Link>
+ </Compile>
+ <Compile Include="..\RangeCoder\RangeCoder.cs">
+ <Link>RangeCoder\RangeCoder.cs</Link>
+ </Compile>
+ <Compile Include="..\RangeCoder\RangeCoderBit.cs">
+ <Link>RangeCoder\RangeCoderBit.cs</Link>
+ </Compile>
+ <Compile Include="..\RangeCoder\RangeCoderBitTree.cs">
+ <Link>RangeCoder\RangeCoderBitTree.cs</Link>
+ </Compile>
+ <Compile Include="LzmaAlone.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="LzmaBench.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Properties\Settings.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.cs</LastGenOutput>
+ </None>
+ <AppDesigner Include="Properties\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+</Project>
\ No newline at end of file
Added: trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln
===================================================================
--- trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C# Express 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LzmaAlone", "LzmaAlone.csproj", "{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
Added: trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaBench.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaBench.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LzmaAlone/LzmaBench.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,340 @@
+// LzmaBench.cs
+
+using System;
+using System.IO;
+
+namespace SevenZip
+{
+ /// <summary>
+ /// LZMA Benchmark
+ /// </summary>
+ internal abstract class LzmaBench
+ {
+ const UInt32 kAdditionalSize = (6 << 20);
+ const UInt32 kCompressedAdditionalSize = (1 << 10);
+ const UInt32 kMaxLzmaPropSize = 10;
+
+ class CRandomGenerator
+ {
+ UInt32 A1;
+ UInt32 A2;
+ public CRandomGenerator() { Init(); }
+ public void Init() { A1 = 362436069; A2 = 521288629; }
+ public UInt32 GetRnd()
+ {
+ return
+ ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^
+ ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)));
+ }
+ };
+
+ class CBitRandomGenerator
+ {
+ CRandomGenerator RG = new CRandomGenerator();
+ UInt32 Value;
+ int NumBits;
+ public void Init()
+ {
+ Value = 0;
+ NumBits = 0;
+ }
+ public UInt32 GetRnd(int numBits)
+ {
+ UInt32 result;
+ if (NumBits > numBits)
+ {
+ result = Value & (((UInt32)1 << numBits) - 1);
+ Value >>= numBits;
+ NumBits -= numBits;
+ return result;
+ }
+ numBits -= NumBits;
+ result = (Value << numBits);
+ Value = RG.GetRnd();
+ result |= Value & (((UInt32)1 << numBits) - 1);
+ Value >>= numBits;
+ NumBits = 32 - numBits;
+ return result;
+ }
+ };
+
+ class CBenchRandomGenerator
+ {
+ CBitRandomGenerator RG = new CBitRandomGenerator();
+ UInt32 Pos;
+ UInt32 Rep0;
+
+ public UInt32 BufferSize;
+ public Byte[] Buffer = null;
+
+ public CBenchRandomGenerator() { }
+
+ public void Set(UInt32 bufferSize)
+ {
+ Buffer = new Byte[bufferSize];
+ Pos = 0;
+ BufferSize = bufferSize;
+ }
+ UInt32 GetRndBit() { return RG.GetRnd(1); }
+ UInt32 GetLogRandBits(int numBits)
+ {
+ UInt32 len = RG.GetRnd(numBits);
+ return RG.GetRnd((int)len);
+ }
+ UInt32 GetOffset()
+ {
+ if (GetRndBit() == 0)
+ return GetLogRandBits(4);
+ return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
+ }
+ UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }
+ UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }
+ public void Generate()
+ {
+ RG.Init();
+ Rep0 = 1;
+ while (Pos < BufferSize)
+ {
+ if (GetRndBit() == 0 || Pos < 1)
+ Buffer[Pos++] = (Byte)RG.GetRnd(8);
+ else
+ {
+ UInt32 len;
+ if (RG.GetRnd(3) == 0)
+ len = 1 + GetLen1();
+ else
+ {
+ do
+ Rep0 = GetOffset();
+ while (Rep0 >= Pos);
+ Rep0++;
+ len = 2 + GetLen2();
+ }
+ for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++)
+ Buffer[Pos] = Buffer[Pos - Rep0];
+ }
+ }
+ }
+ };
+
+ class CrcOutStream : System.IO.Stream
+ {
+ public CRC CRC = new CRC();
+ public void Init() { CRC.Init(); }
+ public UInt32 GetDigest() { return CRC.GetDigest(); }
+
+ public override bool CanRead { get { return false; } }
+ public override bool CanSeek { get { return false; } }
+ public override bool CanWrite { get { return true; } }
+ public override Int64 Length { get { return 0; } }
+ public override Int64 Position { get { return 0; } set { } }
+ public override void Flush() { }
+ public override long Seek(long offset, SeekOrigin origin) { return 0; }
+ public override void SetLength(long value) { }
+ public override int Read(byte[] buffer, int offset, int count) { return 0; }
+
+ public override void WriteByte(byte b)
+ {
+ CRC.UpdateByte(b);
+ }
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ CRC.Update(buffer, (uint)offset, (uint)count);
+ }
+ };
+
+ class CProgressInfo : ICodeProgress
+ {
+ public Int64 ApprovedStart;
+ public Int64 InSize;
+ public System.DateTime Time;
+ public void Init() { InSize = 0; }
+ public void SetProgress(Int64 inSize, Int64 outSize)
+ {
+ if (inSize >= ApprovedStart && InSize == 0)
+ {
+ Time = DateTime.UtcNow;
+ InSize = inSize;
+ }
+ }
+ }
+ const int kSubBits = 8;
+
+ static UInt32 GetLogSize(UInt32 size)
+ {
+ for (int i = kSubBits; i < 32; i++)
+ for (UInt32 j = 0; j < (1 << kSubBits); j++)
+ if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
+ return (UInt32)(i << kSubBits) + j;
+ return (32 << kSubBits);
+ }
+
+ static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime)
+ {
+ UInt64 freq = TimeSpan.TicksPerSecond;
+ UInt64 elTime = elapsedTime;
+ while (freq > 1000000)
+ {
+ freq >>= 1;
+ elTime >>= 1;
+ }
+ if (elTime == 0)
+ elTime = 1;
+ return value * freq / elTime;
+ }
+
+ static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 size)
+ {
+ UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits);
+ UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
+ UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
+ return MyMultDiv64(numCommands, elapsedTime);
+ }
+
+ static UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 outSize, UInt64 inSize)
+ {
+ UInt64 numCommands = inSize * 220 + outSize * 20;
+ return MyMultDiv64(numCommands, elapsedTime);
+ }
+
+ static UInt64 GetTotalRating(
+ UInt32 dictionarySize,
+ UInt64 elapsedTimeEn, UInt64 sizeEn,
+ UInt64 elapsedTimeDe,
+ UInt64 inSizeDe, UInt64 outSizeDe)
+ {
+ return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
+ GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
+ }
+
+ static void PrintValue(UInt64 v)
+ {
+ string s = v.ToString();
+ for (int i = 0; i + s.Length < 6; i++)
+ System.Console.Write(" ");
+ System.Console.Write(s);
+ }
+
+ static void PrintRating(UInt64 rating)
+ {
+ PrintValue(rating / 1000000);
+ System.Console.Write(" MIPS");
+ }
+
+ static void PrintResults(
+ UInt32 dictionarySize,
+ UInt64 elapsedTime,
+ UInt64 size,
+ bool decompressMode, UInt64 secondSize)
+ {
+ UInt64 speed = MyMultDiv64(size, elapsedTime);
+ PrintValue(speed / 1024);
+ System.Console.Write(" KB/s ");
+ UInt64 rating;
+ if (decompressMode)
+ rating = GetDecompressRating(elapsedTime, size, secondSize);
+ else
+ rating = GetCompressRating(dictionarySize, elapsedTime, size);
+ PrintRating(rating);
+ }
+
+ static public int LzmaBenchmark(Int32 numIterations, UInt32 dictionarySize)
+ {
+ if (numIterations <= 0)
+ return 0;
+ if (dictionarySize < (1 << 18))
+ {
+ System.Console.WriteLine("\nError: dictionary size for benchmark must be >= 19 (512 KB)");
+ return 1;
+ }
+ System.Console.Write("\n Compressing Decompressing\n\n");
+
+ Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();
+ Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();
+
+
+ CoderPropID[] propIDs =
+ {
+ CoderPropID.DictionarySize,
+ };
+ object[] properties =
+ {
+ (Int32)(dictionarySize),
+ };
+
+ UInt32 kBufferSize = dictionarySize + kAdditionalSize;
+ UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+
+ encoder.SetCoderProperties(propIDs, properties);
+ System.IO.MemoryStream propStream = new System.IO.MemoryStream();
+ encoder.WriteCoderProperties(propStream);
+ byte[] propArray = propStream.ToArray();
+
+ CBenchRandomGenerator rg = new CBenchRandomGenerator();
+
+ rg.Set(kBufferSize);
+ rg.Generate();
+ CRC crc = new CRC();
+ crc.Init();
+ crc.Update(rg.Buffer, 0, rg.BufferSize);
+
+ CProgressInfo progressInfo = new CProgressInfo();
+ progressInfo.ApprovedStart = dictionarySize;
+
+ UInt64 totalBenchSize = 0;
+ UInt64 totalEncodeTime = 0;
+ UInt64 totalDecodeTime = 0;
+ UInt64 totalCompressedSize = 0;
+
+ MemoryStream inStream = new MemoryStream(rg.Buffer, 0, (int)rg.BufferSize);
+ MemoryStream compressedStream = new MemoryStream((int)kCompressedBufferSize);
+ CrcOutStream crcOutStream = new CrcOutStream();
+ for (Int32 i = 0; i < numIterations; i++)
+ {
+ progressInfo.Init();
+ inStream.Seek(0, SeekOrigin.Begin);
+ compressedStream.Seek(0, SeekOrigin.Begin);
+ encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
+ TimeSpan sp2 = DateTime.UtcNow - progressInfo.Time;
+ UInt64 encodeTime = (UInt64)sp2.Ticks;
+
+ long compressedSize = compressedStream.Position;
+ if (progressInfo.InSize == 0)
+ throw (new Exception("Internal ERROR 1282"));
+
+ UInt64 decodeTime = 0;
+ for (int j = 0; j < 2; j++)
+ {
+ compressedStream.Seek(0, SeekOrigin.Begin);
+ crcOutStream.Init();
+
+ decoder.SetDecoderProperties(propArray);
+ UInt64 outSize = kBufferSize;
+ System.DateTime startTime = DateTime.UtcNow;
+ decoder.Code(compressedStream, crcOutStream, 0, (Int64)outSize, null);
+ TimeSpan sp = (DateTime.UtcNow - startTime);
+ decodeTime = (ulong)sp.Ticks;
+ if (crcOutStream.GetDigest() != crc.GetDigest())
+ throw (new Exception("CRC Error"));
+ }
+ UInt64 benchSize = kBufferSize - (UInt64)progressInfo.InSize;
+ PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
+ System.Console.Write(" ");
+ PrintResults(dictionarySize, decodeTime, kBufferSize, true, (ulong)compressedSize);
+ System.Console.WriteLine();
+
+ totalBenchSize += benchSize;
+ totalEncodeTime += encodeTime;
+ totalDecodeTime += decodeTime;
+ totalCompressedSize += (ulong)compressedSize;
+ }
+ System.Console.WriteLine("---------------------------------------------------");
+ PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
+ System.Console.Write(" ");
+ PrintResults(dictionarySize, totalDecodeTime,
+ kBufferSize * (UInt64)numIterations, true, totalCompressedSize);
+ System.Console.WriteLine(" Average");
+ return 0;
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,29 @@
+#region Using directives
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+#endregion
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("LZMA#")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Igor Pavlov")]
+[assembly: AssemblyProduct("LZMA# SDK")]
+[assembly: AssemblyCopyright("Copyright @ Igor Pavlov 1999-2004")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("4.12.*")]
Added: trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,70 @@
+//------------------------------------------------------------------------------
+// <autogenerated>
+// This code was generated by a tool.
+// Runtime Version:2.0.40607.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </autogenerated>
+//------------------------------------------------------------------------------
+
+namespace LzmaAlone.Properties
+{
+ using System;
+ using System.IO;
+ using System.Resources;
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the Strongly Typed Resource Builder
+ // class via a tool like ResGen or Visual Studio.NET.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ class Resources
+ {
+
+ private static System.Resources.ResourceManager _resMgr;
+
+ private static System.Globalization.CultureInfo _resCulture;
+
+ /*FamANDAssem*/
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((_resMgr == null))
+ {
+ System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Resources", typeof(Resources).Assembly);
+ _resMgr = temp;
+ }
+ return _resMgr;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return _resCulture;
+ }
+ set
+ {
+ _resCulture = value;
+ }
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <autogenerated>
+// This code was generated by a tool.
+// Runtime Version:2.0.40607.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </autogenerated>
+//------------------------------------------------------------------------------
+
+namespace LzmaAlone.Properties
+{
+ public partial class Settings : System.Configuration.ApplicationSettingsBase
+ {
+ private static Settings m_Value;
+
+ private static object m_SyncObject = new object();
+
+ public static Settings Value
+ {
+ get
+ {
+ if ((Settings.m_Value == null))
+ {
+ System.Threading.Monitor.Enter(Settings.m_SyncObject);
+ if ((Settings.m_Value == null))
+ {
+ try
+ {
+ Settings.m_Value = new Settings();
+ }
+ finally
+ {
+ System.Threading.Monitor.Exit(Settings.m_SyncObject);
+ }
+ }
+ }
+ return Settings.m_Value;
+ }
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoder.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoder.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoder.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,234 @@
+using System;
+
+namespace SevenZip.Compression.RangeCoder
+{
+ class Encoder
+ {
+ public const uint kTopValue = (1 << 24);
+
+ System.IO.Stream Stream;
+
+ public UInt64 Low;
+ public uint Range;
+ uint _cacheSize;
+ byte _cache;
+
+ long StartPosition;
+
+ public void SetStream(System.IO.Stream stream)
+ {
+ Stream = stream;
+ }
+
+ public void ReleaseStream()
+ {
+ Stream = null;
+ }
+
+ public void Init()
+ {
+ StartPosition = Stream.Position;
+
+ Low = 0;
+ Range = 0xFFFFFFFF;
+ _cacheSize = 1;
+ _cache = 0;
+ }
+
+ public void FlushData()
+ {
+ for (int i = 0; i < 5; i++)
+ ShiftLow();
+ }
+
+ public void FlushStream()
+ {
+ Stream.Flush();
+ }
+
+ public void CloseStream()
+ {
+ Stream.Close();
+ }
+
+ public void Encode(uint start, uint size, uint total)
+ {
+ Low += start * (Range /= total);
+ Range *= size;
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ public void ShiftLow()
+ {
+ if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1)
+ {
+ byte temp = _cache;
+ do
+ {
+ Stream.WriteByte((byte)(temp + (Low >> 32)));
+ temp = 0xFF;
+ }
+ while (--_cacheSize != 0);
+ _cache = (byte)(((uint)Low) >> 24);
+ }
+ _cacheSize++;
+ Low = ((uint)Low) << 8;
+ }
+
+ public void EncodeDirectBits(uint v, int numTotalBits)
+ {
+ for (int i = numTotalBits - 1; i >= 0; i--)
+ {
+ Range >>= 1;
+ if (((v >> i) & 1) == 1)
+ Low += Range;
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+ }
+
+ public void EncodeBit(uint size0, int numTotalBits, uint symbol)
+ {
+ uint newBound = (Range >> numTotalBits) * size0;
+ if (symbol == 0)
+ Range = newBound;
+ else
+ {
+ Low += newBound;
+ Range -= newBound;
+ }
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ public long GetProcessedSizeAdd()
+ {
+ return _cacheSize +
+ Stream.Position - StartPosition + 4;
+ // (long)Stream.GetProcessedSize();
+ }
+ }
+
+ class Decoder
+ {
+ public const uint kTopValue = (1 << 24);
+ public uint Range;
+ public uint Code;
+ // public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);
+ public System.IO.Stream Stream;
+
+ public void Init(System.IO.Stream stream)
+ {
+ // Stream.Init(stream);
+ Stream = stream;
+
+ Code = 0;
+ Range = 0xFFFFFFFF;
+ for (int i = 0; i < 5; i++)
+ Code = (Code << 8) | (byte)Stream.ReadByte();
+ }
+
+ public void ReleaseStream()
+ {
+ // Stream.ReleaseStream();
+ Stream = null;
+ }
+
+ public void CloseStream()
+ {
+ Stream.Close();
+ }
+
+ public void Normalize()
+ {
+ while (Range < kTopValue)
+ {
+ Code = (Code << 8) | (byte)Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ public void Normalize2()
+ {
+ if (Range < kTopValue)
+ {
+ Code = (Code << 8) | (byte)Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ public uint GetThreshold(uint total)
+ {
+ return Code / (Range /= total);
+ }
+
+ public void Decode(uint start, uint size, uint total)
+ {
+ Code -= start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ public uint DecodeDirectBits(int numTotalBits)
+ {
+ uint range = Range;
+ uint code = Code;
+ uint result = 0;
+ for (int i = numTotalBits; i > 0; i--)
+ {
+ range >>= 1;
+ /*
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ */
+ uint t = (code - range) >> 31;
+ code -= range & (t - 1);
+ result = (result << 1) | (1 - t);
+
+ if (range < kTopValue)
+ {
+ code = (code << 8) | (byte)Stream.ReadByte();
+ range <<= 8;
+ }
+ }
+ Range = range;
+ Code = code;
+ return result;
+ }
+
+ public uint DecodeBit(uint size0, int numTotalBits)
+ {
+ uint newBound = (Range >> numTotalBits) * size0;
+ uint symbol;
+ if (Code < newBound)
+ {
+ symbol = 0;
+ Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ Code -= newBound;
+ Range -= newBound;
+ }
+ Normalize();
+ return symbol;
+ }
+
+ // ulong GetProcessedSize() {return Stream.GetProcessedSize(); }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,117 @@
+using System;
+
+namespace SevenZip.Compression.RangeCoder
+{
+ struct BitEncoder
+ {
+ public const int kNumBitModelTotalBits = 11;
+ public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
+ const int kNumMoveBits = 5;
+ const int kNumMoveReducingBits = 2;
+ public const int kNumBitPriceShiftBits = 6;
+
+ uint Prob;
+
+ public void Init() { Prob = kBitModelTotal >> 1; }
+
+ public void UpdateModel(uint symbol)
+ {
+ if (symbol == 0)
+ Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
+ else
+ Prob -= (Prob) >> kNumMoveBits;
+ }
+
+ public void Encode(Encoder encoder, uint symbol)
+ {
+ // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);
+ // UpdateModel(symbol);
+ uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob;
+ if (symbol == 0)
+ {
+ encoder.Range = newBound;
+ Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
+ }
+ else
+ {
+ encoder.Low += newBound;
+ encoder.Range -= newBound;
+ Prob -= (Prob) >> kNumMoveBits;
+ }
+ if (encoder.Range < Encoder.kTopValue)
+ {
+ encoder.Range <<= 8;
+ encoder.ShiftLow();
+ }
+ }
+
+ private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits];
+
+ static BitEncoder()
+ {
+ const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+ for (int i = kNumBits - 1; i >= 0; i--)
+ {
+ UInt32 start = (UInt32)1 << (kNumBits - i - 1);
+ UInt32 end = (UInt32)1 << (kNumBits - i);
+ for (UInt32 j = start; j < end; j++)
+ ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) +
+ (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+ }
+ }
+
+ public uint GetPrice(uint symbol)
+ {
+ return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+ public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; }
+ public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; }
+ }
+
+ struct BitDecoder
+ {
+ public const int kNumBitModelTotalBits = 11;
+ public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
+ const int kNumMoveBits = 5;
+
+ uint Prob;
+
+ public void UpdateModel(int numMoveBits, uint symbol)
+ {
+ if (symbol == 0)
+ Prob += (kBitModelTotal - Prob) >> numMoveBits;
+ else
+ Prob -= (Prob) >> numMoveBits;
+ }
+
+ public void Init() { Prob = kBitModelTotal >> 1; }
+
+ public uint Decode(RangeCoder.Decoder rangeDecoder)
+ {
+ uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob;
+ if (rangeDecoder.Code < newBound)
+ {
+ rangeDecoder.Range = newBound;
+ Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
+ if (rangeDecoder.Range < Decoder.kTopValue)
+ {
+ rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
+ rangeDecoder.Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ rangeDecoder.Range -= newBound;
+ rangeDecoder.Code -= newBound;
+ Prob -= (Prob) >> kNumMoveBits;
+ if (rangeDecoder.Range < Decoder.kTopValue)
+ {
+ rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
+ rangeDecoder.Range <<= 8;
+ }
+ return 1;
+ }
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
===================================================================
--- trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs (rev 0)
+++ trunk/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,157 @@
+using System;
+
+namespace SevenZip.Compression.RangeCoder
+{
+ struct BitTreeEncoder
+ {
+ BitEncoder[] Models;
+ int NumBitLevels;
+
+ public BitTreeEncoder(int numBitLevels)
+ {
+ NumBitLevels = numBitLevels;
+ Models = new BitEncoder[1 << numBitLevels];
+ }
+
+ public void Init()
+ {
+ for (uint i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+
+ public void Encode(Encoder rangeEncoder, UInt32 symbol)
+ {
+ UInt32 m = 1;
+ for (int bitIndex = NumBitLevels; bitIndex > 0; )
+ {
+ bitIndex--;
+ UInt32 bit = (symbol >> bitIndex) & 1;
+ Models[m].Encode(rangeEncoder, bit);
+ m = (m << 1) | bit;
+ }
+ }
+
+ public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
+ {
+ UInt32 m = 1;
+ for (UInt32 i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[m].Encode(rangeEncoder, bit);
+ m = (m << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+
+ public UInt32 GetPrice(UInt32 symbol)
+ {
+ UInt32 price = 0;
+ UInt32 m = 1;
+ for (int bitIndex = NumBitLevels; bitIndex > 0; )
+ {
+ bitIndex--;
+ UInt32 bit = (symbol >> bitIndex) & 1;
+ price += Models[m].GetPrice(bit);
+ m = (m << 1) + bit;
+ }
+ return price;
+ }
+
+ public UInt32 ReverseGetPrice(UInt32 symbol)
+ {
+ UInt32 price = 0;
+ UInt32 m = 1;
+ for (int i = NumBitLevels; i > 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[m].GetPrice(bit);
+ m = (m << 1) | bit;
+ }
+ return price;
+ }
+
+ public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex,
+ int NumBitLevels, UInt32 symbol)
+ {
+ UInt32 price = 0;
+ UInt32 m = 1;
+ for (int i = NumBitLevels; i > 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[startIndex + m].GetPrice(bit);
+ m = (m << 1) | bit;
+ }
+ return price;
+ }
+
+ public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex,
+ Encoder rangeEncoder, int NumBitLevels, UInt32 symbol)
+ {
+ UInt32 m = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[startIndex + m].Encode(rangeEncoder, bit);
+ m = (m << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+ }
+
+ struct BitTreeDecoder
+ {
+ BitDecoder[] Models;
+ int NumBitLevels;
+
+ public BitTreeDecoder(int numBitLevels)
+ {
+ NumBitLevels = numBitLevels;
+ Models = new BitDecoder[1 << numBitLevels];
+ }
+
+ public void Init()
+ {
+ for (uint i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+
+ public uint Decode(RangeCoder.Decoder rangeDecoder)
+ {
+ uint m = 1;
+ for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
+ m = (m << 1) + Models[m].Decode(rangeDecoder);
+ return m - ((uint)1 << NumBitLevels);
+ }
+
+ public uint ReverseDecode(RangeCoder.Decoder rangeDecoder)
+ {
+ uint m = 1;
+ uint symbol = 0;
+ for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ uint bit = Models[m].Decode(rangeDecoder);
+ m <<= 1;
+ m += bit;
+ symbol |= (bit << bitIndex);
+ }
+ return symbol;
+ }
+
+ public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,
+ RangeCoder.Decoder rangeDecoder, int NumBitLevels)
+ {
+ uint m = 1;
+ uint symbol = 0;
+ for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ uint bit = Models[startIndex + m].Decode(rangeDecoder);
+ m <<= 1;
+ m += bit;
+ symbol |= (bit << bitIndex);
+ }
+ return symbol;
+ }
+ }
+}
Added: trunk/lzma/CS/7zip/ICoder.cs
===================================================================
--- trunk/lzma/CS/7zip/ICoder.cs (rev 0)
+++ trunk/lzma/CS/7zip/ICoder.cs 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,145 @@
+// ICoder.h
+
+using System;
+
+namespace SevenZip
+{
+ /// <summary>
+ /// The exception that is thrown when an error in input stream occurs during decoding.
+ /// </summary>
+ class DataErrorException : ApplicationException
+ {
+ public DataErrorException(): base("Data Error") { }
+ }
+
+ /// <summary>
+ /// The exception that is thrown when the value of an argument is outside the allowable range.
+ /// </summary>
+ class InvalidParamException : ApplicationException
+ {
+ public InvalidParamException(): base("Invalid Parameter") { }
+ }
+
+ public interface ICodeProgress
+ {
+ /// <summary>
+ /// Callback progress.
+ /// </summary>
+ /// <param name="inSize">
+ /// input size. -1 if unknown.
+ /// </param>
+ /// <param name="outSize">
+ /// output size. -1 if unknown.
+ /// </param>
+ void SetProgress(Int64 inSize, Int64 outSize);
+ };
+
+ public interface ICoder
+ {
+ /// <summary>
+ /// Codes streams.
+ /// </summary>
+ /// <param name="inStream">
+ /// input Stream.
+ /// </param>
+ /// <param name="outStream">
+ /// output Stream.
+ /// </param>
+ /// <param name="inSize">
+ /// input Size. -1 if unknown.
+ /// </param>
+ /// <param name="outSize">
+ /// output Size. -1 if unknown.
+ /// </param>
+ /// <param name="progress">
+ /// callback progress reference.
+ /// </param>
+ /// <exception cref="SevenZip.DataErrorException">
+ /// if input stream is not valid
+ /// </exception>
+ void Code(System.IO.Stream inStream, System.IO.Stream outStream,
+ Int64 inSize, Int64 outSize, ICodeProgress progress);
+ };
+
+ /*
+ public interface ICoder2
+ {
+ void Code(ISequentialInStream []inStreams,
+ const UInt64 []inSizes,
+ ISequentialOutStream []outStreams,
+ UInt64 []outSizes,
+ ICodeProgress progress);
+ };
+ */
+
+ /// <summary>
+ /// Provides the fields that represent properties idenitifiers for compressing.
+ /// </summary>
+ public enum CoderPropID
+ {
+ /// <summary>
+ /// Specifies size of dictionary.
+ /// </summary>
+ DictionarySize = 0x400,
+ /// <summary>
+ /// Specifies size of memory for PPM*.
+ /// </summary>
+ UsedMemorySize,
+ /// <summary>
+ /// Specifies order for PPM methods.
+ /// </summary>
+ Order,
+ /// <summary>
+ /// Specifies number of postion state bits for LZMA (0 <= x <= 4).
+ /// </summary>
+ PosStateBits = 0x440,
+ /// <summary>
+ /// Specifies number of literal context bits for LZMA (0 <= x <= 8).
+ /// </summary>
+ LitContextBits,
+ /// <summary>
+ /// Specifies number of literal position bits for LZMA (0 <= x <= 4).
+ /// </summary>
+ LitPosBits,
+ /// <summary>
+ /// Specifies number of fast bytes for LZ*.
+ /// </summary>
+ NumFastBytes = 0x450,
+ /// <summary>
+ /// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".
+ /// </summary>
+ MatchFinder,
+ /// <summary>
+ /// Specifies number of passes.
+ /// </summary>
+ NumPasses = 0x460,
+ /// <summary>
+ /// Specifies number of algorithm.
+ /// </summary>
+ Algorithm = 0x470,
+ /// <summary>
+ /// Specifies multithread mode.
+ /// </summary>
+ MultiThread = 0x480,
+ /// <summary>
+ /// Specifies mode with end marker.
+ /// </summary>
+ EndMarker = 0x490
+ };
+
+
+ public interface ISetCoderProperties
+ {
+ void SetCoderProperties(CoderPropID[] propIDs, object[] properties);
+ };
+
+ public interface IWriteCoderProperties
+ {
+ void WriteCoderProperties(System.IO.Stream outStream);
+ }
+
+ public interface ISetDecoderProperties
+ {
+ void SetDecoderProperties(byte[] properties);
+ }
+}
Added: trunk/lzma/Java/SevenZip/CRC.java
===================================================================
--- trunk/lzma/Java/SevenZip/CRC.java (rev 0)
+++ trunk/lzma/Java/SevenZip/CRC.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,52 @@
+// SevenZip/CRC.java
+
+package SevenZip;
+
+public class CRC
+{
+ static public int[] Table = new int[256];
+
+ static
+ {
+ for (int i = 0; i < 256; i++)
+ {
+ int r = i;
+ for (int j = 0; j < 8; j++)
+ if ((r & 1) != 0)
+ r = (r >>> 1) ^ 0xEDB88320;
+ else
+ r >>>= 1;
+ Table[i] = r;
+ }
+ }
+
+ int _value = -1;
+
+ public void Init()
+ {
+ _value = -1;
+ }
+
+ public void Update(byte[] data, int offset, int size)
+ {
+ for (int i = 0; i < size; i++)
+ _value = Table[(_value ^ data[offset + i]) & 0xFF] ^ (_value >>> 8);
+ }
+
+ public void Update(byte[] data)
+ {
+ int size = data.length;
+ for (int i = 0; i < size; i++)
+ _value = Table[(_value ^ data[i]) & 0xFF] ^ (_value >>> 8);
+ }
+
+ public void UpdateByte(int b)
+ {
+ _value = Table[(_value ^ b) & 0xFF] ^ (_value >>> 8);
+ }
+
+ public int GetDigest()
+ {
+ return _value ^ (-1);
+ }
+}
Added: trunk/lzma/Java/SevenZip/Compression/LZ/BinTree.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/LZ/BinTree.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/LZ/BinTree.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,382 @@
+// LZ.BinTree
+
+package SevenZip.Compression.LZ;
+import java.io.IOException;
+
+
+public class BinTree extends InWindow
+{
+ int _cyclicBufferPos;
+ int _cyclicBufferSize = 0;
+ int _matchMaxLen;
+
+ int[] _son;
+ int[] _hash;
+
+ int _cutValue = 0xFF;
+ int _hashMask;
+ int _hashSizeSum = 0;
+
+ boolean HASH_ARRAY = true;
+
+ static final int kHash2Size = 1 << 10;
+ static final int kHash3Size = 1 << 16;
+ static final int kBT2HashSize = 1 << 16;
+ static final int kStartMaxLen = 1;
+ static final int kHash3Offset = kHash2Size;
+ static final int kEmptyHashValue = 0;
+ static final int kMaxValForNormalize = (1 << 30) - 1;
+
+ int kNumHashDirectBytes = 0;
+ int kMinMatchCheck = 4;
+ int kFixHashSize = kHash2Size + kHash3Size;
+
+ public void SetType(int numHashBytes)
+ {
+ HASH_ARRAY = (numHashBytes > 2);
+ if (HASH_ARRAY)
+ {
+ kNumHashDirectBytes = 0;
+ kMinMatchCheck = 4;
+ kFixHashSize = kHash2Size + kHash3Size;
+ }
+ else
+ {
+ kNumHashDirectBytes = 2;
+ kMinMatchCheck = 2 + 1;
+ kFixHashSize = 0;
+ }
+ }
+
+
+
+
+ public void Init() throws IOException
+ {
+ super.Init();
+ for (int i = 0; i < _hashSizeSum; i++)
+ _hash[i] = kEmptyHashValue;
+ _cyclicBufferPos = 0;
+ ReduceOffsets(-1);
+ }
+
+ public void MovePos() throws IOException
+ {
+ if (++_cyclicBufferPos >= _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ super.MovePos();
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ }
+
+
+
+
+
+
+
+
+ public boolean Create(int historySize, int keepAddBufferBefore,
+ int matchMaxLen, int keepAddBufferAfter)
+ {
+ if (historySize > kMaxValForNormalize - 256)
+ return false;
+ _cutValue = 16 + (matchMaxLen >> 1);
+
+ int windowReservSize = (historySize + keepAddBufferBefore +
+ matchMaxLen + keepAddBufferAfter) / 2 + 256;
+
+ super.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
+
+ _matchMaxLen = matchMaxLen;
+
+ int cyclicBufferSize = historySize + 1;
+ if (_cyclicBufferSize != cyclicBufferSize)
+ _son = new int[(_cyclicBufferSize = cyclicBufferSize) * 2];
+
+ int hs = kBT2HashSize;
+
+ if (HASH_ARRAY)
+ {
+ hs = historySize - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ hs |= 0xFFFF;
+ if (hs > (1 << 24))
+ hs >>= 1;
+ _hashMask = hs;
+ hs++;
+ hs += kFixHashSize;
+ }
+ if (hs != _hashSizeSum)
+ _hash = new int [_hashSizeSum = hs];
+ return true;
+ }
+ public int GetMatches(int[] distances) throws IOException
+ {
+ int lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if (lenLimit < kMinMatchCheck)
+ {
+ MovePos();
+ return 0;
+ }
+ }
+
+ int offset = 0;
+ int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ int cur = _bufferOffset + _pos;
+ int maxLen = kStartMaxLen; // to avoid items for len < hashSize;
+ int hashValue, hash2Value = 0, hash3Value = 0;
+
+ if (HASH_ARRAY)
+ {
+ int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);
+ hash2Value = temp & (kHash2Size - 1);
+ temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);
+ hash3Value = temp & (kHash3Size - 1);
+ hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;
+ }
+ else
+ hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));
+
+ int curMatch = _hash[kFixHashSize + hashValue];
+ if (HASH_ARRAY)
+ {
+ int curMatch2 = _hash[hash2Value];
+ int curMatch3 = _hash[kHash3Offset + hash3Value];
+ _hash[hash2Value] = _pos;
+ _hash[kHash3Offset + hash3Value] = _pos;
+ if (curMatch2 > matchMinPos)
+ if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
+ {
+ distances[offset++] = maxLen = 2;
+ distances[offset++] = _pos - curMatch2 - 1;
+ }
+ if (curMatch3 > matchMinPos)
+ if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
+ {
+ if (curMatch3 == curMatch2)
+ offset -= 2;
+ distances[offset++] = maxLen = 3;
+ distances[offset++] = _pos - curMatch3 - 1;
+ curMatch2 = curMatch3;
+ }
+ if (offset != 0 && curMatch2 == curMatch)
+ {
+ offset -= 2;
+ maxLen = kStartMaxLen;
+ }
+ }
+
+ _hash[kFixHashSize + hashValue] = _pos;
+
+ int ptr0 = (_cyclicBufferPos << 1) + 1;
+ int ptr1 = (_cyclicBufferPos << 1);
+
+ int len0, len1;
+ len0 = len1 = kNumHashDirectBytes;
+
+ if (kNumHashDirectBytes != 0)
+ {
+ if (curMatch > matchMinPos)
+ {
+ if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
+ _bufferBase[cur + kNumHashDirectBytes])
+ {
+ distances[offset++] = maxLen = kNumHashDirectBytes;
+ distances[offset++] = _pos - curMatch - 1;
+ }
+ }
+ }
+
+ int count = _cutValue;
+
+ while (true)
+ {
+ if (curMatch <= matchMinPos || count-- == 0)
+ {
+ _son[ptr0] = _son[ptr1] = kEmptyHashValue;
+ break;
+ }
+ int delta = _pos - curMatch;
+ int cyclicPos = ((delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta) :
+ (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
+
+ int pby1 = _bufferOffset + curMatch;
+ int len = Math.min(len0, len1);
+ if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
+ {
+ while(++len != lenLimit)
+ if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
+ break;
+ if (maxLen < len)
+ {
+ distances[offset++] = maxLen = len;
+ distances[offset++] = delta - 1;
+ if (len == lenLimit)
+ {
+ _son[ptr1] = _son[cyclicPos];
+ _son[ptr0] = _son[cyclicPos + 1];
+ break;
+ }
+ }
+ }
+ if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))
+ {
+ _son[ptr1] = curMatch;
+ ptr1 = cyclicPos + 1;
+ curMatch = _son[ptr1];
+ len1 = len;
+ }
+ else
+ {
+ _son[ptr0] = curMatch;
+ ptr0 = cyclicPos;
+ curMatch = _son[ptr0];
+ len0 = len;
+ }
+ }
+ MovePos();
+ return offset;
+ }
+
+ public void Skip(int num) throws IOException
+ {
+ do
+ {
+ int lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if (lenLimit < kMinMatchCheck)
+ {
+ MovePos();
+ continue;
+ }
+ }
+
+ int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ int cur = _bufferOffset + _pos;
+
+ int hashValue;
+
+ if (HASH_ARRAY)
+ {
+ int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);
+ int hash2Value = temp & (kHash2Size - 1);
+ _hash[hash2Value] = _pos;
+ temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);
+ int hash3Value = temp & (kHash3Size - 1);
+ _hash[kHash3Offset + hash3Value] = _pos;
+ hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;
+ }
+ else
+ hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));
+
+ int curMatch = _hash[kFixHashSize + hashValue];
+ _hash[kFixHashSize + hashValue] = _pos;
+
+ int ptr0 = (_cyclicBufferPos << 1) + 1;
+ int ptr1 = (_cyclicBufferPos << 1);
+
+ int len0, len1;
+ len0 = len1 = kNumHashDirectBytes;
+
+ int count = _cutValue;
+ while (true)
+ {
+ if (curMatch <= matchMinPos || count-- == 0)
+ {
+ _son[ptr0] = _son[ptr1] = kEmptyHashValue;
+ break;
+ }
+
+ int delta = _pos - curMatch;
+ int cyclicPos = ((delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta) :
+ (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
+
+ int pby1 = _bufferOffset + curMatch;
+ int len = Math.min(len0, len1);
+ if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
+ {
+ while (++len != lenLimit)
+ if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
+ break;
+ if (len == lenLimit)
+ {
+ _son[ptr1] = _son[cyclicPos];
+ _son[ptr0] = _son[cyclicPos + 1];
+ break;
+ }
+ }
+ if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))
+ {
+ _son[ptr1] = curMatch;
+ ptr1 = cyclicPos + 1;
+ curMatch = _son[ptr1];
+ len1 = len;
+ }
+ else
+ {
+ _son[ptr0] = curMatch;
+ ptr0 = cyclicPos;
+ curMatch = _son[ptr0];
+ len0 = len;
+ }
+ }
+ MovePos();
+ }
+ while (--num != 0);
+ }
+
+ void NormalizeLinks(int[] items, int numItems, int subValue)
+ {
+ for (int i = 0; i < numItems; i++)
+ {
+ int value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+ }
+
+ void Normalize()
+ {
+ int subValue = _pos - _cyclicBufferSize;
+ NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
+ NormalizeLinks(_hash, _hashSizeSum, subValue);
+ ReduceOffsets(subValue);
+ }
+
+ public void SetCutValue(int cutValue) { _cutValue = cutValue; }
+
+ private static final int[] CrcTable = new int[256];
+
+ static
+ {
+ for (int i = 0; i < 256; i++)
+ {
+ int r = i;
+ for (int j = 0; j < 8; j++)
+ if ((r & 1) != 0)
+ r = (r >>> 1) ^ 0xEDB88320;
+ else
+ r >>>= 1;
+ CrcTable[i] = r;
+ }
+ }
+}
Added: trunk/lzma/Java/SevenZip/Compression/LZ/InWindow.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/LZ/InWindow.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/LZ/InWindow.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,131 @@
+// LZ.InWindow
+
+package SevenZip.Compression.LZ;
+
+import java.io.IOException;
+
+public class InWindow
+{
+ public byte[] _bufferBase; // pointer to buffer with data
+ java.io.InputStream _stream;
+ int _posLimit; // offset (from _buffer) of first byte when new block reading must be done
+ boolean _streamEndWasReached; // if (true) then _streamPos shows real end of stream
+
+ int _pointerToLastSafePosition;
+
+ public int _bufferOffset;
+
+ public int _blockSize; // Size of Allocated memory block
+ public int _pos; // offset (from _buffer) of curent byte
+ int _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
+ int _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
+ public int _streamPos; // offset (from _buffer) of first not read byte from Stream
+
+ public void MoveBlock()
+ {
+ int offset = _bufferOffset + _pos - _keepSizeBefore;
+ // we need one additional byte, since MovePos moves on 1 byte.
+ if (offset > 0)
+ offset--;
+
+ int numBytes = _bufferOffset + _streamPos - offset;
+
+ // check negative offset ????
+ for (int i = 0; i < numBytes; i++)
+ _bufferBase[i] = _bufferBase[offset + i];
+ _bufferOffset -= offset;
+ }
+
+ public void ReadBlock() throws IOException
+ {
+ if (_streamEndWasReached)
+ return;
+ while (true)
+ {
+ int size = (0 - _bufferOffset) + _blockSize - _streamPos;
+ if (size == 0)
+ return;
+ int numReadBytes = _stream.read(_bufferBase, _bufferOffset + _streamPos, size);
+ if (numReadBytes == -1)
+ {
+ _posLimit = _streamPos;
+ int pointerToPostion = _bufferOffset + _posLimit;
+ if (pointerToPostion > _pointerToLastSafePosition)
+ _posLimit = _pointerToLastSafePosition - _bufferOffset;
+
+ _streamEndWasReached = true;
+ return;
+ }
+ _streamPos += numReadBytes;
+ if (_streamPos >= _pos + _keepSizeAfter)
+ _posLimit = _streamPos - _keepSizeAfter;
+ }
+ }
+
+ void Free() { _bufferBase = null; }
+
+ public void Create(int keepSizeBefore, int keepSizeAfter, int keepSizeReserv)
+ {
+ _keepSizeBefore = keepSizeBefore;
+ _keepSizeAfter = keepSizeAfter;
+ int blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
+ if (_bufferBase == null || _blockSize != blockSize)
+ {
+ Free();
+ _blockSize = blockSize;
+ _bufferBase = new byte[_blockSize];
+ }
+ _pointerToLastSafePosition = _blockSize - keepSizeAfter;
+ }
+
+ public void SetStream(java.io.InputStream stream) { _stream = stream; }
+ public void ReleaseStream() { _stream = null; }
+
+ public void Init() throws IOException
+ {
+ _bufferOffset = 0;
+ _pos = 0;
+ _streamPos = 0;
+ _streamEndWasReached = false;
+ ReadBlock();
+ }
+
+ public void MovePos() throws IOException
+ {
+ _pos++;
+ if (_pos > _posLimit)
+ {
+ int pointerToPostion = _bufferOffset + _pos;
+ if (pointerToPostion > _pointerToLastSafePosition)
+ MoveBlock();
+ ReadBlock();
+ }
+ }
+
+ public byte GetIndexByte(int index) { return _bufferBase[_bufferOffset + _pos + index]; }
+
+ // index + limit have not to exceed _keepSizeAfter;
+ public int GetMatchLen(int index, int distance, int limit)
+ {
+ if (_streamEndWasReached)
+ if ((_pos + index) + limit > _streamPos)
+ limit = _streamPos - (_pos + index);
+ distance++;
+ // Byte *pby = _buffer + (size_t)_pos + index;
+ int pby = _bufferOffset + _pos + index;
+
+ int i;
+ for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
+ return i;
+ }
+
+ public int GetNumAvailableBytes() { return _streamPos - _pos; }
+
+ public void ReduceOffsets(int subValue)
+ {
+ _bufferOffset += subValue;
+ _posLimit -= subValue;
+ _pos -= subValue;
+ _streamPos -= subValue;
+ }
+}
Added: trunk/lzma/Java/SevenZip/Compression/LZ/OutWindow.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/LZ/OutWindow.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/LZ/OutWindow.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,85 @@
+// LZ.OutWindow
+
+package SevenZip.Compression.LZ;
+
+import java.io.IOException;
+
+public class OutWindow
+{
+ byte[] _buffer;
+ int _pos;
+ int _windowSize = 0;
+ int _streamPos;
+ java.io.OutputStream _stream;
+
+ public void Create(int windowSize)
+ {
+ if (_buffer == null || _windowSize != windowSize)
+ _buffer = new byte[windowSize];
+ _windowSize = windowSize;
+ _pos = 0;
+ _streamPos = 0;
+ }
+
+ public void SetStream(java.io.OutputStream stream) throws IOException
+ {
+ ReleaseStream();
+ _stream = stream;
+ }
+
+ public void ReleaseStream() throws IOException
+ {
+ Flush();
+ _stream = null;
+ }
+
+ public void Init(boolean solid)
+ {
+ if (!solid)
+ {
+ _streamPos = 0;
+ _pos = 0;
+ }
+ }
+
+ public void Flush() throws IOException
+ {
+ int size = _pos - _streamPos;
+ if (size == 0)
+ return;
+ _stream.write(_buffer, _streamPos, size);
+ if (_pos >= _windowSize)
+ _pos = 0;
+ _streamPos = _pos;
+ }
+
+ public void CopyBlock(int distance, int len) throws IOException
+ {
+ int pos = _pos - distance - 1;
+ if (pos < 0)
+ pos += _windowSize;
+ for (; len != 0; len--)
+ {
+ if (pos >= _windowSize)
+ pos = 0;
+ _buffer[_pos++] = _buffer[pos++];
+ if (_pos >= _windowSize)
+ Flush();
+ }
+ }
+
+ public void PutByte(byte b) throws IOException
+ {
+ _buffer[_pos++] = b;
+ if (_pos >= _windowSize)
+ Flush();
+ }
+
+ public byte GetByte(int distance)
+ {
+ int pos = _pos - distance - 1;
+ if (pos < 0)
+ pos += _windowSize;
+ return _buffer[pos];
+ }
+}
Added: trunk/lzma/Java/SevenZip/Compression/LZMA/Base.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/LZMA/Base.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/LZMA/Base.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,88 @@
+// Base.java
+
+package SevenZip.Compression.LZMA;
+
+public class Base
+{
+ public static final int kNumRepDistances = 4;
+ public static final int kNumStates = 12;
+
+ public static final int StateInit()
+ {
+ return 0;
+ }
+
+ public static final int StateUpdateChar(int index)
+ {
+ if (index < 4)
+ return 0;
+ if (index < 10)
+ return index - 3;
+ return index - 6;
+ }
+
+ public static final int StateUpdateMatch(int index)
+ {
+ return (index < 7 ? 7 : 10);
+ }
+
+ public static final int StateUpdateRep(int index)
+ {
+ return (index < 7 ? 8 : 11);
+ }
+
+ public static final int StateUpdateShortRep(int index)
+ {
+ return (index < 7 ? 9 : 11);
+ }
+
+ public static final boolean StateIsCharState(int index)
+ {
+ return index < 7;
+ }
+
+ public static final int kNumPosSlotBits = 6;
+ public static final int kDicLogSizeMin = 0;
+ // public static final int kDicLogSizeMax = 28;
+ // public static final int kDistTableSizeMax = kDicLogSizeMax * 2;
+
+ public static final int kNumLenToPosStatesBits = 2; // it's for speed optimization
+ public static final int kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
+
+ public static final int kMatchMinLen = 2;
+
+ public static final int GetLenToPosState(int len)
+ {
+ len -= kMatchMinLen;
+ if (len < kNumLenToPosStates)
+ return len;
+ return (int)(kNumLenToPosStates - 1);
+ }
+
+ public static final int kNumAlignBits = 4;
+ public static final int kAlignTableSize = 1 << kNumAlignBits;
+ public static final int kAlignMask = (kAlignTableSize - 1);
+
+ public static final int kStartPosModelIndex = 4;
+ public static final int kEndPosModelIndex = 14;
+ public static final int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+ public static final int kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+
+ public static final int kNumLitPosStatesBitsEncodingMax = 4;
+ public static final int kNumLitContextBitsMax = 8;
+
+ public static final int kNumPosStatesBitsMax = 4;
+ public static final int kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+ public static final int kNumPosStatesBitsEncodingMax = 4;
+ public static final int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+ public static final int kNumLowLenBits = 3;
+ public static final int kNumMidLenBits = 3;
+ public static final int kNumHighLenBits = 8;
+ public static final int kNumLowLenSymbols = 1 << kNumLowLenBits;
+ public static final int kNumMidLenSymbols = 1 << kNumMidLenBits;
+ public static final int kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
+ (1 << kNumHighLenBits);
+ public static final int kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
+}
Added: trunk/lzma/Java/SevenZip/Compression/LZMA/Decoder.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/LZMA/Decoder.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/LZMA/Decoder.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,329 @@
+package SevenZip.Compression.LZMA;
+
+import SevenZip.Compression.RangeCoder.BitTreeDecoder;
+import SevenZip.Compression.LZMA.Base;
+import SevenZip.Compression.LZ.OutWindow;
+import java.io.IOException;
+
+public class Decoder
+{
+ class LenDecoder
+ {
+ short[] m_Choice = new short[2];
+ BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
+ BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
+ BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
+ int m_NumPosStates = 0;
+
+ public void Create(int numPosStates)
+ {
+ for (; m_NumPosStates < numPosStates; m_NumPosStates++)
+ {
+ m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits);
+ m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits);
+ }
+ }
+
+ public void Init()
+ {
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Choice);
+ for (int posState = 0; posState < m_NumPosStates; posState++)
+ {
+ m_LowCoder[posState].Init();
+ m_MidCoder[posState].Init();
+ }
+ m_HighCoder.Init();
+ }
+
+ public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException
+ {
+ if (rangeDecoder.DecodeBit(m_Choice, 0) == 0)
+ return m_LowCoder[posState].Decode(rangeDecoder);
+ int symbol = Base.kNumLowLenSymbols;
+ if (rangeDecoder.DecodeBit(m_Choice, 1) == 0)
+ symbol += m_MidCoder[posState].Decode(rangeDecoder);
+ else
+ symbol += Base.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder);
+ return symbol;
+ }
+ }
+
+ class LiteralDecoder
+ {
+ class Decoder2
+ {
+ short[] m_Decoders = new short[0x300];
+
+ public void Init()
+ {
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Decoders);
+ }
+
+ public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException
+ {
+ int symbol = 1;
+ do
+ symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
+ while (symbol < 0x100);
+ return (byte)symbol;
+ }
+
+ public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException
+ {
+ int symbol = 1;
+ do
+ {
+ int matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ int bit = rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) << 8) + symbol);
+ symbol = (symbol << 1) | bit;
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ return (byte)symbol;
+ }
+ }
+
+ Decoder2[] m_Coders;
+ int m_NumPrevBits;
+ int m_NumPosBits;
+ int m_PosMask;
+
+ public void Create(int numPosBits, int numPrevBits)
+ {
+ if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
+ return;
+ m_NumPosBits = numPosBits;
+ m_PosMask = (1 << numPosBits) - 1;
+ m_NumPrevBits = numPrevBits;
+ int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
+ m_Coders = new Decoder2[numStates];
+ for (int i = 0; i < numStates; i++)
+ m_Coders[i] = new Decoder2();
+ }
+
+ public void Init()
+ {
+ int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
+ for (int i = 0; i < numStates; i++)
+ m_Coders[i].Init();
+ }
+
+ Decoder2 GetDecoder(int pos, byte prevByte)
+ {
+ return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))];
+ }
+ }
+
+ OutWindow m_OutWindow = new OutWindow();
+ SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder();
+
+ short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
+ short[] m_IsRepDecoders = new short[Base.kNumStates];
+ short[] m_IsRepG0Decoders = new short[Base.kNumStates];
+ short[] m_IsRepG1Decoders = new short[Base.kNumStates];
+ short[] m_IsRepG2Decoders = new short[Base.kNumStates];
+ short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
+
+ BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
+ short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex];
+
+ BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
+
+ LenDecoder m_LenDecoder = new LenDecoder();
+ LenDecoder m_RepLenDecoder = new LenDecoder();
+
+ LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
+
+ int m_DictionarySize = -1;
+ int m_DictionarySizeCheck = -1;
+
+ int m_PosStateMask;
+
+ public Decoder()
+ {
+ for (int i = 0; i < Base.kNumLenToPosStates; i++)
+ m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
+ }
+
+ boolean SetDictionarySize(int dictionarySize)
+ {
+ if (dictionarySize < 0)
+ return false;
+ if (m_DictionarySize != dictionarySize)
+ {
+ m_DictionarySize = dictionarySize;
+ m_DictionarySizeCheck = Math.max(m_DictionarySize, 1);
+ m_OutWindow.Create(Math.max(m_DictionarySizeCheck, (1 << 12)));
+ }
+ return true;
+ }
+
+ boolean SetLcLpPb(int lc, int lp, int pb)
+ {
+ if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax)
+ return false;
+ m_LiteralDecoder.Create(lp, lc);
+ int numPosStates = 1 << pb;
+ m_LenDecoder.Create(numPosStates);
+ m_RepLenDecoder.Create(numPosStates);
+ m_PosStateMask = numPosStates - 1;
+ return true;
+ }
+
+ void Init() throws IOException
+ {
+ m_OutWindow.Init(false);
+
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsMatchDecoders);
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0LongDecoders);
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDecoders);
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0Decoders);
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1Decoders);
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2Decoders);
+ SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecoders);
+
+ m_LiteralDecoder.Init();
+ int i;
+ for (i = 0; i < Base.kNumLenToPosStates; i++)
+ m_PosSlotDecoder[i].Init();
+ m_LenDecoder.Init();
+ m_RepLenDecoder.Init();
+ m_PosAlignDecoder.Init();
+ m_RangeDecoder.Init();
+ }
+
+ public boolean Code(java.io.InputStream inStream, java.io.OutputStream outStream,
+ long outSize) throws IOException
+ {
+ m_RangeDecoder.SetStream(inStream);
+ m_OutWindow.SetStream(outStream);
+ Init();
+
+ int state = Base.StateInit();
+ int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
+
+ long nowPos64 = 0;
+ byte prevByte = 0;
+ while (outSize < 0 || nowPos64 < outSize)
+ {
+ int posState = (int)nowPos64 & m_PosStateMask;
+ if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
+ {
+ LiteralDecoder.Decoder2 decoder2 = m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte);
+ if (!Base.StateIsCharState(state))
+ prevByte = decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0));
+ else
+ prevByte = decoder2.DecodeNormal(m_RangeDecoder);
+ m_OutWindow.PutByte(prevByte);
+ state = Base.StateUpdateChar(state);
+ nowPos64++;
+ }
+ else
+ {
+ int len;
+ if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) == 1)
+ {
+ len = 0;
+ if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) == 0)
+ {
+ if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
+ {
+ state = Base.StateUpdateShortRep(state);
+ len = 1;
+ }
+ }
+ else
+ {
+ int distance;
+ if (m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) == 0)
+ distance = rep1;
+ else
+ {
+ if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ if (len == 0)
+ {
+ len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
+ state = Base.StateUpdateRep(state);
+ }
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
+ state = Base.StateUpdateMatch(state);
+ int posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
+ if (posSlot >= Base.kStartPosModelIndex)
+ {
+ int numDirectBits = (posSlot >> 1) - 1;
+ rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+ if (posSlot < Base.kEndPosModelIndex)
+ rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
+ rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
+ else
+ {
+ rep0 += (m_RangeDecoder.DecodeDirectBits(
+ numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
+ rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
+ if (rep0 < 0)
+ {
+ if (rep0 == -1)
+ break;
+ return false;
+ }
+ }
+ }
+ else
+ rep0 = posSlot;
+ }
+ if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck)
+ {
+ // m_OutWindow.Flush();
+ return false;
+ }
+ m_OutWindow.CopyBlock(rep0, len);
+ nowPos64 += len;
+ prevByte = m_OutWindow.GetByte(0);
+ }
+ }
+ m_OutWindow.Flush();
+ m_OutWindow.ReleaseStream();
+ m_RangeDecoder.ReleaseStream();
+ return true;
+ }
+
+ public boolean SetDecoderProperties(byte[] properties)
+ {
+ if (properties.length < 5)
+ return false;
+ int val = properties[0] & 0xFF;
+ int lc = val % 9;
+ int remainder = val / 9;
+ int lp = remainder % 5;
+ int pb = remainder / 5;
+ int dictionarySize = 0;
+ for (int i = 0; i < 4; i++)
+ dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8);
+ if (!SetLcLpPb(lc, lp, pb))
+ return false;
+ return SetDictionarySize(dictionarySize);
+ }
+}
Added: trunk/lzma/Java/SevenZip/Compression/LZMA/Encoder.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/LZMA/Encoder.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/LZMA/Encoder.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,1416 @@
+package SevenZip.Compression.LZMA;
+
+import SevenZip.Compression.RangeCoder.BitTreeEncoder;
+import SevenZip.Compression.LZMA.Base;
+import SevenZip.Compression.LZ.BinTree;
+import SevenZip.ICodeProgress;
+import java.io.IOException;
+
+public class Encoder
+{
+ public static final int EMatchFinderTypeBT2 = 0;
+ public static final int EMatchFinderTypeBT4 = 1;
+
+
+
+
+ static final int kIfinityPrice = 0xFFFFFFF;
+
+ static byte[] g_FastPos = new byte[1 << 11];
+
+ static
+ {
+ int kFastSlots = 22;
+ int c = 2;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+ for (int slotFast = 2; slotFast < kFastSlots; slotFast++)
+ {
+ int k = (1 << ((slotFast >> 1) - 1));
+ for (int j = 0; j < k; j++, c++)
+ g_FastPos[c] = (byte)slotFast;
+ }
+ }
+
+ static int GetPosSlot(int pos)
+ {
+ if (pos < (1 << 11))
+ return g_FastPos[pos];
+ if (pos < (1 << 21))
+ return (g_FastPos[pos >> 10] + 20);
+ return (g_FastPos[pos >> 20] + 40);
+ }
+
+ static int GetPosSlot2(int pos)
+ {
+ if (pos < (1 << 17))
+ return (g_FastPos[pos >> 6] + 12);
+ if (pos < (1 << 27))
+ return (g_FastPos[pos >> 16] + 32);
+ return (g_FastPos[pos >> 26] + 52);
+ }
+
+ int _state = Base.StateInit();
+ byte _previousByte;
+ int[] _repDistances = new int[Base.kNumRepDistances];
+
+ void BaseInit()
+ {
+ _state = Base.StateInit();
+ _previousByte = 0;
+ for (int i = 0; i < Base.kNumRepDistances; i++)
+ _repDistances[i] = 0;
+ }
+
+ static final int kDefaultDictionaryLogSize = 22;
+ static final int kNumFastBytesDefault = 0x20;
+
+ class LiteralEncoder
+ {
+ class Encoder2
+ {
+ short[] m_Encoders = new short[0x300];
+
+ public void Init() { SevenZip.Compression.RangeCoder.Encoder.InitBitModels(m_Encoders); }
+
+
+
+ public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte symbol) throws IOException
+ {
+ int context = 1;
+ for (int i = 7; i >= 0; i--)
+ {
+ int bit = ((symbol >> i) & 1);
+ rangeEncoder.Encode(m_Encoders, context, bit);
+ context = (context << 1) | bit;
+ }
+ }
+
+ public void EncodeMatched(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) throws IOException
+ {
+ int context = 1;
+ boolean same = true;
+ for (int i = 7; i >= 0; i--)
+ {
+ int bit = ((symbol >> i) & 1);
+ int state = context;
+ if (same)
+ {
+ int matchBit = ((matchByte >> i) & 1);
+ state += ((1 + matchBit) << 8);
+ same = (matchBit == bit);
+ }
+ rangeEncoder.Encode(m_Encoders, state, bit);
+ context = (context << 1) | bit;
+ }
+ }
+
+ public int GetPrice(boolean matchMode, byte matchByte, byte symbol)
+ {
+ int price = 0;
+ int context = 1;
+ int i = 7;
+ if (matchMode)
+ {
+ for (; i >= 0; i--)
+ {
+ int matchBit = (matchByte >> i) & 1;
+ int bit = (symbol >> i) & 1;
+ price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[((1 + matchBit) << 8) + context], bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ {
+ i--;
+ break;
+ }
+ }
+ }
+ for (; i >= 0; i--)
+ {
+ int bit = (symbol >> i) & 1;
+ price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[context], bit);
+ context = (context << 1) | bit;
+ }
+ return price;
+ }
+ }
+
+ Encoder2[] m_Coders;
+ int m_NumPrevBits;
+ int m_NumPosBits;
+ int m_PosMask;
+
+ public void Create(int numPosBits, int numPrevBits)
+ {
+ if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
+ return;
+ m_NumPosBits = numPosBits;
+ m_PosMask = (1 << numPosBits) - 1;
+ m_NumPrevBits = numPrevBits;
+ int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
+ m_Coders = new Encoder2[numStates];
+ for (int i = 0; i < numStates; i++)
+ m_Coders[i] = new Encoder2();
+ }
+
+ public void Init()
+ {
+ int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
+ for (int i = 0; i < numStates; i++)
+ m_Coders[i].Init();
+ }
+
+ public Encoder2 GetSubCoder(int pos, byte prevByte)
+ { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; }
+ }
+
+ class LenEncoder
+ {
+ short[] _choice = new short[2];
+ BitTreeEncoder[] _lowCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];
+ BitTreeEncoder[] _midCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];
+ BitTreeEncoder _highCoder = new BitTreeEncoder(Base.kNumHighLenBits);
+
+
+ public LenEncoder()
+ {
+ for (int posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)
+ {
+ _lowCoder[posState] = new BitTreeEncoder(Base.kNumLowLenBits);
+ _midCoder[posState] = new BitTreeEncoder(Base.kNumMidLenBits);
+ }
+ }
+
+ public void Init(int numPosStates)
+ {
+ SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_choice);
+
+ for (int posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+ }
+
+ public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException
+ {
+ if (symbol < Base.kNumLowLenSymbols)
+ {
+ rangeEncoder.Encode(_choice, 0, 0);
+ _lowCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ symbol -= Base.kNumLowLenSymbols;
+ rangeEncoder.Encode(_choice, 0, 1);
+ if (symbol < Base.kNumMidLenSymbols)
+ {
+ rangeEncoder.Encode(_choice, 1, 0);
+ _midCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ rangeEncoder.Encode(_choice, 1, 1);
+ _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);
+ }
+ }
+ }
+
+ public void SetPrices(int posState, int numSymbols, int[] prices, int st)
+ {
+ int a0 = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[0]);
+ int a1 = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[0]);
+ int b0 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[1]);
+ int b1 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[1]);
+ int i = 0;
+ for (i = 0; i < Base.kNumLowLenSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);
+ }
+ for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);
+ }
+ for (; i < numSymbols; i++)
+ prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);
+ }
+ };
+
+ public static final int kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;
+
+ class LenPriceTableEncoder extends LenEncoder
+ {
+ int[] _prices = new int[Base.kNumLenSymbols<<Base.kNumPosStatesBitsEncodingMax];
+ int _tableSize;
+ int[] _counters = new int[Base.kNumPosStatesEncodingMax];
+
+ public void SetTableSize(int tableSize) { _tableSize = tableSize; }
+
+ public int GetPrice(int symbol, int posState)
+ {
+ return _prices[posState * Base.kNumLenSymbols + symbol];
+ }
+
+ void UpdateTable(int posState)
+ {
+ SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);
+ _counters[posState] = _tableSize;
+ }
+
+ public void UpdateTables(int numPosStates)
+ {
+ for (int posState = 0; posState < numPosStates; posState++)
+ UpdateTable(posState);
+ }
+
+ public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException
+ {
+ super.Encode(rangeEncoder, symbol, posState);
+ if (--_counters[posState] == 0)
+ UpdateTable(posState);
+ }
+ }
+
+ static final int kNumOpts = 1 << 12;
+ class Optimal
+ {
+ public int State;
+
+ public boolean Prev1IsChar;
+ public boolean Prev2;
+
+ public int PosPrev2;
+ public int BackPrev2;
+
+ public int Price;
+ public int PosPrev;
+ public int BackPrev;
+
+ public int Backs0;
+ public int Backs1;
+ public int Backs2;
+ public int Backs3;
+
+ public void MakeAsChar() { BackPrev = -1; Prev1IsChar = false; }
+ public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+ public boolean IsShortRep() { return (BackPrev == 0); }
+ };
+ Optimal[] _optimum = new Optimal[kNumOpts];
+ SevenZip.Compression.LZ.BinTree _matchFinder = null;
+ SevenZip.Compression.RangeCoder.Encoder _rangeEncoder = new SevenZip.Compression.RangeCoder.Encoder();
+
+ short[] _isMatch = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];
+ short[] _isRep = new short[Base.kNumStates];
+ short[] _isRepG0 = new short[Base.kNumStates];
+ short[] _isRepG1 = new short[Base.kNumStates];
+ short[] _isRepG2 = new short[Base.kNumStates];
+ short[] _isRep0Long = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];
+
+ BitTreeEncoder[] _posSlotEncoder = new BitTreeEncoder[Base.kNumLenToPosStates]; // kNumPosSlotBits
+
+ short[] _posEncoders = new short[Base.kNumFullDistances-Base.kEndPosModelIndex];
+ BitTreeEncoder _posAlignEncoder = new BitTreeEncoder(Base.kNumAlignBits);
+
+ LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
+ LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();
+
+ LiteralEncoder _literalEncoder = new LiteralEncoder();
+
+ int[] _matchDistances = new int[Base.kMatchMaxLen*2+2];
+
+ int _numFastBytes = kNumFastBytesDefault;
+ int _longestMatchLength;
+ int _numDistancePairs;
+
+ int _additionalOffset;
+
+ int _optimumEndIndex;
+ int _optimumCurrentIndex;
+
+ boolean _longestMatchWasFound;
+
+ int[] _posSlotPrices = new int[1<<(Base.kNumPosSlotBits+Base.kNumLenToPosStatesBits)];
+ int[] _distancesPrices = new int[Base.kNumFullDistances<<Base.kNumLenToPosStatesBits];
+ int[] _alignPrices = new int[Base.kAlignTableSize];
+ int _alignPriceCount;
+
+ int _distTableSize = (kDefaultDictionaryLogSize * 2);
+
+ int _posStateBits = 2;
+ int _posStateMask = (4 - 1);
+ int _numLiteralPosStateBits = 0;
+ int _numLiteralContextBits = 3;
+
+ int _dictionarySize = (1 << kDefaultDictionaryLogSize);
+ int _dictionarySizePrev = -1;
+ int _numFastBytesPrev = -1;
+
+ long nowPos64;
+ boolean _finished;
+ java.io.InputStream _inStream;
+
+ int _matchFinderType = EMatchFinderTypeBT4;
+ boolean _writeEndMark = false;
+
+ boolean _needReleaseMFStream = false;
+
+ void Create()
+ {
+ if (_matchFinder == null)
+ {
+ SevenZip.Compression.LZ.BinTree bt = new SevenZip.Compression.LZ.BinTree();
+ int numHashBytes = 4;
+ if (_matchFinderType == EMatchFinderTypeBT2)
+ numHashBytes = 2;
+ bt.SetType(numHashBytes);
+ _matchFinder = bt;
+ }
+ _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);
+
+ if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
+ return;
+ _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);
+ _dictionarySizePrev = _dictionarySize;
+ _numFastBytesPrev = _numFastBytes;
+ }
+
+ public Encoder()
+ {
+ for (int i = 0; i < kNumOpts; i++)
+ _optimum[i] = new Optimal();
+ for (int i = 0; i < Base.kNumLenToPosStates; i++)
+ _posSlotEncoder[i] = new BitTreeEncoder(Base.kNumPosSlotBits);
+ }
+
+ void SetWriteEndMarkerMode(boolean writeEndMarker)
+ {
+ _writeEndMark = writeEndMarker;
+ }
+
+ void Init()
+ {
+ BaseInit();
+ _rangeEncoder.Init();
+
+ SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isMatch);
+ SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep0Long);
+ SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep);
+ SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG0);
+ SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG1);
+ SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG2);
+ SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_posEncoders);
+
+
+
+
+
+
+
+ _literalEncoder.Init();
+ for (int i = 0; i < Base.kNumLenToPosStates; i++)
+ _posSlotEncoder[i].Init();
+
+
+
+ _lenEncoder.Init(1 << _posStateBits);
+ _repMatchLenEncoder.Init(1 << _posStateBits);
+
+ _posAlignEncoder.Init();
+
+ _longestMatchWasFound = false;
+ _optimumEndIndex = 0;
+ _optimumCurrentIndex = 0;
+ _additionalOffset = 0;
+ }
+
+ int ReadMatchDistances() throws java.io.IOException
+ {
+ int lenRes = 0;
+ _numDistancePairs = _matchFinder.GetMatches(_matchDistances);
+ if (_numDistancePairs > 0)
+ {
+ lenRes = _matchDistances[_numDistancePairs - 2];
+ if (lenRes == _numFastBytes)
+ lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[_numDistancePairs - 1],
+ Base.kMatchMaxLen - lenRes);
+ }
+ _additionalOffset++;
+ return lenRes;
+ }
+
+ void MovePos(int num) throws java.io.IOException
+ {
+ if (num > 0)
+ {
+ _matchFinder.Skip(num);
+ _additionalOffset += num;
+ }
+ }
+
+ int GetRepLen1Price(int state, int posState)
+ {
+ return SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]) +
+ SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);
+ }
+
+ int GetPureRepPrice(int repIndex, int state, int posState)
+ {
+ int price;
+ if (repIndex == 0)
+ {
+ price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]);
+ price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);
+ }
+ else
+ {
+ price = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG0[state]);
+ if (repIndex == 1)
+ price += SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG1[state]);
+ else
+ {
+ price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG1[state]);
+ price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(_isRepG2[state], repIndex - 2);
+ }
+ }
+ return price;
+ }
+
+ int GetRepPrice(int repIndex, int len, int state, int posState)
+ {
+ int price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
+ return price + GetPureRepPrice(repIndex, state, posState);
+ }
+
+ int GetPosLenPrice(int pos, int len, int posState)
+ {
+ int price;
+ int lenToPosState = Base.GetLenToPosState(len);
+ if (pos < Base.kNumFullDistances)
+ price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];
+ else
+ price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] +
+ _alignPrices[pos & Base.kAlignMask];
+ return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
+ }
+
+ int Backward(int cur)
+ {
+ _optimumEndIndex = cur;
+ int posMem = _optimum[cur].PosPrev;
+ int backMem = _optimum[cur].BackPrev;
+ do
+ {
+ if (_optimum[cur].Prev1IsChar)
+ {
+ _optimum[posMem].MakeAsChar();
+ _optimum[posMem].PosPrev = posMem - 1;
+ if (_optimum[cur].Prev2)
+ {
+ _optimum[posMem - 1].Prev1IsChar = false;
+ _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+ _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+ }
+ }
+ int posPrev = posMem;
+ int backCur = backMem;
+
+ backMem = _optimum[posPrev].BackPrev;
+ posMem = _optimum[posPrev].PosPrev;
+
+ _optimum[posPrev].BackPrev = backCur;
+ _optimum[posPrev].PosPrev = cur;
+ cur = posPrev;
+ }
+ while (cur > 0);
+ backRes = _optimum[0].BackPrev;
+ _optimumCurrentIndex = _optimum[0].PosPrev;
+ return _optimumCurrentIndex;
+ }
+
+ int[] reps = new int[Base.kNumRepDistances];
+ int[] repLens = new int[Base.kNumRepDistances];
+ int backRes;
+
+ int GetOptimum(int position) throws IOException
+ {
+ if (_optimumEndIndex != _optimumCurrentIndex)
+ {
+ int lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;
+ backRes = _optimum[_optimumCurrentIndex].BackPrev;
+ _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;
+ return lenRes;
+ }
+ _optimumCurrentIndex = _optimumEndIndex = 0;
+
+ int lenMain, numDistancePairs;
+ if (!_longestMatchWasFound)
+ {
+ lenMain = ReadMatchDistances();
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ _longestMatchWasFound = false;
+ }
+ numDistancePairs = _numDistancePairs;
+
+ int numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;
+ if (numAvailableBytes < 2)
+ {
+ backRes = -1;
+ return 1;
+ }
+ if (numAvailableBytes > Base.kMatchMaxLen)
+ numAvailableBytes = Base.kMatchMaxLen;
+
+ int repMaxIndex = 0;
+ int i;
+ for (i = 0; i < Base.kNumRepDistances; i++)
+ {
+ reps[i] = _repDistances[i];
+ repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);
+ if (repLens[i] > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if (repLens[repMaxIndex] >= _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ int lenRes = repLens[repMaxIndex];
+ MovePos(lenRes - 1);
+ return lenRes;
+ }
+
+ if (lenMain >= _numFastBytes)
+ {
+ backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+
+ byte currentByte = _matchFinder.GetIndexByte(0 - 1);
+ byte matchByte = _matchFinder.GetIndexByte(0 - _repDistances[0] - 1 - 1);
+
+ if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+ {
+ backRes = -1;
+ return 1;
+ }
+
+ _optimum[0].State = _state;
+
+ int posState = (position & _posStateMask);
+
+ _optimum[1].Price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]) +
+ _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!Base.StateIsCharState(_state), matchByte, currentByte);
+ _optimum[1].MakeAsChar();
+
+ int matchPrice = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]);
+ int repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[_state]);
+
+ if (matchByte == currentByte)
+ {
+ int shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+ if (shortRepPrice < _optimum[1].Price)
+ {
+ _optimum[1].Price = shortRepPrice;
+ _optimum[1].MakeAsShortRep();
+ }
+ }
+
+ int lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+ if (lenEnd < 2)
+ {
+ backRes = _optimum[1].BackPrev;
+ return 1;
+ }
+
+ _optimum[1].PosPrev = 0;
+
+ _optimum[0].Backs0 = reps[0];
+ _optimum[0].Backs1 = reps[1];
+ _optimum[0].Backs2 = reps[2];
+ _optimum[0].Backs3 = reps[3];
+
+ int len = lenEnd;
+ do
+ _optimum[len--].Price = kIfinityPrice;
+ while (len >= 2);
+
+ for (i = 0; i < Base.kNumRepDistances; i++)
+ {
+ int repLen = repLens[i];
+ if (repLen < 2)
+ continue;
+ int price = repMatchPrice + GetPureRepPrice(i, _state, posState);
+ do
+ {
+ int curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
+ Optimal optimum = _optimum[repLen];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = i;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while (--repLen >= 2);
+ }
+
+ int normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[_state]);
+
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= lenMain)
+ {
+ int offs = 0;
+ while (len > _matchDistances[offs])
+ offs += 2;
+ for (; ; len++)
+ {
+ int distance = _matchDistances[offs + 1];
+ int curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
+ Optimal optimum = _optimum[len];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = distance + Base.kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+ if (len == _matchDistances[offs])
+ {
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ }
+ }
+ }
+
+ int cur = 0;
+
+ while (true)
+ {
+ cur++;
+ if (cur == lenEnd)
+ return Backward(cur);
+ int newLen = ReadMatchDistances();
+ numDistancePairs = _numDistancePairs;
+ if (newLen >= _numFastBytes)
+ {
+
+ _longestMatchLength = newLen;
+ _longestMatchWasFound = true;
+ return Backward(cur);
+ }
+ position++;
+ int posPrev = _optimum[cur].PosPrev;
+ int state;
+ if (_optimum[cur].Prev1IsChar)
+ {
+ posPrev--;
+ if (_optimum[cur].Prev2)
+ {
+ state = _optimum[_optimum[cur].PosPrev2].State;
+ if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)
+ state = Base.StateUpdateRep(state);
+ else
+ state = Base.StateUpdateMatch(state);
+ }
+ else
+ state = _optimum[posPrev].State;
+ state = Base.StateUpdateChar(state);
+ }
+ else
+ state = _optimum[posPrev].State;
+ if (posPrev == cur - 1)
+ {
+ if (_optimum[cur].IsShortRep())
+ state = Base.StateUpdateShortRep(state);
+ else
+ state = Base.StateUpdateChar(state);
+ }
+ else
+ {
+ int pos;
+ if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)
+ {
+ posPrev = _optimum[cur].PosPrev2;
+ pos = _optimum[cur].BackPrev2;
+ state = Base.StateUpdateRep(state);
+ }
+ else
+ {
+ pos = _optimum[cur].BackPrev;
+ if (pos < Base.kNumRepDistances)
+ state = Base.StateUpdateRep(state);
+ else
+ state = Base.StateUpdateMatch(state);
+ }
+ Optimal opt = _optimum[posPrev];
+ if (pos < Base.kNumRepDistances)
+ {
+ if (pos == 0)
+ {
+ reps[0] = opt.Backs0;
+ reps[1] = opt.Backs1;
+ reps[2] = opt.Backs2;
+ reps[3] = opt.Backs3;
+ }
+ else if (pos == 1)
+ {
+ reps[0] = opt.Backs1;
+ reps[1] = opt.Backs0;
+ reps[2] = opt.Backs2;
+ reps[3] = opt.Backs3;
+ }
+ else if (pos == 2)
+ {
+ reps[0] = opt.Backs2;
+ reps[1] = opt.Backs0;
+ reps[2] = opt.Backs1;
+ reps[3] = opt.Backs3;
+ }
+ else
+ {
+ reps[0] = opt.Backs3;
+ reps[1] = opt.Backs0;
+ reps[2] = opt.Backs1;
+ reps[3] = opt.Backs2;
+ }
+ }
+ else
+ {
+ reps[0] = (pos - Base.kNumRepDistances);
+ reps[1] = opt.Backs0;
+ reps[2] = opt.Backs1;
+ reps[3] = opt.Backs2;
+ }
+ }
+ _optimum[cur].State = state;
+ _optimum[cur].Backs0 = reps[0];
+ _optimum[cur].Backs1 = reps[1];
+ _optimum[cur].Backs2 = reps[2];
+ _optimum[cur].Backs3 = reps[3];
+ int curPrice = _optimum[cur].Price;
+
+ currentByte = _matchFinder.GetIndexByte(0 - 1);
+ matchByte = _matchFinder.GetIndexByte(0 - reps[0] - 1 - 1);
+
+ posState = (position & _posStateMask);
+
+ int curAnd1Price = curPrice +
+ SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]) +
+ _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)).
+ GetPrice(!Base.StateIsCharState(state), matchByte, currentByte);
+
+ Optimal nextOptimum = _optimum[cur + 1];
+
+ boolean nextIsChar = false;
+ if (curAnd1Price < nextOptimum.Price)
+ {
+ nextOptimum.Price = curAnd1Price;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsChar();
+ nextIsChar = true;
+ }
+
+ matchPrice = curPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]);
+ repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state]);
+
+ if (matchByte == currentByte &&
+ !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+ {
+ int shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+ if (shortRepPrice <= nextOptimum.Price)
+ {
+ nextOptimum.Price = shortRepPrice;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsShortRep();
+ nextIsChar = true;
+ }
+ }
+
+ int numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;
+ numAvailableBytesFull = Math.min(kNumOpts - 1 - cur, numAvailableBytesFull);
+ numAvailableBytes = numAvailableBytesFull;
+
+ if (numAvailableBytes < 2)
+ continue;
+ if (numAvailableBytes > _numFastBytes)
+ numAvailableBytes = _numFastBytes;
+ if (!nextIsChar && matchByte != currentByte)
+ {
+ // try Literal + rep0
+ int t = Math.min(numAvailableBytesFull - 1, _numFastBytes);
+ int lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);
+ if (lenTest2 >= 2)
+ {
+ int state2 = Base.StateUpdateChar(state);
+
+ int posStateNext = (position + 1) & _posStateMask;
+ int nextRepMatchPrice = curAnd1Price +
+ SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
+ SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
+ {
+ int offset = cur + 1 + lenTest2;
+ while (lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ int curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ Optimal optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = false;
+ }
+ }
+ }
+ }
+
+ int startLen = 2; // speed optimization
+
+ for (int repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)
+ {
+ int lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes);
+ if (lenTest < 2)
+ continue;
+ int lenTestTemp = lenTest;
+ do
+ {
+ while (lenEnd < cur + lenTest)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ int curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
+ Optimal optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = repIndex;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while (--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (repIndex == 0)
+ startLen = lenTest + 1;
+
+ // if (_maxMode)
+ if (lenTest < numAvailableBytesFull)
+ {
+ int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
+ int lenTest2 = _matchFinder.GetMatchLen(lenTest, reps[repIndex], t);
+ if (lenTest2 >= 2)
+ {
+ int state2 = Base.StateUpdateRep(state);
+
+ int posStateNext = (position + lenTest) & _posStateMask;
+ int curAndLenCharPrice =
+ repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) +
+ SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
+ _literalEncoder.GetSubCoder(position + lenTest,
+ _matchFinder.GetIndexByte(lenTest - 1 - 1)).GetPrice(true,
+ _matchFinder.GetIndexByte(lenTest - 1 - (reps[repIndex] + 1)),
+ _matchFinder.GetIndexByte(lenTest - 1));
+ state2 = Base.StateUpdateChar(state2);
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);
+ int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ int offset = lenTest + 1 + lenTest2;
+ while (lenEnd < cur + offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ int curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+ Optimal optimum = _optimum[cur + offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+
+ if (newLen > numAvailableBytes)
+ {
+ newLen = numAvailableBytes;
+ for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ;
+ _matchDistances[numDistancePairs] = newLen;
+ numDistancePairs += 2;
+ }
+ if (newLen >= startLen)
+ {
+ normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[state]);
+ while (lenEnd < cur + newLen)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+
+ int offs = 0;
+ while (startLen > _matchDistances[offs])
+ offs += 2;
+
+ for (int lenTest = startLen; ; lenTest++)
+ {
+ int curBack = _matchDistances[offs + 1];
+ int curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
+ Optimal optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = curBack + Base.kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+
+ if (lenTest == _matchDistances[offs])
+ {
+ if (lenTest < numAvailableBytesFull)
+ {
+ int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
+ int lenTest2 = _matchFinder.GetMatchLen(lenTest, curBack, t);
+ if (lenTest2 >= 2)
+ {
+ int state2 = Base.StateUpdateMatch(state);
+
+ int posStateNext = (position + lenTest) & _posStateMask;
+ int curAndLenCharPrice = curAndLenPrice +
+ SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
+ _literalEncoder.GetSubCoder(position + lenTest,
+ _matchFinder.GetIndexByte(lenTest - 1 - 1)).
+ GetPrice(true,
+ _matchFinder.GetIndexByte(lenTest - (curBack + 1) - 1),
+ _matchFinder.GetIndexByte(lenTest - 1));
+ state2 = Base.StateUpdateChar(state2);
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);
+ int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
+
+ int offset = lenTest + 1 + lenTest2;
+ while (lenEnd < cur + offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+ optimum = _optimum[cur + offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = curBack + Base.kNumRepDistances;
+ }
+ }
+ }
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ boolean ChangePair(int smallDist, int bigDist)
+ {
+ int kDif = 7;
+ return (smallDist < (1 << (32 - kDif)) && bigDist >= (smallDist << kDif));
+ }
+
+ void WriteEndMarker(int posState) throws IOException
+ {
+ if (!_writeEndMark)
+ return;
+
+ _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 1);
+ _rangeEncoder.Encode(_isRep, _state, 0);
+ _state = Base.StateUpdateMatch(_state);
+ int len = Base.kMatchMinLen;
+ _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+ int posSlot = (1 << Base.kNumPosSlotBits) - 1;
+ int lenToPosState = Base.GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
+ int footerBits = 30;
+ int posReduced = (1 << footerBits) - 1;
+ _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
+ }
+
+ void Flush(int nowPos) throws IOException
+ {
+ ReleaseMFStream();
+ WriteEndMarker(nowPos & _posStateMask);
+ _rangeEncoder.FlushData();
+ _rangeEncoder.FlushStream();
+ }
+
+ public void CodeOneBlock(long[] inSize, long[] outSize, boolean[] finished) throws IOException
+ {
+ inSize[0] = 0;
+ outSize[0] = 0;
+ finished[0] = true;
+
+ if (_inStream != null)
+ {
+ _matchFinder.SetStream(_inStream);
+ _matchFinder.Init();
+ _needReleaseMFStream = true;
+ _inStream = null;
+ }
+
+ if (_finished)
+ return;
+ _finished = true;
+
+
+ long progressPosValuePrev = nowPos64;
+ if (nowPos64 == 0)
+ {
+ if (_matchFinder.GetNumAvailableBytes() == 0)
+ {
+ Flush((int)nowPos64);
+ return;
+ }
+
+ ReadMatchDistances();
+ int posState = (int)(nowPos64) & _posStateMask;
+ _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 0);
+ _state = Base.StateUpdateChar(_state);
+ byte curByte = _matchFinder.GetIndexByte(0 - _additionalOffset);
+ _literalEncoder.GetSubCoder((int)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);
+ _previousByte = curByte;
+ _additionalOffset--;
+ nowPos64++;
+ }
+ if (_matchFinder.GetNumAvailableBytes() == 0)
+ {
+ Flush((int)nowPos64);
+ return;
+ }
+ while (true)
+ {
+
+ int len = GetOptimum((int)nowPos64);
+ int pos = backRes;
+ int posState = ((int)nowPos64) & _posStateMask;
+ int complexState = (_state << Base.kNumPosStatesBitsMax) + posState;
+ if (len == 1 && pos == -1)
+ {
+ _rangeEncoder.Encode(_isMatch, complexState, 0);
+ byte curByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset));
+ LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((int)nowPos64, _previousByte);
+ if (!Base.StateIsCharState(_state))
+ {
+ byte matchByte = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - _additionalOffset));
+ subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);
+ }
+ else
+ subCoder.Encode(_rangeEncoder, curByte);
+ _previousByte = curByte;
+ _state = Base.StateUpdateChar(_state);
+ }
+ else
+ {
+ _rangeEncoder.Encode(_isMatch, complexState, 1);
+ if (pos < Base.kNumRepDistances)
+ {
+ _rangeEncoder.Encode(_isRep, _state, 1);
+ if (pos == 0)
+ {
+ _rangeEncoder.Encode(_isRepG0, _state, 0);
+ if (len == 1)
+ _rangeEncoder.Encode(_isRep0Long, complexState, 0);
+ else
+ _rangeEncoder.Encode(_isRep0Long, complexState, 1);
+ }
+ else
+ {
+ _rangeEncoder.Encode(_isRepG0, _state, 1);
+ if (pos == 1)
+ _rangeEncoder.Encode(_isRepG1, _state, 0);
+ else
+ {
+ _rangeEncoder.Encode(_isRepG1, _state, 1);
+ _rangeEncoder.Encode(_isRepG2, _state, pos - 2);
+ }
+ }
+ if (len == 1)
+ _state = Base.StateUpdateShortRep(_state);
+ else
+ {
+ _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+ _state = Base.StateUpdateRep(_state);
+ }
+ int distance = _repDistances[pos];
+ if (pos != 0)
+ {
+ for (int i = pos; i >= 1; i--)
+ _repDistances[i] = _repDistances[i - 1];
+ _repDistances[0] = distance;
+ }
+ }
+ else
+ {
+ _rangeEncoder.Encode(_isRep, _state, 0);
+ _state = Base.StateUpdateMatch(_state);
+ _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+ pos -= Base.kNumRepDistances;
+ int posSlot = GetPosSlot(pos);
+ int lenToPosState = Base.GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
+
+ if (posSlot >= Base.kStartPosModelIndex)
+ {
+ int footerBits = (int)((posSlot >> 1) - 1);
+ int baseVal = ((2 | (posSlot & 1)) << footerBits);
+ int posReduced = pos - baseVal;
+
+ if (posSlot < Base.kEndPosModelIndex)
+ BitTreeEncoder.ReverseEncode(_posEncoders,
+ baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);
+ else
+ {
+ _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
+ _alignPriceCount++;
+ }
+ }
+ int distance = pos;
+ for (int i = Base.kNumRepDistances - 1; i >= 1; i--)
+ _repDistances[i] = _repDistances[i - 1];
+ _repDistances[0] = distance;
+ _matchPriceCount++;
+ }
+ _previousByte = _matchFinder.GetIndexByte(len - 1 - _additionalOffset);
+ }
+ _additionalOffset -= len;
+ nowPos64 += len;
+ if (_additionalOffset == 0)
+ {
+ // if (!_fastMode)
+ if (_matchPriceCount >= (1 << 7))
+ FillDistancesPrices();
+ if (_alignPriceCount >= Base.kAlignTableSize)
+ FillAlignPrices();
+ inSize[0] = nowPos64;
+ outSize[0] = _rangeEncoder.GetProcessedSizeAdd();
+ if (_matchFinder.GetNumAvailableBytes() == 0)
+ {
+ Flush((int)nowPos64);
+ return;
+ }
+
+ if (nowPos64 - progressPosValuePrev >= (1 << 12))
+ {
+ _finished = false;
+ finished[0] = false;
+ return;
+ }
+ }
+ }
+ }
+
+ void ReleaseMFStream()
+ {
+ if (_matchFinder != null && _needReleaseMFStream)
+ {
+ _matchFinder.ReleaseStream();
+ _needReleaseMFStream = false;
+ }
+ }
+
+ void SetOutStream(java.io.OutputStream outStream)
+ { _rangeEncoder.SetStream(outStream); }
+ void ReleaseOutStream()
+ { _rangeEncoder.ReleaseStream(); }
+
+ void ReleaseStreams()
+ {
+ ReleaseMFStream();
+ ReleaseOutStream();
+ }
+
+ void SetStreams(java.io.InputStream inStream, java.io.OutputStream outStream,
+ long inSize, long outSize)
+ {
+ _inStream = inStream;
+ _finished = false;
+ Create();
+ SetOutStream(outStream);
+ Init();
+
+ // if (!_fastMode)
+ {
+ FillDistancesPrices();
+ FillAlignPrices();
+ }
+
+ _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
+ _lenEncoder.UpdateTables(1 << _posStateBits);
+ _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
+ _repMatchLenEncoder.UpdateTables(1 << _posStateBits);
+
+ nowPos64 = 0;
+ }
+
+ long[] processedInSize = new long[1]; long[] processedOutSize = new long[1]; boolean[] finished = new boolean[1];
+ public void Code(java.io.InputStream inStream, java.io.OutputStream outStream,
+ long inSize, long outSize, ICodeProgress progress) throws IOException
+ {
+ _needReleaseMFStream = false;
+ try
+ {
+ SetStreams(inStream, outStream, inSize, outSize);
+ while (true)
+ {
+
+
+
+ CodeOneBlock(processedInSize, processedOutSize, finished);
+ if (finished[0])
+ return;
+ if (progress != null)
+ {
+ progress.SetProgress(processedInSize[0], processedOutSize[0]);
+ }
+ }
+ }
+ finally
+ {
+ ReleaseStreams();
+ }
+ }
+
+ public static final int kPropSize = 5;
+ byte[] properties = new byte[kPropSize];
+
+ public void WriteCoderProperties(java.io.OutputStream outStream) throws IOException
+ {
+ properties[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
+ for (int i = 0; i < 4; i++)
+ properties[1 + i] = (byte)(_dictionarySize >> (8 * i));
+ outStream.write(properties, 0, kPropSize);
+ }
+
+ int[] tempPrices = new int[Base.kNumFullDistances];
+ int _matchPriceCount;
+
+ void FillDistancesPrices()
+ {
+ for (int i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)
+ {
+ int posSlot = GetPosSlot(i);
+ int footerBits = (int)((posSlot >> 1) - 1);
+ int baseVal = ((2 | (posSlot & 1)) << footerBits);
+ tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders,
+ baseVal - posSlot - 1, footerBits, i - baseVal);
+ }
+
+ for (int lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)
+ {
+ int posSlot;
+ BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];
+
+ int st = (lenToPosState << Base.kNumPosSlotBits);
+ for (posSlot = 0; posSlot < _distTableSize; posSlot++)
+ _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);
+ for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
+ _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << SevenZip.Compression.RangeCoder.Encoder.kNumBitPriceShiftBits);
+
+ int st2 = lenToPosState * Base.kNumFullDistances;
+ int i;
+ for (i = 0; i < Base.kStartPosModelIndex; i++)
+ _distancesPrices[st2 + i] = _posSlotPrices[st + i];
+ for (; i < Base.kNumFullDistances; i++)
+ _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];
+ }
+ _matchPriceCount = 0;
+ }
+
+ void FillAlignPrices()
+ {
+ for (int i = 0; i < Base.kAlignTableSize; i++)
+ _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+ _alignPriceCount = 0;
+ }
+
+
+ public boolean SetAlgorithm(int algorithm)
+ {
+ /*
+ _fastMode = (algorithm == 0);
+ _maxMode = (algorithm >= 2);
+ */
+ return true;
+ }
+
+ public boolean SetDictionarySize(int dictionarySize)
+ {
+ int kDicLogSizeMaxCompress = 29;
+ if (dictionarySize < (1 << Base.kDicLogSizeMin) || dictionarySize > (1 << kDicLogSizeMaxCompress))
+ return false;
+ _dictionarySize = dictionarySize;
+ int dicLogSize;
+ for (dicLogSize = 0; dictionarySize > (1 << dicLogSize); dicLogSize++) ;
+ _distTableSize = dicLogSize * 2;
+ return true;
+ }
+
+ public boolean SeNumFastBytes(int numFastBytes)
+ {
+ if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)
+ return false;
+ _numFastBytes = numFastBytes;
+ return true;
+ }
+
+ public boolean SetMatchFinder(int matchFinderIndex)
+ {
+ if (matchFinderIndex < 0 || matchFinderIndex > 2)
+ return false;
+ int matchFinderIndexPrev = _matchFinderType;
+ _matchFinderType = matchFinderIndex;
+ if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
+ {
+ _dictionarySizePrev = -1;
+ _matchFinder = null;
+ }
+ return true;
+ }
+
+ public boolean SetLcLpPb(int lc, int lp, int pb)
+ {
+ if (
+ lp < 0 || lp > Base.kNumLitPosStatesBitsEncodingMax ||
+ lc < 0 || lc > Base.kNumLitContextBitsMax ||
+ pb < 0 || pb > Base.kNumPosStatesBitsEncodingMax)
+ return false;
+ _numLiteralPosStateBits = lp;
+ _numLiteralContextBits = lc;
+ _posStateBits = pb;
+ _posStateMask = ((1) << _posStateBits) - 1;
+ return true;
+ }
+
+ public void SetEndMarkerMode(boolean endMarkerMode)
+ {
+ _writeEndMark = endMarkerMode;
+ }
+}
+
Added: trunk/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,55 @@
+package SevenZip.Compression.RangeCoder;
+
+public class BitTreeDecoder
+{
+ short[] Models;
+ int NumBitLevels;
+
+ public BitTreeDecoder(int numBitLevels)
+ {
+ NumBitLevels = numBitLevels;
+ Models = new short[1 << numBitLevels];
+ }
+
+ public void Init()
+ {
+ Decoder.InitBitModels(Models);
+ }
+
+ public int Decode(Decoder rangeDecoder) throws java.io.IOException
+ {
+ int m = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+ m = (m << 1) + rangeDecoder.DecodeBit(Models, m);
+ return m - (1 << NumBitLevels);
+ }
+
+ public int ReverseDecode(Decoder rangeDecoder) throws java.io.IOException
+ {
+ int m = 1;
+ int symbol = 0;
+ for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ int bit = rangeDecoder.DecodeBit(Models, m);
+ m <<= 1;
+ m += bit;
+ symbol |= (bit << bitIndex);
+ }
+ return symbol;
+ }
+
+ public static int ReverseDecode(short[] Models, int startIndex,
+ Decoder rangeDecoder, int NumBitLevels) throws java.io.IOException
+ {
+ int m = 1;
+ int symbol = 0;
+ for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ int bit = rangeDecoder.DecodeBit(Models, startIndex + m);
+ m <<= 1;
+ m += bit;
+ symbol |= (bit << bitIndex);
+ }
+ return symbol;
+ }
+}
Added: trunk/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,99 @@
+package SevenZip.Compression.RangeCoder;
+import java.io.IOException;
+
+public class BitTreeEncoder
+{
+ short[] Models;
+ int NumBitLevels;
+
+ public BitTreeEncoder(int numBitLevels)
+ {
+ NumBitLevels = numBitLevels;
+ Models = new short[1 << numBitLevels];
+ }
+
+ public void Init()
+ {
+ Decoder.InitBitModels(Models);
+ }
+
+ public void Encode(Encoder rangeEncoder, int symbol) throws IOException
+ {
+ int m = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0; )
+ {
+ bitIndex--;
+ int bit = (symbol >>> bitIndex) & 1;
+ rangeEncoder.Encode(Models, m, bit);
+ m = (m << 1) | bit;
+ }
+ }
+
+ public void ReverseEncode(Encoder rangeEncoder, int symbol) throws IOException
+ {
+ int m = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ int bit = symbol & 1;
+ rangeEncoder.Encode(Models, m, bit);
+ m = (m << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+
+ public int GetPrice(int symbol)
+ {
+ int price = 0;
+ int m = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0; )
+ {
+ bitIndex--;
+ int bit = (symbol >>> bitIndex) & 1;
+ price += Encoder.GetPrice(Models[m], bit);
+ m = (m << 1) + bit;
+ }
+ return price;
+ }
+
+ public int ReverseGetPrice(int symbol)
+ {
+ int price = 0;
+ int m = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ int bit = symbol & 1;
+ symbol >>>= 1;
+ price += Encoder.GetPrice(Models[m], bit);
+ m = (m << 1) | bit;
+ }
+ return price;
+ }
+
+ public static int ReverseGetPrice(short[] Models, int startIndex,
+ int NumBitLevels, int symbol)
+ {
+ int price = 0;
+ int m = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ int bit = symbol & 1;
+ symbol >>>= 1;
+ price += Encoder.GetPrice(Models[startIndex + m], bit);
+ m = (m << 1) | bit;
+ }
+ return price;
+ }
+
+ public static void ReverseEncode(short[] Models, int startIndex,
+ Encoder rangeEncoder, int NumBitLevels, int symbol) throws IOException
+ {
+ int m = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ int bit = symbol & 1;
+ rangeEncoder.Encode(Models, startIndex + m, bit);
+ m = (m << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+}
Added: trunk/lzma/Java/SevenZip/Compression/RangeCoder/Decoder.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/RangeCoder/Decoder.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/RangeCoder/Decoder.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,88 @@
+package SevenZip.Compression.RangeCoder;
+import java.io.IOException;
+
+public class Decoder
+{
+ static final int kTopMask = ~((1 << 24) - 1);
+
+ static final int kNumBitModelTotalBits = 11;
+ static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
+ static final int kNumMoveBits = 5;
+
+ int Range;
+ int Code;
+
+ java.io.InputStream Stream;
+
+ public final void SetStream(java.io.InputStream stream)
+ {
+ Stream = stream;
+ }
+
+ public final void ReleaseStream()
+ {
+ Stream = null;
+ }
+
+ public final void Init() throws IOException
+ {
+ Code = 0;
+ Range = -1;
+ for (int i = 0; i < 5; i++)
+ Code = (Code << 8) | Stream.read();
+ }
+
+ public final int DecodeDirectBits(int numTotalBits) throws IOException
+ {
+ int result = 0;
+ for (int i = numTotalBits; i != 0; i--)
+ {
+ Range >>>= 1;
+ int t = ((Code - Range) >>> 31);
+ Code -= Range & (t - 1);
+ result = (result << 1) | (1 - t);
+
+ if ((Range & kTopMask) == 0)
+ {
+ Code = (Code << 8) | Stream.read();
+ Range <<= 8;
+ }
+ }
+ return result;
+ }
+
+ public int DecodeBit(short []probs, int index) throws IOException
+ {
+ int prob = probs[index];
+ int newBound = (Range >>> kNumBitModelTotalBits) * prob;
+ if ((Code ^ 0x80000000) < (newBound ^ 0x80000000))
+ {
+ Range = newBound;
+ probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
+ if ((Range & kTopMask) == 0)
+ {
+ Code = (Code << 8) | Stream.read();
+ Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ Range -= newBound;
+ Code -= newBound;
+ probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
+ if ((Range & kTopMask) == 0)
+ {
+ Code = (Code << 8) | Stream.read();
+ Range <<= 8;
+ }
+ return 1;
+ }
+ }
+
+ public static void InitBitModels(short []probs)
+ {
+ for (int i = 0; i < probs.length; i++)
+ probs[i] = (kBitModelTotal >>> 1);
+ }
+}
Added: trunk/lzma/Java/SevenZip/Compression/RangeCoder/Encoder.java
===================================================================
--- trunk/lzma/Java/SevenZip/Compression/RangeCoder/Encoder.java (rev 0)
+++ trunk/lzma/Java/SevenZip/Compression/RangeCoder/Encoder.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,151 @@
+package SevenZip.Compression.RangeCoder;
+import java.io.IOException;
+
+public class Encoder
+{
+ static final int kTopMask = ~((1 << 24) - 1);
+
+ static final int kNumBitModelTotalBits = 11;
+ static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
+ static final int kNumMoveBits = 5;
+
+ java.io.OutputStream Stream;
+
+ long Low;
+ int Range;
+ int _cacheSize;
+ int _cache;
+
+ long _position;
+
+ public void SetStream(java.io.OutputStream stream)
+ {
+ Stream = stream;
+ }
+
+ public void ReleaseStream()
+ {
+ Stream = null;
+ }
+
+ public void Init()
+ {
+ _position = 0;
+ Low = 0;
+ Range = -1;
+ _cacheSize = 1;
+ _cache = 0;
+ }
+
+ public void FlushData() throws IOException
+ {
+ for (int i = 0; i < 5; i++)
+ ShiftLow();
+ }
+
+ public void FlushStream() throws IOException
+ {
+ Stream.flush();
+ }
+
+ public void ShiftLow() throws IOException
+ {
+ int LowHi = (int)(Low >>> 32);
+ if (LowHi != 0 || Low < 0xFF000000L)
+ {
+ _position += _cacheSize;
+ int temp = _cache;
+ do
+ {
+ Stream.write(temp + LowHi);
+ temp = 0xFF;
+ }
+ while(--_cacheSize != 0);
+ _cache = (((int)Low) >>> 24);
+ }
+ _cacheSize++;
+ Low = (Low & 0xFFFFFF) << 8;
+ }
+
+ public void EncodeDirectBits(int v, int numTotalBits) throws IOException
+ {
+ for (int i = numTotalBits - 1; i >= 0; i--)
+ {
+ Range >>>= 1;
+ if (((v >>> i) & 1) == 1)
+ Low += Range;
+ if ((Range & Encoder.kTopMask) == 0)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+ }
+
+
+ public long GetProcessedSizeAdd()
+ {
+ return _cacheSize + _position + 4;
+ }
+
+
+
+ static final int kNumMoveReducingBits = 2;
+ public static final int kNumBitPriceShiftBits = 6;
+
+ public static void InitBitModels(short []probs)
+ {
+ for (int i = 0; i < probs.length; i++)
+ probs[i] = (kBitModelTotal >>> 1);
+ }
+
+ public void Encode(short []probs, int index, int symbol) throws IOException
+ {
+ int prob = probs[index];
+ int newBound = (Range >>> kNumBitModelTotalBits) * prob;
+ if (symbol == 0)
+ {
+ Range = newBound;
+ probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
+ }
+ else
+ {
+ Low += (newBound & 0xFFFFFFFFL);
+ Range -= newBound;
+ probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
+ }
+ if ((Range & kTopMask) == 0)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];
+
+ static
+ {
+ int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+ for (int i = kNumBits - 1; i >= 0; i--)
+ {
+ int start = 1 << (kNumBits - i - 1);
+ int end = 1 << (kNumBits - i);
+ for (int j = start; j < end; j++)
+ ProbPrices[j] = (i << kNumBitPriceShiftBits) +
+ (((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));
+ }
+ }
+
+ static public int GetPrice(int Prob, int symbol)
+ {
+ return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
+ }
+ static public int GetPrice0(int Prob)
+ {
+ return ProbPrices[Prob >>> kNumMoveReducingBits];
+ }
+ static public int GetPrice1(int Prob)
+ {
+ return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits];
+ }
+}
Added: trunk/lzma/Java/SevenZip/ICodeProgress.java
===================================================================
--- trunk/lzma/Java/SevenZip/ICodeProgress.java (rev 0)
+++ trunk/lzma/Java/SevenZip/ICodeProgress.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,6 @@
+package SevenZip;
+
+public interface ICodeProgress
+{
+ public void SetProgress(long inSize, long outSize);
+}
Added: trunk/lzma/Java/SevenZip/LzmaAlone.java
===================================================================
--- trunk/lzma/Java/SevenZip/LzmaAlone.java (rev 0)
+++ trunk/lzma/Java/SevenZip/LzmaAlone.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,253 @@
+package SevenZip;
+
+public class LzmaAlone
+{
+ static public class CommandLine
+ {
+ public static final int kEncode = 0;
+ public static final int kDecode = 1;
+ public static final int kBenchmak = 2;
+
+ public int Command = -1;
+ public int NumBenchmarkPasses = 10;
+
+ public int DictionarySize = 1 << 23;
+ public boolean DictionarySizeIsDefined = false;
+
+ public int Lc = 3;
+ public int Lp = 0;
+ public int Pb = 2;
+
+ public int Fb = 128;
+ public boolean FbIsDefined = false;
+
+ public boolean Eos = false;
+
+ public int Algorithm = 2;
+ public int MatchFinder = 1;
+
+ public String InFile;
+ public String OutFile;
+
+ boolean ParseSwitch(String s)
+ {
+ if (s.startsWith("d"))
+ {
+ DictionarySize = 1 << Integer.parseInt(s.substring(1));
+ DictionarySizeIsDefined = true;
+ }
+ else if (s.startsWith("fb"))
+ {
+ Fb = Integer.parseInt(s.substring(2));
+ FbIsDefined = true;
+ }
+ else if (s.startsWith("a"))
+ Algorithm = Integer.parseInt(s.substring(1));
+ else if (s.startsWith("lc"))
+ Lc = Integer.parseInt(s.substring(2));
+ else if (s.startsWith("lp"))
+ Lp = Integer.parseInt(s.substring(2));
+ else if (s.startsWith("pb"))
+ Pb = Integer.parseInt(s.substring(2));
+ else if (s.startsWith("eos"))
+ Eos = true;
+ else if (s.startsWith("mf"))
+ {
+ String mfs = s.substring(2);
+ if (mfs.equals("bt2"))
+ MatchFinder = 0;
+ else if (mfs.equals("bt4"))
+ MatchFinder = 1;
+ else if (mfs.equals("bt4b"))
+ MatchFinder = 2;
+ else
+ return false;
+ }
+ else
+ return false;
+ return true;
+ }
+
+ public boolean Parse(String[] args) throws Exception
+ {
+ int pos = 0;
+ boolean switchMode = true;
+ for (int i = 0; i < args.length; i++)
+ {
+ String s = args[i];
+ if (s.length() == 0)
+ return false;
+ if (switchMode)
+ {
+ if (s.compareTo("--") == 0)
+ {
+ switchMode = false;
+ continue;
+ }
+ if (s.charAt(0) == '-')
+ {
+ String sw = s.substring(1).toLowerCase();
+ if (sw.length() == 0)
+ return false;
+ try
+ {
+ if (!ParseSwitch(sw))
+ return false;
+ }
+ catch (NumberFormatException e)
+ {
+ return false;
+ }
+ continue;
+ }
+ }
+ if (pos == 0)
+ {
+ if (s.equalsIgnoreCase("e"))
+ Command = kEncode;
+ else if (s.equalsIgnoreCase("d"))
+ Command = kDecode;
+ else if (s.equalsIgnoreCase("b"))
+ Command = kBenchmak;
+ else
+ return false;
+ }
+ else if(pos == 1)
+ {
+ if (Command == kBenchmak)
+ {
+ try
+ {
+ NumBenchmarkPasses = Integer.parseInt(s);
+ if (NumBenchmarkPasses < 1)
+ return false;
+ }
+ catch (NumberFormatException e)
+ {
+ return false;
+ }
+ }
+ else
+ InFile = s;
+ }
+ else if(pos == 2)
+ OutFile = s;
+ else
+ return false;
+ pos++;
+ continue;
+ }
+ return true;
+ }
+ }
+
+
+ static void PrintHelp()
+ {
+ System.out.println(
+ "\nUsage: LZMA <e|d> [<switches>...] inputFile outputFile\n" +
+ " e: encode file\n" +
+ " d: decode file\n" +
+ " b: Benchmark\n" +
+ "<Switches>\n" +
+ // " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" +
+ " -d{N}: set dictionary - [0,28], default: 23 (8MB)\n" +
+ " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +
+ " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +
+ " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +
+ " -pb{N}: set number of pos bits - [0, 4], default: 2\n" +
+ " -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +
+ " -eos: write End Of Stream marker\n"
+ );
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ System.out.println("\nLZMA (Java) 4.42 Copyright (c) 1999-2006 Igor Pavlov 2006-05-15\n");
+
+ if (args.length < 1)
+ {
+ PrintHelp();
+ return;
+ }
+
+ CommandLine params = new CommandLine();
+ if (!params.Parse(args))
+ {
+ System.out.println("\nIncorrect command");
+ return;
+ }
+
+ if (params.Command == CommandLine.kBenchmak)
+ {
+ int dictionary = (1 << 21);
+ if (params.DictionarySizeIsDefined)
+ dictionary = params.DictionarySize;
+ if (params.MatchFinder > 1)
+ throw new Exception("Unsupported match finder");
+ SevenZip.LzmaBench.LzmaBenchmark(params.NumBenchmarkPasses, dictionary);
+ }
+ else if (params.Command == CommandLine.kEncode || params.Command == CommandLine.kDecode)
+ {
+ java.io.File inFile = new java.io.File(params.InFile);
+ java.io.File outFile = new java.io.File(params.OutFile);
+
+ java.io.BufferedInputStream inStream = new java.io.BufferedInputStream(new java.io.FileInputStream(inFile));
+ java.io.BufferedOutputStream outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outFile));
+
+ boolean eos = false;
+ if (params.Eos)
+ eos = true;
+ if (params.Command == CommandLine.kEncode)
+ {
+ SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
+ if (!encoder.SetAlgorithm(params.Algorithm))
+ throw new Exception("Incorrect compression mode");
+ if (!encoder.SetDictionarySize(params.DictionarySize))
+ throw new Exception("Incorrect dictionary size");
+ if (!encoder.SeNumFastBytes(params.Fb))
+ throw new Exception("Incorrect -fb value");
+ if (!encoder.SetMatchFinder(params.MatchFinder))
+ throw new Exception("Incorrect -mf value");
+ if (!encoder.SetLcLpPb(params.Lc, params.Lp, params.Pb))
+ throw new Exception("Incorrect -lc or -lp or -pb value");
+ encoder.SetEndMarkerMode(eos);
+ encoder.WriteCoderProperties(outStream);
+ long fileSize;
+ if (eos)
+ fileSize = -1;
+ else
+ fileSize = inFile.length();
+ for (int i = 0; i < 8; i++)
+ outStream.write((int)(fileSize >>> (8 * i)) & 0xFF);
+ encoder.Code(inStream, outStream, -1, -1, null);
+ }
+ else
+ {
+ int propertiesSize = 5;
+ byte[] properties = new byte[propertiesSize];
+ if (inStream.read(properties, 0, propertiesSize) != propertiesSize)
+ throw new Exception("input .lzma file is too short");
+ SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
+ if (!decoder.SetDecoderProperties(properties))
+ throw new Exception("Incorrect stream properties");
+ long outSize = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ int v = inStream.read();
+ if (v < 0)
+ throw new Exception("Can't read stream size");
+ outSize |= ((long)v) << (8 * i);
+ }
+ if (!decoder.Code(inStream, outStream, outSize))
+ throw new Exception("Error in data stream");
+ }
+ outStream.flush();
+ outStream.close();
+ inStream.close();
+ }
+ else
+ throw new Exception("Incorrect command");
+ return;
+ }
+}
Added: trunk/lzma/Java/SevenZip/LzmaBench.java
===================================================================
--- trunk/lzma/Java/SevenZip/LzmaBench.java (rev 0)
+++ trunk/lzma/Java/SevenZip/LzmaBench.java 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,392 @@
+package SevenZip;
+
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+public class LzmaBench
+{
+ static final int kAdditionalSize = (1 << 21);
+ static final int kCompressedAdditionalSize = (1 << 10);
+
+ static class CRandomGenerator
+ {
+ int A1;
+ int A2;
+ public CRandomGenerator() { Init(); }
+ public void Init() { A1 = 362436069; A2 = 521288629; }
+ public int GetRnd()
+ {
+ return
+ ((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 16) ^
+ ((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16)));
+ }
+ };
+
+ static class CBitRandomGenerator
+ {
+ CRandomGenerator RG = new CRandomGenerator();
+ int Value;
+ int NumBits;
+ public void Init()
+ {
+ Value = 0;
+ NumBits = 0;
+ }
+ public int GetRnd(int numBits)
+ {
+ int result;
+ if (NumBits > numBits)
+ {
+ result = Value & ((1 << numBits) - 1);
+ Value >>>= numBits;
+ NumBits -= numBits;
+ return result;
+ }
+ numBits -= NumBits;
+ result = (Value << numBits);
+ Value = RG.GetRnd();
+ result |= Value & (((int)1 << numBits) - 1);
+ Value >>>= numBits;
+ NumBits = 32 - numBits;
+ return result;
+ }
+ };
+
+ static class CBenchRandomGenerator
+ {
+ CBitRandomGenerator RG = new CBitRandomGenerator();
+ int Pos;
+ int Rep0;
+
+ public int BufferSize;
+ public byte[] Buffer = null;
+
+ public CBenchRandomGenerator() { }
+ public void Set(int bufferSize)
+ {
+ Buffer = new byte[bufferSize];
+ Pos = 0;
+ BufferSize = bufferSize;
+ }
+ int GetRndBit() { return RG.GetRnd(1); }
+ int GetLogRandBits(int numBits)
+ {
+ int len = RG.GetRnd(numBits);
+ return RG.GetRnd((int)len);
+ }
+ int GetOffset()
+ {
+ if (GetRndBit() == 0)
+ return GetLogRandBits(4);
+ return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
+ }
+ int GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }
+ int GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }
+ public void Generate()
+ {
+ RG.Init();
+ Rep0 = 1;
+ while (Pos < BufferSize)
+ {
+ if (GetRndBit() == 0 || Pos < 1)
+ Buffer[Pos++] = (byte)(RG.GetRnd(8));
+ else
+ {
+ int len;
+ if (RG.GetRnd(3) == 0)
+ len = 1 + GetLen1();
+ else
+ {
+ do
+ Rep0 = GetOffset();
+ while (Rep0 >= Pos);
+ Rep0++;
+ len = 2 + GetLen2();
+ }
+ for (int i = 0; i < len && Pos < BufferSize; i++, Pos++)
+ Buffer[Pos] = Buffer[Pos - Rep0];
+ }
+ }
+ }
+ };
+
+ static class CrcOutStream extends java.io.OutputStream
+ {
+ public CRC CRC = new CRC();
+
+ public void Init()
+ {
+ CRC.Init();
+ }
+ public int GetDigest()
+ {
+ return CRC.GetDigest();
+ }
+ public void write(byte[] b)
+ {
+ CRC.Update(b);
+ }
+ public void write(byte[] b, int off, int len)
+ {
+ CRC.Update(b, off, len);
+ }
+ public void write(int b)
+ {
+ CRC.UpdateByte(b);
+ }
+ };
+
+ static class MyOutputStream extends java.io.OutputStream
+ {
+ byte[] _buffer;
+ int _size;
+ int _pos;
+
+ public MyOutputStream(byte[] buffer)
+ {
+ _buffer = buffer;
+ _size = _buffer.length;
+ }
+
+ public void reset()
+ {
+ _pos = 0;
+ }
+
+ public void write(int b) throws IOException
+ {
+ if (_pos >= _size)
+ throw new IOException("Error");
+ _buffer[_pos++] = (byte)b;
+ }
+
+ public int size()
+ {
+ return _pos;
+ }
+ };
+
+ static class MyInputStream extends java.io.InputStream
+ {
+ byte[] _buffer;
+ int _size;
+ int _pos;
+
+ public MyInputStream(byte[] buffer, int size)
+ {
+ _buffer = buffer;
+ _size = size;
+ }
+
+ public void reset()
+ {
+ _pos = 0;
+ }
+
+ public int read()
+ {
+ if (_pos >= _size)
+ return -1;
+ return _buffer[_pos++] & 0xFF;
+ }
+ };
+
+ static class CProgressInfo implements ICodeProgress
+ {
+ public long ApprovedStart;
+ public long InSize;
+ public long Time;
+ public void Init()
+ { InSize = 0; }
+ public void SetProgress(long inSize, long outSize)
+ {
+ if (inSize >= ApprovedStart && InSize == 0)
+ {
+ Time = System.currentTimeMillis();
+ InSize = inSize;
+ }
+ }
+ }
+ static final int kSubBits = 8;
+
+ static int GetLogSize(int size)
+ {
+ for (int i = kSubBits; i < 32; i++)
+ for (int j = 0; j < (1 << kSubBits); j++)
+ if (size <= ((1) << i) + (j << (i - kSubBits)))
+ return (i << kSubBits) + j;
+ return (32 << kSubBits);
+ }
+
+ static long MyMultDiv64(long value, long elapsedTime)
+ {
+ long freq = 1000; // ms
+ long elTime = elapsedTime;
+ while (freq > 1000000)
+ {
+ freq >>>= 1;
+ elTime >>>= 1;
+ }
+ if (elTime == 0)
+ elTime = 1;
+ return value * freq / elTime;
+ }
+
+ static long GetCompressRating(int dictionarySize, long elapsedTime, long size)
+ {
+ long t = GetLogSize(dictionarySize) - (18 << kSubBits);
+ long numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
+ long numCommands = (long)(size) * numCommandsForOne;
+ return MyMultDiv64(numCommands, elapsedTime);
+ }
+
+ static long GetDecompressRating(long elapsedTime, long outSize, long inSize)
+ {
+ long numCommands = inSize * 220 + outSize * 20;
+ return MyMultDiv64(numCommands, elapsedTime);
+ }
+
+ static long GetTotalRating(
+ int dictionarySize,
+ long elapsedTimeEn, long sizeEn,
+ long elapsedTimeDe,
+ long inSizeDe, long outSizeDe)
+ {
+ return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
+ GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
+ }
+
+ static void PrintValue(long v)
+ {
+ String s = "";
+ s += v;
+ for (int i = 0; i + s.length() < 6; i++)
+ System.out.print(" ");
+ System.out.print(s);
+ }
+
+ static void PrintRating(long rating)
+ {
+ PrintValue(rating / 1000000);
+ System.out.print(" MIPS");
+ }
+
+ static void PrintResults(
+ int dictionarySize,
+ long elapsedTime,
+ long size,
+ boolean decompressMode, long secondSize)
+ {
+ long speed = MyMultDiv64(size, elapsedTime);
+ PrintValue(speed / 1024);
+ System.out.print(" KB/s ");
+ long rating;
+ if (decompressMode)
+ rating = GetDecompressRating(elapsedTime, size, secondSize);
+ else
+ rating = GetCompressRating(dictionarySize, elapsedTime, size);
+ PrintRating(rating);
+ }
+
+ static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception
+ {
+ if (numIterations <= 0)
+ return 0;
+ if (dictionarySize < (1 << 18))
+ {
+ System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)");
+ return 1;
+ }
+ System.out.print("\n Compressing Decompressing\n\n");
+
+ SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
+ SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
+
+ if (!encoder.SetDictionarySize(dictionarySize))
+ throw new Exception("Incorrect dictionary size");
+
+ int kBufferSize = dictionarySize + kAdditionalSize;
+ int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+
+ ByteArrayOutputStream propStream = new ByteArrayOutputStream();
+ encoder.WriteCoderProperties(propStream);
+ byte[] propArray = propStream.toByteArray();
+ decoder.SetDecoderProperties(propArray);
+
+ CBenchRandomGenerator rg = new CBenchRandomGenerator();
+
+ rg.Set(kBufferSize);
+ rg.Generate();
+ CRC crc = new CRC();
+ crc.Init();
+ crc.Update(rg.Buffer, 0, rg.BufferSize);
+
+ CProgressInfo progressInfo = new CProgressInfo();
+ progressInfo.ApprovedStart = dictionarySize;
+
+ long totalBenchSize = 0;
+ long totalEncodeTime = 0;
+ long totalDecodeTime = 0;
+ long totalCompressedSize = 0;
+
+ MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferSize);
+
+ byte[] compressedBuffer = new byte[kCompressedBufferSize];
+ MyOutputStream compressedStream = new MyOutputStream(compressedBuffer);
+ CrcOutStream crcOutStream = new CrcOutStream();
+ MyInputStream inputCompressedStream = null;
+ int compressedSize = 0;
+ for (int i = 0; i < numIterations; i++)
+ {
+ progressInfo.Init();
+ inStream.reset();
+ compressedStream.reset();
+ encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
+ long encodeTime = System.currentTimeMillis() - progressInfo.Time;
+
+ if (i == 0)
+ {
+ compressedSize = compressedStream.size();
+ inputCompressedStream = new MyInputStream(compressedBuffer, compressedSize);
+ }
+ else if (compressedSize != compressedStream.size())
+ throw (new Exception("Encoding error"));
+
+ if (progressInfo.InSize == 0)
+ throw (new Exception("Internal ERROR 1282"));
+
+ long decodeTime = 0;
+ for (int j = 0; j < 2; j++)
+ {
+ inputCompressedStream.reset();
+ crcOutStream.Init();
+
+ long outSize = kBufferSize;
+ long startTime = System.currentTimeMillis();
+ if (!decoder.Code(inputCompressedStream, crcOutStream, outSize))
+ throw (new Exception("Decoding Error"));;
+ decodeTime = System.currentTimeMillis() - startTime;
+ if (crcOutStream.GetDigest() != crc.GetDigest())
+ throw (new Exception("CRC Error"));
+ }
+ long benchSize = kBufferSize - (long)progressInfo.InSize;
+ PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
+ System.out.print(" ");
+ PrintResults(dictionarySize, decodeTime, kBufferSize, true, compressedSize);
+ System.out.println();
+
+ totalBenchSize += benchSize;
+ totalEncodeTime += encodeTime;
+ totalDecodeTime += decodeTime;
+ totalCompressedSize += compressedSize;
+ }
+ System.out.println("---------------------------------------------------");
+ PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
+ System.out.print(" ");
+ PrintResults(dictionarySize, totalDecodeTime,
+ kBufferSize * (long)numIterations, true, totalCompressedSize);
+ System.out.println(" Average");
+ return 0;
+ }
+}
Added: trunk/lzma/LGPL.txt
===================================================================
--- trunk/lzma/LGPL.txt (rev 0)
+++ trunk/lzma/LGPL.txt 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
Added: trunk/lzma/Methods.txt
===================================================================
--- trunk/lzma/Methods.txt (rev 0)
+++ trunk/lzma/Methods.txt 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,141 @@
+7-Zip method IDs (4.56)
+-----------------------
+
+Each compression or crypto method in 7z has unique binary value (ID).
+The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes).
+
+If you want to add some new ID, you have two ways:
+1) Write request for allocating IDs to 7-zip developers.
+2) Generate 8-bytes ID:
+
+ 7F ZZ ZZ ZZ ZZ ZZ MM MM
+
+ 7F - Prefix for random IDs (1 byte)
+ ZZ ZZ ZZ ZZ ZZ - Developer ID (5 bytes). Use real random bytes.
+
+ MM MM - Method ID (2 bytes)
+
+ You can notify 7-Zip developers about your Developer ID / Method ID.
+
+ Note: Use new ID only if old codec can not decode data encoded with new version.
+
+
+List of defined IDs
+-------------------
+
+00 - Copy
+01 - Reserved
+02 - Common
+ 03 Swap
+ - 2 Swap2
+ - 4 Swap4
+ 04 Delta (subject to change)
+
+03 - 7z
+ 01 - LZMA
+ 01 - Version
+
+ 03 - Branch
+ 01 - x86
+ 03 - BCJ
+ 1B - BCJ2
+ 02 - PPC
+ 05 - BC_PPC_B (Big Endian)
+ 03 - Alpha
+ 01 - BC_Alpha
+ 04 - IA64
+ 01 - BC_IA64
+ 05 - ARM
+ 01 - BC_ARM
+ 06 - M68
+ 05 - BC_M68_B (Big Endian)
+ 07 - ARM Thumb
+ 01 - BC_ARMThumb
+ 08 - SPARC
+ 05 - BC_SPARC
+
+ 04 - PPMD
+ 01 - Version
+
+ 7F -
+ 01 - experimental methods.
+
+ 80 - reserved for independent developers
+
+ E0 - Random IDs
+
+04 - Misc
+ 00 - Reserved
+ 01 - Zip
+ 00 - Copy (not used). Use {00} instead
+ 01 - Shrink
+ 06 - Implode
+ 08 - Deflate
+ 09 - Deflate64
+ 12 - BZip2 (not used). Use {04 02 02} instead
+ 02 - BZip
+ 02 - BZip2
+ 03 - Rar
+ 01 - Rar15
+ 02 - Rar20
+ 03 - Rar29
+ 04 - Arj
+ 01 - Arj (1,2,3)
+ 02 - Arj 4
+ 05 - Z
+ 06 - Lzh
+ 07 - Reserved for 7z
+ 08 - Cab
+ 09 - NSIS
+ 01 - DeflateNSIS
+ 02 - BZip2NSIS
+
+
+06 - Crypto
+ 00 -
+ 01 - AES
+ 0x - AES-128
+ 4x - AES-192
+ 8x - AES-256
+ Cx - AES
+
+ x0 - ECB
+ x1 - CBC
+ x2 - CFB
+ x3 - OFB
+
+ 07 - Reserved
+ 0F - Reserved
+
+ F0 - Misc Ciphers (Real Ciphers without hashing algo)
+
+ F1 - Misc Ciphers (Combine)
+ 01 - Zip
+ 01 - Main Zip crypto algo
+ 03 - RAR
+ 02 -
+ 03 - Rar29 AES-128 + (modified SHA-1)
+ 07 - 7z
+ 01 - AES-256 + SHA-256
+
+07 - Hash (subject to change)
+ 00 -
+ 01 - CRC
+ 02 - SHA-1
+ 03 - SHA-256
+ 04 - SHA-384
+ 05 - SHA-512
+
+ F0 - Misc Hash
+
+ F1 - Misc
+ 03 - RAR
+ 03 - Rar29 Password Hashing (modified SHA1)
+ 07 - 7z
+ 01 - SHA-256 Password Hashing
+
+
+
+
+---
+End of document
Added: trunk/lzma/history.txt
===================================================================
--- trunk/lzma/history.txt (rev 0)
+++ trunk/lzma/history.txt 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,198 @@
+HISTORY of the LZMA SDK
+-----------------------
+
+ 4.57 2007-12-12
+ -------------------------
+ - Speed optimizations in Ñ++ LZMA Decoder.
+ - Small changes for more compatibility with some C/C++ compilers.
+
+
+ 4.49 beta 2007-07-05
+ -------------------------
+ - .7z ANSI-C Decoder:
+ - now it supports BCJ and BCJ2 filters
+ - now it supports files larger than 4 GB.
+ - now it supports "Last Write Time" field for files.
+ - C++ code for .7z archives compressing/decompressing from 7-zip
+ was included to LZMA SDK.
+
+
+ 4.43 2006-06-04
+ -------------------------
+ - Small changes for more compatibility with some C/C++ compilers.
+
+
+ 4.42 2006-05-15
+ -------------------------
+ - Small changes in .h files in ANSI-C version.
+
+
+ 4.39 beta 2006-04-14
+ -------------------------
+ - Bug in versions 4.33b:4.38b was fixed:
+ C++ version of LZMA encoder could not correctly compress
+ files larger than 2 GB with HC4 match finder (-mfhc4).
+
+
+ 4.37 beta 2005-04-06
+ -------------------------
+ - Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
+
+
+ 4.35 beta 2005-03-02
+ -------------------------
+ - Bug was fixed in C++ version of LZMA Decoder:
+ If encoded stream was corrupted, decoder could access memory
+ outside of allocated range.
+
+
+ 4.34 beta 2006-02-27
+ -------------------------
+ - Compressing speed and memory requirements for compressing were increased
+ - LZMA now can use only these match finders: HC4, BT2, BT3, BT4
+
+
+ 4.32 2005-12-09
+ -------------------------
+ - Java version of LZMA SDK was included
+
+
+ 4.30 2005-11-20
+ -------------------------
+ - Compression ratio was improved in -a2 mode
+ - Speed optimizations for compressing in -a2 mode
+ - -fb switch now supports values up to 273
+ - Bug in 7z_C (7zIn.c) was fixed:
+ It used Alloc/Free functions from different memory pools.
+ So if program used two memory pools, it worked incorrectly.
+ - 7z_C: .7z format supporting was improved
+ - LZMA# SDK (C#.NET version) was included
+
+
+ 4.27 (Updated) 2005-09-21
+ -------------------------
+ - Some GUIDs/interfaces in C++ were changed.
+ IStream.h:
+ ISequentialInStream::Read now works as old ReadPart
+ ISequentialOutStream::Write now works as old WritePart
+
+
+ 4.27 2005-08-07
+ -------------------------
+ - Bug in LzmaDecodeSize.c was fixed:
+ if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
+ decompressing worked incorrectly.
+
+
+ 4.26 2005-08-05
+ -------------------------
+ - Fixes in 7z_C code and LzmaTest.c:
+ previous versions could work incorrectly,
+ if malloc(0) returns 0
+
+
+ 4.23 2005-06-29
+ -------------------------
+ - Small fixes in C++ code
+
+
+ 4.22 2005-06-10
+ -------------------------
+ - Small fixes
+
+
+ 4.21 2005-06-08
+ -------------------------
+ - Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
+ - New additional version of ANSI-C LZMA Decoder with zlib-like interface:
+ - LzmaStateDecode.h
+ - LzmaStateDecode.c
+ - LzmaStateTest.c
+ - ANSI-C LZMA Decoder now can decompress files larger than 4 GB
+
+
+ 4.17 2005-04-18
+ -------------------------
+ - New example for RAM->RAM compressing/decompressing:
+ LZMA + BCJ (filter for x86 code):
+ - LzmaRam.h
+ - LzmaRam.cpp
+ - LzmaRamDecode.h
+ - LzmaRamDecode.c
+ - -f86 switch for lzma.exe
+
+
+ 4.16 2005-03-29
+ -------------------------
+ - Bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
+ If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
+ decoder could access memory outside of allocated range.
+ - Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
+ Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
+ LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
+ - Small speed optimization in LZMA C++ code
+ - filter for SPARC's code was added
+ - Simplified version of .7z ANSI-C Decoder was included
+
+
+ 4.06 2004-09-05
+ -------------------------
+ - Bug in v4.05 was fixed:
+ LZMA-Encoder didn't release output stream in some cases.
+
+
+ 4.05 2004-08-25
+ -------------------------
+ - Source code of filters for x86, IA-64, ARM, ARM-Thumb
+ and PowerPC code was included to SDK
+ - Some internal minor changes
+
+
+ 4.04 2004-07-28
+ -------------------------
+ - More compatibility with some C++ compilers
+
+
+ 4.03 2004-06-18
+ -------------------------
+ - "Benchmark" command was added. It measures compressing
+ and decompressing speed and shows rating values.
+ Also it checks hardware errors.
+
+
+ 4.02 2004-06-10
+ -------------------------
+ - C++ LZMA Encoder/Decoder code now is more portable
+ and it can be compiled by GCC on Linux.
+
+
+ 4.01 2004-02-15
+ -------------------------
+ - Some detection of data corruption was enabled.
+ LzmaDecode.c / RangeDecoderReadByte
+ .....
+ {
+ rd->ExtraBytes = 1;
+ return 0xFF;
+ }
+
+
+ 4.00 2004-02-13
+ -------------------------
+ - Original version of LZMA SDK
+
+
+
+HISTORY of the LZMA
+-------------------
+ 2001-2007: Improvements to LZMA compressing/decompressing code,
+ keeping compatibility with original LZMA format
+ 1996-2001: Development of LZMA compression format
+
+ Some milestones:
+
+ 2001-08-30: LZMA compression was added to 7-Zip
+ 1999-01-02: First version of 7-Zip was released
+
+
+End of document
Added: trunk/lzma/lzma.exe
===================================================================
(Binary files differ)
Property changes on: trunk/lzma/lzma.exe
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/lzma/lzma.txt
===================================================================
--- trunk/lzma/lzma.txt (rev 0)
+++ trunk/lzma/lzma.txt 2008-01-23 03:52:35 UTC (rev 923)
@@ -0,0 +1,663 @@
+LZMA SDK 4.57
+-------------
+
+LZMA SDK Copyright (C) 1999-2007 Igor Pavlov
+
+LZMA SDK provides the documentation, samples, header files, libraries,
+and tools you need to develop applications that use LZMA compression.
+
+LZMA is default and general compression method of 7z format
+in 7-Zip compression program (www.7-zip.org). LZMA provides high
+compression ratio and very fast decompression.
+
+LZMA is an improved version of famous LZ77 compression algorithm.
+It was improved in way of maximum increasing of compression ratio,
+keeping high decompression speed and low memory requirements for
+decompressing.
+
+
+
+LICENSE
+-------
+
+LZMA SDK is available under any of the following licenses:
+
+1) GNU Lesser General Public License (GNU LGPL)
+2) Common Public License (CPL)
+3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
+4) Proprietary license
+
+It means that you can select one of these four options and follow rules of that license.
+
+
+1,2) GNU LGPL and CPL licenses are pretty similar and both these
+licenses are classified as
+ - "Free software licenses" at http://www.gnu.org/
+ - "OSI-approved" at http://www.opensource.org/
+
+
+3) SPECIAL EXCEPTION
+
+Igor Pavlov, as the author of this code, expressly permits you
+to statically or dynamically link your code (or bind by name)
+to the files from LZMA SDK without subjecting your linked
+code to the terms of the CPL or GNU LGPL.
+Any modifications or additions to files from LZMA SDK, however,
+are subject to the GNU LGPL or CPL terms.
+
+SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
+while you keep LZMA SDK code unmodified.
+
+
+SPECIAL EXCEPTION #2: Igor Pavlov, as the author of this code, expressly permits
+you to use this code under the same terms and conditions contained in the License
+Agreement you have for any previous version of LZMA SDK developed by Igor Pavlov.
+
+SPECIAL EXCEPTION #2 allows owners of proprietary licenses to use latest version
+of LZMA SDK as update for previous versions.
+
+
+SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits
+you to use code of the following files:
+BranchTypes.h, LzmaTypes.h, LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp,
+LzmaAlone.cs, LzmaAlone.java
+as public domain code.
+
+
+4) Proprietary license
+
+LZMA SDK also can be available under a proprietary license which
+can include:
+
+1) Right to modify code without subjecting modified code to the
+terms of the CPL or GNU LGPL
+2) Technical support for code
+
+To request such proprietary license or any additional consultations,
+send email message from that page:
+http://www.7-zip.org/support.html
+
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You should have received a copy of the Common Public License
+along with this library.
+
+
+LZMA SDK Contents
+-----------------
+
+LZMA SDK includes:
+
+ - C++ source code of LZMA compressing and decompressing
+ - ANSI-C compatible source code for LZMA decompressing
+ - C# source code for LZMA compressing and decompressing
+ - Java source code for LZMA compressing and decompressing
+ - Compiled file->file LZMA compressing/decompressing program for Windows system
+
+ANSI-C LZMA decompression code was ported from original C++ sources to C.
+Also it was simplified and optimized for code size.
+But it is fully compatible with LZMA from 7-Zip.
+
+
+UNIX/Linux version
+------------------
+To compile C++ version of file->file LZMA, go to directory
+C/7zip/Compress/LZMA_Alone
+and type "make" or "make clean all" to recompile all.
+
+In some UNIX/Linux versions you must compile LZMA with static libraries.
+To compile with static libraries, change string in makefile
+LIB = -lm
+to string
+LIB = -lm -static
+
+
+Files
+---------------------
+C - C source code
+CPP - CPP source code
+CS - C# source code
+Java - Java source code
+lzma.txt - LZMA SDK description (this file)
+7zFormat.txt - 7z Format description
+7zC.txt - 7z ANSI-C Decoder description (this file)
+methods.txt - Compression method IDs for .7z
+LGPL.txt - GNU Lesser General Public License
+CPL.html - Common Public License
+lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
+history.txt - history of the LZMA SDK
+
+
+Source code structure
+---------------------
+
+C - C files
+ Compress - files related to compression/decompression
+ Lz - files related to LZ (Lempel-Ziv) compression algorithm
+ Lzma - ANSI-C compatible LZMA decompressor
+
+ LzmaDecode.h - interface for LZMA decoding on ANSI-C
+ LzmaDecode.c - LZMA decoding on ANSI-C (new fastest version)
+ LzmaDecodeSize.c - LZMA decoding on ANSI-C (old size-optimized version)
+ LzmaTest.c - test application that decodes LZMA encoded file
+ LzmaTypes.h - basic types for LZMA Decoder
+ LzmaStateDecode.h - interface for LZMA decoding (State version)
+ LzmaStateDecode.c - LZMA decoding on ANSI-C (State version)
+ LzmaStateTest.c - test application (State version)
+
+ Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
+
+ Archive - files related to archiving
+ 7z_C - 7z ANSI-C Decoder
+
+
+CPP -- CPP files
+
+ Common - common files for C++ projects
+ Windows - common files for Windows related code
+ 7zip - files related to 7-Zip Project
+
+ Common - common files for 7-Zip
+
+ Compress - files related to compression/decompression
+
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+
+ Copy - Copy coder
+ RangeCoder - Range Coder (special code of compression/decompression)
+ LZMA - LZMA compression/decompression on C++
+ LZMA_Alone - file->file LZMA compression/decompression
+
+ Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
+
+ Archive - files related to archiving
+
+ Common - common files for archive handling
+ 7z - 7z C++ Encoder/Decoder
+
+ Bundles - Modules that are bundles of other modules
+
+ Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
+ Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
+ Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
+
+ UI - User Interface files
+
+ Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
+ Common - Common UI files
+ Console - Code for console archiver
+
+
+
+CS - C# files
+ 7zip
+ Common - some common files for 7-Zip
+ Compress - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ LzmaAlone - file->file LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+Java - Java files
+ SevenZip
+ Compression - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+C/C++ source code of LZMA SDK is part of 7-Zip project.
+
+You can find ANSI-C LZMA decompressing code at folder
+ C/7zip/Compress/Lzma
+7-Zip doesn't use that ANSI-C LZMA code and that code was developed
+specially for this SDK. And files from C/7zip/Compress/Lzma do not need
+files from other directories of SDK for compiling.
+
+7-Zip source code can be downloaded from 7-Zip's SourceForge page:
+
+ http://sourceforge.net/projects/sevenzip/
+
+
+LZMA features
+-------------
+ - Variable dictionary size (up to 1 GB)
+ - Estimated compressing speed: about 1 MB/s on 1 GHz CPU
+ - Estimated decompressing speed:
+ - 8-12 MB/s on 1 GHz Intel Pentium 3 or AMD Athlon
+ - 500-1000 KB/s on 100 MHz ARM, MIPS, PowerPC or other simple RISC
+ - Small memory requirements for decompressing (8-32 KB + DictionarySize)
+ - Small code size for decompressing: 2-8 KB (depending from
+ speed optimizations)
+
+LZMA decoder uses only integer operations and can be
+implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
+
+Some critical operations that affect to speed of LZMA decompression:
+ 1) 32*16 bit integer multiply
+ 2) Misspredicted branches (penalty mostly depends from pipeline length)
+ 3) 32-bit shift and arithmetic operations
+
+Speed of LZMA decompressing mostly depends from CPU speed.
+Memory speed has no big meaning. But if your CPU has small data cache,
+overall weight of memory speed will slightly increase.
+
+
+How To Use
+----------
+
+Using LZMA encoder/decoder executable
+--------------------------------------
+
+Usage: LZMA <e|d> inputFile outputFile [<switches>...]
+
+ e: encode file
+
+ d: decode file
+
+ b: Benchmark. There are two tests: compressing and decompressing
+ with LZMA method. Benchmark shows rating in MIPS (million
+ instructions per second). Rating value is calculated from
+ measured speed and it is normalized with AMD Athlon 64 X2 CPU
+ results. Also Benchmark checks possible hardware errors (RAM
+ errors in most cases). Benchmark uses these settings:
+ (-a1, -d21, -fb32, -mfbt4). You can change only -d. Also you
+ can change number of iterations. Example for 30 iterations:
+ LZMA b 30
+ Default number of iterations is 10.
+
+<Switches>
+
+
+ -a{N}: set compression mode 0 = fast, 1 = normal
+ default: 1 (normal)
+
+ d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
+ The maximum value for dictionary size is 1 GB = 2^30 bytes.
+ Dictionary size is calculated as DictionarySize = 2^N bytes.
+ For decompressing file compressed by LZMA method with dictionary
+ size D = 2^N you need about D bytes of memory (RAM).
+
+ -fb{N}: set number of fast bytes - [5, 273], default: 128
+ Usually big number gives a little bit better compression ratio
+ and slower compression process.
+
+ -lc{N}: set number of literal context bits - [0, 8], default: 3
+ Sometimes lc=4 gives gain for big files.
+
+ -lp{N}: set number of literal pos bits - [0, 4], default: 0
+ lp switch is intended for periodical data when period is
+ equal 2^N. For example, for 32-bit (4 bytes)
+ periodical data you can use lp=2. Often it's better to set lc0,
+ if you change lp switch.
+
+ -pb{N}: set number of pos bits - [0, 4], default: 2
+ pb switch is intended for periodical data
+ when period is equal 2^N.
+
+ -mf{MF_ID}: set Match Finder. Default: bt4.
+ Algorithms from hc* group doesn't provide good compression
+ ratio, but they often works pretty fast in combination with
+ fast mode (-a0).
+
+ Memory requirements depend from dictionary size
+ (parameter "d" in table below).
+
+ MF_ID Memory Description
+
+ bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
+ bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
+ bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
+ hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
+
+ -eos: write End Of Stream marker. By default LZMA doesn't write
+ eos marker, since LZMA decoder knows uncompressed size
+ stored in .lzma file header.
+
+ -si: Read data from stdin (it will write End Of Stream marker).
+ -so: Write data to stdout
+
+
+Examples:
+
+1) LZMA e file.bin file.lzma -d16 -lc0
+
+compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
+and 0 literal context bits. -lc0 allows to reduce memory requirements
+for decompression.
+
+
+2) LZMA e file.bin file.lzma -lc0 -lp2
+
+compresses file.bin to file.lzma with settings suitable
+for 32-bit periodical data (for example, ARM or MIPS code).
+
+3) LZMA d file.lzma file.bin
+
+decompresses file.lzma to file.bin.
+
+
+Compression ratio hints
+-----------------------
+
+Recommendations
+---------------
+
+To increase compression ratio for LZMA compressing it's desirable
+to have aligned data (if it's possible) and also it's desirable to locate
+data in such order, where code is grouped in one place and data is
+grouped in other place (it's better than such mixing: code, data, code,
+data, ...).
+
+
+Using Filters
+-------------
+You can increase compression ratio for some data types, using
+special filters before compressing. For example, it's possible to
+increase compression ratio on 5-10% for code for those CPU ISAs:
+x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
+
+You can find C/C++ source code of such filters in folder "7zip/Compress/Branch"
+
+You can check compression ratio gain of these filters with such
+7-Zip commands (example for ARM code):
+No filter:
+ 7z a a1.7z a.bin -m0=lzma
+
+With filter for little-endian ARM code:
+ 7z a a2.7z a.bin -m0=bc_arm -m1=lzma
+
+With filter for big-endian ARM code (using additional Swap4 filter):
+ 7z a a3.7z a.bin -m0=swap4 -m1=bc_arm -m2=lzma
+
+It works in such manner:
+Compressing = Filter_encoding + LZMA_encoding
+Decompressing = LZMA_decoding + Filter_decoding
+
+Compressing and decompressing speed of such filters is very high,
+so it will not increase decompressing time too much.
+Moreover, it reduces decompression time for LZMA_decoding,
+since compression ratio with filtering is higher.
+
+These filters convert CALL (calling procedure) instructions
+from relative offsets to absolute addresses, so such data becomes more
+compressible. Source code of these CALL filters is pretty simple
+(about 20 lines of C++), so you can convert it from C++ version yourself.
+
+For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
+
+
+LZMA compressed file format
+---------------------------
+Offset Size Description
+ 0 1 Special LZMA properties for compressed data
+ 1 4 Dictionary size (little endian)
+ 5 8 Uncompressed size (little endian). -1 means unknown size
+ 13 Compressed data
+
+
+ANSI-C LZMA Decoder
+~~~~~~~~~~~~~~~~~~~
+
+To compile ANSI-C LZMA Decoder you can use one of the following files sets:
+1) LzmaDecode.h + LzmaDecode.c + LzmaTest.c (fastest version)
+2) LzmaDecode.h + LzmaDecodeSize.c + LzmaTest.c (old size-optimized version)
+3) LzmaStateDecode.h + LzmaStateDecode.c + LzmaStateTest.c (zlib-like interface)
+
+
+Memory requirements for LZMA decoding
+-------------------------------------
+
+LZMA decoder doesn't allocate memory itself, so you must
+allocate memory and send it to LZMA.
+
+Stack usage of LZMA decoding function for local variables is not
+larger than 200 bytes.
+
+How To decompress data
+----------------------
+
+LZMA Decoder (ANSI-C version) now supports 5 interfaces:
+1) Single-call Decompressing
+2) Single-call Decompressing with input stream callback
+3) Multi-call Decompressing with output buffer
+4) Multi-call Decompressing with input callback and output buffer
+5) Multi-call State Decompressing (zlib-like interface)
+
+Variant-5 is similar to Variant-4, but Variant-5 doesn't use callback functions.
+
+Decompressing steps
+-------------------
+
+1) read LZMA properties (5 bytes):
+ unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+2) read uncompressed size (8 bytes, little-endian)
+
+3) Decode properties:
+
+ CLzmaDecoderState state; /* it's 24-140 bytes structure, if int is 32-bit */
+
+ if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return PrintError(rs, "Incorrect stream properties");
+
+4) Allocate memory block for internal Structures:
+
+ state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return PrintError(rs, kCantAllocateMessage);
+
+ LZMA decoder uses array of CProb variables as internal structure.
+ By default, CProb is unsigned_short. But you can define _LZMA_PROB32 to make
+ it unsigned_int. It can increase speed on some 32-bit CPUs, but memory
+ usage will be doubled in that case.
+
+
+5) Main Decompressing
+
+You must use one of the following interfaces:
+
+5.1 Single-call Decompressing
+-----------------------------
+When to use: RAM->RAM decompressing
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: no defines
+Memory Requirements:
+ - Input buffer: compressed size
+ - Output buffer: uncompressed size
+ - LZMA Internal Structures (~16 KB for default settings)
+
+Interface:
+ int res = LzmaDecode(&state,
+ inStream, compressedSize, &inProcessed,
+ outStream, outSize, &outProcessed);
+
+
+5.2 Single-call Decompressing with input stream callback
+--------------------------------------------------------
+When to use: File->RAM or Flash->RAM decompressing.
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_IN_CB
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Output buffer: uncompressed size
+ - LZMA Internal Structures (~16 KB for default settings)
+
+Interface:
+ typedef struct _CBuffer
+ {
+ ILzmaInCallback InCallback;
+ FILE *File;
+ unsigned char Buffer[kInBufferSize];
+ } CBuffer;
+
+ int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
+ {
+ CBuffer *bo = (CBuffer *)object;
+ *buffer = bo->Buffer;
+ *size = MyReadFile(bo->File, bo->Buffer, kInBufferSize);
+ return LZMA_RESULT_OK;
+ }
+
+ CBuffer g_InBuffer;
+
+ g_InBuffer.File = inFile;
+ g_InBuffer.InCallback.Read = LzmaReadCompressed;
+ int res = LzmaDecode(&state,
+ &g_InBuffer.InCallback,
+ outStream, outSize, &outProcessed);
+
+
+5.3 Multi-call decompressing with output buffer
+-----------------------------------------------
+When to use: RAM->File decompressing
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_OUT_READ
+Memory Requirements:
+ - Input buffer: compressed size
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings)
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+
+Interface:
+
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+
+ LzmaDecoderInit(&state);
+ do
+ {
+ LzmaDecode(&state,
+ inBuffer, inAvail, &inProcessed,
+ g_OutBuffer, outAvail, &outProcessed);
+ inAvail -= inProcessed;
+ inBuffer += inProcessed;
+ }
+ while you need more bytes
+
+ see LzmaTest.c for more details.
+
+
+5.4 Multi-call decompressing with input callback and output buffer
+------------------------------------------------------------------
+When to use: File->File decompressing
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_IN_CB, _LZMA_OUT_READ
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings)
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+
+Interface:
+
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+
+ LzmaDecoderInit(&state);
+ do
+ {
+ LzmaDecode(&state,
+ &bo.InCallback,
+ g_OutBuffer, outAvail, &outProcessed);
+ }
+ while you need more bytes
+
+ see LzmaTest.c for more details:
+
+
+5.5 Multi-call State Decompressing (zlib-like interface)
+------------------------------------------------------------------
+When to use: file->file decompressing
+Compile files: LzmaStateDecode.h, LzmaStateDecode.c
+Compile defines:
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings)
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+
+Interface:
+
+ state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+
+
+ LzmaDecoderInit(&state);
+ do
+ {
+ res = LzmaDecode(&state,
+ inBuffer, inAvail, &inProcessed,
+ g_OutBuffer, outAvail, &outProcessed,
+ finishDecoding);
+ inAvail -= inProcessed;
+ inBuffer += inProcessed;
+ }
+ while you need more bytes
+
+ see LzmaStateTest.c for more details:
+
+
+6) Free all allocated blocks
+
+
+Note
+----
+LzmaDecodeSize.c is size-optimized version of LzmaDecode.c.
+But compiled code of LzmaDecodeSize.c can be larger than
+compiled code of LzmaDecode.c. So it's better to use
+LzmaDecode.c in most cases.
+
+
+EXIT codes
+-----------
+
+LZMA decoder can return one of the following codes:
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+If you use callback function for input data and you return some
+error code, LZMA Decoder also returns that code.
+
+
+
+LZMA Defines
+------------
+
+_LZMA_IN_CB - Use callback for input data
+
+_LZMA_OUT_READ - Use read function for output data
+
+_LZMA_LOC_OPT - Enable local speed optimizations inside code.
+ _LZMA_LOC_OPT is only for LzmaDecodeSize.c (size-optimized version).
+ _LZMA_LOC_OPT doesn't affect LzmaDecode.c (speed-optimized version)
+ and LzmaStateDecode.c
+
+_LZMA_PROB32 - It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case
+
+_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler
+ and long is 32-bit.
+
+_LZMA_SYSTEM_SIZE_T - Define it if you want to use system's size_t.
+ You can use it to enable 64-bit sizes supporting
+
+
+
+C++ LZMA Encoder/Decoder
+~~~~~~~~~~~~~~~~~~~~~~~~
+C++ LZMA code use COM-like interfaces. So if you want to use it,
+you can study basics of COM/OLE.
+
+By default, LZMA Encoder contains all Match Finders.
+But for compressing it's enough to have just one of them.
+So for reducing size of compressing code you can define:
+ #define COMPRESS_MF_BT
+ #define COMPRESS_MF_BT4
+and it will use only bt4 match finder.
+
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/support.html
More information about the physfs-commits
mailing list