From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- release/src/linux/linux/scripts/squashfs/Makefile | 34 +- release/src/linux/linux/scripts/squashfs/global.h | 46 + .../src/linux/linux/scripts/squashfs/lzma/7zC.txt | 235 +++ .../linux/linux/scripts/squashfs/lzma/7zFormat.txt | 471 ++++++ .../squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.c | 70 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.h | 20 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.c | 29 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.h | 19 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.c | 76 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.h | 24 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.c | 150 ++ .../squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.h | 21 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.c | 116 ++ .../squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.h | 40 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.c | 5 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.h | 55 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zIn.c | 1292 +++++++++++++++++ .../squashfs/lzma/C/7zip/Archive/7z_C/7zIn.h | 55 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zItem.c | 133 ++ .../squashfs/lzma/C/7zip/Archive/7z_C/7zItem.h | 90 ++ .../squashfs/lzma/C/7zip/Archive/7z_C/7zMain.c | 223 +++ .../squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.c | 14 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.h | 18 + .../squashfs/lzma/C/7zip/Archive/7z_C/7zTypes.h | 61 + .../squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsp | 178 +++ .../squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsw | 29 + .../squashfs/lzma/C/7zip/Archive/7z_C/makefile | 55 + .../squashfs/lzma/C/7zip/Archive/7z_C/makefile.gcc | 50 + .../squashfs/lzma/C/7zip/Common/FileStreams.cpp | 251 ++++ .../squashfs/lzma/C/7zip/Common/FileStreams.h | 98 ++ .../squashfs/lzma/C/7zip/Common/InBuffer.cpp | 80 ++ .../scripts/squashfs/lzma/C/7zip/Common/InBuffer.h | 76 + .../squashfs/lzma/C/7zip/Common/OutBuffer.cpp | 117 ++ .../squashfs/lzma/C/7zip/Common/OutBuffer.h | 64 + .../scripts/squashfs/lzma/C/7zip/Common/StdAfx.h | 9 + .../squashfs/lzma/C/7zip/Common/StreamUtils.cpp | 44 + .../squashfs/lzma/C/7zip/Common/StreamUtils.h | 11 + .../squashfs/lzma/C/7zip/Compress/Branch/ARM.cpp | 16 + .../squashfs/lzma/C/7zip/Compress/Branch/ARM.h | 10 + .../lzma/C/7zip/Compress/Branch/ARMThumb.cpp | 16 + .../lzma/C/7zip/Compress/Branch/ARMThumb.h | 10 + .../lzma/C/7zip/Compress/Branch/BranchARM.c | 26 + .../lzma/C/7zip/Compress/Branch/BranchARM.h | 10 + .../lzma/C/7zip/Compress/Branch/BranchARMThumb.c | 35 + .../lzma/C/7zip/Compress/Branch/BranchARMThumb.h | 10 + .../lzma/C/7zip/Compress/Branch/BranchCoder.cpp | 18 + .../lzma/C/7zip/Compress/Branch/BranchCoder.h | 54 + .../lzma/C/7zip/Compress/Branch/BranchIA64.c | 65 + .../lzma/C/7zip/Compress/Branch/BranchIA64.h | 10 + .../lzma/C/7zip/Compress/Branch/BranchPPC.c | 36 + .../lzma/C/7zip/Compress/Branch/BranchPPC.h | 10 + .../lzma/C/7zip/Compress/Branch/BranchSPARC.c | 36 + .../lzma/C/7zip/Compress/Branch/BranchSPARC.h | 10 + .../lzma/C/7zip/Compress/Branch/BranchX86.c | 101 ++ .../lzma/C/7zip/Compress/Branch/BranchX86.h | 19 + .../squashfs/lzma/C/7zip/Compress/Branch/IA64.cpp | 16 + .../squashfs/lzma/C/7zip/Compress/Branch/IA64.h | 10 + .../squashfs/lzma/C/7zip/Compress/Branch/PPC.cpp | 17 + .../squashfs/lzma/C/7zip/Compress/Branch/PPC.h | 10 + .../squashfs/lzma/C/7zip/Compress/Branch/SPARC.cpp | 17 + .../squashfs/lzma/C/7zip/Compress/Branch/SPARC.h | 10 + .../squashfs/lzma/C/7zip/Compress/Branch/StdAfx.h | 8 + .../squashfs/lzma/C/7zip/Compress/Branch/x86.cpp | 18 + .../squashfs/lzma/C/7zip/Compress/Branch/x86.h | 19 + .../squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp | 412 ++++++ .../squashfs/lzma/C/7zip/Compress/Branch/x86_2.h | 133 ++ .../lzma/C/7zip/Compress/LZ/BinTree/BinTree.h | 55 + .../lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h | 12 + .../lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h | 16 + .../lzma/C/7zip/Compress/LZ/BinTree/BinTree3Z.h | 16 + .../lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h | 18 + .../lzma/C/7zip/Compress/LZ/BinTree/BinTree4b.h | 20 + .../lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h | 444 ++++++ .../lzma/C/7zip/Compress/LZ/HashChain/HC.h | 55 + .../lzma/C/7zip/Compress/LZ/HashChain/HC2.h | 13 + .../lzma/C/7zip/Compress/LZ/HashChain/HC3.h | 17 + .../lzma/C/7zip/Compress/LZ/HashChain/HC4.h | 19 + .../lzma/C/7zip/Compress/LZ/HashChain/HC4b.h | 21 + .../lzma/C/7zip/Compress/LZ/HashChain/HCMain.h | 350 +++++ .../lzma/C/7zip/Compress/LZ/IMatchFinder.h | 63 + .../lzma/C/7zip/Compress/LZ/LZInWindow.cpp | 102 ++ .../squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.h | 84 ++ .../lzma/C/7zip/Compress/LZ/LZOutWindow.cpp | 17 + .../squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.h | 64 + .../lzma/C/7zip/Compress/LZ/Patricia/Pat.h | 318 +++++ .../lzma/C/7zip/Compress/LZ/Patricia/Pat2.h | 22 + .../lzma/C/7zip/Compress/LZ/Patricia/Pat2H.h | 24 + .../lzma/C/7zip/Compress/LZ/Patricia/Pat2R.h | 20 + .../lzma/C/7zip/Compress/LZ/Patricia/Pat3H.h | 24 + .../lzma/C/7zip/Compress/LZ/Patricia/Pat4H.h | 24 + .../lzma/C/7zip/Compress/LZ/Patricia/PatMain.h | 989 +++++++++++++ .../squashfs/lzma/C/7zip/Compress/LZ/StdAfx.h | 6 + .../squashfs/lzma/C/7zip/Compress/LZMA/LZMA.h | 82 ++ .../lzma/C/7zip/Compress/LZMA/LZMADecoder.cpp | 342 +++++ .../lzma/C/7zip/Compress/LZMA/LZMADecoder.h | 249 ++++ .../lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp | 1504 ++++++++++++++++++++ .../lzma/C/7zip/Compress/LZMA/LZMAEncoder.h | 416 ++++++ .../squashfs/lzma/C/7zip/Compress/LZMA/StdAfx.h | 8 + .../lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp | 523 +++++++ .../lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw | 29 + .../lzma/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp | 509 +++++++ .../lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp | 508 +++++++ .../lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.h | 11 + .../lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp | 228 +++ .../lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.h | 46 + .../C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c | 79 + .../C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h | 55 + .../lzma/C/7zip/Compress/LZMA_Alone/StdAfx.cpp | 3 + .../lzma/C/7zip/Compress/LZMA_Alone/StdAfx.h | 8 + .../lzma/C/7zip/Compress/LZMA_Alone/makefile | 100 ++ .../lzma/C/7zip/Compress/LZMA_Alone/makefile.gcc | 113 ++ .../lzma/C/7zip/Compress/LZMA_C/LzmaDecode.c | 588 ++++++++ .../lzma/C/7zip/Compress/LZMA_C/LzmaDecode.h | 131 ++ .../lzma/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c | 716 ++++++++++ .../lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.c | 521 +++++++ .../lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.h | 115 ++ .../lzma/C/7zip/Compress/LZMA_C/LzmaStateTest.c | 195 +++ .../lzma/C/7zip/Compress/LZMA_C/LzmaTest.c | 342 +++++ .../squashfs/lzma/C/7zip/Compress/LZMA_C/makefile | 43 + .../lzma/C/7zip/Compress/LZMA_C/makefile.gcc | 23 + .../lzma/C/7zip/Compress/LZMA_Lib/ZLib.cpp | 273 ++++ .../lzma/C/7zip/Compress/LZMA_Lib/makefile | 92 ++ .../lzma/C/7zip/Compress/RangeCoder/RangeCoder.h | 205 +++ .../C/7zip/Compress/RangeCoder/RangeCoderBit.cpp | 80 ++ .../C/7zip/Compress/RangeCoder/RangeCoderBit.h | 120 ++ .../C/7zip/Compress/RangeCoder/RangeCoderBitTree.h | 161 +++ .../C/7zip/Compress/RangeCoder/RangeCoderOpt.h | 31 + .../lzma/C/7zip/Compress/RangeCoder/StdAfx.h | 6 + .../linux/scripts/squashfs/lzma/C/7zip/ICoder.h | 156 ++ .../linux/scripts/squashfs/lzma/C/7zip/IStream.h | 62 + .../linux/scripts/squashfs/lzma/C/Common/Alloc.cpp | 118 ++ .../linux/scripts/squashfs/lzma/C/Common/Alloc.h | 29 + .../linux/scripts/squashfs/lzma/C/Common/CRC.cpp | 61 + .../linux/scripts/squashfs/lzma/C/Common/CRC.h | 36 + .../scripts/squashfs/lzma/C/Common/C_FileIO.cpp | 78 + .../scripts/squashfs/lzma/C/Common/C_FileIO.h | 45 + .../linux/scripts/squashfs/lzma/C/Common/ComTry.h | 17 + .../squashfs/lzma/C/Common/CommandLineParser.cpp | 263 ++++ .../squashfs/lzma/C/Common/CommandLineParser.h | 82 ++ .../linux/scripts/squashfs/lzma/C/Common/Defs.h | 20 + .../linux/scripts/squashfs/lzma/C/Common/MyCom.h | 203 +++ .../scripts/squashfs/lzma/C/Common/MyGuidDef.h | 54 + .../scripts/squashfs/lzma/C/Common/MyInitGuid.h | 13 + .../scripts/squashfs/lzma/C/Common/MyUnknown.h | 24 + .../scripts/squashfs/lzma/C/Common/MyWindows.h | 183 +++ .../scripts/squashfs/lzma/C/Common/NewHandler.cpp | 114 ++ .../scripts/squashfs/lzma/C/Common/NewHandler.h | 14 + .../linux/scripts/squashfs/lzma/C/Common/StdAfx.h | 9 + .../scripts/squashfs/lzma/C/Common/String.cpp | 198 +++ .../linux/scripts/squashfs/lzma/C/Common/String.h | 631 ++++++++ .../squashfs/lzma/C/Common/StringConvert.cpp | 93 ++ .../scripts/squashfs/lzma/C/Common/StringConvert.h | 71 + .../scripts/squashfs/lzma/C/Common/StringToInt.cpp | 68 + .../scripts/squashfs/lzma/C/Common/StringToInt.h | 17 + .../linux/scripts/squashfs/lzma/C/Common/Types.h | 19 + .../scripts/squashfs/lzma/C/Common/Vector.cpp | 74 + .../linux/scripts/squashfs/lzma/C/Common/Vector.h | 211 +++ .../linux/scripts/squashfs/lzma/C/Windows/Defs.h | 18 + .../scripts/squashfs/lzma/C/Windows/FileIO.cpp | 245 ++++ .../linux/scripts/squashfs/lzma/C/Windows/FileIO.h | 98 ++ .../linux/scripts/squashfs/lzma/C/Windows/StdAfx.h | 9 + .../src/linux/linux/scripts/squashfs/lzma/CPL.html | 224 +++ .../src/linux/linux/scripts/squashfs/lzma/LGPL.txt | 504 +++++++ .../linux/linux/scripts/squashfs/lzma/Methods.txt | 114 ++ .../linux/linux/scripts/squashfs/lzma/history.txt | 147 ++ .../src/linux/linux/scripts/squashfs/lzma/lzma.txt | 637 +++++++++ .../src/linux/linux/scripts/squashfs/mksquashfs.c | 1317 +++++++++++------ .../src/linux/linux/scripts/squashfs/mksquashfs.h | 3 +- release/src/linux/linux/scripts/squashfs/read_fs.c | 344 +++-- release/src/linux/linux/scripts/squashfs/read_fs.h | 3 +- release/src/linux/linux/scripts/squashfs/sort.c | 227 ++- release/src/linux/linux/scripts/squashfs/sort.h | 56 + .../src/linux/linux/scripts/squashfs/squashfs_fs.h | 735 +++++++--- .../src/linux/linux/scripts/squashfs/unsquashfs.c | 946 ++++++++++++ 174 files changed, 24490 insertions(+), 889 deletions(-) create mode 100644 release/src/linux/linux/scripts/squashfs/global.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/7zC.txt create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/7zFormat.txt create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zIn.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zIn.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zItem.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zItem.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMain.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zTypes.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsw create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/makefile create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/makefile.gcc create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/FileStreams.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/FileStreams.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/InBuffer.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/InBuffer.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/OutBuffer.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/OutBuffer.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StdAfx.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StreamUtils.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StreamUtils.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARM.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARM.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARMThumb.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARMThumb.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARM.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARM.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARMThumb.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARMThumb.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchCoder.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchCoder.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchIA64.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchIA64.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchPPC.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchPPC.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchSPARC.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchSPARC.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchX86.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchX86.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/IA64.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/IA64.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/PPC.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/PPC.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/SPARC.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/SPARC.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/StdAfx.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree3Z.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree4b.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC2.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC3.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC4.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC4b.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/IMatchFinder.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2H.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2R.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat3H.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat4H.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/PatMain.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/StdAfx.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMA.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMADecoder.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMADecoder.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/StdAfx.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/makefile create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/makefile.gcc create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateTest.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaTest.c create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/makefile create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/makefile.gcc create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Lib/ZLib.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Lib/makefile create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/StdAfx.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/ICoder.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/IStream.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/Alloc.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/Alloc.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/CRC.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/CRC.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/C_FileIO.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/C_FileIO.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/ComTry.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/CommandLineParser.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/CommandLineParser.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/Defs.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyCom.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyGuidDef.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyInitGuid.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyUnknown.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyWindows.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/NewHandler.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/NewHandler.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/StdAfx.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/String.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/String.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringConvert.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringConvert.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringToInt.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringToInt.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/Types.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/Vector.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Common/Vector.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Windows/Defs.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Windows/FileIO.cpp create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Windows/FileIO.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/Windows/StdAfx.h create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/CPL.html create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/LGPL.txt create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/Methods.txt create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/history.txt create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/lzma.txt create mode 100644 release/src/linux/linux/scripts/squashfs/sort.h create mode 100644 release/src/linux/linux/scripts/squashfs/unsquashfs.c (limited to 'release/src/linux/linux/scripts/squashfs') diff --git a/release/src/linux/linux/scripts/squashfs/Makefile b/release/src/linux/linux/scripts/squashfs/Makefile index f563eceb..fa3f29e4 100644 --- a/release/src/linux/linux/scripts/squashfs/Makefile +++ b/release/src/linux/linux/scripts/squashfs/Makefile @@ -1,17 +1,39 @@ -INCLUDEDIR = . - CC=gcc +CXX=g++ +INCLUDEDIR = . +LZMALIB = lzma/C/7zip/Compress/LZMA_Lib +LZMAPATH = lzma/C/7zip/Compress/LZMA_Alone CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -O2 +all: liblzma.a mksquashfs unsquashfs mksquashfs-lzma lzma + mksquashfs: mksquashfs.o read_fs.o sort.o $(CC) mksquashfs.o read_fs.o sort.o -lz -o $@ -mksquashfs.o: mksquashfs.c mksquashfs.h +mksquashfs-lzma: liblzma.a mksquashfs.o read_fs.o sort.o + $(CXX) mksquashfs.o read_fs.o sort.o -L$(LZMALIB) -llzma -o $@ + +mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h -read_fs.o: read_fs.c read_fs.h +read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h -sort.o: sort.c +sort.o: sort.c squashfs_fs.h global.h sort.h + +unsquashfs: unsquashfs.o + $(CC) unsquashfs.o -lz -o $@ + +unsquashfs.o: unsquashfs.c squashfs_fs.h read_fs.h global.h + +liblzma.a: + $(MAKE) -C $(LZMALIB) + +lzma: + $(MAKE) -C $(LZMAPATH) -f makefile.gcc clean: - rm -f *.o mksquashfs + find . -iname "*.o" -exec rm -f {} \; + find . -iname "*.a" -exec rm -f {} \; + rm -f mksquashfs unsquashfs mksquashfs-lzma $(LZMAPATH)/lzma + +.PHONY: lzma diff --git a/release/src/linux/linux/scripts/squashfs/global.h b/release/src/linux/linux/scripts/squashfs/global.h new file mode 100644 index 00000000..2c45c4a4 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/global.h @@ -0,0 +1,46 @@ +#ifndef GLOBAL_H +#define GLOBAL_H + +/* + * Squashfs + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006 + * Phillip Lougher + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * global.h + */ + +typedef struct squashfs_super_block squashfs_super_block; +typedef struct squashfs_dir_index squashfs_dir_index; +typedef struct squashfs_base_inode_header squashfs_base_inode_header; +typedef struct squashfs_ipc_inode_header squashfs_ipc_inode_header; +typedef struct squashfs_dev_inode_header squashfs_dev_inode_header; +typedef struct squashfs_symlink_inode_header squashfs_symlink_inode_header; +typedef struct squashfs_reg_inode_header squashfs_reg_inode_header; +typedef struct squashfs_lreg_inode_header squashfs_lreg_inode_header; +typedef struct squashfs_dir_inode_header squashfs_dir_inode_header; +typedef struct squashfs_ldir_inode_header squashfs_ldir_inode_header; +typedef struct squashfs_dir_entry squashfs_dir_entry; +typedef struct squashfs_dir_header squashfs_dir_header; +typedef struct squashfs_fragment_entry squashfs_fragment_entry; + +typedef union squashfs_inode_header squashfs_inode_header; +typedef unsigned int squashfs_uid; +typedef long long squashfs_fragment_index; +typedef squashfs_inode_t squashfs_inode; +typedef squashfs_block_t squashfs_block; +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/7zC.txt b/release/src/linux/linux/scripts/squashfs/lzma/7zC.txt new file mode 100644 index 00000000..1c81eacf --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/7zC.txt @@ -0,0 +1,235 @@ +7z ANSI-C Decoder 4.23 +---------------------- + +7z ANSI-C Decoder 4.23 Copyright (C) 1999-2005 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", and "CRC" information for each file in archive. + - It supports only LZMA and Copy (no compression) methods. + - 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 + +: + 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) + - 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 + + +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_64 - define it if you need support for files larger than 4 GB +_SZ_NO_INT_64 - define it if your compiler doesn't support long long int + +_LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs. + +_SZ_ONE_DIRECTORY - define it if you want to locate all source files to one directory +_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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/7zFormat.txt b/release/src/linux/linux/scripts/squashfs/lzma/7zFormat.txt new file mode 100644 index 00000000..7e2b14ad --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/7zFormat.txt @@ -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) +while(true) +{ + 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 + + while(true) + { + BYTE PropertyType; + if (aType == 0) + break; + + UINT64 Size; + + switch(PropertyType) + { + kEmptyStream: (0x0E) + for(NumFiles) + BIT IsEmptyStream + + kEmptyFile: (0x0F) + for(EmptyStreams) + BIT IsEmptyFile + + kAnti: (0x10) + for(EmptyStreams) + BIT IsAntiFile + + case kCreationTime: (0x12) + case kLastAccessTime: (0x13) + case kLastWriteTime: (0x14) + BYTE AllAreDefined + if (AllAreDefined == 0) + { + for(NumFiles) + BIT TimeDefined + } + BYTE External; + if(External != 0) + UINT64 DataIndex + [] + for(Definded Items) + UINT32 Time + [] + + kNames: (0x11) + BYTE External; + if(External != 0) + UINT64 DataIndex + [] + for(Files) + { + wchar_t Names[NameSize]; + wchar_t 0; + } + [] + + kAttributes: (0x15) + BYTE AllAreDefined + if (AllAreDefined == 0) + { + for(NumFiles) + BIT AttributesAreDefined + } + BYTE External; + if(External != 0) + UINT64 DataIndex + [] + for(Definded Attributes) + UINT32 Attributes + [] + } + } + + +Header +~~~~~~ + BYTE NID::kHeader (0x01) + + [] + ArchiveProperties + [] + + [] + BYTE NID::kAdditionalStreamsInfo; (0x03) + StreamsInfo + [] + + [] + BYTE NID::kMainStreamsInfo; (0x04) + StreamsInfo + [] + + [] + FilesInfo + [] + + BYTE NID::kEnd + + +HeaderInfo +~~~~~~~~~~ + [] + BYTE NID::kEncodedHeader; (0x17) + StreamsInfo for Encoded Header + [] + + +--- +End of document diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.c new file mode 100644 index 00000000..d5da81b1 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.c @@ -0,0 +1,70 @@ +/* 7zAlloc.c */ + +#include +#include "7zAlloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ + +#ifdef _SZ_ALLOC_DEBUG + +#ifdef _WIN32 +#include +#endif +#include +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); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.h new file mode 100644 index 00000000..b02c1dea --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zAlloc.h @@ -0,0 +1,20 @@ +/* 7zAlloc.h */ + +#ifndef __7Z_ALLOC_H +#define __7Z_ALLOC_H + +#include + +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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.c new file mode 100644 index 00000000..8bc8e067 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.c @@ -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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.h new file mode 100644 index 00000000..afea3ca8 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zBuffer.h @@ -0,0 +1,19 @@ +/* 7zBuffer.h */ + +#ifndef __7Z_BUFFER_H +#define __7Z_BUFFER_H + +#include +#include "7zTypes.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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.c new file mode 100644 index 00000000..6dc7dd32 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.c @@ -0,0 +1,76 @@ +/* 7zCrc.c */ + +#include "7zCrc.h" + +#define kCrcPoly 0xEDB88320 + +UInt32 g_CrcTable[256]; + +void InitCrcTable() +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCrcPoly; + else + r >>= 1; + g_CrcTable[i] = r; + } +} + +void CrcInit(UInt32 *crc) { *crc = 0xFFFFFFFF; } +UInt32 CrcGetDigest(UInt32 *crc) { return *crc ^ 0xFFFFFFFF; } + +void CrcUpdateByte(UInt32 *crc, Byte b) +{ + *crc = g_CrcTable[((Byte)(*crc)) ^ b] ^ (*crc >> 8); +} + +void CrcUpdateUInt16(UInt32 *crc, UInt16 v) +{ + CrcUpdateByte(crc, (Byte)v); + CrcUpdateByte(crc, (Byte)(v >> 8)); +} + +void CrcUpdateUInt32(UInt32 *crc, UInt32 v) +{ + int i; + for (i = 0; i < 4; i++) + CrcUpdateByte(crc, (Byte)(v >> (8 * i))); +} + +void CrcUpdateUInt64(UInt32 *crc, UInt64 v) +{ + int i; + for (i = 0; i < 8; i++) + { + CrcUpdateByte(crc, (Byte)(v)); + v >>= 8; + } +} + +void CrcUpdate(UInt32 *crc, const void *data, size_t size) +{ + UInt32 v = *crc; + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = g_CrcTable[((Byte)(v)) ^ *p] ^ (v >> 8); + *crc = v; +} + +UInt32 CrcCalculateDigest(const void *data, size_t size) +{ + UInt32 crc; + CrcInit(&crc); + CrcUpdate(&crc, data, size); + return CrcGetDigest(&crc); +} + +int CrcVerifyDigest(UInt32 digest, const void *data, size_t size) +{ + return (CrcCalculateDigest(data, size) == digest); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.h new file mode 100644 index 00000000..bac26b14 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zCrc.h @@ -0,0 +1,24 @@ +/* 7zCrc.h */ + +#ifndef __7Z_CRC_H +#define __7Z_CRC_H + +#include + +#include "7zTypes.h" + +extern UInt32 g_CrcTable[256]; +void InitCrcTable(); + +void CrcInit(UInt32 *crc); +UInt32 CrcGetDigest(UInt32 *crc); +void CrcUpdateByte(UInt32 *crc, Byte v); +void CrcUpdateUInt16(UInt32 *crc, UInt16 v); +void CrcUpdateUInt32(UInt32 *crc, UInt32 v); +void CrcUpdateUInt64(UInt32 *crc, UInt64 v); +void CrcUpdate(UInt32 *crc, const void *data, size_t size); + +UInt32 CrcCalculateDigest(const void *data, size_t size); +int CrcVerifyDigest(UInt32 digest, const void *data, size_t size); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.c new file mode 100644 index 00000000..9dfbe7dc --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.c @@ -0,0 +1,150 @@ +/* 7zDecode.c */ + +#include "7zDecode.h" +#ifdef _SZ_ONE_DIRECTORY +#include "LzmaDecode.h" +#else +#include "../../Compress/LZMA_C/LzmaDecode.h" +#endif + +CMethodID k_Copy = { { 0x0 }, 1 }; +CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; + +#ifdef _LZMA_IN_CB + +typedef struct _CLzmaInCallbackImp +{ + ILzmaInCallback InCallback; + ISzInStream *InStream; + size_t Size; +} CLzmaInCallbackImp; + +int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size) +{ + CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object; + size_t processedSize; + SZ_RESULT res; + *size = 0; + res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize); + *size = (SizeT)processedSize; + if (processedSize > cb->Size) + return (int)SZE_FAIL; + cb->Size -= processedSize; + if (res == SZ_OK) + return 0; + return (int)res; +} + +#endif + +SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, + #ifdef _LZMA_IN_CB + ISzInStream *inStream, + #else + const Byte *inBuffer, + #endif + Byte *outBuffer, size_t outSize, + size_t *outSizeProcessed, ISzAlloc *allocMain) +{ + UInt32 si; + size_t inSize = 0; + CCoderInfo *coder; + if (folder->NumPackStreams != 1) + return SZE_NOTIMPL; + if (folder->NumCoders != 1) + return SZE_NOTIMPL; + coder = folder->Coders; + *outSizeProcessed = 0; + + for (si = 0; si < folder->NumPackStreams; si++) + inSize += (size_t)packSizes[si]; + + if (AreMethodsEqual(&coder->MethodID, &k_Copy)) + { + size_t i; + if (inSize != outSize) + return SZE_DATA_ERROR; + #ifdef _LZMA_IN_CB + for (i = 0; i < inSize;) + { + size_t j; + Byte *inBuffer; + size_t bufferSize; + RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize)); + if (bufferSize == 0) + return SZE_DATA_ERROR; + if (bufferSize > inSize - i) + return SZE_FAIL; + *outSizeProcessed += bufferSize; + for (j = 0; j < bufferSize && i < inSize; j++, i++) + outBuffer[i] = inBuffer[j]; + } + #else + for (i = 0; i < inSize; i++) + outBuffer[i] = inBuffer[i]; + *outSizeProcessed = inSize; + #endif + return SZ_OK; + } + + if (AreMethodsEqual(&coder->MethodID, &k_LZMA)) + { + #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, + 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); + *outSizeProcessed = (size_t)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 SZ_OK; + } + return SZE_NOTIMPL; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.h new file mode 100644 index 00000000..432b7ce3 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zDecode.h @@ -0,0 +1,21 @@ +/* 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, + #else + const Byte *inBuffer, + #endif + Byte *outBuffer, size_t outSize, + size_t *outSizeProcessed, ISzAlloc *allocMain); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.c new file mode 100644 index 00000000..21fb0131 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.c @@ -0,0 +1,116 @@ +/* 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 unPackSize = SzFolderGetUnPackSize(folder); + #ifndef _LZMA_IN_CB + CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex); + Byte *inBuffer = 0; + size_t processedSize; + #endif + *blockIndex = folderIndex; + allocMain->Free(*outBuffer); + *outBuffer = 0; + + RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0))); + + #ifndef _LZMA_IN_CB + if (packSize != 0) + { + inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); + if (inBuffer == 0) + return SZE_OUTOFMEMORY; + } + res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize); + if (res == SZ_OK && processedSize != (size_t)packSize) + res = SZE_FAIL; + #endif + if (res == SZ_OK) + { + *outBufferSize = (size_t)unPackSize; + if (unPackSize != 0) + { + *outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize); + if (*outBuffer == 0) + res = SZE_OUTOFMEMORY; + } + if (res == SZ_OK) + { + size_t outRealSize; + res = SzDecode(db->Database.PackSizes + + db->FolderStartPackStreamIndex[folderIndex], folder, + #ifdef _LZMA_IN_CB + inStream, + #else + inBuffer, + #endif + *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp); + if (res == SZ_OK) + { + if (outRealSize == (size_t)unPackSize) + { + if (folder->UnPackCRCDefined) + { + if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize)) + res = SZE_FAIL; + } + } + else + res = SZE_FAIL; + } + } + } + #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 (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed)) + res = SZE_FAIL; + } + } + } + return res; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.h new file mode 100644 index 00000000..4ae2a056 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zExtract.h @@ -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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.c new file mode 100644 index 00000000..e26c0143 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.c @@ -0,0 +1,5 @@ +/* 7zHeader.c */ + +#include "7zHeader.h" + +Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.h new file mode 100644 index 00000000..7edf640f --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zHeader.h @@ -0,0 +1,55 @@ +/* 7zHeader.h */ + +#ifndef __7Z_HEADER_H +#define __7Z_HEADER_H + +#include "7zTypes.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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zIn.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zIn.c new file mode 100644 index 00000000..6d910b6c --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zIn.c @@ -0,0 +1,1292 @@ +/* 7zIn.c */ + +#include "7zIn.h" +#include "7zCrc.h" +#include "7zDecode.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; +} +*/ + + +SZ_RESULT MySzInAlloc(void **p, size_t size, void * (*allocFunc)(size_t size)) +{ + if (size == 0) + *p = 0; + else + { + *p = allocFunc(size); + RINOM(*p); + } + return SZ_OK; +} + +SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size)) +{ + UInt32 startPos = 0; + CFileSize startPosSize = 0; + UInt32 i; + UInt32 folderIndex = 0; + UInt32 indexInFolder = 0; + RINOK(MySzInAlloc((void **)&db->FolderStartPackStreamIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc)); + for(i = 0; i < db->Database.NumFolders; i++) + { + db->FolderStartPackStreamIndex[i] = startPos; + startPos += db->Database.Folders[i].NumPackStreams; + } + + RINOK(MySzInAlloc((void **)&db->PackStreamStartPositions, db->Database.NumPackStreams * sizeof(CFileSize), allocFunc)); + + for(i = 0; i < db->Database.NumPackStreams; i++) + { + db->PackStreamStartPositions[i] = startPosSize; + startPosSize += db->Database.PackSizes[i]; + } + + RINOK(MySzInAlloc((void **)&db->FolderStartFileIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc)); + RINOK(MySzInAlloc((void **)&db->FileIndexToFolderIndexMap, db->Database.NumFiles * sizeof(UInt32), 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 + */ + while(1) + { + 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]; +} + +CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex) +{ + UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex]; + CFolder *folder = db->Database.Folders + folderIndex; + CFileSize size = 0; + UInt32 i; + for (i = 0; i < folder->NumPackStreams; i++) + size += db->Database.PackSizes[packStreamIndex + i]; + return size; +} + + +/* +SZ_RESULT SzReadTime(const CObjectVector &dataVector, + CObjectVector &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) + { + Byte *inBuffer; + size_t processedSize; + RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize)); + 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) +{ + int i; + *value = 0; + for (i = 0; i < 4; i++) + { + Byte b; + RINOK(SafeReadDirectByte(inStream, &b)); + *value |= ((UInt32)b << (8 * i)); + } + return SZ_OK; +} + +SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value) +{ + int i; + *value = 0; + for (i = 0; i < 8; i++) + { + Byte b; + RINOK(SafeReadDirectByte(inStream, &b)); + *value |= ((UInt32)b << (8 * i)); + } + 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) +{ + while(1) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + SzSkeepData(sd); + } + return SZ_OK; +} + +SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute) +{ + while(1) + { + 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; + RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), 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); + RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), 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)); + RINOK(MySzInAlloc((void **)digests, numItems * sizeof(UInt32), 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)); + + RINOK(MySzInAlloc((void **)packSizes, (size_t)*numPackStreams * sizeof(CFileSize), allocFunc)); + + for(i = 0; i < *numPackStreams; i++) + { + RINOK(SzReadSize(sd, (*packSizes) + i)); + } + + while(1) + { + 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) + { + RINOK(MySzInAlloc((void **)packCRCsDefined, (size_t)*numPackStreams * sizeof(Byte), allocFunc)); + RINOK(MySzInAlloc((void **)packCRCs, (size_t)*numPackStreams * sizeof(UInt32), 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; + + RINOK(MySzInAlloc((void **)&folder->Coders, (size_t)numCoders * sizeof(CCoderInfo), allocFunc)); + + for (i = 0; i < numCoders; i++) + SzCoderInfoInit(folder->Coders + i); + + for (i = 0; i < numCoders; i++) + { + Byte mainByte; + CCoderInfo *coder = folder->Coders + i; + { + RINOK(SzReadByte(sd, &mainByte)); + coder->MethodID.IDSize = (Byte)(mainByte & 0xF); + RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize)); + 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; + + + RINOK(MySzInAlloc((void **)&folder->BindPairs, (size_t)numBindPairs * sizeof(CBindPair), 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; + RINOK(MySzInAlloc((void **)&folder->PackStreams, (size_t)numPackedStreams * sizeof(UInt32), 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)); + + + RINOK(MySzInAlloc((void **)folders, (size_t)*numFolders * sizeof(CFolder), 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); + + RINOK(MySzInAlloc((void **)&folder->UnPackSizes, (size_t)numOutStreams * sizeof(CFileSize), allocFunc)); + + for(j = 0; j < numOutStreams; j++) + { + RINOK(SzReadSize(sd, folder->UnPackSizes + j)); + } + } + + while(1) + { + 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; + + while(1) + { + 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; + while(1) + { + 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) +{ + while(1) + { + 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; + } + + RINOK(MySzInAlloc((void **)&file->Name, (size_t)len * sizeof(char), 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 */ + 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; + + RINOK(MySzInAlloc((void **)&files, (size_t)numFiles * sizeof(CFileItem), allocMain->Alloc)); + + db->Database.Files = files; + for(i = 0; i < numFiles; i++) + SzFileInit(files + i); + + while(1) + { + 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; + } + 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; + SZ_RESULT res = SzReadHeader2(sd, db, + &unPackSizes, &digestsDefined, &digests, + &emptyStreamVector, &emptyFileVector, + allocMain, allocTemp); + allocTemp->Free(unPackSizes); + allocTemp->Free(digestsDefined); + allocTemp->Free(digests); + allocTemp->Free(emptyStreamVector); + allocTemp->Free(emptyFileVector); + 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; + size_t outRealSize; + 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]; + + RINOK(MySzInAlloc((void **)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, + #else + *inBuffer, + #endif + outBuffer->Items, (size_t)unPackSize, + &outRealSize, allocTemp); + RINOK(res) + if (outRealSize != (UInt32)unPackSize) + return SZE_FAIL; + if (folder->UnPackCRCDefined) + if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize)) + 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; + 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)); + + CrcInit(&crc); + RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset)); + CrcUpdateUInt64(&crc, nextHeaderOffset); + RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize)); + CrcUpdateUInt64(&crc, nextHeaderSize); + RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC)); + CrcUpdateUInt32(&crc, nextHeaderCRC); + + pos = k7zStartHeaderSize; + db->ArchiveInfo.StartPositionAfterHeader = pos; + + if (CrcGetDigest(&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) + { + if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize)) + { + while (1) + { + 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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zIn.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zIn.h new file mode 100644 index 00000000..8ded0ecc --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zIn.h @@ -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); +CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex); + +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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zItem.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zItem.c new file mode 100644 index 00000000..5f9a37f6 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zItem.c @@ -0,0 +1,133 @@ +/* 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->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); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zItem.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zItem.h new file mode 100644 index 00000000..e59b73f0 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zItem.h @@ -0,0 +1,90 @@ +/* 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); + +/* #define CArchiveFileTime UInt64 */ + +typedef struct _CFileItem +{ + /* + CArchiveFileTime LastWriteTime; + CFileSize StartPos; + UInt32 Attributes; + */ + CFileSize Size; + UInt32 FileCRC; + char *Name; + + Byte IsFileCRCDefined; + Byte HasStream; + Byte IsDirectory; + Byte IsAnti; + /* + 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMain.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMain.c new file mode 100644 index 00000000..6b496da9 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMain.c @@ -0,0 +1,223 @@ +/* +7zMain.c +Test application for 7z Decoder +LZMA SDK 4.26 Copyright (c) 1999-2005 Igor Pavlov (2005-08-02) +*/ + +#include +#include +#include + +#include "7zCrc.h" +#include "7zIn.h" +#include "7zExtract.h" + +typedef struct _CFileInStream +{ + ISzInStream InStream; + FILE *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 = fread(g_Buffer, 1, maxRequiredSize, s->File); + *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 = fread(buffer, 1, size, s->File); + if (processedSize != 0) + *processedSize = processedSizeLoc; + return SZ_OK; +} + +#endif + +SZ_RESULT SzFileSeekImp(void *object, CFileSize pos) +{ + CFileInStream *s = (CFileInStream *)object; + int res = fseek(s->File, (long)pos, SEEK_SET); + if (res == 0) + return SZ_OK; + return SZE_FAIL; +} + +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.30 Copyright (c) 1999-2005 Igor Pavlov 2005-11-20\n"); + if (numargs == 1) + { + printf( + "\nUsage: 7zDec \n\n" + "\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 = fopen(args[2], "rb"); + if (archiveStream.File == 0) + { + 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; + + InitCrcTable(); + 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; + printf("%10d %s\n", (int)f->Size, 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) + { + FILE *outputHandle; + UInt32 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 = fopen(fileName, "wb+"); + if (outputHandle == 0) + { + PrintError("can not open output file"); + res = SZE_FAIL; + break; + } + processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle); + if (processedSize != outSizeProcessed) + { + PrintError("can not write output file"); + res = SZE_FAIL; + break; + } + if (fclose(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); + + fclose(archiveStream.File); + if (res == SZ_OK) + { + printf("\nEverything is Ok\n"); + return 0; + } + if (res == SZE_OUTOFMEMORY) + PrintError("can not allocate memory"); + else + printf("\nERROR #%d\n", res); + return 1; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.c new file mode 100644 index 00000000..9daf39c2 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.c @@ -0,0 +1,14 @@ +/* 7zMethodID.c */ + +#include "7zMethodID.h" + +int AreMethodsEqual(CMethodID *a1, CMethodID *a2) +{ + int i; + if (a1->IDSize != a2->IDSize) + return 0; + for (i = 0; i < a1->IDSize; i++) + if (a1->ID[i] != a2->ID[i]) + return 0; + return 1; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.h new file mode 100644 index 00000000..4d886899 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zMethodID.h @@ -0,0 +1,18 @@ +/* 7zMethodID.h */ + +#ifndef __7Z_METHOD_ID_H +#define __7Z_METHOD_ID_H + +#include "7zTypes.h" + +#define kMethodIDSize 15 + +typedef struct _CMethodID +{ + Byte ID[kMethodIDSize]; + Byte IDSize; +} CMethodID; + +int AreMethodsEqual(CMethodID *a1, CMethodID *a2); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zTypes.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zTypes.h new file mode 100644 index 00000000..28adc729 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7zTypes.h @@ -0,0 +1,61 @@ +/* 7zTypes.h */ + +#ifndef __COMMON_TYPES_H +#define __COMMON_TYPES_H + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifndef Byte +#define Byte unsigned char +#endif + +#ifndef UInt16 +#define UInt16 unsigned short +#endif + +/* #define _SZ_NO_INT_64 */ +/* define it your compiler doesn't support long long int */ + +#ifdef _SZ_NO_INT_64 +#define UInt64 unsigned long +#else +#ifdef _MSC_VER +#define UInt64 unsigned __int64 +#else +#define UInt64 unsigned long long int +#endif +#endif + + +/* #define _SZ_FILE_SIZE_64 */ +/* Use _SZ_FILE_SIZE_64 if you need support for files larger than 4 GB*/ + +#ifndef CFileSize +#ifdef _SZ_FILE_SIZE_64 +#define CFileSize UInt64 +#else +#define CFileSize UInt32 +#endif +#endif + +#define SZ_RESULT int + +#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) + +#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; } + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsp new file mode 100644 index 00000000..d83b30e3 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsp @@ -0,0 +1,178 @@ +# 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 /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" + +!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 /W3 /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_C\LzmaDecode.c +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA_C\LzmaDecode.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=.\7zCrc.c +# End Source File +# Begin Source File + +SOURCE=.\7zCrc.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 +# Begin Source File + +SOURCE=.\7zTypes.h +# End Source File +# End Target +# End Project diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsw b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsw new file mode 100644 index 00000000..f1ee72bf --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/7z_C.dsw @@ -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> +{{{ +}}} + +############################################################################### + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/makefile b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/makefile new file mode 100644 index 00000000..eafbd057 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/makefile @@ -0,0 +1,55 @@ +PROG = 7zDec.exe + +!IFNDEF O +!IFDEF CPU +O=$(CPU) +!ELSE +O=O +!ENDIF +!ENDIF + +CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS- +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) $** + + +7Z_OBJS = \ + $O\7zAlloc.obj \ + $O\7zBuffer.obj \ + $O\7zCrc.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 \ + +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_C/$(*B).c + $(COMPL_O2) diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/makefile.gcc b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/makefile.gcc new file mode 100644 index 00000000..cc8bebf7 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Archive/7z_C/makefile.gcc @@ -0,0 +1,50 @@ +PROG = 7zDec +CXX = g++ +LIB = +RM = rm -f +CFLAGS = -c -O2 -Wall + +OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.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_C/LzmaDecode.c + $(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c + + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/FileStreams.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/FileStreams.cpp new file mode 100644 index 00000000..7a32c6e7 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/FileStreams.cpp @@ -0,0 +1,251 @@ +// FileStreams.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 +#include +#include +#include +#endif + +#include "FileStreams.h" + +static inline HRESULT ConvertBoolToHRESULT(bool result) +{ + // return result ? S_OK: E_FAIL; + #ifdef _WIN32 + return result ? S_OK: (::GetLastError()); + #else + return result ? S_OK: E_FAIL; + #endif +} + +bool CInFileStream::Open(LPCTSTR fileName) +{ + return File.Open(fileName); +} + +#ifdef _WIN32 +#ifndef _UNICODE +bool CInFileStream::Open(LPCWSTR fileName) +{ + return File.Open(fileName); +} +#endif +#endif + +STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + + 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 _WIN32 + + 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 + +bool COutFileStream::Create(LPCTSTR fileName, bool createAlways) +{ + return File.Create(fileName, createAlways); +} + +#ifdef _WIN32 +#ifndef _UNICODE +bool COutFileStream::Create(LPCWSTR fileName, bool createAlways) +{ + return File.Create(fileName, createAlways); +} +#endif +#endif + +STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + + UInt32 realProcessedSize; + bool result = File.WritePart(data, size, 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; + return S_OK; + + #endif +} + +STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + #ifdef _WIN32 + + 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 _WIN32 + 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/FileStreams.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/FileStreams.h new file mode 100644 index 00000000..e6494f67 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/FileStreams.h @@ -0,0 +1,98 @@ +// FileStreams.h + +#ifndef __FILESTREAMS_H +#define __FILESTREAMS_H + +#ifdef _WIN32 +#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 _WIN32 + NWindows::NFile::NIO::CInFile File; + #else + NC::NFile::NIO::CInFile File; + #endif + CInFileStream() {} + virtual ~CInFileStream() {} + + bool Open(LPCTSTR fileName); + #ifdef _WIN32 + #ifndef _UNICODE + bool Open(LPCWSTR fileName); + #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 +{ +public: + #ifdef _WIN32 + NWindows::NFile::NIO::COutFile File; + #else + NC::NFile::NIO::COutFile File; + #endif + virtual ~COutFileStream() {} + bool Create(LPCTSTR fileName, bool createAlways); + #ifdef _WIN32 + #ifndef _UNICODE + bool Create(LPCWSTR fileName, bool createAlways); + #endif + #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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/InBuffer.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/InBuffer.cpp new file mode 100644 index 00000000..17280b5b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/InBuffer.cpp @@ -0,0 +1,80 @@ +// InBuffer.cpp + +#include "StdAfx.h" + +#include "InBuffer.h" + +#include "../../Common/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++; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/InBuffer.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/InBuffer.h new file mode 100644 index 00000000..a59ecefa --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/InBuffer.h @@ -0,0 +1,76 @@ +// InBuffer.h + +#ifndef __INBUFFER_H +#define __INBUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" + +#ifndef _NO_EXCEPTIONS +class CInBufferException +{ +public: + HRESULT ErrorCode; + CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {} +}; +#endif + +class CInBuffer +{ + Byte *_buffer; + Byte *_bufferLimit; + Byte *_bufferBase; + CMyComPtr _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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/OutBuffer.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/OutBuffer.cpp new file mode 100644 index 00000000..e76e6f4d --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/OutBuffer.cpp @@ -0,0 +1,117 @@ +// OutByte.cpp + +#include "StdAfx.h" + +#include "OutBuffer.h" + +#include "../../Common/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 + if (ErrorCode != S_OK) + 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 = FlushPart(); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw COutBufferException(result); + #endif +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/OutBuffer.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/OutBuffer.h new file mode 100644 index 00000000..37eefbdf --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/OutBuffer.h @@ -0,0 +1,64 @@ +// OutBuffer.h + +#ifndef __OUTBUFFER_H +#define __OUTBUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" + +#ifndef _NO_EXCEPTIONS +struct COutBufferException +{ + HRESULT ErrorCode; + COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {} +}; +#endif + +class COutBuffer +{ +protected: + Byte *_buffer; + UInt32 _pos; + UInt32 _limitPos; + UInt32 _streamPos; + UInt32 _bufferSize; + CMyComPtr _stream; + UInt64 _processedSize; + Byte *_buffer2; + bool _overDict; + + HRESULT FlushPart(); + void FlushWithCheck(); +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 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StdAfx.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StdAfx.h new file mode 100644 index 00000000..d7d9211b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../Common/MyWindows.h" +#include "../../Common/NewHandler.h" + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StreamUtils.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StreamUtils.cpp new file mode 100644 index 00000000..712a7858 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StreamUtils.cpp @@ -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) + break; + } + return S_OK; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StreamUtils.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StreamUtils.h new file mode 100644 index 00000000..c8cd8cef --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Common/StreamUtils.h @@ -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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARM.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARM.cpp new file mode 100644 index 00000000..1a52ea9e --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARM.cpp @@ -0,0 +1,16 @@ +// ARM.cpp + +#include "StdAfx.h" +#include "ARM.h" + +#include "BranchARM.c" + +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); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARM.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARM.h new file mode 100644 index 00000000..83c91e31 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARM.h @@ -0,0 +1,10 @@ +// ARM.h + +#ifndef __ARM_H +#define __ARM_H + +#include "BranchCoder.h" + +MyClassA(BC_ARM, 0x05, 1) + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARMThumb.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARMThumb.cpp new file mode 100644 index 00000000..83f5d9b8 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARMThumb.cpp @@ -0,0 +1,16 @@ +// ARMThumb.cpp + +#include "StdAfx.h" +#include "ARMThumb.h" + +#include "BranchARMThumb.c" + +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); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARMThumb.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARMThumb.h new file mode 100644 index 00000000..f59c737b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/ARMThumb.h @@ -0,0 +1,10 @@ +// ARMThumb.h + +#ifndef __ARMTHUMB_H +#define __ARMTHUMB_H + +#include "BranchCoder.h" + +MyClassA(BC_ARMThumb, 0x07, 1) + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARM.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARM.c new file mode 100644 index 00000000..53680ef4 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARM.c @@ -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 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]); + src <<= 2; + UInt32 dest; + if (encoding) + dest = nowPos + i + 8 + src; + else + dest = src - (nowPos + i + 8); + dest >>= 2; + data[i + 2] = (dest >> 16); + data[i + 1] = (dest >> 8); + data[i + 0] = dest; + } + } + return i; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARM.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARM.h new file mode 100644 index 00000000..63e55dc8 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARM.h @@ -0,0 +1,10 @@ +// BranchARM.h + +#ifndef __BRANCH_ARM_H +#define __BRANCH_ARM_H + +#include "Common/Types.h" + +UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARMThumb.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARMThumb.c new file mode 100644 index 00000000..6d0f5ba1 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARMThumb.c @@ -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 src = + ((data[i + 1] & 0x7) << 19) | + (data[i + 0] << 11) | + ((data[i + 3] & 0x7) << 8) | + (data[i + 2]); + + src <<= 1; + UInt32 dest; + if (encoding) + dest = nowPos + i + 4 + src; + else + dest = src - (nowPos + i + 4); + dest >>= 1; + + data[i + 1] = 0xF0 | ((dest >> 19) & 0x7); + data[i + 0] = (dest >> 11); + data[i + 3] = 0xF8 | ((dest >> 8) & 0x7); + data[i + 2] = (dest); + i += 2; + } + } + return i; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARMThumb.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARMThumb.h new file mode 100644 index 00000000..032d94da --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchARMThumb.h @@ -0,0 +1,10 @@ +// BranchARMThumb.h + +#ifndef __BRANCH_ARM_THUMB_H +#define __BRANCH_ARM_THUMB_H + +#include "Common/Types.h" + +UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchCoder.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchCoder.cpp new file mode 100644 index 00000000..68e938bd --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchCoder.cpp @@ -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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchCoder.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchCoder.h new file mode 100644 index 00000000..b64562df --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchCoder.h @@ -0,0 +1,54 @@ +// BranchCoder.h + +#ifndef __BRANCH_CODER_H +#define __BRANCH_CODER_H + +#include "Common/MyCom.h" +#include "Common/Types.h" +#include "Common/Alloc.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 MyClass2b(Name, id, subId, encodingId) \ +DEFINE_GUID(CLSID_CCompressConvert ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); + +#define MyClassA(Name, id, subId) \ +MyClass2b(Name ## _Encoder, id, subId, 0x01) \ +MyClassEncoderA(Name ## _Encoder) \ +MyClass2b(Name ## _Decoder, id, subId, 0x00) \ +MyClassDecoderA(Name ## _Decoder) + +#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \ +MyClass2b(Name ## _Encoder, id, subId, 0x01) \ +MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \ +MyClass2b(Name ## _Decoder, id, subId, 0x00) \ +MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT) + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchIA64.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchIA64.c new file mode 100644 index 00000000..8571aac1 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchIA64.c @@ -0,0 +1,65 @@ +// 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; + for (int slot = 0; slot < 3; slot++, bitPos += 41) + { + if (((mask >> slot) & 1) == 0) + continue; + UInt32 bytePos = (bitPos >> 3); + UInt32 bitRes = bitPos & 0x7; + // UInt64 instruction = *(UInt64 *)(data + i + bytePos); + UInt64 instruction = 0; + int j; + for (j = 0; j < 6; j++) + instruction += (UInt64)(data[i + j + bytePos]) << (8 * j); + + UInt64 instNorm = instruction >> bitRes; + if (((instNorm >> 37) & 0xF) == 0x5 + && ((instNorm >> 9) & 0x7) == 0 + // && (instNorm & 0x3F)== 0 + ) + { + UInt32 src = UInt32((instNorm >> 13) & 0xFFFFF); + src |= ((instNorm >> 36) & 1) << 20; + + src <<= 4; + + UInt32 dest; + 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); + // *(UInt64 *)(data + i + bytePos) = instruction; + for (j = 0; j < 6; j++) + data[i + j + bytePos] = Byte(instruction >> (8 * j)); + } + } + } + return i; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchIA64.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchIA64.h new file mode 100644 index 00000000..2e96c137 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchIA64.h @@ -0,0 +1,10 @@ +// BranchIA64.h + +#ifndef __BRANCH_IA64_H +#define __BRANCH_IA64_H + +#include "Common/Types.h" + +UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchPPC.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchPPC.c new file mode 100644 index 00000000..407bae61 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchPPC.c @@ -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] = 0x48 | ((dest >> 24) & 0x3); + data[i + 1] = (dest >> 16); + data[i + 2] = (dest >> 8); + data[i + 3] &= 0x3; + data[i + 3] |= dest; + } + } + return i; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchPPC.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchPPC.h new file mode 100644 index 00000000..405efbb1 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchPPC.h @@ -0,0 +1,10 @@ +// BranchPPC.h + +#ifndef __BRANCH_PPC_H +#define __BRANCH_PPC_H + +#include "Common/Types.h" + +UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchSPARC.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchSPARC.c new file mode 100644 index 00000000..abbf1d75 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchSPARC.c @@ -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]); + + src <<= 2; + UInt32 dest; + 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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchSPARC.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchSPARC.h new file mode 100644 index 00000000..431bac58 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchSPARC.h @@ -0,0 +1,10 @@ +// BranchSPARC.h + +#ifndef __BRANCH_SPARC_H +#define __BRANCH_SPARC_H + +#include "Common/Types.h" + +UInt32 SPARC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchX86.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchX86.c new file mode 100644 index 00000000..2d2c03d2 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchX86.c @@ -0,0 +1,101 @@ +/* BranchX86.c */ + +#include "BranchX86.h" + +/* +static int inline Test86MSByte(Byte b) +{ + return (b == 0 || b == 0xFF); +} +*/ +#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) + +const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; +const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; + +/* +void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos) +{ + *prevMask = 0; + *prevPos = (UInt32)(-5); +} +*/ + +UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos, + UInt32 *prevMask, UInt32 *prevPos, int encoding) +{ + UInt32 bufferPos = 0; + UInt32 limit; + + if (endPos < 5) + return 0; + + if (nowPos - *prevPos > 5) + *prevPos = nowPos - 5; + + limit = endPos - 5; + while(bufferPos <= limit) + { + Byte b = buffer[bufferPos]; + UInt32 offset; + if (b != 0xE8 && b != 0xE9) + { + bufferPos++; + continue; + } + offset = (nowPos + bufferPos - *prevPos); + *prevPos = (nowPos + bufferPos); + if (offset > 5) + *prevMask = 0; + else + { + UInt32 i; + for (i = 0; i < offset; i++) + { + *prevMask &= 0x77; + *prevMask <<= 1; + } + } + b = buffer[bufferPos + 4]; + if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] && + (*prevMask >> 1) < 0x10) + { + UInt32 src = + ((UInt32)(b) << 24) | + ((UInt32)(buffer[bufferPos + 3]) << 16) | + ((UInt32)(buffer[bufferPos + 2]) << 8) | + (buffer[bufferPos + 1]); + + UInt32 dest; + while(1) + { + UInt32 index; + if (encoding) + dest = (nowPos + bufferPos + 5) + src; + else + dest = src - (nowPos + bufferPos + 5); + if (*prevMask == 0) + break; + index = kMaskToBitNumber[*prevMask >> 1]; + b = (Byte)(dest >> (24 - index * 8)); + if (!Test86MSByte(b)) + break; + src = dest ^ ((1 << (32 - index * 8)) - 1); + } + buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1)); + buffer[bufferPos + 3] = (Byte)(dest >> 16); + buffer[bufferPos + 2] = (Byte)(dest >> 8); + buffer[bufferPos + 1] = (Byte)dest; + bufferPos += 5; + *prevMask = 0; + } + else + { + bufferPos++; + *prevMask |= 1; + if (Test86MSByte(b)) + *prevMask |= 0x10; + } + } + return bufferPos; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchX86.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchX86.h new file mode 100644 index 00000000..879fd50e --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/BranchX86.h @@ -0,0 +1,19 @@ +/* BranchX86.h */ + +#ifndef __BRANCHX86_H +#define __BRANCHX86_H + +#ifndef UInt32 +#define UInt32 unsigned int +#endif + +#ifndef Byte +#define Byte unsigned char +#endif + +#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); } + +UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos, + UInt32 *prevMask, UInt32 *prevPos, int encoding); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/IA64.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/IA64.cpp new file mode 100644 index 00000000..a579c408 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/IA64.cpp @@ -0,0 +1,16 @@ +// IA64.cpp + +#include "StdAfx.h" +#include "IA64.h" + +#include "BranchIA64.c" + +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); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/IA64.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/IA64.h new file mode 100644 index 00000000..f47d5e4b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/IA64.h @@ -0,0 +1,10 @@ +// IA64.h + +#ifndef __IA64_H +#define __IA64_H + +#include "BranchCoder.h" + +MyClassA(BC_IA64, 0x04, 1) + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/PPC.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/PPC.cpp new file mode 100644 index 00000000..c191f519 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/PPC.cpp @@ -0,0 +1,17 @@ +// PPC.cpp + +#include "StdAfx.h" +#include "PPC.h" + +#include "Windows/Defs.h" +#include "BranchPPC.c" + +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); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/PPC.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/PPC.h new file mode 100644 index 00000000..e2fbb409 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/PPC.h @@ -0,0 +1,10 @@ +// PPC.h + +#ifndef __PPC_H +#define __PPC_H + +#include "BranchCoder.h" + +MyClassA(BC_PPC_B, 0x02, 5) + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/SPARC.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/SPARC.cpp new file mode 100644 index 00000000..552551db --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/SPARC.cpp @@ -0,0 +1,17 @@ +// SPARC.cpp + +#include "StdAfx.h" +#include "SPARC.h" + +#include "Windows/Defs.h" +#include "BranchSPARC.c" + +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); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/SPARC.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/SPARC.h new file mode 100644 index 00000000..1e2c8afe --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/SPARC.h @@ -0,0 +1,10 @@ +// SPARC.h + +#ifndef __SPARC_H +#define __SPARC_H + +#include "BranchCoder.h" + +MyClassA(BC_SPARC, 0x08, 5) + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/StdAfx.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/StdAfx.h new file mode 100644 index 00000000..83fdd22d --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86.cpp new file mode 100644 index 00000000..929484ad --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86.cpp @@ -0,0 +1,18 @@ +// x86.cpp + +#include "StdAfx.h" +#include "x86.h" + +#include "Windows/Defs.h" + +#include "BranchX86.c" + +UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1); +} + +UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86.h new file mode 100644 index 00000000..85882d91 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86.h @@ -0,0 +1,19 @@ +// x86.h + +#ifndef __X86_H +#define __X86_H + +#include "BranchCoder.h" +#include "BranchX86.h" + +struct CBranch86 +{ + UInt32 _prevMask; + UInt32 _prevPos; + void x86Init() { x86_Convert_Init(_prevMask, _prevPos); } +}; + +MyClassB(BCJ_x86, 0x01, 3, CBranch86 , + virtual void SubInit() { x86Init(); }) + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp new file mode 100644 index 00000000..fc87bd93 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp @@ -0,0 +1,412 @@ +// x86_2.cpp + +#include "StdAfx.h" +#include "x86_2.h" + +#include "../../../Common/Alloc.h" + +static const int kBufferSize = 1 << 17; + +inline bool IsJcc(Byte b0, Byte b1) +{ + return (b0 == 0x0F && (b1 & 0xF0) == 0x80); +} + +#ifndef EXTRACT_ONLY + +static bool inline Test86MSByte(Byte b) +{ + return (b == 0 || b == 0xFF); +} + +bool CBCJ2_x86_Encoder::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; +} + +CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder() +{ + ::MidFree(_buffer); +} + +HRESULT CBCJ2_x86_Encoder::Flush() +{ + RINOK(_mainStream.Flush()); + RINOK(_callStream.Flush()); + RINOK(_jumpStream.Flush()); + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); +} + +const UInt32 kDefaultLimit = (1 << 24); + +HRESULT CBCJ2_x86_Encoder::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; + 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; i++) + _statusE8Encoder[i].Init(); + _statusE9Encoder.Init(); + _statusJccEncoder.Init(); + CCoderReleaser releaser(this); + + CMyComPtr 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; + + while(true) + { + UInt32 processedSize = 0; + while(true) + { + 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); + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 0); + else if (IsJcc(prevByte, b)) + _statusJccEncoder.Encode(&_rangeEncoder, 0); + prevByte = b; + } + return Flush(); + } + + bufferPos = 0; + + UInt32 limit = endPos - 5; + while(bufferPos <= limit) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + if (b != 0xE8 && b != 0xE9 && !IsJcc(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); + if (convert) + { + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 1); + else + _statusJccEncoder.Encode(&_rangeEncoder, 1); + + bufferPos += 5; + if (b == 0xE8) + { + _callStream.WriteByte((Byte)(dest >> 24)); + _callStream.WriteByte((Byte)(dest >> 16)); + _callStream.WriteByte((Byte)(dest >> 8)); + _callStream.WriteByte((Byte)(dest)); + } + else + { + _jumpStream.WriteByte((Byte)(dest >> 24)); + _jumpStream.WriteByte((Byte)(dest >> 16)); + _jumpStream.WriteByte((Byte)(dest >> 8)); + _jumpStream.WriteByte((Byte)(dest)); + } + prevByte = nextByte; + } + else + { + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 0); + else + _statusJccEncoder.Encode(&_rangeEncoder, 0); + bufferPos++; + prevByte = b; + } + } + nowPos += bufferPos; + nowPos64 += bufferPos; + + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&nowPos64, NULL)); + } + + UInt32 i = 0; + while(bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } +} + +STDMETHODIMP CBCJ2_x86_Encoder::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 CBCJ2_x86_Decoder::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; i++) + _statusE8Decoder[i].Init(); + _statusE9Decoder.Init(); + _statusJccDecoder.Init(); + + CCoderReleaser releaser(this); + + Byte prevByte = 0; + UInt32 processedBytes = 0; + while(true) + { + if (processedBytes > (1 << 20) && progress != NULL) + { + UInt64 nowPos64 = _outStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(NULL, &nowPos64)); + processedBytes = 0; + } + processedBytes++; + Byte b; + if (!_mainInStream.ReadByte(b)) + return Flush(); + _outStream.WriteByte(b); + if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b)) + { + prevByte = b; + continue; + } + bool status; + if (b == 0xE8) + status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1); + else if (b == 0xE9) + status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1); + else + status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1); + if (status) + { + UInt32 src; + if (b == 0xE8) + { + Byte b0; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0); + } + else + { + Byte b0; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + 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 = (dest >> 24); + processedBytes += 4; + } + else + prevByte = b; + } +} + +STDMETHODIMP CBCJ2_x86_Decoder::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; } +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.h new file mode 100644 index 00000000..9e7780c8 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.h @@ -0,0 +1,133 @@ +// x86_2.h + +#ifndef __BRANCH_X86_2_H +#define __BRANCH_X86_2_H + +#include "../../../Common/MyCom.h" +#include "../RangeCoder/RangeCoderBit.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278B-0303-010100000100} +#define MyClass2_a(Name, id, subId, encodingId) \ +DEFINE_GUID(CLSID_CCompressConvert ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); + +#define MyClass_a(Name, id, subId) \ +MyClass2_a(Name ## _Encoder, id, subId, 0x01) \ +MyClass2_a(Name ## _Decoder, id, subId, 0x00) + +MyClass_a(BCJ2_x86, 0x01, 0x1B) + +const int kNumMoveBits = 5; + +#ifndef EXTRACT_ONLY + +class CBCJ2_x86_Encoder: + public ICompressCoder2, + public CMyUnknownImp +{ + Byte *_buffer; +public: + CBCJ2_x86_Encoder(): _buffer(0) {}; + ~CBCJ2_x86_Encoder(); + bool Create(); + + COutBuffer _mainStream; + COutBuffer _callStream; + COutBuffer _jumpStream; + NCompress::NRangeCoder::CEncoder _rangeEncoder; + NCompress::NRangeCoder::CBitEncoder _statusE8Encoder[256]; + NCompress::NRangeCoder::CBitEncoder _statusE9Encoder; + NCompress::NRangeCoder::CBitEncoder _statusJccEncoder; + + HRESULT Flush(); + void ReleaseStreams() + { + _mainStream.ReleaseStream(); + _callStream.ReleaseStream(); + _jumpStream.ReleaseStream(); + _rangeEncoder.ReleaseStream(); + } + + class CCoderReleaser + { + CBCJ2_x86_Encoder *_coder; + public: + CCoderReleaser(CBCJ2_x86_Encoder *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 CBCJ2_x86_Decoder: + public ICompressCoder2, + public CMyUnknownImp +{ +public: + CInBuffer _mainInStream; + CInBuffer _callStream; + CInBuffer _jumpStream; + NCompress::NRangeCoder::CDecoder _rangeDecoder; + NCompress::NRangeCoder::CBitDecoder _statusE8Decoder[256]; + NCompress::NRangeCoder::CBitDecoder _statusE9Decoder; + NCompress::NRangeCoder::CBitDecoder _statusJccDecoder; + + COutBuffer _outStream; + + void ReleaseStreams() + { + _mainInStream.ReleaseStream(); + _callStream.ReleaseStream(); + _jumpStream.ReleaseStream(); + _rangeDecoder.ReleaseStream(); + _outStream.ReleaseStream(); + } + + HRESULT Flush() { return _outStream.Flush(); } + class CCoderReleaser + { + CBCJ2_x86_Decoder *_coder; + public: + CCoderReleaser(CBCJ2_x86_Decoder *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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h new file mode 100644 index 00000000..19a1de0e --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h @@ -0,0 +1,55 @@ +// BinTree.h + +#include "../LZInWindow.h" +#include "../IMatchFinder.h" + +namespace BT_NAMESPACE { + +typedef UInt32 CIndex; +const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1; + +class CMatchFinderBinTree: + public IMatchFinder, + public IMatchFinderSetCallback, + public CLZInWindow, + public CMyUnknownImp +{ + UInt32 _cyclicBufferPos; + UInt32 _cyclicBufferSize; // it must be historySize + 1 + UInt32 _matchMaxLen; + CIndex *_hash; + UInt32 _cutValue; + + CMyComPtr m_Callback; + + void Normalize(); + void FreeThisClassMemory(); + void FreeMemory(); + + MY_UNKNOWN_IMP1(IMatchFinderSetCallback) + + STDMETHOD(Init)(ISequentialInStream *inStream); + STDMETHOD_(void, ReleaseStream)(); + STDMETHOD(MovePos)(); + STDMETHOD_(Byte, GetIndexByte)(Int32 index); + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit); + STDMETHOD_(UInt32, GetNumAvailableBytes)(); + STDMETHOD_(const Byte *, GetPointerToCurrentPos)(); + STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter); + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances); + STDMETHOD_(void, DummyLongestMatch)(); + + // IMatchFinderSetCallback + STDMETHOD(SetCallback)(IMatchFinderCallback *callback); + + virtual void BeforeMoveBlock(); + virtual void AfterMoveBlock(); + +public: + CMatchFinderBinTree(); + virtual ~CMatchFinderBinTree(); + void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; } +}; + +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h new file mode 100644 index 00000000..9dbe35d6 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h @@ -0,0 +1,12 @@ +// BinTree2.h + +#ifndef __BINTREE2_H +#define __BINTREE2_H + +#undef BT_NAMESPACE +#define BT_NAMESPACE NBT2 + +#include "BinTree.h" +#include "BinTreeMain.h" + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h new file mode 100644 index 00000000..9a68669f --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h @@ -0,0 +1,16 @@ +// BinTree3.h + +#ifndef __BINTREE3_H +#define __BINTREE3_H + +#undef BT_NAMESPACE +#define BT_NAMESPACE NBT3 + +#define HASH_ARRAY_2 + +#include "BinTree.h" +#include "BinTreeMain.h" + +#undef HASH_ARRAY_2 + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree3Z.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree3Z.h new file mode 100644 index 00000000..b77de3d9 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree3Z.h @@ -0,0 +1,16 @@ +// BinTree3Z.h + +#ifndef __BINTREE3Z_H +#define __BINTREE3Z_H + +#undef BT_NAMESPACE +#define BT_NAMESPACE NBT3Z + +#define HASH_ZIP + +#include "BinTree.h" +#include "BinTreeMain.h" + +#undef HASH_ZIP + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h new file mode 100644 index 00000000..bdc4a87b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h @@ -0,0 +1,18 @@ +// BinTree4.h + +#ifndef __BINTREE4_H +#define __BINTREE4_H + +#undef BT_NAMESPACE +#define BT_NAMESPACE NBT4 + +#define HASH_ARRAY_2 +#define HASH_ARRAY_3 + +#include "BinTree.h" +#include "BinTreeMain.h" + +#undef HASH_ARRAY_2 +#undef HASH_ARRAY_3 + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree4b.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree4b.h new file mode 100644 index 00000000..06f56662 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTree4b.h @@ -0,0 +1,20 @@ +// BinTree4b.h + +#ifndef __BINTREE4B_H +#define __BINTREE4B_H + +#undef BT_NAMESPACE +#define BT_NAMESPACE NBT4B + +#define HASH_ARRAY_2 +#define HASH_ARRAY_3 +#define HASH_BIG + +#include "BinTree.h" +#include "BinTreeMain.h" + +#undef HASH_ARRAY_2 +#undef HASH_ARRAY_3 +#undef HASH_BIG + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h new file mode 100644 index 00000000..452466a7 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h @@ -0,0 +1,444 @@ +// BinTreeMain.h + +#include "../../../../Common/Defs.h" +#include "../../../../Common/CRC.h" +#include "../../../../Common/Alloc.h" + +namespace BT_NAMESPACE { + +#ifdef HASH_ARRAY_2 + static const UInt32 kHash2Size = 1 << 10; + #ifdef HASH_ARRAY_3 + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 4; + static const UInt32 kHash3Size = 1 << 18; + #ifdef HASH_BIG + static const UInt32 kHashSize = 1 << 23; + #else + static const UInt32 kHashSize = 1 << 20; + #endif + #else + static const UInt32 kNumHashDirectBytes = 3; + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); + #endif +#else + #ifdef HASH_ZIP + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << 16; + #else + #define THERE_ARE_DIRECT_HASH_BYTES + static const UInt32 kNumHashDirectBytes = 2; + static const UInt32 kNumHashBytes = 2; + static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); + #endif +#endif + +static const UInt32 kHashSizeSum = kHashSize + #ifdef HASH_ARRAY_2 + + kHash2Size + #ifdef HASH_ARRAY_3 + + kHash3Size + #endif + #endif + ; + +#ifdef HASH_ARRAY_2 +static const UInt32 kHash2Offset = kHashSize; +#ifdef HASH_ARRAY_3 +static const UInt32 kHash3Offset = kHashSize + kHash2Size; +#endif +#endif + +CMatchFinderBinTree::CMatchFinderBinTree(): + _hash(0), + _cutValue(0xFF) +{ +} + +void CMatchFinderBinTree::FreeThisClassMemory() +{ + BigFree(_hash); + _hash = 0; +} + +void CMatchFinderBinTree::FreeMemory() +{ + FreeThisClassMemory(); + CLZInWindow::Free(); +} + +CMatchFinderBinTree::~CMatchFinderBinTree() +{ + FreeMemory(); +} + +STDMETHODIMP CMatchFinderBinTree::Create(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) +{ + UInt32 sizeReserv = (historySize + keepAddBufferBefore + + matchMaxLen + keepAddBufferAfter) / 2 + 256; + if (CLZInWindow::Create(historySize + keepAddBufferBefore, + matchMaxLen + keepAddBufferAfter, sizeReserv)) + { + if (historySize + 256 > kMaxValForNormalize) + { + FreeMemory(); + return E_INVALIDARG; + } + _matchMaxLen = matchMaxLen; + UInt32 newCyclicBufferSize = historySize + 1; + if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize) + return S_OK; + FreeThisClassMemory(); + _cyclicBufferSize = newCyclicBufferSize; // don't change it + _hash = (CIndex *)BigAlloc((kHashSizeSum + _cyclicBufferSize * 2) * sizeof(CIndex)); + if (_hash != 0) + return S_OK; + } + FreeMemory(); + return E_OUTOFMEMORY; +} + +static const UInt32 kEmptyHashValue = 0; + +STDMETHODIMP CMatchFinderBinTree::Init(ISequentialInStream *stream) +{ + RINOK(CLZInWindow::Init(stream)); + for(UInt32 i = 0; i < kHashSizeSum; i++) + _hash[i] = kEmptyHashValue; + _cyclicBufferPos = 0; + ReduceOffsets(-1); + return S_OK; +} + +STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream() +{ + // ReleaseStream(); +} + +#ifdef HASH_ARRAY_2 +#ifdef HASH_ARRAY_3 +inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value) +{ + UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; + hash2Value = temp & (kHash2Size - 1); + hash3Value = (temp ^ (UInt32(pointer[2]) << 8)) & (kHash3Size - 1); + return (temp ^ (UInt32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) & + (kHashSize - 1); +} +#else // no HASH_ARRAY_3 +inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value) +{ + hash2Value = (CCRC::Table[pointer[0]] ^ pointer[1]) & (kHash2Size - 1); + return ((UInt32(pointer[0]) << 16)) | ((UInt32(pointer[1]) << 8)) | pointer[2]; +} +#endif // HASH_ARRAY_3 +#else // no HASH_ARRAY_2 +#ifdef HASH_ZIP +inline UInt32 Hash(const Byte *pointer) +{ + return ((UInt32(pointer[0]) << 8) ^ + CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1); +} +#else // no HASH_ZIP +inline UInt32 Hash(const Byte *pointer) +{ + return pointer[0] ^ (UInt32(pointer[1]) << 8); +} +#endif // HASH_ZIP +#endif // HASH_ARRAY_2 + +STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetLongestMatch(UInt32 *distances) +{ + UInt32 lenLimit; + if (_pos + _matchMaxLen <= _streamPos) + lenLimit = _matchMaxLen; + else + { + lenLimit = _streamPos - _pos; + if(lenLimit < kNumHashBytes) + return 0; + } + + UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + Byte *cur = _buffer + _pos; + + UInt32 maxLen = 0; + + #ifdef HASH_ARRAY_2 + UInt32 hash2Value; + #ifdef HASH_ARRAY_3 + UInt32 hash3Value; + UInt32 hashValue = Hash(cur, hash2Value, hash3Value); + #else + UInt32 hashValue = Hash(cur, hash2Value); + #endif + #else + UInt32 hashValue = Hash(cur); + #endif + + UInt32 curMatch = _hash[hashValue]; + #ifdef HASH_ARRAY_2 + UInt32 curMatch2 = _hash[kHash2Offset + hash2Value]; + #ifdef HASH_ARRAY_3 + UInt32 curMatch3 = _hash[kHash3Offset + hash3Value]; + #endif + _hash[kHash2Offset + hash2Value] = _pos; + distances[2] = 0xFFFFFFFF; + if(curMatch2 > matchMinPos) + if (_buffer[curMatch2] == cur[0]) + { + distances[2] = _pos - curMatch2 - 1; + maxLen = 2; + } + + #ifdef HASH_ARRAY_3 + _hash[kHash3Offset + hash3Value] = _pos; + distances[3] = 0xFFFFFFFF; + if(curMatch3 > matchMinPos) + if (_buffer[curMatch3] == cur[0]) + { + distances[3] = _pos - curMatch3 - 1; + maxLen = 3; + } + #endif + #endif + + _hash[hashValue] = _pos; + + CIndex *son = _hash + kHashSizeSum; + CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CIndex *ptr1 = son + (_cyclicBufferPos << 1); + + distances[kNumHashBytes] = 0xFFFFFFFF; + + #ifdef THERE_ARE_DIRECT_HASH_BYTES + if (lenLimit == kNumHashDirectBytes) + { + if(curMatch > matchMinPos) + while (maxLen < kNumHashDirectBytes) + distances[++maxLen] = _pos - curMatch - 1; + // We don't need tree in this case + } + else + #endif + { + UInt32 len0, len1; + len0 = len1 = kNumHashDirectBytes; + UInt32 count = _cutValue; + while(true) + { + if(curMatch <= matchMinPos || count-- == 0) + { + *ptr0 = kEmptyHashValue; + *ptr1 = kEmptyHashValue; + break; + } + Byte *pb = _buffer + curMatch; + UInt32 len = MyMin(len0, len1); + do + { + if (pb[len] != cur[len]) + break; + } + while(++len != lenLimit); + + UInt32 delta = _pos - curMatch; + while (maxLen < len) + distances[++maxLen] = delta - 1; + + UInt32 cyclicPos = (delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta): + (_cyclicBufferPos - delta + _cyclicBufferSize); + CIndex *pair = son + (cyclicPos << 1); + + if (len != lenLimit) + { + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + else + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + break; + } + } + } + #ifdef HASH_ARRAY_2 + #ifdef HASH_ARRAY_3 + if (distances[4] < distances[3]) + distances[3] = distances[4]; + #endif + if (distances[3] < distances[2]) + distances[2] = distances[3]; + #endif + return maxLen; +} + +STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch() +{ + UInt32 lenLimit; + if (_pos + _matchMaxLen <= _streamPos) + lenLimit = _matchMaxLen; + else + { + lenLimit = _streamPos - _pos; + if(lenLimit < kNumHashBytes) + return; + } + UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + Byte *cur = _buffer + _pos; + + #ifdef HASH_ARRAY_2 + UInt32 hash2Value; + #ifdef HASH_ARRAY_3 + UInt32 hash3Value; + UInt32 hashValue = Hash(cur, hash2Value, hash3Value); + _hash[kHash3Offset + hash3Value] = _pos; + #else + UInt32 hashValue = Hash(cur, hash2Value); + #endif + _hash[kHash2Offset + hash2Value] = _pos; + #else + UInt32 hashValue = Hash(cur); + #endif + + UInt32 curMatch = _hash[hashValue]; + _hash[hashValue] = _pos; + + CIndex *son = _hash + kHashSizeSum; + CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CIndex *ptr1 = son + (_cyclicBufferPos << 1); + + #ifdef THERE_ARE_DIRECT_HASH_BYTES + if (lenLimit != kNumHashDirectBytes) + #endif + { + UInt32 len0, len1; + len0 = len1 = kNumHashDirectBytes; + UInt32 count = _cutValue; + while(true) + { + if(curMatch <= matchMinPos || count-- == 0) + break; + Byte *pb = _buffer + curMatch; + UInt32 len = MyMin(len0, len1); + do + { + if (pb[len] != cur[len]) + break; + } + while(++len != lenLimit); + + UInt32 delta = _pos - curMatch; + UInt32 cyclicPos = (delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta): + (_cyclicBufferPos - delta + _cyclicBufferSize); + CIndex *pair = son + (cyclicPos << 1); + + if (len != lenLimit) + { + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + else + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + } + *ptr0 = kEmptyHashValue; + *ptr1 = kEmptyHashValue; +} + +void CMatchFinderBinTree::Normalize() +{ + UInt32 subValue = _pos - _cyclicBufferSize; + CIndex *items = _hash; + UInt32 numItems = (kHashSizeSum + _cyclicBufferSize * 2); + for (UInt32 i = 0; i < numItems; i++) + { + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } + ReduceOffsets(subValue); +} + +STDMETHODIMP CMatchFinderBinTree::MovePos() +{ + if (++_cyclicBufferPos == _cyclicBufferSize) + _cyclicBufferPos = 0; + RINOK(CLZInWindow::MovePos()); + if (_pos == kMaxValForNormalize) + Normalize(); + return S_OK; +} + +STDMETHODIMP_(Byte) CMatchFinderBinTree::GetIndexByte(Int32 index) + { return CLZInWindow::GetIndexByte(index); } + +STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetMatchLen(Int32 index, + UInt32 back, UInt32 limit) + { return CLZInWindow::GetMatchLen(index, back, limit); } + +STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetNumAvailableBytes() + { return CLZInWindow::GetNumAvailableBytes(); } + +STDMETHODIMP_(const Byte *) CMatchFinderBinTree::GetPointerToCurrentPos() + { return CLZInWindow::GetPointerToCurrentPos(); } + +// IMatchFinderSetCallback +STDMETHODIMP CMatchFinderBinTree::SetCallback(IMatchFinderCallback *callback) +{ + m_Callback = callback; + return S_OK; +} + +void CMatchFinderBinTree::BeforeMoveBlock() +{ + if (m_Callback) + m_Callback->BeforeChangingBufferPos(); + CLZInWindow::BeforeMoveBlock(); +} + +void CMatchFinderBinTree::AfterMoveBlock() +{ + if (m_Callback) + m_Callback->AfterChangingBufferPos(); + CLZInWindow::AfterMoveBlock(); +} + +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC.h new file mode 100644 index 00000000..53f3e217 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC.h @@ -0,0 +1,55 @@ +// HC.h + +#include "../LZInWindow.h" +#include "../IMatchFinder.h" + +namespace HC_NAMESPACE { + +typedef UInt32 CIndex; +const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1; + +class CMatchFinderHC: + public IMatchFinder, + public IMatchFinderSetCallback, + public CLZInWindow, + public CMyUnknownImp +{ + UInt32 _cyclicBufferPos; + UInt32 _cyclicBufferSize; // it must be historySize + 1 + UInt32 _matchMaxLen; + CIndex *_hash; + UInt32 _cutValue; + + CMyComPtr m_Callback; + + void Normalize(); + void FreeThisClassMemory(); + void FreeMemory(); + + MY_UNKNOWN_IMP1(IMatchFinderSetCallback) + + STDMETHOD(Init)(ISequentialInStream *inStream); + STDMETHOD_(void, ReleaseStream)(); + STDMETHOD(MovePos)(); + STDMETHOD_(Byte, GetIndexByte)(Int32 index); + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit); + STDMETHOD_(UInt32, GetNumAvailableBytes)(); + STDMETHOD_(const Byte *, GetPointerToCurrentPos)(); + STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter); + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances); + STDMETHOD_(void, DummyLongestMatch)(); + + // IMatchFinderSetCallback + STDMETHOD(SetCallback)(IMatchFinderCallback *callback); + + virtual void BeforeMoveBlock(); + virtual void AfterMoveBlock(); + +public: + CMatchFinderHC(); + virtual ~CMatchFinderHC(); + void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; } +}; + +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC2.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC2.h new file mode 100644 index 00000000..7211cc50 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC2.h @@ -0,0 +1,13 @@ +// HC2.h + +#ifndef __HC2_H +#define __HC2_H + +#undef HC_NAMESPACE +#define HC_NAMESPACE NHC2 + +#include "HCMF.h" +#include "HCMFMain.h" + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC3.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC3.h new file mode 100644 index 00000000..38f05d23 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC3.h @@ -0,0 +1,17 @@ +// HC3.h + +#ifndef __HC3_H +#define __HC3_H + +#undef HC_NAMESPACE +#define HC_NAMESPACE NHC3 + +#define HASH_ARRAY_2 + +#include "HC.h" +#include "HCMain.h" + +#undef HASH_ARRAY_2 + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC4.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC4.h new file mode 100644 index 00000000..7d4e2117 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC4.h @@ -0,0 +1,19 @@ +// HC4.h + +#ifndef __HC4_H +#define __HC4_H + +#undef HC_NAMESPACE +#define HC_NAMESPACE NHC4 + +#define HASH_ARRAY_2 +#define HASH_ARRAY_3 + +#include "HC.h" +#include "HCMain.h" + +#undef HASH_ARRAY_2 +#undef HASH_ARRAY_3 + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC4b.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC4b.h new file mode 100644 index 00000000..229e5fdf --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HC4b.h @@ -0,0 +1,21 @@ +// HC4b.h + +#ifndef __HC4B__H +#define __HC4B__H + +#undef HC_NAMESPACE +#define HC_NAMESPACE NHC4b + +#define HASH_ARRAY_2 +#define HASH_ARRAY_3 +#define HASH_BIG + +#include "HC.h" +#include "HCMain.h" + +#undef HASH_ARRAY_2 +#undef HASH_ARRAY_3 +#undef HASH_BIG + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h new file mode 100644 index 00000000..61d932cb --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h @@ -0,0 +1,350 @@ +// HC.h + +#include "../../../../Common/Defs.h" +#include "../../../../Common/CRC.h" +#include "../../../../Common/Alloc.h" + +namespace HC_NAMESPACE { + +#ifdef HASH_ARRAY_2 + static const UInt32 kHash2Size = 1 << 10; + #ifdef HASH_ARRAY_3 + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 4; + static const UInt32 kHash3Size = 1 << 18; + #ifdef HASH_BIG + static const UInt32 kHashSize = 1 << 23; + #else + static const UInt32 kHashSize = 1 << 20; + #endif + #else + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << (16); + #endif +#else + #ifdef HASH_ZIP + static const UInt32 kNumHashDirectBytes = 0; + static const UInt32 kNumHashBytes = 3; + static const UInt32 kHashSize = 1 << 16; + #else + #define THERE_ARE_DIRECT_HASH_BYTES + static const UInt32 kNumHashDirectBytes = 2; + static const UInt32 kNumHashBytes = 2; + static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); + #endif +#endif + +static const UInt32 kHashSizeSum = kHashSize + #ifdef HASH_ARRAY_2 + + kHash2Size + #ifdef HASH_ARRAY_3 + + kHash3Size + #endif + #endif + ; + +#ifdef HASH_ARRAY_2 +static const UInt32 kHash2Offset = kHashSize; +#ifdef HASH_ARRAY_3 +static const UInt32 kHash3Offset = kHashSize + kHash2Size; +#endif +#endif + +CMatchFinderHC::CMatchFinderHC(): + _hash(0), + _cutValue(16) +{ +} + +void CMatchFinderHC::FreeThisClassMemory() +{ + BigFree(_hash); + _hash = 0; +} + +void CMatchFinderHC::FreeMemory() +{ + FreeThisClassMemory(); + CLZInWindow::Free(); +} + +CMatchFinderHC::~CMatchFinderHC() +{ + FreeMemory(); +} + +STDMETHODIMP CMatchFinderHC::Create(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) +{ + UInt32 sizeReserv = (historySize + keepAddBufferBefore + + matchMaxLen + keepAddBufferAfter) / 2 + 256; + if (CLZInWindow::Create(historySize + keepAddBufferBefore, + matchMaxLen + keepAddBufferAfter, sizeReserv)) + { + if (historySize + 256 > kMaxValForNormalize) + { + FreeMemory(); + return E_INVALIDARG; + } + _matchMaxLen = matchMaxLen; + UInt32 newCyclicBufferSize = historySize + 1; + if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize) + return S_OK; + FreeThisClassMemory(); + _cyclicBufferSize = newCyclicBufferSize; // don't change it + _hash = (CIndex *)BigAlloc((kHashSizeSum + _cyclicBufferSize) * sizeof(CIndex)); + if (_hash != 0) + return S_OK; + } + FreeMemory(); + return E_OUTOFMEMORY; +} + +static const UInt32 kEmptyHashValue = 0; + +STDMETHODIMP CMatchFinderHC::Init(ISequentialInStream *stream) +{ + RINOK(CLZInWindow::Init(stream)); + for(UInt32 i = 0; i < kHashSizeSum; i++) + _hash[i] = kEmptyHashValue; + _cyclicBufferPos = 0; + ReduceOffsets(-1); + return S_OK; +} + +STDMETHODIMP_(void) CMatchFinderHC::ReleaseStream() +{ + // ReleaseStream(); +} + +#ifdef HASH_ARRAY_2 +#ifdef HASH_ARRAY_3 +inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value, UInt32 &hash3Value) +{ + UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; + hash2Value = temp & (kHash2Size - 1); + hash3Value = (temp ^ (UInt32(pointer[2]) << 8)) & (kHash3Size - 1); + return (temp ^ (UInt32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) & + (kHashSize - 1); +} +#else // no HASH_ARRAY_3 +inline UInt32 Hash(const Byte *pointer, UInt32 &hash2Value) +{ + UInt32 temp = CCRC::Table[pointer[0]] ^ pointer[1]; + hash2Value = temp & (kHash2Size - 1); + return (temp ^ (UInt32(pointer[2]) << 8)) & (kHashSize - 1);; +} +#endif // HASH_ARRAY_3 +#else // no HASH_ARRAY_2 +#ifdef HASH_ZIP +inline UInt32 Hash(const Byte *pointer) +{ + return ((UInt32(pointer[0]) << 8) ^ + CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1); +} +#else // no HASH_ZIP +inline UInt32 Hash(const Byte *pointer) +{ + return pointer[0] ^ (UInt32(pointer[1]) << 8); +} +#endif // HASH_ZIP +#endif // HASH_ARRAY_2 + + +STDMETHODIMP_(UInt32) CMatchFinderHC::GetLongestMatch(UInt32 *distances) +{ + UInt32 lenLimit; + if (_pos + _matchMaxLen <= _streamPos) + lenLimit = _matchMaxLen; + else + { + lenLimit = _streamPos - _pos; + if(lenLimit < kNumHashBytes) + return 0; + } + + UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + Byte *cur = _buffer + _pos; + + UInt32 maxLen = 0; + + #ifdef HASH_ARRAY_2 + UInt32 hash2Value; + #ifdef HASH_ARRAY_3 + UInt32 hash3Value; + UInt32 hashValue = Hash(cur, hash2Value, hash3Value); + #else + UInt32 hashValue = Hash(cur, hash2Value); + #endif + #else + UInt32 hashValue = Hash(cur); + #endif + #ifdef HASH_ARRAY_2 + + UInt32 curMatch2 = _hash[kHash2Offset + hash2Value]; + _hash[kHash2Offset + hash2Value] = _pos; + distances[2] = 0xFFFFFFFF; + if(curMatch2 > matchMinPos) + if (_buffer[curMatch2] == cur[0]) + { + distances[2] = _pos - curMatch2 - 1; + maxLen = 2; + } + + #ifdef HASH_ARRAY_3 + + UInt32 curMatch3 = _hash[kHash3Offset + hash3Value]; + _hash[kHash3Offset + hash3Value] = _pos; + distances[3] = 0xFFFFFFFF; + if(curMatch3 > matchMinPos) + if (_buffer[curMatch3] == cur[0]) + { + distances[3] = _pos - curMatch3 - 1; + maxLen = 3; + } + + #endif + #endif + + UInt32 curMatch = _hash[hashValue]; + _hash[hashValue] = _pos; + CIndex *chain = _hash + kHashSizeSum; + chain[_cyclicBufferPos] = curMatch; + distances[kNumHashBytes] = 0xFFFFFFFF; + #ifdef THERE_ARE_DIRECT_HASH_BYTES + if (lenLimit == kNumHashDirectBytes) + { + if(curMatch > matchMinPos) + while (maxLen < kNumHashDirectBytes) + distances[++maxLen] = _pos - curMatch - 1; + } + else + #endif + { + UInt32 count = _cutValue; + do + { + if(curMatch <= matchMinPos) + break; + Byte *pby1 = _buffer + curMatch; + UInt32 currentLen = kNumHashDirectBytes; + do + { + if (pby1[currentLen] != cur[currentLen]) + break; + } + while(++currentLen != lenLimit); + + UInt32 delta = _pos - curMatch; + while (maxLen < currentLen) + distances[++maxLen] = delta - 1; + if(currentLen == lenLimit) + break; + + UInt32 cyclicPos = (delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta): + (_cyclicBufferPos - delta + _cyclicBufferSize); + + curMatch = chain[cyclicPos]; + } + while(--count != 0); + } + #ifdef HASH_ARRAY_2 + #ifdef HASH_ARRAY_3 + if (distances[4] < distances[3]) + distances[3] = distances[4]; + #endif + if (distances[3] < distances[2]) + distances[2] = distances[3]; + #endif + return maxLen; +} + +STDMETHODIMP_(void) CMatchFinderHC::DummyLongestMatch() +{ + if (_streamPos - _pos < kNumHashBytes) + return; + + Byte *cur = _buffer + _pos; + + #ifdef HASH_ARRAY_2 + UInt32 hash2Value; + #ifdef HASH_ARRAY_3 + UInt32 hash3Value; + UInt32 hashValue = Hash(cur, hash2Value, hash3Value); + _hash[kHash3Offset + hash3Value] = _pos; + #else + UInt32 hashValue = Hash(cur, hash2Value); + #endif + _hash[kHash2Offset + hash2Value] = _pos; + #else + UInt32 hashValue = Hash(cur); + #endif + + _hash[kHashSizeSum + _cyclicBufferPos] = _hash[hashValue]; + _hash[hashValue] = _pos; +} + +void CMatchFinderHC::Normalize() +{ + UInt32 subValue = _pos - _cyclicBufferSize; + CIndex *items = _hash; + UInt32 numItems = kHashSizeSum + _cyclicBufferSize; + for (UInt32 i = 0; i < numItems; i++) + { + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } + ReduceOffsets(subValue); +} + +STDMETHODIMP CMatchFinderHC::MovePos() +{ + if (++_cyclicBufferPos == _cyclicBufferSize) + _cyclicBufferPos = 0; + RINOK(CLZInWindow::MovePos()); + if (_pos == kMaxValForNormalize) + Normalize(); + return S_OK; +} + +STDMETHODIMP_(Byte) CMatchFinderHC::GetIndexByte(Int32 index) + { return CLZInWindow::GetIndexByte(index); } + +STDMETHODIMP_(UInt32) CMatchFinderHC::GetMatchLen(Int32 index, + UInt32 back, UInt32 limit) + { return CLZInWindow::GetMatchLen(index, back, limit); } + +STDMETHODIMP_(UInt32) CMatchFinderHC::GetNumAvailableBytes() + { return CLZInWindow::GetNumAvailableBytes(); } + +STDMETHODIMP_(const Byte *) CMatchFinderHC::GetPointerToCurrentPos() + { return CLZInWindow::GetPointerToCurrentPos(); } + +// IMatchFinderSetCallback +STDMETHODIMP CMatchFinderHC::SetCallback(IMatchFinderCallback *callback) +{ + m_Callback = callback; + return S_OK; +} + +void CMatchFinderHC::BeforeMoveBlock() +{ + if (m_Callback) + m_Callback->BeforeChangingBufferPos(); + CLZInWindow::BeforeMoveBlock(); +} + +void CMatchFinderHC::AfterMoveBlock() +{ + if (m_Callback) + m_Callback->AfterChangingBufferPos(); + CLZInWindow::AfterMoveBlock(); +} + +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/IMatchFinder.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/IMatchFinder.h new file mode 100644 index 00000000..1d9c88f2 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/IMatchFinder.h @@ -0,0 +1,63 @@ +// MatchFinders/IMatchFinder.h + +#ifndef __IMATCHFINDER_H +#define __IMATCHFINDER_H + +// {23170F69-40C1-278A-0000-000200010000} +DEFINE_GUID(IID_IInWindowStream, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200010000") +IInWindowStream: public IUnknown +{ + STDMETHOD(Init)(ISequentialInStream *inStream) PURE; + STDMETHOD_(void, ReleaseStream)() PURE; + STDMETHOD(MovePos)() PURE; + STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE; + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE; + STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE; + STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE; +}; + +// {23170F69-40C1-278A-0000-000200020000} +DEFINE_GUID(IID_IMatchFinder, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000") +IMatchFinder: public IInWindowStream +{ + STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE; + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances) PURE; + STDMETHOD_(void, DummyLongestMatch)() PURE; +}; + +// {23170F69-40C1-278A-0000-000200020100} +DEFINE_GUID(IID_IMatchFinderCallback, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020100") +IMatchFinderCallback: public IUnknown +{ + STDMETHOD(BeforeChangingBufferPos)() PURE; + STDMETHOD(AfterChangingBufferPos)() PURE; +}; + +// {23170F69-40C1-278A-0000-000200020200} +DEFINE_GUID(IID_IMatchFinderSetCallback, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020200") +IMatchFinderSetCallback: public IUnknown +{ + STDMETHOD(SetCallback)(IMatchFinderCallback *callback) PURE; +}; + +/* +// {23170F69-40C1-278A-0000-000200030000} +DEFINE_GUID(IID_IInitMatchFinder, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000200030000") +IMatchFinderInit: public IUnknown +{ + STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder) PURE; +}; +*/ + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.cpp new file mode 100644 index 00000000..a7b7a387 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.cpp @@ -0,0 +1,102 @@ +// LZInWindow.cpp + +#include "StdAfx.h" + +#include "LZInWindow.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" + +void CLZInWindow::Free() +{ + ::BigFree(_bufferBase); + _bufferBase = 0; +} + +bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) +{ + _keepSizeBefore = keepSizeBefore; + _keepSizeAfter = keepSizeAfter; + _keepSizeReserv = keepSizeReserv; + UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; + if (_bufferBase == 0 || _blockSize != blockSize) + { + Free(); + _blockSize = blockSize; + if (_blockSize != 0) + _bufferBase = (Byte *)::BigAlloc(_blockSize); + } + _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter; + if (_blockSize == 0) + return true; + return (_bufferBase != 0); +} + + +HRESULT CLZInWindow::Init(ISequentialInStream *stream) +{ + _stream = stream; + _buffer = _bufferBase; + _pos = 0; + _streamPos = 0; + _streamEndWasReached = false; + return ReadBlock(); +} + +/* +void CLZInWindow::ReleaseStream() +{ + _stream.Release(); +} +*/ + +/////////////////////////////////////////// +// ReadBlock + +// In State: +// (_buffer + _streamPos) <= (_bufferBase + _blockSize) +// Out State: +// _posLimit <= _blockSize - _keepSizeAfter; +// if(_streamEndWasReached == false): +// _streamPos >= _pos + _keepSizeAfter +// _posLimit = _streamPos - _keepSizeAfter; +// else +// + +HRESULT CLZInWindow::ReadBlock() +{ + if(_streamEndWasReached) + return S_OK; + while(true) + { + UInt32 size = UInt32(_bufferBase - _buffer) + _blockSize - _streamPos; + if(size == 0) + return S_OK; + UInt32 numReadBytes; + RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes)); + if(numReadBytes == 0) + { + _posLimit = _streamPos; + const Byte *pointerToPostion = _buffer + _posLimit; + if(pointerToPostion > _pointerToLastSafePosition) + _posLimit = (UInt32)(_pointerToLastSafePosition - _buffer); + _streamEndWasReached = true; + return S_OK; + } + _streamPos += numReadBytes; + if(_streamPos >= _pos + _keepSizeAfter) + { + _posLimit = _streamPos - _keepSizeAfter; + return S_OK; + } + } +} + +void CLZInWindow::MoveBlock() +{ + BeforeMoveBlock(); + UInt32 offset = UInt32(_buffer - _bufferBase) + _pos - _keepSizeBefore; + UInt32 numBytes = UInt32(_buffer - _bufferBase) + _streamPos - offset; + memmove(_bufferBase, _bufferBase + offset, numBytes); + _buffer -= offset; + AfterMoveBlock(); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.h new file mode 100644 index 00000000..7dc194f2 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZInWindow.h @@ -0,0 +1,84 @@ +// LZInWindow.h + +#ifndef __LZ_IN_WINDOW_H +#define __LZ_IN_WINDOW_H + +#include "../../IStream.h" + +class CLZInWindow +{ + Byte *_bufferBase; // pointer to buffer with data + ISequentialInStream *_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 + const Byte *_pointerToLastSafePosition; +protected: + Byte *_buffer; // Pointer to virtual Buffer begin + UInt32 _blockSize; // Size of Allocated memory block + 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 + UInt32 _keepSizeReserv; // how many BYTEs must be kept as reserv + UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream + + virtual void BeforeMoveBlock() {}; + virtual void AfterMoveBlock() {}; + void MoveBlock(); + virtual HRESULT ReadBlock(); + void Free(); +public: + CLZInWindow(): _bufferBase(0) {} + virtual ~CLZInWindow() { Free(); } + + bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, + UInt32 keepSizeReserv = (1<<17)); + + HRESULT Init(ISequentialInStream *stream); + // void ReleaseStream(); + + Byte *GetBuffer() const { return _buffer; } + + const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; } + + HRESULT MovePos() + { + _pos++; + if (_pos > _posLimit) + { + const Byte *pointerToPostion = _buffer + _pos; + if(pointerToPostion > _pointerToLastSafePosition) + MoveBlock(); + return ReadBlock(); + } + else + return S_OK; + } + Byte GetIndexByte(Int32 index)const + { return _buffer[(size_t)_pos + index]; } + + // index + limit have not to exceed _keepSizeAfter; + UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const + { + if(_streamEndWasReached) + if ((_pos + index) + limit > _streamPos) + limit = _streamPos - (_pos + index); + distance++; + Byte *pby = _buffer + (size_t)_pos + index; + UInt32 i; + for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++); + return i; + } + + UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; } + + void ReduceOffsets(Int32 subValue) + { + _buffer += subValue; + _posLimit -= subValue; + _pos -= subValue; + _streamPos -= subValue; + } + +}; + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.cpp new file mode 100644 index 00000000..329a7db3 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.cpp @@ -0,0 +1,17 @@ +// LZOutWindow.cpp + +#include "StdAfx.h" + +#include "../../../Common/Alloc.h" +#include "LZOutWindow.h" + +void CLZOutWindow::Init(bool solid) +{ + if(!solid) + COutBuffer::Init(); + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.h new file mode 100644 index 00000000..ba38c5e2 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/LZOutWindow.h @@ -0,0 +1,64 @@ +// LZOutWindow.h + +#ifndef __LZ_OUT_WINDOW_H +#define __LZ_OUT_WINDOW_H + +#include "../../IStream.h" +#include "../../Common/OutBuffer.h" + +/* +#ifndef _NO_EXCEPTIONS +class CLZOutWindowException +{ +public: + HRESULT ErrorCode; + CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {} +}; +#endif +*/ +typedef COutBufferException CLZOutWindowException; + +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 (pos >= _bufferSize) + { + if (!_overDict) + return false; + pos += _bufferSize; + } + 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat.h new file mode 100644 index 00000000..2d0ce6d0 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat.h @@ -0,0 +1,318 @@ +// Pat.h + +// #ifndef __PATRICIA__H +// #define __PATRICIA__H + +#include "../../../../Common/MyCom.h" +#include "../../../../Common/Types.h" +#include "../LZInWindow.h" + +namespace PAT_NAMESPACE { + +struct CNode; + +typedef CNode *CNodePointer; + +// #define __AUTO_REMOVE + +// #define __NODE_4_BITS +// #define __NODE_3_BITS +// #define __NODE_2_BITS +// #define __NODE_2_BITS_PADDING + +// #define __HASH_3 + + +typedef UInt32 CIndex; + +#ifdef __NODE_4_BITS + typedef UInt32 CIndex2; + typedef UInt32 CSameBitsType; +#else +#ifdef __NODE_3_BITS + typedef UInt32 CIndex2; + typedef UInt32 CSameBitsType; +#else + + typedef UInt32 CIndex; + typedef UInt32 CSameBitsType; + + typedef CIndex CIndex2; +#endif +#endif + +const UInt32 kNumBitsInIndex = sizeof(CIndex) * 8; +const UInt32 kMatchStartValue = UInt32(1) << (kNumBitsInIndex - 1); +// don't change kMatchStartValue definition, since it is used in +// PatMain.h: + +typedef CIndex CMatchPointer; + +const UInt32 kDescendantEmptyValue = kMatchStartValue - 1; + +union CDescendant +{ + CIndex NodePointer; + CMatchPointer MatchPointer; + bool IsEmpty() const { return NodePointer == kDescendantEmptyValue; } + bool IsNode() const { return NodePointer < kDescendantEmptyValue; } + bool IsMatch() const { return NodePointer > kDescendantEmptyValue; } + void MakeEmpty() { NodePointer = kDescendantEmptyValue; } +}; + +#undef MY_BYTE_SIZE + +#ifdef __NODE_4_BITS + #define MY_BYTE_SIZE 8 + const UInt32 kNumSubBits = 4; +#else +#ifdef __NODE_3_BITS + #define MY_BYTE_SIZE 9 + const UInt32 kNumSubBits = 3; +#else + #define MY_BYTE_SIZE 8 + #ifdef __NODE_2_BITS + const UInt32 kNumSubBits = 2; + #else + const UInt32 kNumSubBits = 1; + #endif +#endif +#endif + +const UInt32 kNumSubNodes = 1 << kNumSubBits; +const UInt32 kSubNodesMask = kNumSubNodes - 1; + +struct CNode +{ + CIndex2 LastMatch; + CSameBitsType NumSameBits; + union + { + CDescendant Descendants[kNumSubNodes]; + UInt32 NextFreeNode; + }; + #ifdef __NODE_2_BITS + #ifdef __NODE_2_BITS_PADDING + UInt32 Padding[2]; + #endif + #endif +}; + +#undef kIDNumBitsByte +#undef kIDNumBitsString + +#ifdef __NODE_4_BITS + #define kIDNumBitsByte 0x30 + #define kIDNumBitsString TEXT("4") +#else +#ifdef __NODE_3_BITS + #define kIDNumBitsByte 0x20 + #define kIDNumBitsString TEXT("3") +#else +#ifdef __NODE_2_BITS + #define kIDNumBitsByte 0x10 + #define kIDNumBitsString TEXT("2") +#else + #define kIDNumBitsByte 0x00 + #define kIDNumBitsString TEXT("1") +#endif +#endif +#endif + +#undef kIDManualRemoveByte +#undef kIDManualRemoveString + +#ifdef __AUTO_REMOVE + #define kIDManualRemoveByte 0x00 + #define kIDManualRemoveString TEXT("") +#else + #define kIDManualRemoveByte 0x08 + #define kIDManualRemoveString TEXT("R") +#endif + +#undef kIDHash3Byte +#undef kIDHash3String + +#ifdef __HASH_3 + #define kIDHash3Byte 0x04 + #define kIDHash3String TEXT("H") +#else + #define kIDHash3Byte 0x00 + #define kIDHash3String TEXT("") +#endif + +#undef kIDUse3BytesByte +#undef kIDUse3BytesString + +#define kIDUse3BytesByte 0x00 +#define kIDUse3BytesString TEXT("") + +#undef kIDPaddingByte +#undef kIDPaddingString + +#ifdef __NODE_2_BITS_PADDING + #define kIDPaddingByte 0x01 + #define kIDPaddingString TEXT("P") +#else + #define kIDPaddingByte 0x00 + #define kIDPaddingString TEXT("") +#endif + + +// #undef kIDString +// #define kIDString TEXT("Compress.MatchFinderPat") kIDNumBitsString kIDManualRemoveString kIDUse3BytesString kIDPaddingString kIDHash3String + +// {23170F69-40C1-278C-01XX-0000000000} + +DEFINE_GUID(PAT_CLSID, +0x23170F69, 0x40C1, 0x278C, 0x01, +kIDNumBitsByte | +kIDManualRemoveByte | kIDHash3Byte | kIDUse3BytesByte | kIDPaddingByte, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + +// III(PAT_NAMESPACE) + +class CPatricia: + public IMatchFinder, + public IMatchFinderSetCallback, + public CMyUnknownImp, + CLZInWindow +{ + MY_UNKNOWN_IMP1(IMatchFinderSetCallback) + + STDMETHOD(Init)(ISequentialInStream *aStream); + STDMETHOD_(void, ReleaseStream)(); + STDMETHOD(MovePos)(); + STDMETHOD_(Byte, GetIndexByte)(Int32 index); + STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit); + STDMETHOD_(UInt32, GetNumAvailableBytes)(); + STDMETHOD(Create)(UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, + UInt32 keepAddBufferAfter); + STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances); + STDMETHOD_(void, DummyLongestMatch)(); + STDMETHOD_(const Byte *, GetPointerToCurrentPos)(); + + void FreeMemory(); +public: + CPatricia(); + ~CPatricia(); + + UInt32 _sizeHistory; + UInt32 _matchMaxLen; + + CDescendant *m_HashDescendants; + #ifdef __HASH_3 + CDescendant *m_Hash2Descendants; + #endif + + CNode *m_Nodes; + + UInt32 m_FreeNode; + UInt32 m_FreeNodeMax; + + #ifdef __AUTO_REMOVE + UInt32 m_NumUsedNodes; + UInt32 m_NumNodes; + #else + bool m_SpecialRemoveMode; + #endif + + bool m_SpecialMode; + UInt32 m_NumNotChangedCycles; + UInt32 *m_TmpBacks; + + CMyComPtr m_Callback; + + virtual void BeforeMoveBlock(); + virtual void AfterMoveBlock(); + + // IMatchFinderSetCallback + STDMETHOD(SetCallback)(IMatchFinderCallback *callback); + + void ChangeLastMatch(UInt32 hashValue); + + #ifdef __AUTO_REMOVE + void TestRemoveDescendant(CDescendant &descendant, UInt32 limitPos); + void TestRemoveNodes(); + void RemoveNode(UInt32 index); + void TestRemoveAndNormalizeDescendant(CDescendant &descendant, + UInt32 limitPos, UInt32 subValue); + void TestRemoveNodesAndNormalize(); + #else + void NormalizeDescendant(CDescendant &descendant, UInt32 subValue); + void Normalize(); + void RemoveMatch(); + #endif +private: + void AddInternalNode(CNodePointer aNode, CIndex *aNodePointerPointer, + Byte aByte, Byte aByteXOR, UInt32 aNumSameBits, UInt32 aPos) + { + while((aByteXOR & kSubNodesMask) == 0) + { + aByteXOR >>= kNumSubBits; + aByte >>= kNumSubBits; + aNumSameBits -= kNumSubBits; + } + // Insert New Node + CNodePointer aNewNode = &m_Nodes[m_FreeNode]; + UInt32 aNodeIndex = *aNodePointerPointer; + *aNodePointerPointer = m_FreeNode; + m_FreeNode = aNewNode->NextFreeNode; + #ifdef __AUTO_REMOVE + m_NumUsedNodes++; + #endif + if (m_FreeNode > m_FreeNodeMax) + { + m_FreeNodeMax = m_FreeNode; + m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1; + } + + UInt32 aBitsNew = aByte & kSubNodesMask; + UInt32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask; + for (UInt32 i = 0; i < kNumSubNodes; i++) + aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue; + aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue; + aNewNode->Descendants[aBitsOld].NodePointer = aNodeIndex; + aNewNode->NumSameBits = CSameBitsType(aNode->NumSameBits - aNumSameBits); + aNewNode->LastMatch = aPos; + + aNode->NumSameBits = CSameBitsType(aNumSameBits - kNumSubBits); + } + + void AddLeafNode(CNodePointer aNode, Byte aByte, Byte aByteXOR, + UInt32 aNumSameBits, UInt32 aPos, UInt32 aDescendantIndex) + { + for(;(aByteXOR & kSubNodesMask) == 0; aNumSameBits += kNumSubBits) + { + aByte >>= kNumSubBits; + aByteXOR >>= kNumSubBits; + } + UInt32 aNewNodeIndex = m_FreeNode; + CNodePointer aNewNode = &m_Nodes[m_FreeNode]; + m_FreeNode = aNewNode->NextFreeNode; + #ifdef __AUTO_REMOVE + m_NumUsedNodes++; + #endif + if (m_FreeNode > m_FreeNodeMax) + { + m_FreeNodeMax = m_FreeNode; + m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1; + } + + UInt32 aBitsNew = (aByte & kSubNodesMask); + UInt32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask; + for (UInt32 i = 0; i < kNumSubNodes; i++) + aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue; + aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue; + aNewNode->Descendants[aBitsOld].MatchPointer = + aNode->Descendants[aDescendantIndex].MatchPointer; + aNewNode->NumSameBits = CSameBitsType(aNumSameBits); + aNewNode->LastMatch = aPos; + aNode->Descendants[aDescendantIndex].NodePointer = aNewNodeIndex; + } +}; + +} + +// #endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2.h new file mode 100644 index 00000000..0c97164d --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2.h @@ -0,0 +1,22 @@ +// Pat2.h + +#ifndef __PAT2__H +#define __PAT2__H + +#undef PAT_CLSID +#define PAT_CLSID CLSID_CMatchFinderPat2 + +#undef PAT_NAMESPACE +#define PAT_NAMESPACE NPat2 + +#define __AUTO_REMOVE +#define __NODE_2_BITS + +#include "Pat.h" +#include "PatMain.h" + +#undef __AUTO_REMOVE +#undef __NODE_2_BITS + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2H.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2H.h new file mode 100644 index 00000000..c3a374fa --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2H.h @@ -0,0 +1,24 @@ +// Pat2H.h + +#ifndef __PAT2H__H +#define __PAT2H__H + +#undef PAT_CLSID +#define PAT_CLSID CLSID_CMatchFinderPat2H + +#undef PAT_NAMESPACE +#define PAT_NAMESPACE NPat2H + +#define __AUTO_REMOVE +#define __NODE_2_BITS +#define __HASH_3 + +#include "Pat.h" +#include "PatMain.h" + +#undef __AUTO_REMOVE +#undef __NODE_2_BITS +#undef __HASH_3 + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2R.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2R.h new file mode 100644 index 00000000..2c6267e8 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat2R.h @@ -0,0 +1,20 @@ +// Pat2R.h + +#ifndef __PAT2R__H +#define __PAT2R__H + +#undef PAT_CLSID +#define PAT_CLSID CLSID_CMatchFinderPat2R + +#undef PAT_NAMESPACE +#define PAT_NAMESPACE NPat2R + +#define __NODE_2_BITS + +#include "Pat.h" +#include "PatMain.h" + +#undef __NODE_2_BITS + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat3H.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat3H.h new file mode 100644 index 00000000..96bdccd4 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat3H.h @@ -0,0 +1,24 @@ +// Pat3H.h + +#ifndef __PAT3H__H +#define __PAT3H__H + +#undef PAT_CLSID +#define PAT_CLSID CLSID_CMatchFinderPat3H + +#undef PAT_NAMESPACE +#define PAT_NAMESPACE NPat3H + +#define __AUTO_REMOVE +#define __NODE_3_BITS +#define __HASH_3 + +#include "Pat.h" +#include "PatMain.h" + +#undef __AUTO_REMOVE +#undef __NODE_3_BITS +#undef __HASH_3 + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat4H.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat4H.h new file mode 100644 index 00000000..ff5fdbf4 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/Pat4H.h @@ -0,0 +1,24 @@ +// Pat4H.h + +#ifndef __PAT4H__H +#define __PAT4H__H + +#undef PAT_CLSID +#define PAT_CLSID CLSID_CMatchFinderPat4H + +#undef PAT_NAMESPACE +#define PAT_NAMESPACE NPat4H + +#define __AUTO_REMOVE +#define __NODE_4_BITS +#define __HASH_3 + +#include "Pat.h" +#include "PatMain.h" + +#undef __AUTO_REMOVE +#undef __NODE_4_BITS +#undef __HASH_3 + +#endif + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/PatMain.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/PatMain.h new file mode 100644 index 00000000..028f16ba --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/Patricia/PatMain.h @@ -0,0 +1,989 @@ +// PatMain.h + +#include "../../../../Common/Defs.h" +#include "../../../../Common/Alloc.h" + +namespace PAT_NAMESPACE { + +STDMETHODIMP CPatricia::SetCallback(IMatchFinderCallback *callback) +{ + m_Callback = callback; + return S_OK; +} + +void CPatricia::BeforeMoveBlock() +{ + if (m_Callback) + m_Callback->BeforeChangingBufferPos(); + CLZInWindow::BeforeMoveBlock(); +} + +void CPatricia::AfterMoveBlock() +{ + if (m_Callback) + m_Callback->AfterChangingBufferPos(); + CLZInWindow::AfterMoveBlock(); +} + +const UInt32 kMatchStartValue2 = 2; +const UInt32 kDescendantEmptyValue2 = kMatchStartValue2 - 1; +const UInt32 kDescendantsNotInitilized2 = kDescendantEmptyValue2 - 1; + +#ifdef __HASH_3 + +static const UInt32 kNumHashBytes = 3; +static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); + +static const UInt32 kNumHash2Bytes = 2; +static const UInt32 kHash2Size = 1 << (8 * kNumHash2Bytes); +static const UInt32 kPrevHashSize = kNumHash2Bytes; + +#else + +static const UInt32 kNumHashBytes = 2; +static const UInt32 kHashSize = 1 << (8 * kNumHashBytes); +static const UInt32 kPrevHashSize = 0; + +#endif + + +CPatricia::CPatricia(): + m_HashDescendants(0), + #ifdef __HASH_3 + m_Hash2Descendants(0), + #endif + m_Nodes(0), + m_TmpBacks(0) +{ +} + +CPatricia::~CPatricia() +{ + FreeMemory(); +} + +void CPatricia::FreeMemory() +{ + MyFree(m_TmpBacks); + m_TmpBacks = 0; + + ::BigFree(m_Nodes); + m_Nodes = 0; + + ::BigFree(m_HashDescendants); + m_HashDescendants = 0; + + #ifdef __HASH_3 + + ::BigFree(m_Hash2Descendants); + m_Hash2Descendants = 0; + + CLZInWindow::Free(); + + #endif +} + +STDMETHODIMP CPatricia::Create(UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter) +{ + FreeMemory(); + int kNumBitsInNumSameBits = sizeof(CSameBitsType) * 8; + if (kNumBitsInNumSameBits < 32 && ((matchMaxLen * MY_BYTE_SIZE) > ((UInt32)1 << kNumBitsInNumSameBits))) + return E_INVALIDARG; + + const UInt32 kAlignMask = (1 << 16) - 1; + UInt32 windowReservSize = historySize; + windowReservSize += kAlignMask; + windowReservSize &= ~(kAlignMask); + + const UInt32 kMinReservSize = (1 << 19); + if (windowReservSize < kMinReservSize) + windowReservSize = kMinReservSize; + windowReservSize += 256; + + if (!CLZInWindow::Create(historySize + keepAddBufferBefore, + matchMaxLen + keepAddBufferAfter, windowReservSize)) + return E_OUTOFMEMORY; + + _sizeHistory = historySize; + _matchMaxLen = matchMaxLen; + m_HashDescendants = (CDescendant *)BigAlloc(kHashSize * sizeof(CDescendant)); + if (m_HashDescendants == 0) + { + FreeMemory(); + return E_OUTOFMEMORY; + } + + #ifdef __HASH_3 + m_Hash2Descendants = (CDescendant *)BigAlloc(kHash2Size * sizeof(CDescendant)); + if (m_Hash2Descendants == 0) + { + FreeMemory(); + return E_OUTOFMEMORY; + } + #endif + + #ifdef __AUTO_REMOVE + + #ifdef __HASH_3 + m_NumNodes = historySize + _sizeHistory * 4 / 8 + (1 << 19); + #else + m_NumNodes = historySize + _sizeHistory * 4 / 8 + (1 << 10); + #endif + + #else + + UInt32 m_NumNodes = historySize; + + #endif + + const UInt32 kMaxNumNodes = UInt32(1) << (sizeof(CIndex) * 8 - 1); + if (m_NumNodes + 32 > kMaxNumNodes) + return E_INVALIDARG; + + // m_Nodes = (CNode *)::BigAlloc((m_NumNodes + 2) * sizeof(CNode)); + m_Nodes = (CNode *)::BigAlloc((m_NumNodes + 12) * sizeof(CNode)); + if (m_Nodes == 0) + { + FreeMemory(); + return E_OUTOFMEMORY; + } + + m_TmpBacks = (UInt32 *)MyAlloc((_matchMaxLen + 1) * sizeof(UInt32)); + if (m_TmpBacks == 0) + { + FreeMemory(); + return E_OUTOFMEMORY; + } + return S_OK; +} + +STDMETHODIMP CPatricia::Init(ISequentialInStream *aStream) +{ + RINOK(CLZInWindow::Init(aStream)); + + // memset(m_HashDescendants, 0xFF, kHashSize * sizeof(m_HashDescendants[0])); + + #ifdef __HASH_3 + for (UInt32 i = 0; i < kHash2Size; i++) + m_Hash2Descendants[i].MatchPointer = kDescendantsNotInitilized2; + #else + for (UInt32 i = 0; i < kHashSize; i++) + m_HashDescendants[i].MakeEmpty(); + #endif + + m_Nodes[0].NextFreeNode = 1; + m_FreeNode = 0; + m_FreeNodeMax = 0; + #ifdef __AUTO_REMOVE + m_NumUsedNodes = 0; + #else + m_SpecialRemoveMode = false; + #endif + m_SpecialMode = false; + return S_OK; +} + +STDMETHODIMP_(void) CPatricia::ReleaseStream() +{ + // CLZInWindow::ReleaseStream(); +} + +// pos = _pos + kNumHashBytes +// fullCurrentLimit = currentLimit + kNumHashBytes +// fullMatchLen = matchLen + kNumHashBytes + +void CPatricia::ChangeLastMatch(UInt32 hashValue) +{ + UInt32 pos = _pos + kNumHashBytes - 1; + UInt32 descendantIndex; + const Byte *currentBytePointer = _buffer + pos; + UInt32 numLoadedBits = 0; + Byte curByte = 0; // = 0 to disable warning of GCC + CNodePointer node = &m_Nodes[m_HashDescendants[hashValue].NodePointer]; + + while(true) + { + UInt32 numSameBits = node->NumSameBits; + if(numSameBits > 0) + { + if (numLoadedBits < numSameBits) + { + numSameBits -= numLoadedBits; + currentBytePointer += (numSameBits / MY_BYTE_SIZE); + numSameBits %= MY_BYTE_SIZE; + curByte = *currentBytePointer++; + numLoadedBits = MY_BYTE_SIZE; + } + curByte >>= numSameBits; + numLoadedBits -= numSameBits; + } + if(numLoadedBits == 0) + { + curByte = *currentBytePointer++; + numLoadedBits = MY_BYTE_SIZE; + } + descendantIndex = (curByte & kSubNodesMask); + node->LastMatch = pos; + numLoadedBits -= kNumSubBits; + curByte >>= kNumSubBits; + if(node->Descendants[descendantIndex].IsNode()) + node = &m_Nodes[node->Descendants[descendantIndex].NodePointer]; + else + break; + } + node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; +} + +UInt32 CPatricia::GetLongestMatch(UInt32 *distances) +{ + UInt32 fullCurrentLimit; + if (_pos + _matchMaxLen <= _streamPos) + fullCurrentLimit = _matchMaxLen; + else + { + fullCurrentLimit = _streamPos - _pos; + if(fullCurrentLimit < kNumHashBytes) + return 0; + } + UInt32 pos = _pos + kNumHashBytes; + + #ifdef __HASH_3 + UInt32 hash2Value = ((UInt32(_buffer[_pos])) << 8) | _buffer[_pos + 1]; + UInt32 hashValue = (hash2Value << 8) | _buffer[_pos + 2]; + CDescendant &hash2Descendant = m_Hash2Descendants[hash2Value]; + CDescendant &hashDescendant = m_HashDescendants[hashValue]; + if(hash2Descendant.MatchPointer <= kDescendantEmptyValue2) + { + if(hash2Descendant.MatchPointer == kDescendantsNotInitilized2) + { + UInt32 base = hashValue & 0xFFFF00; + for (UInt32 i = 0; i < 0x100; i++) + m_HashDescendants[base + i].MakeEmpty(); + } + hash2Descendant.MatchPointer = pos + kMatchStartValue2; + hashDescendant.MatchPointer = pos + kMatchStartValue; + return 0; + } + + distances[kNumHash2Bytes] = pos - (hash2Descendant.MatchPointer - kMatchStartValue2) - 1; + hash2Descendant.MatchPointer = pos + kMatchStartValue2; + #ifdef __AUTO_REMOVE + if (distances[kNumHash2Bytes] >= _sizeHistory) + { + if (hashDescendant.IsNode()) + RemoveNode(hashDescendant.NodePointer); + hashDescendant.MatchPointer = pos + kMatchStartValue; + return 0; + } + #endif + if (fullCurrentLimit == kNumHash2Bytes) + return kNumHash2Bytes; + + #else + UInt32 hashValue = UInt32(GetIndexByte(1)) | (UInt32(GetIndexByte(0)) << 8); + CDescendant &hashDescendant = m_HashDescendants[hashValue]; + #endif + + + if(m_SpecialMode) + { + if(hashDescendant.IsMatch()) + m_NumNotChangedCycles = 0; + if(m_NumNotChangedCycles >= _sizeHistory - 1) + { + ChangeLastMatch(hashValue); + m_NumNotChangedCycles = 0; + } + if(GetIndexByte(fullCurrentLimit - 1) == GetIndexByte(fullCurrentLimit - 2)) + { + if(hashDescendant.IsMatch()) + hashDescendant.MatchPointer = pos + kMatchStartValue; + else + m_NumNotChangedCycles++; + for(UInt32 i = kNumHashBytes; i <= fullCurrentLimit; i++) + distances[i] = 0; + return fullCurrentLimit; + } + else if(m_NumNotChangedCycles > 0) + ChangeLastMatch(hashValue); + m_SpecialMode = false; + } + + if(hashDescendant.IsEmpty()) + { + hashDescendant.MatchPointer = pos + kMatchStartValue; + return kPrevHashSize; + } + + UInt32 currentLimit = fullCurrentLimit - kNumHashBytes; + + if(hashDescendant.IsMatch()) + { + CMatchPointer matchPointer = hashDescendant.MatchPointer; + UInt32 backReal = pos - (matchPointer - kMatchStartValue); + UInt32 back = backReal - 1; + #ifdef __AUTO_REMOVE + if (back >= _sizeHistory) + { + hashDescendant.MatchPointer = pos + kMatchStartValue; + return kPrevHashSize; + } + #endif + + UInt32 matchLen; + distances += kNumHashBytes; + Byte *buffer = _buffer + pos; + for(matchLen = 0; true; matchLen++) + { + *distances++ = back; + if (matchLen == currentLimit) + { + hashDescendant.MatchPointer = pos + kMatchStartValue; + return kNumHashBytes + matchLen; + } + if (buffer[matchLen] != buffer[(size_t)matchLen - backReal]) + break; + } + + // UInt32 matchLen = GetMatchLen(kNumHashBytes, back, currentLimit); + + UInt32 fullMatchLen = matchLen + kNumHashBytes; + hashDescendant.NodePointer = m_FreeNode; + CNodePointer node = &m_Nodes[m_FreeNode]; + m_FreeNode = node->NextFreeNode; + #ifdef __AUTO_REMOVE + m_NumUsedNodes++; + #endif + if (m_FreeNode > m_FreeNodeMax) + { + m_FreeNodeMax = m_FreeNode; + m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1; + } + + for (UInt32 i = 0; i < kNumSubNodes; i++) + node->Descendants[i].NodePointer = kDescendantEmptyValue; + node->LastMatch = pos; + + Byte byteNew = GetIndexByte(fullMatchLen); + Byte byteOld = GetIndexByte(fullMatchLen - backReal); + Byte bitsNew, bitsOld; + UInt32 numSameBits = matchLen * MY_BYTE_SIZE; + while (true) + { + bitsNew = (byteNew & kSubNodesMask); + bitsOld = (byteOld & kSubNodesMask); + if(bitsNew != bitsOld) + break; + byteNew >>= kNumSubBits; + byteOld >>= kNumSubBits; + numSameBits += kNumSubBits; + } + node->NumSameBits = CSameBitsType(numSameBits); + node->Descendants[bitsNew].MatchPointer = pos + kMatchStartValue; + node->Descendants[bitsOld].MatchPointer = matchPointer; + return fullMatchLen; + } + const Byte *baseCurrentBytePointer = _buffer + pos; + const Byte *currentBytePointer = baseCurrentBytePointer; + UInt32 numLoadedBits = 0; + Byte curByte = 0; + CIndex *nodePointerPointer = &hashDescendant.NodePointer; + CNodePointer node = &m_Nodes[*nodePointerPointer]; + distances += kNumHashBytes; + const Byte *bytePointerLimit = baseCurrentBytePointer + currentLimit; + const Byte *currentAddingOffset = _buffer; + + #ifdef __AUTO_REMOVE + UInt32 lowPos; + if (pos > _sizeHistory) + lowPos = pos - _sizeHistory; + else + lowPos = 0; + #endif + + while(true) + { + #ifdef __AUTO_REMOVE + if (node->LastMatch < lowPos) + { + RemoveNode(*nodePointerPointer); + *nodePointerPointer = pos + kMatchStartValue; + if (currentBytePointer == baseCurrentBytePointer) + return kPrevHashSize; + return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1); + } + #endif + if(numLoadedBits == 0) + { + *distances++ = pos - node->LastMatch - 1; + if(currentBytePointer >= bytePointerLimit) + { + for (UInt32 i = 0; i < kNumSubNodes; i++) + node->Descendants[i].MatchPointer = pos + kMatchStartValue; + node->LastMatch = pos; + node->NumSameBits = 0; + return fullCurrentLimit; + } + curByte = (*currentBytePointer++); + currentAddingOffset++; + numLoadedBits = MY_BYTE_SIZE; + } + UInt32 numSameBits = node->NumSameBits; + if(numSameBits > 0) + { + Byte byteXOR = ((*(currentAddingOffset + node->LastMatch -1)) >> + (MY_BYTE_SIZE - numLoadedBits)) ^ curByte; + while(numLoadedBits <= numSameBits) + { + if(byteXOR != 0) + { + AddInternalNode(node, nodePointerPointer, curByte, byteXOR, + numSameBits, pos); + return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1); + } + *distances++ = pos - node->LastMatch - 1; + numSameBits -= numLoadedBits; + if(currentBytePointer >= bytePointerLimit) + { + for (UInt32 i = 0; i < kNumSubNodes; i++) + node->Descendants[i].MatchPointer = pos + kMatchStartValue; + node->LastMatch = pos; + node->NumSameBits = CSameBitsType(node->NumSameBits - numSameBits); + return fullCurrentLimit; + } + numLoadedBits = MY_BYTE_SIZE; + curByte = (*currentBytePointer++); + byteXOR = curByte ^ (*(currentAddingOffset + node->LastMatch)); + currentAddingOffset++; + } + if((byteXOR & ((1 << numSameBits) - 1)) != 0) + { + AddInternalNode(node, nodePointerPointer, curByte, byteXOR, + numSameBits, pos); + return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1); + } + curByte >>= numSameBits; + numLoadedBits -= numSameBits; + } + UInt32 descendantIndex = (curByte & kSubNodesMask); + numLoadedBits -= kNumSubBits; + nodePointerPointer = &node->Descendants[descendantIndex].NodePointer; + UInt32 nextNodeIndex = *nodePointerPointer; + node->LastMatch = pos; + if (nextNodeIndex < kDescendantEmptyValue) + { + curByte >>= kNumSubBits; + node = &m_Nodes[nextNodeIndex]; + } + else if (nextNodeIndex == kDescendantEmptyValue) + { + node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; + return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1); + } + else + break; + } + + UInt32 descendantIndex = (curByte & kSubNodesMask); + curByte >>= kNumSubBits; + CMatchPointer matchPointer = node->Descendants[descendantIndex].MatchPointer; + CMatchPointer realMatchPointer; + realMatchPointer = matchPointer - kMatchStartValue; + + #ifdef __AUTO_REMOVE + if (realMatchPointer < lowPos) + { + node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; + return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1); + } + #endif + + Byte byteXOR; + UInt32 numSameBits = 0; + if(numLoadedBits != 0) + { + Byte matchByte = *(currentAddingOffset + realMatchPointer -1); + matchByte >>= (MY_BYTE_SIZE - numLoadedBits); + byteXOR = matchByte ^ curByte; + if(byteXOR != 0) + { + AddLeafNode(node, curByte, byteXOR, numSameBits, pos, descendantIndex); + return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1); + } + numSameBits += numLoadedBits; + } + + const Byte *matchBytePointer = _buffer + realMatchPointer + + (currentBytePointer - baseCurrentBytePointer); + for(; currentBytePointer < bytePointerLimit; numSameBits += MY_BYTE_SIZE) + { + curByte = (*currentBytePointer++); + *distances++ = pos - realMatchPointer - 1; + byteXOR = curByte ^ (*matchBytePointer++); + if(byteXOR != 0) + { + AddLeafNode(node, curByte, byteXOR, numSameBits, pos, descendantIndex); + return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1); + } + } + *distances = pos - realMatchPointer - 1; + node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue; + + if(*distances == 0) + { + m_SpecialMode = true; + m_NumNotChangedCycles = 0; + } + return fullCurrentLimit; +} + +STDMETHODIMP_(void) CPatricia::DummyLongestMatch() +{ + GetLongestMatch(m_TmpBacks); +} + + +// ------------------------------------ +// Remove Match + +typedef Byte CRemoveDataWord; + +static const int kSizeRemoveDataWordInBits = MY_BYTE_SIZE * sizeof(CRemoveDataWord); + +#ifndef __AUTO_REMOVE + +void CPatricia::RemoveMatch() +{ + if(m_SpecialRemoveMode) + { + if(GetIndexByte(_matchMaxLen - 1 - _sizeHistory) == + GetIndexByte(_matchMaxLen - _sizeHistory)) + return; + m_SpecialRemoveMode = false; + } + UInt32 pos = _pos + kNumHashBytes - _sizeHistory; + + #ifdef __HASH_3 + const Byte *pp = _buffer + _pos - _sizeHistory; + UInt32 hash2Value = ((UInt32(pp[0])) << 8) | pp[1]; + UInt32 hashValue = (hash2Value << 8) | pp[2]; + CDescendant &hashDescendant = m_HashDescendants[hashValue]; + CDescendant &hash2Descendant = m_Hash2Descendants[hash2Value]; + if (hash2Descendant >= kMatchStartValue2) + if(hash2Descendant.MatchPointer == pos + kMatchStartValue2) + hash2Descendant.MatchPointer = kDescendantEmptyValue2; + #else + UInt32 hashValue = UInt32(GetIndexByte(1 - _sizeHistory)) | + (UInt32(GetIndexByte(0 - _sizeHistory)) << 8); + CDescendant &hashDescendant = m_HashDescendants[hashValue]; + #endif + + if(hashDescendant.IsEmpty()) + return; + if(hashDescendant.IsMatch()) + { + if(hashDescendant.MatchPointer == pos + kMatchStartValue) + hashDescendant.MakeEmpty(); + return; + } + + UInt32 descendantIndex; + const CRemoveDataWord *currentPointer = (const CRemoveDataWord *)(_buffer + pos); + UInt32 numLoadedBits = 0; + CRemoveDataWord curWord = 0; // = 0 to disable GCC warning + + CIndex *nodePointerPointer = &hashDescendant.NodePointer; + + CNodePointer node = &m_Nodes[hashDescendant.NodePointer]; + + while(true) + { + if(numLoadedBits == 0) + { + curWord = *currentPointer++; + numLoadedBits = kSizeRemoveDataWordInBits; + } + UInt32 numSameBits = node->NumSameBits; + if(numSameBits > 0) + { + if (numLoadedBits <= numSameBits) + { + numSameBits -= numLoadedBits; + currentPointer += (numSameBits / kSizeRemoveDataWordInBits); + numSameBits %= kSizeRemoveDataWordInBits; + curWord = *currentPointer++; + numLoadedBits = kSizeRemoveDataWordInBits; + } + curWord >>= numSameBits; + numLoadedBits -= numSameBits; + } + descendantIndex = (curWord & kSubNodesMask); + numLoadedBits -= kNumSubBits; + curWord >>= kNumSubBits; + UInt32 nextNodeIndex = node->Descendants[descendantIndex].NodePointer; + if (nextNodeIndex < kDescendantEmptyValue) + { + nodePointerPointer = &node->Descendants[descendantIndex].NodePointer; + node = &m_Nodes[nextNodeIndex]; + } + else + break; + } + if (node->Descendants[descendantIndex].MatchPointer != pos + kMatchStartValue) + { + const Byte *currentBytePointer = _buffer + _pos - _sizeHistory; + const Byte *currentBytePointerLimit = currentBytePointer + _matchMaxLen; + for(;currentBytePointer < currentBytePointerLimit; currentBytePointer++) + if(*currentBytePointer != *(currentBytePointer+1)) + return; + m_SpecialRemoveMode = true; + return; + } + + UInt32 numNodes = 0, numMatches = 0; + + UInt32 i; + for (i = 0; i < kNumSubNodes; i++) + { + UInt32 nodeIndex = node->Descendants[i].NodePointer; + if (nodeIndex < kDescendantEmptyValue) + numNodes++; + else if (nodeIndex > kDescendantEmptyValue) + numMatches++; + } + numMatches -= 1; + if (numNodes + numMatches > 1) + { + node->Descendants[descendantIndex].MakeEmpty(); + return; + } + if(numNodes == 1) + { + UInt32 i; + for (i = 0; i < kNumSubNodes; i++) + if (node->Descendants[i].IsNode()) + break; + UInt32 nextNodeIndex = node->Descendants[i].NodePointer; + CNodePointer nextNode = &m_Nodes[nextNodeIndex]; + nextNode->NumSameBits += node->NumSameBits + kNumSubBits; + *node = *nextNode; + + nextNode->NextFreeNode = m_FreeNode; + m_FreeNode = nextNodeIndex; + return; + } + UInt32 matchPointer = 0; // = 0 to disable GCC warning + for (i = 0; i < kNumSubNodes; i++) + if (node->Descendants[i].IsMatch() && i != descendantIndex) + { + matchPointer = node->Descendants[i].MatchPointer; + break; + } + node->NextFreeNode = m_FreeNode; + m_FreeNode = *nodePointerPointer; + *nodePointerPointer = matchPointer; +} +#endif + + +// Commented code is more correct, but it gives warning +// on GCC: (1 << 32) +// So we use kMatchStartValue twice: +// kMatchStartValue = UInt32(1) << (kNumBitsInIndex - 1); +// must be defined in Pat.h +/* +const UInt32 kNormalizeStartPos = (UInt32(1) << (kNumBitsInIndex)) - + kMatchStartValue - kNumHashBytes - 1; +*/ +const UInt32 kNormalizeStartPos = kMatchStartValue - kNumHashBytes - 1; + +STDMETHODIMP CPatricia::MovePos() +{ + #ifndef __AUTO_REMOVE + if(_pos >= _sizeHistory) + RemoveMatch(); + #endif + RINOK(CLZInWindow::MovePos()); + #ifdef __AUTO_REMOVE + if (m_NumUsedNodes >= m_NumNodes) + TestRemoveNodes(); + #endif + if (_pos >= kNormalizeStartPos) + { + #ifdef __AUTO_REMOVE + TestRemoveNodesAndNormalize(); + #else + Normalize(); + #endif + } + return S_OK; +} + +#ifndef __AUTO_REMOVE + +void CPatricia::NormalizeDescendant(CDescendant &descendant, UInt32 subValue) +{ + if (descendant.IsEmpty()) + return; + if (descendant.IsMatch()) + descendant.MatchPointer = descendant.MatchPointer - subValue; + else + { + CNode &node = m_Nodes[descendant.NodePointer]; + node.LastMatch = node.LastMatch - subValue; + for (UInt32 i = 0; i < kNumSubNodes; i++) + NormalizeDescendant(node.Descendants[i], subValue); + } +} + +void CPatricia::Normalize() +{ + UInt32 subValue = _pos - _sizeHistory; + CLZInWindow::ReduceOffsets(subValue); + + #ifdef __HASH_3 + + for(UInt32 hash = 0; hash < kHash2Size; hash++) + { + CDescendant &descendant = m_Hash2Descendants[hash]; + if (descendant.MatchPointer != kDescendantsNotInitilized2) + { + UInt32 base = hash << 8; + for (UInt32 i = 0; i < 0x100; i++) + NormalizeDescendant(m_HashDescendants[base + i], subValue); + } + if (descendant.MatchPointer < kMatchStartValue2) + continue; + descendant.MatchPointer = descendant.MatchPointer - subValue; + } + + #else + + for(UInt32 hash = 0; hash < kHashSize; hash++) + NormalizeDescendant(m_HashDescendants[hash], subValue); + + #endif + +} + +#else + +void CPatricia::TestRemoveDescendant(CDescendant &descendant, UInt32 limitPos) +{ + CNode &node = m_Nodes[descendant.NodePointer]; + UInt32 numChilds = 0; + UInt32 childIndex = 0; // = 0 to disable GCC warning + for (UInt32 i = 0; i < kNumSubNodes; i++) + { + CDescendant &descendant2 = node.Descendants[i]; + if (descendant2.IsEmpty()) + continue; + if (descendant2.IsMatch()) + { + if (descendant2.MatchPointer < limitPos) + descendant2.MakeEmpty(); + else + { + numChilds++; + childIndex = i; + } + } + else + { + TestRemoveDescendant(descendant2, limitPos); + if (!descendant2.IsEmpty()) + { + numChilds++; + childIndex = i; + } + } + } + if (numChilds > 1) + return; + + CIndex nodePointerTemp = descendant.NodePointer; + if (numChilds == 1) + { + const CDescendant &descendant2 = node.Descendants[childIndex]; + if (descendant2.IsNode()) + m_Nodes[descendant2.NodePointer].NumSameBits += node.NumSameBits + kNumSubBits; + descendant = descendant2; + } + else + descendant.MakeEmpty(); + node.NextFreeNode = m_FreeNode; + m_FreeNode = nodePointerTemp; + m_NumUsedNodes--; +} + +void CPatricia::RemoveNode(UInt32 index) +{ + CNode &node = m_Nodes[index]; + for (UInt32 i = 0; i < kNumSubNodes; i++) + { + CDescendant &descendant2 = node.Descendants[i]; + if (descendant2.IsNode()) + RemoveNode(descendant2.NodePointer); + } + node.NextFreeNode = m_FreeNode; + m_FreeNode = index; + m_NumUsedNodes--; +} + +void CPatricia::TestRemoveNodes() +{ + UInt32 limitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes; + + #ifdef __HASH_3 + + UInt32 limitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes; + for(UInt32 hash = 0; hash < kHash2Size; hash++) + { + CDescendant &descendant = m_Hash2Descendants[hash]; + if (descendant.MatchPointer != kDescendantsNotInitilized2) + { + UInt32 base = hash << 8; + for (UInt32 i = 0; i < 0x100; i++) + { + CDescendant &descendant = m_HashDescendants[base + i]; + if (descendant.IsEmpty()) + continue; + if (descendant.IsMatch()) + { + if (descendant.MatchPointer < limitPos) + descendant.MakeEmpty(); + } + else + TestRemoveDescendant(descendant, limitPos); + } + } + if (descendant.MatchPointer < kMatchStartValue2) + continue; + if (descendant.MatchPointer < limitPos2) + descendant.MatchPointer = kDescendantEmptyValue2; + } + + #else + + for(UInt32 hash = 0; hash < kHashSize; hash++) + { + CDescendant &descendant = m_HashDescendants[hash]; + if (descendant.IsEmpty()) + continue; + if (descendant.IsMatch()) + { + if (descendant.MatchPointer < limitPos) + descendant.MakeEmpty(); + } + else + TestRemoveDescendant(descendant, limitPos); + } + + #endif +} + +void CPatricia::TestRemoveAndNormalizeDescendant(CDescendant &descendant, + UInt32 limitPos, UInt32 subValue) +{ + if (descendant.IsEmpty()) + return; + if (descendant.IsMatch()) + { + if (descendant.MatchPointer < limitPos) + descendant.MakeEmpty(); + else + descendant.MatchPointer = descendant.MatchPointer - subValue; + return; + } + CNode &node = m_Nodes[descendant.NodePointer]; + UInt32 numChilds = 0; + UInt32 childIndex = 0; // = 0 to disable GCC warning + for (UInt32 i = 0; i < kNumSubNodes; i++) + { + CDescendant &descendant2 = node.Descendants[i]; + TestRemoveAndNormalizeDescendant(descendant2, limitPos, subValue); + if (!descendant2.IsEmpty()) + { + numChilds++; + childIndex = i; + } + } + if (numChilds > 1) + { + node.LastMatch = node.LastMatch - subValue; + return; + } + + CIndex nodePointerTemp = descendant.NodePointer; + if (numChilds == 1) + { + const CDescendant &descendant2 = node.Descendants[childIndex]; + if (descendant2.IsNode()) + m_Nodes[descendant2.NodePointer].NumSameBits += node.NumSameBits + kNumSubBits; + descendant = descendant2; + } + else + descendant.MakeEmpty(); + node.NextFreeNode = m_FreeNode; + m_FreeNode = nodePointerTemp; + m_NumUsedNodes--; +} + +void CPatricia::TestRemoveNodesAndNormalize() +{ + UInt32 subValue = _pos - _sizeHistory; + UInt32 limitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes; + CLZInWindow::ReduceOffsets(subValue); + + #ifdef __HASH_3 + + UInt32 limitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes; + for(UInt32 hash = 0; hash < kHash2Size; hash++) + { + CDescendant &descendant = m_Hash2Descendants[hash]; + if (descendant.MatchPointer != kDescendantsNotInitilized2) + { + UInt32 base = hash << 8; + for (UInt32 i = 0; i < 0x100; i++) + TestRemoveAndNormalizeDescendant(m_HashDescendants[base + i], limitPos, subValue); + } + if (descendant.MatchPointer < kMatchStartValue2) + continue; + if (descendant.MatchPointer < limitPos2) + descendant.MatchPointer = kDescendantEmptyValue2; + else + descendant.MatchPointer = descendant.MatchPointer - subValue; + } + + #else + + for(UInt32 hash = 0; hash < kHashSize; hash++) + TestRemoveAndNormalizeDescendant(m_HashDescendants[hash], limitPos, subValue); + + #endif +} + +#endif + +STDMETHODIMP_(Byte) CPatricia::GetIndexByte(Int32 index) +{ + return CLZInWindow::GetIndexByte(index); +} + +STDMETHODIMP_(UInt32) CPatricia::GetMatchLen(Int32 index, UInt32 back, UInt32 limit) +{ + return CLZInWindow::GetMatchLen(index, back, limit); +} + +STDMETHODIMP_(UInt32) CPatricia::GetNumAvailableBytes() +{ + return CLZInWindow::GetNumAvailableBytes(); +} + +STDMETHODIMP_(const Byte *) CPatricia::GetPointerToCurrentPos() +{ + return CLZInWindow::GetPointerToCurrentPos(); +} + +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/StdAfx.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/StdAfx.h new file mode 100644 index 00000000..3de038a4 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZ/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMA.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMA.h new file mode 100644 index 00000000..d53296ee --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMA.h @@ -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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMADecoder.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMADecoder.cpp new file mode 100644 index 00000000..f672099a --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMADecoder.cpp @@ -0,0 +1,342 @@ +// 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); + + while (true) + { + 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; + UInt32 dictionarySize = 0; + for (int i = 0; i < 4; i++) + dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); + return SetDecoderPropertiesRaw(lc, lp, pb, dictionarySize); +} + +STDMETHODIMP CDecoder::SetDecoderPropertiesRaw(int lc, int lp, int pb, UInt32 dictionarySize) +{ + if (pb > NLength::kNumPosStatesBitsMax) + return E_INVALIDARG; + _posStateMask = (1 << pb) - 1; + 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) +{ + if (_outSizeDefined = (outSize != NULL)) + _outSize = *outSize; + _remainLen = kLenIdNeedInit; + _outWindowStream.Init(); + return S_OK; +} + +#ifdef _ST_MODE + +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 + +}} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMADecoder.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMADecoder.h new file mode 100644 index 00000000..6f5f7ecc --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMADecoder.h @@ -0,0 +1,249 @@ +// LZMA/Decoder.h + +#ifndef __LZMA_DECODER_H +#define __LZMA_DECODER_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" +#include "../../ICoder.h" +#include "../LZ/LZOutWindow.h" +#include "../RangeCoder/RangeCoderBitTree.h" + +#include "LZMA.h" + +namespace NCompress { +namespace NLZMA { + +typedef NRangeCoder::CBitDecoder 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 _lowCoder[kNumPosStatesMax]; + NRangeCoder::CBitTreeDecoder _midCoder[kNumPosStatesMax]; + NRangeCoder::CBitTreeDecoder _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, + #ifdef _ST_MODE + 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 _posSlotDecoder[kNumLenToPosStates]; + + CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex]; + NRangeCoder::CBitTreeDecoder _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: + + #ifdef _ST_MODE + MY_UNKNOWN_IMP4( + ICompressSetDecoderProperties2, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream) + #else + MY_UNKNOWN_IMP1( + ICompressSetDecoderProperties2) + #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(SetDecoderPropertiesRaw)(int lc, int lp, int pb, UInt32 dictionarySize); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifdef _ST_MODE + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + CDecoder(): _outSizeDefined(false) {} + virtual ~CDecoder() {} +}; + +}} + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp new file mode 100644 index 00000000..4f20ed5a --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp @@ -0,0 +1,1504 @@ +// LZMA/Encoder.cpp + +#include "StdAfx.h" + +#include "../../../Common/Defs.h" +#include "../../Common/StreamUtils.h" + +#include "LZMAEncoder.h" + +// for minimal compressing code size define these: +// #define COMPRESS_MF_BT +// #define COMPRESS_MF_BT4 + +#if !defined(COMPRESS_MF_BT) && !defined(COMPRESS_MF_PAT) && !defined(COMPRESS_MF_HC) +#define COMPRESS_MF_BT +#define COMPRESS_MF_PAT +#define COMPRESS_MF_HC +#endif + +#ifdef COMPRESS_MF_BT +#if !defined(COMPRESS_MF_BT2) && !defined(COMPRESS_MF_BT3) && !defined(COMPRESS_MF_BT4) && !defined(COMPRESS_MF_BT4B) +#define COMPRESS_MF_BT2 +#define COMPRESS_MF_BT3 +#define COMPRESS_MF_BT4 +#define COMPRESS_MF_BT4B +#endif +#ifdef COMPRESS_MF_BT2 +#include "../LZ/BinTree/BinTree2.h" +#endif +#ifdef COMPRESS_MF_BT3 +#include "../LZ/BinTree/BinTree3.h" +#endif +#ifdef COMPRESS_MF_BT4 +#include "../LZ/BinTree/BinTree4.h" +#endif +#ifdef COMPRESS_MF_BT4B +#include "../LZ/BinTree/BinTree4b.h" +#endif +#endif + +#ifdef COMPRESS_MF_PAT +#include "../LZ/Patricia/Pat2.h" +#include "../LZ/Patricia/Pat2H.h" +#include "../LZ/Patricia/Pat3H.h" +#include "../LZ/Patricia/Pat4H.h" +#include "../LZ/Patricia/Pat2R.h" +#endif + +#ifdef COMPRESS_MF_HC +#include "../LZ/HashChain/HC3.h" +#include "../LZ/HashChain/HC4.h" +#endif + +#ifdef COMPRESS_MF_MT +#include "../LZ/MT/MT.h" +#endif + +namespace NCompress { +namespace NLZMA { + +const int kDefaultDictionaryLogSize = 20; +const UInt32 kNumFastBytesDefault = 0x20; + +enum +{ + kBT2, + kBT3, + kBT4, + kBT4B, + kPat2, + kPat2H, + kPat3H, + kPat4H, + kPat2R, + kHC3, + kHC4 +}; + +static const wchar_t *kMatchFinderIDs[] = +{ + L"BT2", + L"BT3", + L"BT4", + L"BT4B", + L"PAT2", + L"PAT2H", + L"PAT3H", + L"PAT4H", + L"PAT2R", + L"HC3", + L"HC4" +}; + +Byte g_FastPos[1024]; + +class CFastPosInit +{ +public: + CFastPosInit() { Init(); } + void Init() + { + const Byte kFastSlots = 20; + 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; + + +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); + } + } +} + +UInt32 CEncoder::GetPrice(UInt32 symbol, UInt32 posState) const +{ + if(symbol < kNumLowSymbols) + return _choice.GetPrice0() + _lowCoder[posState].GetPrice(symbol); + UInt32 price = _choice.GetPrice1(); + if(symbol < kNumLowSymbols + kNumMidSymbols) + { + price += _choice2.GetPrice0(); + price += _midCoder[posState].GetPrice(symbol - kNumLowSymbols); + } + else + { + price += _choice2.GetPrice1(); + price += _highCoder.GetPrice(symbol - kNumLowSymbols - kNumMidSymbols); + } + return price; +} + +} +CEncoder::CEncoder(): + _numFastBytes(kNumFastBytesDefault), + _distTableSize(kDefaultDictionaryLogSize * 2), + _posStateBits(2), + _posStateMask(4 - 1), + _numLiteralPosStateBits(0), + _numLiteralContextBits(3), + _dictionarySize(1 << kDefaultDictionaryLogSize), + _dictionarySizePrev(UInt32(-1)), + _numFastBytesPrev(UInt32(-1)), + _matchFinderIndex(kBT4), + #ifdef COMPRESS_MF_MT + _multiThread(false), + #endif + _writeEndMark(false) +{ + _maxMode = false; + _fastMode = false; +} + +HRESULT CEncoder::Create() +{ + if (!_rangeEncoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_matchFinder) + { + switch(_matchFinderIndex) + { + #ifdef COMPRESS_MF_BT + #ifdef COMPRESS_MF_BT2 + case kBT2: + _matchFinder = new NBT2::CMatchFinderBinTree; + break; + #endif + #ifdef COMPRESS_MF_BT3 + case kBT3: + _matchFinder = new NBT3::CMatchFinderBinTree; + break; + #endif + #ifdef COMPRESS_MF_BT4 + case kBT4: + _matchFinder = new NBT4::CMatchFinderBinTree; + break; + #endif + #ifdef COMPRESS_MF_BT4B + case kBT4B: + _matchFinder = new NBT4B::CMatchFinderBinTree; + break; + #endif + #endif + + #ifdef COMPRESS_MF_PAT + case kPat2: + _matchFinder = new NPat2::CPatricia; + break; + case kPat2H: + _matchFinder = new NPat2H::CPatricia; + break; + case kPat3H: + _matchFinder = new NPat3H::CPatricia; + break; + case kPat4H: + _matchFinder = new NPat4H::CPatricia; + break; + case kPat2R: + _matchFinder = new NPat2R::CPatricia; + break; + #endif + + #ifdef COMPRESS_MF_HC + case kHC3: + _matchFinder = new NHC3::CMatchFinderHC; + break; + case kHC4: + _matchFinder = new NHC4::CMatchFinderHC; + break; + #endif + } + if (_matchFinder == 0) + return E_OUTOFMEMORY; + + #ifdef COMPRESS_MF_MT + if (_multiThread && !(_fastMode && (_matchFinderIndex == kHC3 || _matchFinderIndex == kHC4))) + { + CMatchFinderMT *mfSpec = new CMatchFinderMT; + if (mfSpec == 0) + return E_OUTOFMEMORY; + CMyComPtr mf = mfSpec; + RINOK(mfSpec->SetMatchFinder(_matchFinder)); + _matchFinder.Release(); + _matchFinder = mf; + } + #endif + } + + if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits)) + return E_OUTOFMEMORY; + + if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes) + return S_OK; + RINOK(_matchFinder->Create(_dictionarySize, kNumOpts, _numFastBytes, + kMatchMaxLen * 2 + 1 - _numFastBytes)); + _dictionarySizePrev = _dictionarySize; + _numFastBytesPrev = _numFastBytes; + return S_OK; +} + +static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString) +{ + while (true) + { + wchar_t c = *testString; + if (c >= 'a' && c <= 'z') + c -= 0x20; + if (*base != c) + return false; + if (c == 0) + return true; + base++; + testString++; + } +} + +static int FindMatchFinder(const wchar_t *s) +{ + for (int m = 0; m < (int)(sizeof(kMatchFinderIDs) / sizeof(kMatchFinderIDs[0])); m++) + if (AreStringsEqual(kMatchFinderIDs[m], s)) + return m; + 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::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; + int matchFinderIndexPrev = _matchFinderIndex; + int m = FindMatchFinder(prop.bstrVal); + if (m < 0) + return E_INVALIDARG; + _matchFinderIndex = m; + if (_matchFinder && matchFinderIndexPrev != _matchFinderIndex) + { + _dictionarySizePrev = UInt32(-1); + _matchFinder.Release(); + } + break; + } + #ifdef COMPRESS_MF_MT + case NCoderPropID::kMultiThread: + { + if (prop.vt != VT_BOOL) + return E_INVALIDARG; + bool newMultiThread = (prop.boolVal == VARIANT_TRUE); + if (newMultiThread != _multiThread) + { + _dictionarySizePrev = UInt32(-1); + _matchFinder.Release(); + } + _multiThread = newMultiThread; + break; + } + #endif + case NCoderPropID::kDictionarySize: + { + const int kDicLogSizeMaxCompress = 28; + 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] = (_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(); + + // RINOK(_matchFinder->Init(inStream)); + _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(); + + // _repMatchLenEncoder.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; +} + +HRESULT CEncoder::MovePos(UInt32 num) +{ + for (;num != 0; num--) + { + _matchFinder->DummyLongestMatch(); + RINOK(_matchFinder->MovePos()); + _additionalOffset++; + } + return S_OK; +} + +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; +} + +/* +inline UInt32 GetMatchLen(const Byte *data, UInt32 back, UInt32 limit) +{ + back++; + for(UInt32 i = 0; i < limit && data[i] == data[i - back]; i++); + return i; +} +*/ + + +/* +Out: + (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal +*/ + +HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes) +{ + if(_optimumEndIndex != _optimumCurrentIndex) + { + const COptimal &optimum = _optimum[_optimumCurrentIndex]; + lenRes = optimum.PosPrev - _optimumCurrentIndex; + backRes = optimum.BackPrev; + _optimumCurrentIndex = optimum.PosPrev; + return S_OK; + } + _optimumCurrentIndex = 0; + _optimumEndIndex = 0; // test it; + + UInt32 lenMain; + if (!_longestMatchWasFound) + { + RINOK(ReadMatchDistances(lenMain)); + } + else + { + lenMain = _longestMatchLength; + _longestMatchWasFound = false; + } + + + UInt32 reps[kNumRepDistances]; + UInt32 repLens[kNumRepDistances]; + UInt32 repMaxIndex = 0; + UInt32 i; + for(i = 0; i < kNumRepDistances; i++) + { + reps[i] = _repDistances[i]; + repLens[i] = _matchFinder->GetMatchLen(0 - 1, reps[i], kMatchMaxLen); + if (i == 0 || repLens[i] > repLens[repMaxIndex]) + repMaxIndex = i; + } + if(repLens[repMaxIndex] >= _numFastBytes) + { + backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + return MovePos(lenRes - 1); + } + + if(lenMain >= _numFastBytes) + { + backRes = _matchDistances[_numFastBytes] + kNumRepDistances; + lenRes = lenMain; + return MovePos(lenMain - 1); + } + Byte currentByte = _matchFinder->GetIndexByte(0 - 1); + + _optimum[0].State = _state; + + Byte matchByte; + + matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - 1); + + UInt32 posState = (position & _posStateMask); + + _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() + + _literalEncoder.GetPrice(position, _previousByte, !_state.IsCharState(), matchByte, currentByte); + _optimum[1].MakeAsChar(); + + _optimum[1].PosPrev = 0; + + for (i = 0; i < kNumRepDistances; i++) + _optimum[0].Backs[i] = reps[i]; + + 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(); + } + } + if(lenMain < 2) + { + backRes = _optimum[1].BackPrev; + lenRes = 1; + return S_OK; + } + + + UInt32 normalMatchPrice = matchPrice + + _isRep[_state.Index].GetPrice0(); + + if (lenMain <= repLens[repMaxIndex]) + lenMain = 0; + + UInt32 len; + for(len = 2; len <= lenMain; len++) + { + _optimum[len].PosPrev = 0; + _optimum[len].BackPrev = _matchDistances[len] + kNumRepDistances; + _optimum[len].Price = normalMatchPrice + + GetPosLenPrice(_matchDistances[len], len, posState); + _optimum[len].Prev1IsChar = false; + } + + if (lenMain < repLens[repMaxIndex]) + lenMain = repLens[repMaxIndex]; + + for (; len <= lenMain; len++) + _optimum[len].Price = kIfinityPrice; + + for(i = 0; i < kNumRepDistances; i++) + { + UInt32 repLen = repLens[i]; + for(UInt32 lenTest = 2; lenTest <= repLen; lenTest++) + { + UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(i, lenTest, _state, posState); + COptimal &optimum = _optimum[lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = 0; + optimum.BackPrev = i; + optimum.Prev1IsChar = false; + } + } + } + + UInt32 cur = 0; + UInt32 lenEnd = lenMain; + + while(true) + { + cur++; + if(cur == lenEnd) + { + lenRes = Backward(backRes, cur); + return S_OK; + } + 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(); + /* + if (curOptimum.Prev1IsChar) + for(int i = 0; i < kNumRepDistances; i++) + reps[i] = _optimum[posPrev].Backs[i]; + */ + } + 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 newLen; + RINOK(ReadMatchDistances(newLen)); + if(newLen >= _numFastBytes) + { + _longestMatchLength = newLen; + _longestMatchWasFound = true; + lenRes = Backward(backRes, cur); + return S_OK; + } + UInt32 curPrice = curOptimum.Price; + // Byte currentByte = _matchFinder->GetIndexByte(0 - 1); + // Byte matchByte = _matchFinder->GetIndexByte(0 - reps[0] - 1 - 1); + const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1; + Byte currentByte = *data; + Byte matchByte = data[(size_t)0 - reps[0] - 1]; + + UInt32 posState = (position & _posStateMask); + + UInt32 curAnd1Price = curPrice + + _isMatch[state.Index][posState].GetPrice0() + + _literalEncoder.GetPrice(position, data[(size_t)0 - 1], !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 = false; + } + } + /* + if(newLen == 2 && _matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ? + continue; + */ + + UInt32 numAvailableBytesFull = _matchFinder->GetNumAvailableBytes() + 1; + numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull); + UInt32 numAvailableBytes = numAvailableBytesFull; + + if (numAvailableBytes < 2) + continue; + if (numAvailableBytes > _numFastBytes) + numAvailableBytes = _numFastBytes; + if (numAvailableBytes >= 3 && !nextIsChar) + { + // try Literal + rep0 + UInt32 backOffset = reps[0] + 1; + UInt32 temp; + for (temp = 1; temp < numAvailableBytes; temp++) + if (data[temp] != data[(size_t)temp - backOffset]) + break; + 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--) + { + while(lenEnd < cur + 1 + lenTest2) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( + 0, lenTest2, state2, posStateNext); + COptimal &optimum = _optimum[cur + 1 + lenTest2]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = false; + } + } + } + } + for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++) + { + // UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it; + UInt32 backOffset = reps[repIndex] + 1; + if (data[0] != data[(size_t)0 - backOffset] || + data[1] != data[(size_t)1 - backOffset]) + continue; + UInt32 lenTest; + for (lenTest = 2; lenTest < numAvailableBytes; lenTest++) + if (data[lenTest] != data[(size_t)lenTest - backOffset]) + break; + UInt32 lenTestTemp = lenTest; + do + { + while(lenEnd < cur + lenTest) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, 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 (_maxMode) + { + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes); + for (; lenTest2 < limit; lenTest2++) + if (data[lenTest2] != data[(size_t)lenTest2 - backOffset]) + break; + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + CState state2 = state; + state2.UpdateRep(); + UInt32 posStateNext = (position + lenTest) & _posStateMask; + UInt32 curAndLenCharPrice = + repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) + + _isMatch[state2.Index][posStateNext].GetPrice0() + + _literalEncoder.GetPrice(position + lenTest, data[(size_t)lenTest - 1], + true, data[(size_t)lenTest - backOffset], data[lenTest]); + state2.UpdateChar(); + posStateNext = (position + lenTest + 1) & _posStateMask; + UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[state2.Index][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); + COptimal &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; + } + } + } + } + } + + // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++) + if (newLen > numAvailableBytes) + newLen = numAvailableBytes; + if (newLen >= 2) + { + if (newLen == 2 && _matchDistances[2] >= 0x80) + continue; + UInt32 normalMatchPrice = matchPrice + + _isRep[state.Index].GetPrice0(); + while(lenEnd < cur + newLen) + _optimum[++lenEnd].Price = kIfinityPrice; + + for(UInt32 lenTest = newLen; lenTest >= 2; lenTest--) + { + UInt32 curBack = _matchDistances[lenTest]; + UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, 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 == newLen || curBack != _matchDistances[lenTest + 1])) + { + // Try Match + Literal + Rep0 + UInt32 backOffset = curBack + 1; + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes); + for (; lenTest2 < limit; lenTest2++) + if (data[lenTest2] != data[(size_t)lenTest2 - backOffset]) + break; + 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.GetPrice(position + lenTest, data[(size_t)lenTest - 1], + true, data[(size_t)lenTest - backOffset], data[lenTest]); + state2.UpdateChar(); + posStateNext = (position + lenTest + 1) & _posStateMask; + UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[state2.Index][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); + COptimal &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 + kNumRepDistances; + } + } + } + } + } + } + } +} + +static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist) +{ + const int kDif = 7; + return (smallDist < (UInt32(1) << (32-kDif)) && bigDist >= (smallDist << kDif)); +} + + +HRESULT CEncoder::ReadMatchDistances(UInt32 &lenRes) +{ + lenRes = _matchFinder->GetLongestMatch(_matchDistances); + if (lenRes == _numFastBytes) + lenRes += _matchFinder->GetMatchLen(lenRes, _matchDistances[lenRes], + kMatchMaxLen - lenRes); + _additionalOffset++; + return _matchFinder->MovePos(); +} + +HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes) +{ + UInt32 lenMain; + if (!_longestMatchWasFound) + { + RINOK(ReadMatchDistances(lenMain)); + } + else + { + lenMain = _longestMatchLength; + _longestMatchWasFound = false; + } + UInt32 repLens[kNumRepDistances]; + UInt32 repMaxIndex = 0; + for(UInt32 i = 0; i < kNumRepDistances; i++) + { + repLens[i] = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen); + if (i == 0 || repLens[i] > repLens[repMaxIndex]) + repMaxIndex = i; + } + if(repLens[repMaxIndex] >= _numFastBytes) + { + backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + return MovePos(lenRes - 1); + } + if(lenMain >= _numFastBytes) + { + backRes = _matchDistances[_numFastBytes] + kNumRepDistances; + lenRes = lenMain; + return MovePos(lenMain - 1); + } + while (lenMain > 2) + { + if (!ChangePair(_matchDistances[lenMain - 1], _matchDistances[lenMain])) + break; + lenMain--; + } + if (lenMain == 2 && _matchDistances[2] >= 0x80) + lenMain = 1; + + UInt32 backMain = _matchDistances[lenMain]; + if (repLens[repMaxIndex] >= 2) + { + if (repLens[repMaxIndex] + 1 >= lenMain || + repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1<<12))) + { + backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + return MovePos(lenRes - 1); + } + } + + + if (lenMain >= 2) + { + RINOK(ReadMatchDistances(_longestMatchLength)); + if (_longestMatchLength >= 2 && + ( + (_longestMatchLength >= lenMain && _matchDistances[lenMain] < backMain) || + _longestMatchLength == lenMain + 1 && + !ChangePair(backMain, _matchDistances[_longestMatchLength]) || + _longestMatchLength > lenMain + 1 || + _longestMatchLength + 1 >= lenMain && lenMain >= 3 && + ChangePair(_matchDistances[lenMain - 1], backMain) + ) + ) + { + _longestMatchWasFound = true; + backRes = UInt32(-1); + lenRes = 1; + return S_OK; + } + for(UInt32 i = 0; i < kNumRepDistances; i++) + { + UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen); + if (repLen >= 2 && repLen + 1 >= lenMain) + { + _longestMatchWasFound = true; + backRes = UInt32(-1); + lenRes = 1; + return S_OK; + } + } + backRes = backMain + kNumRepDistances; + lenRes = lenMain; + return MovePos(lenMain - 2); + } + backRes = UInt32(-1); + lenRes = 1; + return S_OK; +} + +STDMETHODIMP CEncoder::InitMatchFinder(IMatchFinder *matchFinder) +{ + _matchFinder = matchFinder; + return S_OK; +} + +HRESULT CEncoder::Flush(UInt32 nowPos) +{ + ReleaseMFStream(); + 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); + 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; + CCoderReleaser coderReleaser(this); + RINOK(SetStreams(inStream, outStream, inSize, outSize)); + while(true) + { + UInt64 processedInSize; + UInt64 processedOutSize; + Int32 finished; + RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished)); + if (finished != 0) + return S_OK; + if (progress != 0) + { + RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize)); + } + } +} + +HRESULT CEncoder::SetStreams(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize) +{ + _inStream = inStream; + _finished = false; + RINOK(Create()); + RINOK(SetOutStream(outStream)); + RINOK(Init()); + + // CCoderReleaser releaser(this); + + /* + if (_matchFinder->GetNumAvailableBytes() == 0) + return Flush(); + */ + + if (!_fastMode) + { + FillPosSlotPrices(); + FillDistancesPrices(); + FillAlignPrices(); + } + + _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen); + _lenEncoder.UpdateTables(1 << _posStateBits); + _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen); + _repMatchLenEncoder.UpdateTables(1 << _posStateBits); + + lastPosSlotFillingPos = 0; + nowPos64 = 0; + return S_OK; +} + +HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished) +{ + if (_inStream != 0) + { + RINOK(_matchFinder->Init(_inStream)); + _needReleaseMFStream = true; + _inStream = 0; + } + + + *finished = 1; + if (_finished) + return S_OK; + _finished = true; + + + UInt64 progressPosValuePrev = nowPos64; + if (nowPos64 == 0) + { + if (_matchFinder->GetNumAvailableBytes() == 0) + return Flush(UInt32(nowPos64)); + UInt32 len; // it's not used + RINOK(ReadMatchDistances(len)); + UInt32 posState = UInt32(nowPos64) & _posStateMask; + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0); + _state.UpdateChar(); + Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset); + _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte); + _previousByte = curByte; + _additionalOffset--; + nowPos64++; + } + if (_matchFinder->GetNumAvailableBytes() == 0) + return Flush(UInt32(nowPos64)); + while(true) + { + #ifdef _NO_EXCEPTIONS + if (_rangeEncoder.Stream.ErrorCode != S_OK) + return _rangeEncoder.Stream.ErrorCode; + #endif + UInt32 pos; + UInt32 posState = UInt32(nowPos64) & _posStateMask; + + UInt32 len; + HRESULT result; + if (_fastMode) + result = GetOptimumFast(UInt32(nowPos64), pos, len); + else + result = GetOptimum(UInt32(nowPos64), pos, len); + RINOK(result); + + if(len == 1 && pos == 0xFFFFFFFF) + { + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0); + Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset); + CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte); + if(!_state.IsCharState()) + { + Byte matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - _additionalOffset); + subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte); + } + else + subCoder->Encode(&_rangeEncoder, 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); + if(len == 1) + _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, 0); + else + _isRep0Long[_state.Index][posState].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 - 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 - kMatchMinLen, posState); + pos -= kNumRepDistances; + UInt32 posSlot = GetPosSlot(pos); + UInt32 lenToPosState = GetLenToPosState(len); + _posSlotEncoder[lenToPosState].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); + if (!_fastMode) + if (--_alignPriceCount == 0) + FillAlignPrices(); + } + } + UInt32 distance = pos; + for(UInt32 i = kNumRepDistances - 1; i >= 1; i--) + _repDistances[i] = _repDistances[i - 1]; + _repDistances[0] = distance; + } + _previousByte = _matchFinder->GetIndexByte(len - 1 - _additionalOffset); + } + _additionalOffset -= len; + nowPos64 += len; + if (!_fastMode) + if (nowPos64 - lastPosSlotFillingPos >= (1 << 9)) + { + FillPosSlotPrices(); + FillDistancesPrices(); + lastPosSlotFillingPos = nowPos64; + } + if (_additionalOffset == 0) + { + *inSize = nowPos64; + *outSize = _rangeEncoder.GetProcessedSize(); + if (_matchFinder->GetNumAvailableBytes() == 0) + return Flush(UInt32(nowPos64)); + if (nowPos64 - progressPosValuePrev >= (1 << 12)) + { + _finished = false; + *finished = 0; + return S_OK; + } + } + } +} + +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::FillPosSlotPrices() +{ + for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 posSlot; + for (posSlot = 0; posSlot < kEndPosModelIndex && posSlot < _distTableSize; posSlot++) + _posSlotPrices[lenToPosState][posSlot] = _posSlotEncoder[lenToPosState].GetPrice(posSlot); + for (; posSlot < _distTableSize; posSlot++) + _posSlotPrices[lenToPosState][posSlot] = _posSlotEncoder[lenToPosState].GetPrice(posSlot) + + ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits); + } +} + +void CEncoder::FillDistancesPrices() +{ + for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 i; + for (i = 0; i < kStartPosModelIndex; i++) + _distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][i]; + for (; i < kNumFullDistances; i++) + { + UInt32 posSlot = GetPosSlot(i); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + + _distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][posSlot] + + NRangeCoder::ReverseBitTreeGetPrice(_posEncoders + + base - posSlot - 1, footerBits, i - base); + + } + } +} + +void CEncoder::FillAlignPrices() +{ + for (UInt32 i = 0; i < kAlignTableSize; i++) + _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); + _alignPriceCount = kAlignTableSize; +} + +}} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h new file mode 100644 index 00000000..542994e3 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h @@ -0,0 +1,416 @@ +// LZMA/Encoder.h + +#ifndef __LZMA_ENCODER_H +#define __LZMA_ENCODER_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" +#include "../../ICoder.h" +#include "../LZ/IMatchFinder.h" +#include "../RangeCoder/RangeCoderBitTree.h" + +#include "LZMA.h" + +namespace NCompress { +namespace NLZMA { + +typedef NRangeCoder::CBitEncoder 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); } +}; + + +extern Byte g_FastPos[1024]; +inline UInt32 GetPosSlot(UInt32 pos) +{ + if (pos < (1 << 10)) + return g_FastPos[pos]; + if (pos < (1 << 19)) + return g_FastPos[pos >> 9] + 18; + return g_FastPos[pos >> 18] + 36; +} + +inline UInt32 GetPosSlot2(UInt32 pos) +{ + if (pos < (1 << 16)) + return g_FastPos[pos >> 6] + 12; + if (pos < (1 << 25)) + return g_FastPos[pos >> 15] + 30; + return g_FastPos[pos >> 24] + 48; +} + +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(); + } + UInt32 GetState(UInt32 pos, Byte prevByte) const + { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); } + CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte) + { return &_coders[GetState(pos, prevByte)]; } + /* + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte, + Byte symbol) + { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, symbol); } + void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte, + Byte matchByte, Byte symbol) + { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, + matchByte, symbol); } + */ + UInt32 GetPrice(UInt32 pos, Byte prevByte, bool matchMode, Byte matchByte, Byte symbol) const + { return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); } +}; + +namespace NLength { + +class CEncoder +{ + CMyBitEncoder _choice; + CMyBitEncoder _choice2; + NRangeCoder::CBitTreeEncoder _lowCoder[kNumPosStatesEncodingMax]; + NRangeCoder::CBitTreeEncoder _midCoder[kNumPosStatesEncodingMax]; + NRangeCoder::CBitTreeEncoder _highCoder; +public: + void Init(UInt32 numPosStates); + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState); + UInt32 GetPrice(UInt32 symbol, UInt32 posState) const; +}; + +const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols; + +class CPriceTableEncoder: public CEncoder +{ + UInt32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax]; + UInt32 _tableSize; + UInt32 _counters[kNumPosStatesEncodingMax]; +public: + void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; } + UInt32 GetPrice(UInt32 symbol, UInt32 posState) const + { return _prices[symbol][posState]; } + void UpdateTable(UInt32 posState) + { + for (UInt32 len = 0; len < _tableSize; len++) + _prices[len][posState] = CEncoder::GetPrice(len, 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) + { + CEncoder::Encode(rangeEncoder, symbol, posState); + if (--_counters[posState] == 0) + UpdateTable(posState); + } +}; + +} + +class CEncoder : + public ICompressCoder, + public ICompressSetOutStream, + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + public CBaseState, + public CMyUnknownImp +{ + COptimal _optimum[kNumOpts]; + CMyComPtr _matchFinder; // test it + NRangeCoder::CEncoder _rangeEncoder; + + CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax]; + CMyBitEncoder _isRep[kNumStates]; + CMyBitEncoder _isRepG0[kNumStates]; + CMyBitEncoder _isRepG1[kNumStates]; + CMyBitEncoder _isRepG2[kNumStates]; + CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax]; + + NRangeCoder::CBitTreeEncoder _posSlotEncoder[kNumLenToPosStates]; + + CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex]; + NRangeCoder::CBitTreeEncoder _posAlignEncoder; + + NLength::CPriceTableEncoder _lenEncoder; + NLength::CPriceTableEncoder _repMatchLenEncoder; + + CLiteralEncoder _literalEncoder; + + UInt32 _matchDistances[kMatchMaxLen + 1]; + + bool _fastMode; + bool _maxMode; + UInt32 _numFastBytes; + UInt32 _longestMatchLength; + + 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 _dictionarySizePrev; + UInt32 _numFastBytesPrev; + + UInt64 lastPosSlotFillingPos; + UInt64 nowPos64; + bool _finished; + ISequentialInStream *_inStream; + + int _matchFinderIndex; + #ifdef COMPRESS_MF_MT + bool _multiThread; + #endif + + bool _writeEndMark; + + bool _needReleaseMFStream; + + HRESULT ReadMatchDistances(UInt32 &len); + + HRESULT MovePos(UInt32 num); + UInt32 GetRepLen1Price(CState state, UInt32 posState) const + { + return _isRepG0[state.Index].GetPrice0() + + _isRep0Long[state.Index][posState].GetPrice0(); + } + UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const + { + UInt32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState); + 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 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 + { + if (len == 2 && pos >= 0x80) + return kIfinityPrice; + 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); + HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes); + HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes); + + void FillPosSlotPrices(); + void FillDistancesPrices(); + void FillAlignPrices(); + + void ReleaseMFStream() + { + if (_matchFinder && _needReleaseMFStream) + { + _matchFinder->ReleaseStream(); + _needReleaseMFStream = false; + } + } + + 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); + + // IInitMatchFinder interface + STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder); + + // 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/StdAfx.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/StdAfx.h new file mode 100644 index 00000000..83fdd22d --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp new file mode 100644 index 00000000..41d5b489 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsp @@ -0,0 +1,523 @@ +# 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" /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 /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /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" /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" /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 Group "Pat" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat2.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat2H.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat2R.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat3H.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\Pat4H.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\Patricia\PatMain.h +# End Source File +# End Group +# Begin Group "BT" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree2.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3Z.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3ZMain.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree4b.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeMain.h +# End Source File +# End Group +# Begin Group "HC" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\HashChain\HC.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HC2.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HC3.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HC4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HC4b.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HCMain.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\LZ\IMatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZInWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZInWindow.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Branch\BranchX86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\Branch\BranchX86.h +# End Source File +# End Group +# Begin Group "LZMA_C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZMA_C\LzmaDecode.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\LZMA_C\LzmaDecode.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 +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.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\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# 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\MyCom.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\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.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\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.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 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=.\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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw new file mode 100644 index 00000000..7402f297 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/AloneLZMA.dsw @@ -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> +{{{ +}}} + +############################################################################### + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp new file mode 100644 index 00000000..52149033 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaAlone.cpp @@ -0,0 +1,509 @@ +// LzmaAlone.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include + +#if defined(_WIN32) || defined(OS2) || defined(MSDOS) +#include +#include +#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 "LzmaBench.h" +#include "LzmaRam.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, + kLitContext, + kLitPos, + kPosBits, + kMatchFinder, + 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"LC", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"LP", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"PB", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"MF", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"EOS", NSwitchType::kSimple, false }, + { L"SI", NSwitchType::kSimple, false }, + { L"SO", NSwitchType::kSimple, false }, + { L"F86", NSwitchType::kSimple, false } +}; + +static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]); + +static void PrintHelp() +{ + fprintf(stderr, "\nUsage: LZMA inputFile outputFile [...]\n" + " e: encode file\n" + " d: decode file\n" + " b: Benchmark\n" + "\n" + " -a{N}: set compression mode - [0, 2], default: 2 (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, bt3, bt4, bt4b, pat2r, pat2,\n" + " pat2h, pat3h, pat4h, hc3, hc4], default: bt4\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 4.32 Copyright (c) 1999-2005 Igor Pavlov 2005-12-09\n"); + + if (n == 1) + { + PrintHelp(); + return 0; + } + + if (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4) + { + 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 = 1 << 21; + 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]; + + if (command.CompareNoCase(L"b") == 0) + { + const UInt32 kNumDefaultItereations = 10; + UInt32 numIterations = kNumDefaultItereations; + { + if (paramIndex < nonSwitchStrings.Size()) + if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations)) + numIterations = kNumDefaultItereations; + } + return LzmaBenchmark(stderr, numIterations, dictionary, + mf.CompareNoCase(L"BT4") == 0); + } + + 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 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 outStream; + if (stdOutMode) + { + outStream = new CStdOutFileStream; + MY_SET_BINARY_MODE(stdout); + } + else + { + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &outputName = nonSwitchStrings[paramIndex++]; + COutFileStream *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, 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 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 = 2; + UInt32 numFastBytes = 128; + + 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(); + 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 + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + /* + NWindows::NCOM::CPropVariant properties[kNumProps]; + properties[0] = UInt32(dictionary); + properties[1] = UInt32(posStateBits); + properties[2] = UInt32(litContextBits); + + properties[3] = UInt32(litPosBits); + properties[4] = UInt32(algorithm); + properties[5] = UInt32(numFastBytes); + properties[6] = mf; + properties[7] = eos; + */ + PROPVARIANT properties[kNumProps]; + 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; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != 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 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; + } + } + 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; + } +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp new file mode 100644 index 00000000..fd6af9bd --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.cpp @@ -0,0 +1,508 @@ +// LzmaBench.cpp + +#include "StdAfx.h" + +#include "LzmaBench.h" + +#ifndef _WIN32 +#include +#endif + +#include "../../../Common/CRC.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" + +static const UInt32 kAdditionalSize = +#ifdef _WIN32_WCE +(1 << 20); +#else +(6 << 20); +#endif + +static const UInt32 kCompressedAdditionalSize = (1 << 10); +static const UInt32 kMaxLzmaPropSize = 10; + +class CRandomGenerator +{ + UInt32 A1; + UInt32 A2; +public: + CRandomGenerator() { Init(); } + void Init() { A1 = 362436069; A2 = 521288629;} + UInt32 GetRnd() + { + return + ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^ + ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ); + } +}; + +class CBitRandomGenerator +{ + CRandomGenerator RG; + UInt32 Value; + int NumBits; +public: + void Init() + { + Value = 0; + NumBits = 0; + } + UInt32 GetRnd(int numBits) + { + if (NumBits > numBits) + { + UInt32 result = Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits -= numBits; + return result; + } + numBits -= NumBits; + UInt32 result = (Value << numBits); + Value = RG.GetRnd(); + result |= Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits = 32 - numBits; + return result; + } +}; + +class CBenchRandomGenerator +{ + CBitRandomGenerator RG; + UInt32 Pos; +public: + UInt32 BufferSize; + Byte *Buffer; + CBenchRandomGenerator(): Buffer(0) {} + ~CBenchRandomGenerator() { delete []Buffer; } + void Init() { RG.Init(); } + void Set(UInt32 bufferSize) + { + delete []Buffer; + Buffer = 0; + Buffer = new Byte[bufferSize]; + Pos = 0; + BufferSize = bufferSize; + } + UInt32 GetRndBit() { return RG.GetRnd(1); } + /* + UInt32 GetLogRand(int maxLen) + { + UInt32 len = GetRnd() % (maxLen + 1); + return GetRnd() & ((1 << len) - 1); + } + */ + UInt32 GetLogRandBits(int numBits) + { + UInt32 len = RG.GetRnd(numBits); + return RG.GetRnd(len); + } + UInt32 GetOffset() + { + if (GetRndBit() == 0) + return GetLogRandBits(4); + return (GetLogRandBits(4) << 10) | RG.GetRnd(10); + } + UInt32 GetLen() + { + if (GetRndBit() == 0) + return RG.GetRnd(2); + if (GetRndBit() == 0) + return 4 + RG.GetRnd(3); + return 12 + RG.GetRnd(4); + } + void Generate() + { + while(Pos < BufferSize) + { + if (GetRndBit() == 0 || Pos < 1) + Buffer[Pos++] = Byte(RG.GetRnd(8)); + else + { + UInt32 offset = GetOffset(); + while (offset >= Pos) + offset >>= 1; + offset += 1; + UInt32 len = 2 + GetLen(); + for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++) + Buffer[Pos] = Buffer[Pos - offset]; + } + } + } +}; + +class CBenchmarkInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *Data; + UInt32 Pos; + UInt32 Size; +public: + MY_UNKNOWN_IMP + void Init(const Byte *data, UInt32 size) + { + Data = data; + Size = size; + Pos = 0; + } + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 remain = Size - Pos; + if (size > remain) + size = 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 CMyUnknownImp +{ + UInt32 BufferSize; + FILE *_f; +public: + UInt32 Pos; + Byte *Buffer; + CBenchmarkOutStream(): _f(0), Buffer(0) {} + virtual ~CBenchmarkOutStream() { delete []Buffer; } + void Init(FILE *f, UInt32 bufferSize) + { + delete []Buffer; + Buffer = 0; + Buffer = new Byte[bufferSize]; + Pos = 0; + BufferSize = bufferSize; + _f = f; + } + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 i; + for (i = 0; i < size && Pos < BufferSize; i++) + Buffer[Pos++] = ((const Byte *)data)[i]; + if(processedSize != NULL) + *processedSize = i; + if (i != size) + { + fprintf(_f, "\nERROR: Buffer is full\n"); + return E_FAIL; + } + return S_OK; +} + +class CCrcOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + CCRC CRC; + MY_UNKNOWN_IMP + void Init() { CRC.Init(); } + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + CRC.Update(data, size); + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +static UInt64 GetTimeCount() +{ + #ifdef _WIN32 + LARGE_INTEGER value; + if (::QueryPerformanceCounter(&value)) + return value.QuadPart; + return GetTickCount(); + #else + return clock(); + #endif +} + +static UInt64 GetFreq() +{ + #ifdef _WIN32 + LARGE_INTEGER value; + if (::QueryPerformanceFrequency(&value)) + return value.QuadPart; + return 1000; + #else + return CLOCKS_PER_SEC; + #endif +} + +struct CProgressInfo: + public ICompressProgressInfo, + public CMyUnknownImp +{ + UInt64 ApprovedStart; + UInt64 InSize; + UInt64 Time; + void Init() + { + InSize = 0; + Time = 0; + } + MY_UNKNOWN_IMP + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +STDMETHODIMP CProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + if (*inSize >= ApprovedStart && InSize == 0) + { + Time = ::GetTimeCount(); + InSize = *inSize; + } + return S_OK; +} + +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 UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime) +{ + UInt64 freq = GetFreq(); + UInt64 elTime = elapsedTime; + while(freq > 1000000) + { + freq >>= 1; + elTime >>= 1; + } + if (elTime == 0) + elTime = 1; + return value * freq / elTime; +} + +static UInt64 GetCompressRating(UInt32 dictionarySize, bool isBT4, + UInt64 elapsedTime, UInt64 size) +{ + UInt64 numCommandsForOne; + if (isBT4) + { + UInt64 t = GetLogSize(dictionarySize) - (19 << kSubBits); + numCommandsForOne = 2000 + ((t * t * 68) >> (2 * kSubBits)); + } + else + { + UInt64 t = GetLogSize(dictionarySize) - (15 << kSubBits); + numCommandsForOne = 1500 + ((t * t * 41) >> (2 * kSubBits)); + } + UInt64 numCommands = (UInt64)(size) * numCommandsForOne; + return MyMultDiv64(numCommands, elapsedTime); +} + +static UInt64 GetDecompressRating(UInt64 elapsedTime, + UInt64 outSize, UInt64 inSize) +{ + UInt64 numCommands = inSize * 250 + outSize * 21; + return MyMultDiv64(numCommands, elapsedTime); +} + +/* +static UInt64 GetTotalRating( + UInt32 dictionarySize, + bool isBT4, + UInt64 elapsedTimeEn, UInt64 sizeEn, + UInt64 elapsedTimeDe, + UInt64 inSizeDe, UInt64 outSizeDe) +{ + return (GetCompressRating(dictionarySize, isBT4, elapsedTimeEn, sizeEn) + + GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2; +} +*/ + +static void PrintRating(FILE *f, UInt64 rating) +{ + fprintf(f, "%5d MIPS", (unsigned int)(rating / 1000000)); +} + +static void PrintResults( + FILE *f, + UInt32 dictionarySize, + bool isBT4, + UInt64 elapsedTime, + UInt64 size, + bool decompressMode, UInt64 secondSize) +{ + UInt64 speed = MyMultDiv64(size, elapsedTime); + fprintf(f, "%6d KB/s ", (unsigned int)(speed / 1024)); + UInt64 rating; + if (decompressMode) + rating = GetDecompressRating(elapsedTime, size, secondSize); + else + rating = GetCompressRating(dictionarySize, isBT4, elapsedTime, size); + PrintRating(f, rating); +} + +static void ThrowError(FILE *f, HRESULT result, const char *s) +{ + fprintf(f, "\nError: "); + if (result == E_ABORT) + fprintf(f, "User break"); + if (result == E_OUTOFMEMORY) + fprintf(f, "Can not allocate memory"); + else + fprintf(f, s); + fprintf(f, "\n"); +} + +const wchar_t *bt2 = L"BT2"; +const wchar_t *bt4 = L"BT4"; + +int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize, bool isBT4) +{ + if (numIterations == 0) + return 0; + if (dictionarySize < (1 << 19) && isBT4 || dictionarySize < (1 << 15)) + { + fprintf(f, "\nError: dictionary size for benchmark must be >= 19 (512 KB)\n"); + return 1; + } + fprintf(f, "\n Compressing Decompressing\n\n"); + NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder; + CMyComPtr encoder = encoderSpec; + + NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder; + CMyComPtr decoder = decoderSpec; + + CBenchmarkOutStream *propStreamSpec = new CBenchmarkOutStream; + CMyComPtr propStream = propStreamSpec; + propStreamSpec->Init(f, kMaxLzmaPropSize); + + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kMatchFinder + }; + 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_BSTR; + properties[1].bstrVal = isBT4 ? (BSTR)bt4: (BSTR)bt2; + + const UInt32 kBufferSize = dictionarySize + kAdditionalSize; + const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + { + fprintf(f, "\nError: Incorrect command\n"); + return 1; + } + encoderSpec->WriteCoderProperties(propStream); + + CBenchRandomGenerator rg; + rg.Init(); + rg.Set(kBufferSize); + rg.Generate(); + CCRC crc; + crc.Update(rg.Buffer, rg.BufferSize); + + CProgressInfo *progressInfoSpec = new CProgressInfo; + CMyComPtr progressInfo = progressInfoSpec; + + progressInfoSpec->ApprovedStart = dictionarySize; + + UInt64 totalBenchSize = 0; + UInt64 totalEncodeTime = 0; + UInt64 totalDecodeTime = 0; + UInt64 totalCompressedSize = 0; + + for (UInt32 i = 0; i < numIterations; i++) + { + progressInfoSpec->Init(); + CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; + inStreamSpec->Init(rg.Buffer, rg.BufferSize); + CMyComPtr inStream = inStreamSpec; + CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream; + outStreamSpec->Init(f, kCompressedBufferSize); + CMyComPtr outStream = outStreamSpec; + HRESULT result = encoder->Code(inStream, outStream, 0, 0, progressInfo); + UInt64 encodeTime = ::GetTimeCount() - progressInfoSpec->Time; + UInt32 compressedSize = outStreamSpec->Pos; + if(result != S_OK) + { + ThrowError(f, result, "Encoder Error"); + return 1; + } + if (progressInfoSpec->InSize == 0) + { + fprintf(f, "\nError: Internal ERROR 1282\n"); + return 1; + } + + /////////////////////// + // Decompressing + + CCrcOutStream *crcOutStreamSpec = new CCrcOutStream; + CMyComPtr crcOutStream = crcOutStreamSpec; + + UInt64 decodeTime; + for (int j = 0; j < 2; j++) + { + inStreamSpec->Init(outStreamSpec->Buffer, compressedSize); + crcOutStreamSpec->Init(); + + if (decoderSpec->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos) != S_OK) + { + fprintf(f, "\nError: Set Decoder Properties Error\n"); + return 1; + } + UInt64 outSize = kBufferSize; + UInt64 startTime = ::GetTimeCount(); + result = decoder->Code(inStream, crcOutStream, 0, &outSize, 0); + decodeTime = ::GetTimeCount() - startTime; + if(result != S_OK) + { + ThrowError(f, result, "Decode Error"); + return 1; + } + if (crcOutStreamSpec->CRC.GetDigest() != crc.GetDigest()) + { + fprintf(f, "\nError: CRC Error\n"); + return 1; + } + } + UInt64 benchSize = kBufferSize - progressInfoSpec->InSize; + PrintResults(f, dictionarySize, isBT4, encodeTime, benchSize, false, 0); + fprintf(f, " "); + PrintResults(f, dictionarySize, isBT4, decodeTime, kBufferSize, true, compressedSize); + fprintf(f, "\n"); + + totalBenchSize += benchSize; + totalEncodeTime += encodeTime; + totalDecodeTime += decodeTime; + totalCompressedSize += compressedSize; + } + fprintf(f, "---------------------------------------------------\n"); + PrintResults(f, dictionarySize, isBT4, totalEncodeTime, totalBenchSize, false, 0); + fprintf(f, " "); + PrintResults(f, dictionarySize, isBT4, totalDecodeTime, + kBufferSize * numIterations, true, totalCompressedSize); + fprintf(f, " Average\n"); + return 0; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.h new file mode 100644 index 00000000..9a1a63a5 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaBench.h @@ -0,0 +1,11 @@ +// LzmaBench.h + +#ifndef __LzmaBench_h +#define __LzmaBench_h + +#include +#include "../../../Common/Types.h" + +int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize, bool isBT4); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp new file mode 100644 index 00000000..3cc264a1 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.cpp @@ -0,0 +1,228 @@ +// LzmaRam.cpp + +#include "StdAfx.h" +#include "../../../Common/Types.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" +#include "LzmaRam.h" + +extern "C" +{ +#include "../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) +{ + UInt32 remain = Size - Pos; + if (size > remain) + size = 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 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 SZE_FAIL (1) +#define SZE_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 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 SZE_OUTOFMEMORY; + CMyComPtr outStream = outStreamSpec; + CInStreamRam *inStreamSpec = new CInStreamRam; + if (inStreamSpec == 0) + return SZE_OUTOFMEMORY; + CMyComPtr 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 SZE_OUTOFMEMORY; + memmove(filteredStream, inBuffer, inSize); + } + UInt32 _prevMask; + UInt32 _prevPos; + x86_Convert_Init(_prevMask, _prevPos); + x86_Convert(filteredStream, (UInt32)inSize, 0, &_prevMask, &_prevPos, 1); + } + + UInt32 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 = SZE_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 = SZE_FAIL; + break; + } + } + *outSizeProcessed = outStreamSpec->Pos; + if (bestIsFiltered) + outBuffer[0] = 1; + if (useFilter) + MyFree(filteredStream); + return mainResult; + + #ifndef _NO_EXCEPTIONS + } catch(...) { return SZE_OUTOFMEMORY; } + #endif +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.h new file mode 100644 index 00000000..74d584d2 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRam.h @@ -0,0 +1,46 @@ +// LzmaRam.h + +#ifndef __LzmaRam_h +#define __LzmaRam_h + +#include +#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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c new file mode 100644 index 00000000..0f0f8424 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.c @@ -0,0 +1,79 @@ +/* LzmaRamDecode.c */ + +#include "LzmaRamDecode.h" +#ifdef _SZ_ONE_DIRECTORY +#include "LzmaDecode.h" +#include "BranchX86.h" +#else +#include "../LZMA_C/LzmaDecode.h" +#include "../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 _prevMask; + UInt32 _prevPos; + x86_Convert_Init(_prevMask, _prevPos); + x86_Convert(outBuffer, (UInt32)outSizeProcessedLoc, 0, &_prevMask, &_prevPos, 0); + } + return 0; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h new file mode 100644 index 00000000..783734a4 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/LzmaRamDecode.h @@ -0,0 +1,55 @@ +/* LzmaRamDecode.h */ + +#ifndef __LzmaRamDecode_h +#define __LzmaRamDecode_h + +#include + +/* +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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.cpp new file mode 100644 index 00000000..c6d3b1fa --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.h new file mode 100644 index 00000000..83fdd22d --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/makefile b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/makefile new file mode 100644 index 00000000..5b8d0a32 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/makefile @@ -0,0 +1,100 @@ +PROG = lzma.exe +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +!IFNDEF O +!IFDEF CPU +O=$(CPU) +!ELSE +O=O +!ENDIF +!ENDIF + +CFLAGS = $(CFLAGS) -nologo -EHsc -c -Fo$O/ -GS- +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\LzmaRam.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + $O\LZMAEncoder.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\CommandLineParser.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\StreamUtils.obj \ + +LZ_OBJS = \ + $O\LZInWindow.obj \ + $O\LZOutWindow.obj \ + + +OBJS = \ + $(LZMA_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(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) +$(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: ../LZMA_C/LzmaDecode.c + $(COMPL_O2) +$O\BranchX86.obj: ../Branch/BranchX86.c + $(COMPL_O2) +$O\FileStreams.obj: ../../Common/FileStreams.cpp + $(COMPL) +$O\FileIO.obj: ../../../Windows/FileIO.cpp + $(COMPL) diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/makefile.gcc b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/makefile.gcc new file mode 100644 index 00000000..1e180742 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Alone/makefile.gcc @@ -0,0 +1,113 @@ +PROG = lzma +CXX = g++ -O2 -Wall +CXX_C = gcc -O2 -Wall +LIB = -lm +RM = rm -f +CFLAGS = -c -I ../../../ + +OBJS = \ + LzmaAlone.o \ + LzmaBench.o \ + LzmaRam.o \ + LzmaRamDecode.o \ + LzmaDecode.o \ + BranchX86.o \ + LZMADecoder.o \ + LZMAEncoder.o \ + LZInWindow.o \ + LZOutWindow.o \ + RangeCoderBit.o \ + InBuffer.o \ + OutBuffer.o \ + FileStreams.o \ + StreamUtils.o \ + Alloc.o \ + C_FileIO.o \ + CommandLineParser.o \ + CRC.o \ + String.o \ + StringConvert.o \ + StringToInt.o \ + Vector.o \ + + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +LzmaAlone.o: LzmaAlone.cpp + $(CXX) $(CFLAGS) LzmaAlone.cpp + +LzmaBench.o: LzmaBench.cpp + $(CXX) $(CFLAGS) LzmaBench.cpp + +LzmaRam.o: LzmaRam.cpp + $(CXX) $(CFLAGS) LzmaRam.cpp + +LzmaRamDecode.o: LzmaRamDecode.c + $(CXX_C) $(CFLAGS) LzmaRamDecode.c + +LzmaDecode.o: ../LZMA_C/LzmaDecode.c + $(CXX_C) $(CFLAGS) ../LZMA_C/LzmaDecode.c + +BranchX86.o: ../Branch/BranchX86.c + $(CXX_C) $(CFLAGS) ../Branch/BranchX86.c + +LZMADecoder.o: ../LZMA/LZMADecoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp + +LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp + +LZInWindow.o: ../LZ/LZInWindow.cpp + $(CXX) $(CFLAGS) ../LZ/LZInWindow.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 + +Alloc.o: ../../../Common/Alloc.cpp + $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp + +C_FileIO.o: ../../../Common/C_FileIO.cpp + $(CXX) $(CFLAGS) ../../../Common/C_FileIO.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 + +String.o: ../../../Common/String.cpp + $(CXX) $(CFLAGS) ../../../Common/String.cpp + +StringConvert.o: ../../../Common/StringConvert.cpp + $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp + +StringToInt.o: ../../../Common/StringToInt.cpp + $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp + +Vector.o: ../../../Common/Vector.cpp + $(CXX) $(CFLAGS) ../../../Common/Vector.cpp + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.c new file mode 100644 index 00000000..5c9d67f7 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.c @@ -0,0 +1,588 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10) + 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" + +#ifndef Byte +#define Byte unsigned char +#endif + +#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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.h new file mode 100644 index 00000000..35e37ed0 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecode.h @@ -0,0 +1,131 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08) + 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 + +/* #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 */ + +/* #define _LZMA_SYSTEM_SIZE_T */ +/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/ + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifndef SizeT +#ifdef _LZMA_SYSTEM_SIZE_T +#include +#define SizeT size_t +#else +#define SizeT UInt32 +#endif +#endif + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb unsigned short +#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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c new file mode 100644 index 00000000..fe24cf21 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaDecodeSize.c @@ -0,0 +1,716 @@ +/* + LzmaDecodeSize.c + LZMA Decoder (optimized for Size version) + + LZMA SDK 4.27 Copyright (c) 1999-2005 Igor Pavlov (2005-08-07) + 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" + +#ifndef Byte +#define Byte unsigned char +#endif + +#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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.c new file mode 100644 index 00000000..8ddb6ee1 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.c @@ -0,0 +1,521 @@ +/* + LzmaStateDecode.c + LZMA Decoder (State version) + + LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08) + 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]; + + while(1) + { + 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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.h new file mode 100644 index 00000000..4e6aad89 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateDecode.h @@ -0,0 +1,115 @@ +/* + LzmaStateDecode.h + LZMA Decoder interface (State version) + + LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08) + 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 + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +/* #define _LZMA_SYSTEM_SIZE_T */ +/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/ + + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifndef SizeT +#ifdef _LZMA_SYSTEM_SIZE_T +#include +#define SizeT size_t +#else +#define SizeT UInt32 +#endif +#endif + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb unsigned short +#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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateTest.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateTest.c new file mode 100644 index 00000000..fa791d35 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaStateTest.c @@ -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 +#include +#include + +#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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaTest.c b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaTest.c new file mode 100644 index 00000000..370b9497 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/LzmaTest.c @@ -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 +#include +#include + +#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; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/makefile b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/makefile new file mode 100644 index 00000000..f8e193b2 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/makefile @@ -0,0 +1,43 @@ +PROG = lzmaDec.exe + +!IFNDEF O +!IFDEF CPU +O=$(CPU) +!ELSE +O=O +!ENDIF +!ENDIF + +CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS- +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) $** + + +OBJS = \ + $O\LzmaTest.obj \ + $O\LzmaDecode.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) + + +$O\LzmaTest.obj: $(*B).c + $(COMPL) +$O\LzmaDecode.obj: ../../Compress/LZMA_C/$(*B).c + $(COMPL_O2) diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/makefile.gcc b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/makefile.gcc new file mode 100644 index 00000000..43bbef17 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_C/makefile.gcc @@ -0,0 +1,23 @@ +PROG = lzmadec +CXX = gcc +LIB = +RM = rm -f +CFLAGS = -c -O2 -Wall -pedantic -D _LZMA_PROB32 + +OBJS = LzmaTest.o LzmaDecode.o + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +LzmaTest.o: LzmaTest.c + $(CXX) $(CFLAGS) LzmaTest.c + +LzmaDecode.o: LzmaDecode.c + $(CXX) $(CFLAGS) LzmaDecode.c + + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Lib/ZLib.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Lib/ZLib.cpp new file mode 100644 index 00000000..931c13ac --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Lib/ZLib.cpp @@ -0,0 +1,273 @@ +/* + * lzma zlib simplified wrapper + * + * Copyright (c) 2005-2006 Oleg I. Vdovikin + * + * 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 + */ + +/* + * default values for encoder/decoder used by wrapper + */ + +#include + +#define ZLIB_LC 3 +#define ZLIB_LP 0 +#define ZLIB_PB 2 + +#ifdef WIN32 +#include +#else +#define INITGUID +#endif + +#include "../../../Common/MyWindows.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" + +#define STG_E_SEEKERROR ((HRESULT)0x80030019L) +#define STG_E_MEDIUMFULL ((HRESULT)0x80030070L) + +class CInMemoryStream: + public IInStream, + public IStreamGetSize, + public CMyUnknownImp +{ +public: + CInMemoryStream(const Bytef *data, UInt64 size) : + m_data(data), m_size(size), m_offset(0) {} + + virtual ~CInMemoryStream() {} + + MY_UNKNOWN_IMP2(IInStream, IStreamGetSize) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) + { + if (size > m_size - m_offset) + size = m_size - m_offset; + + if (size) { + memcpy(data, m_data + m_offset, size); + } + + m_offset += size; + + if (processedSize) + *processedSize = size; + + return S_OK; + } + + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize) + { + return Read(data, size, processedSize); + } + + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) + { + UInt64 _offset; + + if (seekOrigin == STREAM_SEEK_SET) _offset = offset; + else if (seekOrigin == STREAM_SEEK_CUR) _offset = m_offset + offset; + else if (seekOrigin == STREAM_SEEK_END) _offset = m_size; + else return STG_E_INVALIDFUNCTION; + + if (_offset < 0 || _offset > m_size) + return STG_E_SEEKERROR; + + m_offset = _offset; + + if (newPosition) + *newPosition = m_offset; + + return S_OK; + } + + STDMETHOD(GetSize)(UInt64 *size) + { + *size = m_size; + return S_OK; + } +protected: + const Bytef *m_data; + UInt64 m_size; + UInt64 m_offset; +}; + +class COutMemoryStream: + public IOutStream, + public CMyUnknownImp +{ +public: + COutMemoryStream(Bytef *data, UInt64 maxsize) : + m_data(data), m_size(0), m_maxsize(maxsize), m_offset(0) {} + virtual ~COutMemoryStream() {} + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) + { + if (size > m_maxsize - m_offset) + size = m_maxsize - m_offset; + + if (size) { + memcpy(m_data + m_offset, data, size); + } + + m_offset += size; + + if (m_offset > m_size) + m_size = m_offset; + + if (processedSize) + *processedSize = size; + + return S_OK; + } + + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) + { + return Write(data, size, processedSize); + } + + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) + { + UInt64 _offset; + + if (seekOrigin == STREAM_SEEK_SET) _offset = offset; + else if (seekOrigin == STREAM_SEEK_CUR) _offset = m_offset + offset; + else if (seekOrigin == STREAM_SEEK_END) _offset = m_size; + else return STG_E_INVALIDFUNCTION; + + if (_offset < 0 || _offset > m_maxsize) + return STG_E_SEEKERROR; + + m_offset = _offset; + + if (newPosition) + *newPosition = m_offset; + + return S_OK; + } + + STDMETHOD(SetSize)(Int64 newSize) + { + if ((UInt64)newSize > m_maxsize) + return STG_E_MEDIUMFULL; + + return S_OK; + } +protected: + Bytef *m_data; + UInt64 m_size; + UInt64 m_maxsize; + UInt64 m_offset; +}; + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)) +{ + CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen); + CMyComPtr inStream = inStreamSpec; + + COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen); + CMyComPtr outStream = outStreamSpec; + + NCompress::NLZMA::CEncoder *encoderSpec = + new NCompress::NLZMA::CEncoder; + CMyComPtr encoder = encoderSpec; + + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kPosStateBits, + NCoderPropID::kLitContextBits, + NCoderPropID::kLitPosBits, + NCoderPropID::kAlgorithm, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinder, + NCoderPropID::kEndMarker + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + + PROPVARIANT properties[kNumProps]; + for (int p = 0; p < 6; p++) + properties[p].vt = VT_UI4; + properties[0].ulVal = UInt32(1 << (level + 14)); + properties[1].ulVal = UInt32(ZLIB_PB); + properties[2].ulVal = UInt32(ZLIB_LC); // for normal files + properties[3].ulVal = UInt32(ZLIB_LP); // for normal files + properties[4].ulVal = UInt32(2); + properties[5].ulVal = UInt32(128); + + properties[6].vt = VT_BSTR; + properties[6].bstrVal = (BSTR)(const wchar_t *)L"BT4"; + + properties[7].vt = VT_BOOL; + properties[7].boolVal = VARIANT_TRUE; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + return Z_MEM_ERROR; // should not happen + + HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0); + if (result == E_OUTOFMEMORY) + { + return Z_MEM_ERROR; + } + else if (result != S_OK) + { + return Z_BUF_ERROR; // should not happen + } + + UInt64 fileSize; + outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize); + *destLen = fileSize; + + return Z_OK; +} + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)) +{ + CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen); + CMyComPtr inStream = inStreamSpec; + + COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen); + CMyComPtr outStream = outStreamSpec; + + NCompress::NLZMA::CDecoder *decoderSpec = + new NCompress::NLZMA::CDecoder; + CMyComPtr decoder = decoderSpec; + + if (decoderSpec->SetDecoderPropertiesRaw(ZLIB_LC, + ZLIB_LP, ZLIB_PB, (1 << 23)) != S_OK) return Z_DATA_ERROR; + + UInt64 fileSize = *destLen; + + if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK) + { + return Z_DATA_ERROR; + } + + outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize); + *destLen = fileSize; + + return Z_OK; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Lib/makefile b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Lib/makefile new file mode 100644 index 00000000..bbf27459 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/LZMA_Lib/makefile @@ -0,0 +1,92 @@ +PROG = liblzma.a +CXX = g++ -O3 -Wall -Wno-non-virtual-dtor +AR = ar +RM = rm -f +CFLAGS = -c -I ../../../ + +OBJS = \ + ZLib.o \ + LZMADecoder.o \ + LZMAEncoder.o \ + LZInWindow.o \ + LZOutWindow.o \ + RangeCoderBit.o \ + InBuffer.o \ + OutBuffer.o \ + FileStreams.o \ + Alloc.o \ + C_FileIO.o \ + CommandLineParser.o \ + CRC.o \ + StreamUtils.o \ + String.o \ + StringConvert.o \ + StringToInt.o \ + Vector.o \ + + +all: $(PROG) + +$(PROG): $(OBJS) + $(AR) r $(PROG) $(OBJS) + +ZLib.o: ZLib.cpp + $(CXX) $(CFLAGS) ZLib.cpp + +LZMADecoder.o: ../LZMA/LZMADecoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp + +LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp + +LZInWindow.o: ../LZ/LZInWindow.cpp + $(CXX) $(CFLAGS) ../LZ/LZInWindow.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 + +StreamUtils.o: ../../Common/StreamUtils.cpp + $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp + +FileStreams.o: ../../Common/FileStreams.cpp + $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp + +Alloc.o: ../../../Common/Alloc.cpp + $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp + +C_FileIO.o: ../../../Common/C_FileIO.cpp + $(CXX) $(CFLAGS) ../../../Common/C_FileIO.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 + +String.o: ../../../Common/String.cpp + $(CXX) $(CFLAGS) ../../../Common/String.cpp + +StringConvert.o: ../../../Common/StringConvert.cpp + $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp + +StringToInt.o: ../../../Common/StringToInt.cpp + $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp + +Vector.o: ../../../Common/Vector.cpp + $(CXX) $(CFLAGS) ../../../Common/Vector.cpp + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h new file mode 100644 index 00000000..9828bc4b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h @@ -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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp new file mode 100644 index 00000000..8d273c8f --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp @@ -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; + } + */ +} + +}} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h new file mode 100644 index 00000000..64538e68 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h @@ -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 +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 +class CBitEncoder: public CBitModel +{ +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 +class CBitDecoder: public CBitModel +{ +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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h new file mode 100644 index 00000000..1fa023f3 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h @@ -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 +class CBitTreeEncoder +{ + CBitEncoder 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 +class CBitTreeDecoder +{ + CBitDecoder 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 +void ReverseBitTreeEncode(CBitEncoder *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 +UInt32 ReverseBitTreeGetPrice(CBitEncoder *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 +UInt32 ReverseBitTreeDecode(CBitDecoder *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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h new file mode 100644 index 00000000..829fc83d --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h @@ -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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/StdAfx.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/StdAfx.h new file mode 100644 index 00000000..21c2fd78 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/RangeCoder/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/ICoder.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/ICoder.h new file mode 100644 index 00000000..ce4594a0 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/ICoder.h @@ -0,0 +1,156 @@ +// ICoder.h + +#ifndef __ICODER_H +#define __ICODER_H + +#include "IStream.h" + +// "23170F69-40C1-278A-0000-000400xx0000" +#define CODER_INTERFACE(i, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \ +struct i: public IUnknown + +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, + kNumPasses = 0x460, + kAlgorithm = 0x470, + kMultiThread = 0x480, + 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(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(ICryptoProperties, 0x80) +{ + STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) 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 + }; +} + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/IStream.h b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/IStream.h new file mode 100644 index 00000000..d92b89aa --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/IStream.h @@ -0,0 +1,62 @@ +// IStream.h + +#ifndef __ISTREAM_H +#define __ISTREAM_H + +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + +// "23170F69-40C1-278A-0000-000300xx0000" + +#define STREAM_INTERFACE_SUB(i, b, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \ +struct i: public b + +#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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Alloc.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Alloc.cpp new file mode 100644 index 00000000..dcb331ee --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Alloc.cpp @@ -0,0 +1,118 @@ +// Common/Alloc.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "MyWindows.h" +#else +#include +#endif + +#include "Alloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef _SZ_ALLOC_DEBUG +#include +int g_allocCount = 0; +int g_allocCountMid = 0; +int g_allocCountBig = 0; +#endif + +void *MyAlloc(size_t size) throw() +{ + 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) throw() +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree; count = %10d", --g_allocCount); + #endif + + ::free(address); +} + +#ifdef _WIN32 + +void *MidAlloc(size_t size) throw() +{ + 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) throw() +{ + #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); +} + +static SIZE_T g_LargePageSize = + #ifdef _WIN64 + (1 << 21); + #else + (1 << 22); + #endif + +typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); + +bool SetLargePageSize() +{ + GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) + ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); + if (largePageMinimum == 0) + return false; + SIZE_T size = largePageMinimum(); + if (size == 0 || (size & (size - 1)) != 0) + return false; + g_LargePageSize = size; + return true; +} + + +void *BigAlloc(size_t size) throw() +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); + #endif + + if (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; + } + return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void BigFree(void *address) throw() +{ + #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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Alloc.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Alloc.h new file mode 100644 index 00000000..2ae3891d --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Alloc.h @@ -0,0 +1,29 @@ +// Common/Alloc.h + +#ifndef __COMMON_ALLOC_H +#define __COMMON_ALLOC_H + +#include + +void *MyAlloc(size_t size) throw(); +void MyFree(void *address) throw(); + +#ifdef _WIN32 + +bool SetLargePageSize(); + +void *MidAlloc(size_t size) throw(); +void MidFree(void *address) throw(); +void *BigAlloc(size_t size) throw(); +void BigFree(void *address) throw(); + +#else + +#define MidAlloc(size) MyAlloc(size) +#define MidFree(address) MyFree(address) +#define BigAlloc(size) MyAlloc(size) +#define BigFree(address) MyFree(address) + +#endif + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CRC.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CRC.cpp new file mode 100644 index 00000000..92bc009c --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CRC.cpp @@ -0,0 +1,61 @@ +// Common/CRC.cpp + +#include "StdAfx.h" + +#include "CRC.h" + +static const UInt32 kCRCPoly = 0xEDB88320; + +UInt32 CCRC::Table[256]; + +void CCRC::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = i; + for (int j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCRCPoly; + else + r >>= 1; + CCRC::Table[i] = r; + } +} + +class CCRCTableInit +{ +public: + CCRCTableInit() { CCRC::InitTable(); } +} g_CRCTableInit; + +void CCRC::UpdateByte(Byte b) +{ + _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8); +} + +void CCRC::UpdateUInt16(UInt16 v) +{ + UpdateByte(Byte(v)); + UpdateByte(Byte(v >> 8)); +} + +void CCRC::UpdateUInt32(UInt32 v) +{ + for (int i = 0; i < 4; i++) + UpdateByte((Byte)(v >> (8 * i))); +} + +void CCRC::UpdateUInt64(UInt64 v) +{ + for (int i = 0; i < 8; i++) + UpdateByte((Byte)(v >> (8 * i))); +} + +void CCRC::Update(const void *data, size_t size) +{ + UInt32 v = _value; + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = Table[((Byte)(v)) ^ *p] ^ (v >> 8); + _value = v; +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CRC.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CRC.h new file mode 100644 index 00000000..c9d43d00 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CRC.h @@ -0,0 +1,36 @@ +// Common/CRC.h + +#ifndef __COMMON_CRC_H +#define __COMMON_CRC_H + +#include +#include "Types.h" + +class CCRC +{ + UInt32 _value; +public: + static UInt32 Table[256]; + static void InitTable(); + + CCRC(): _value(0xFFFFFFFF){}; + void Init() { _value = 0xFFFFFFFF; } + void UpdateByte(Byte v); + void UpdateUInt16(UInt16 v); + void UpdateUInt32(UInt32 v); + void UpdateUInt64(UInt64 v); + void Update(const void *data, size_t size); + UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } + static UInt32 CalculateDigest(const void *data, size_t size) + { + CCRC crc; + crc.Update(data, size); + return crc.GetDigest(); + } + static bool VerifyDigest(UInt32 digest, const void *data, size_t size) + { + return (CalculateDigest(data, size) == digest); + } +}; + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/C_FileIO.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/C_FileIO.cpp new file mode 100644 index 00000000..48deb70a --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/C_FileIO.cpp @@ -0,0 +1,78 @@ +// Common/C_FileIO.h + +#include "C_FileIO.h" + +#include +#include + +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); +} + +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); +} + +ssize_t COutFile::Write(const void *data, size_t size) +{ + return write(_handle, data, size); +} + +}}} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/C_FileIO.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/C_FileIO.h new file mode 100644 index 00000000..48836a15 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/C_FileIO.h @@ -0,0 +1,45 @@ +// Common/C_FileIO.h + +#ifndef __COMMON_C_FILEIO_H +#define __COMMON_C_FILEIO_H + +#include +#include + +#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); + ssize_t Read(void *data, size_t size); +}; + +class COutFile: public CFileBase +{ +public: + bool Create(const char *name, bool createAlways); + ssize_t Write(const void *data, size_t size); +}; + +}}} + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/ComTry.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/ComTry.h new file mode 100644 index 00000000..98e59276 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/ComTry.h @@ -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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CommandLineParser.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CommandLineParser.cpp new file mode 100644 index 00000000..756e7166 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CommandLineParser.cpp @@ -0,0 +1,263 @@ +// 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(); + while (true) + { + UString s1, s2; + SplitCommandLine(sTemp, s1, s2); + // s1.Trim(); + // s2.Trim(); + if (!s1.IsEmpty()) + parts.Add(s1); + if (s2.IsEmpty()) + return; + 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; +} + +bool ParseSubCharsCommand(int numForms, const CCommandSubCharsSet *forms, + const UString &commandString, CIntVector &indices) +{ + indices.Clear(); + int numUsedChars = 0; + for(int i = 0; i < numForms; i++) + { + const CCommandSubCharsSet &set = forms[i]; + int currentIndex = -1; + int len = MyStringLen(set.Chars); + for(int j = 0; j < len; j++) + { + wchar_t c = set.Chars[j]; + int newIndex = commandString.Find(c); + if (newIndex >= 0) + { + if (currentIndex >= 0) + return false; + if (commandString.Find(c, newIndex + 1) >= 0) + return false; + currentIndex = j; + numUsedChars++; + } + } + if(currentIndex == -1 && !set.EmptyAllowed) + return false; + indices.Add(currentIndex); + } + return (numUsedChars == commandString.Length()); +} + +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CommandLineParser.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CommandLineParser.h new file mode 100644 index 00000000..75b3589c --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/CommandLineParser.h @@ -0,0 +1,82 @@ +// Common/CommandLineParser.h + +#ifndef __COMMON_COMMANDLINEPARSER_H +#define __COMMON_COMMANDLINEPARSER_H + +#include "Common/String.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); + +struct CCommandSubCharsSet +{ + wchar_t *Chars; + bool EmptyAllowed; +}; + +// Returns: indices of finded chars; -1 if there is no match +bool ParseSubCharsCommand(int numForms, const CCommandSubCharsSet *forms, + const UString &commandString, CIntVector &indices); + +} + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Defs.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Defs.h new file mode 100644 index 00000000..69b8ecea --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Defs.h @@ -0,0 +1,20 @@ +// Common/Defs.h + +#ifndef __COMMON_DEFS_H +#define __COMMON_DEFS_H + +template inline T MyMin(T a, T b) + { return a < b ? a : b; } +template inline T MyMax(T a, T b) + { return a > b ? a : b; } + +template 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyCom.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyCom.h new file mode 100644 index 00000000..8476b572 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyCom.h @@ -0,0 +1,203 @@ +// MyCom.h + +#ifndef __MYCOM_H +#define __MYCOM_H + +#include "MyWindows.h" + +#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; } + +template +class CMyComPtr +{ + T* _p; +public: + // typedef T _PtrClass; + CMyComPtr() { _p = NULL;} + CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); } + CMyComPtr(const CMyComPtr& 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& 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 + 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_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 STDMETHOD(QueryInterface)(REFGUID, void **) { \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE + +#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i) \ + ) + +#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + ) + +#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \ + 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(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(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + MY_QUERYINTERFACE_ENTRY(i5) \ + ) + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyGuidDef.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyGuidDef.h new file mode 100644 index 00000000..2cc8d199 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyGuidDef.h @@ -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 bool operator==(REFGUID g1, REFGUID g2) +{ + for (int i = 0; i < (int)sizeof(g1); i++) + if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i]) + return false; + return true; +} +inline bool 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyInitGuid.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyInitGuid.h new file mode 100644 index 00000000..53b0f034 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyInitGuid.h @@ -0,0 +1,13 @@ +// Common/MyInitGuid.h + +#ifndef __COMMON_MYINITGUID_H +#define __COMMON_MYINITGUID_H + +#ifdef _WIN32 +#include +#else +#define INITGUID +#include "MyGuidDef.h" +#endif + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyUnknown.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyUnknown.h new file mode 100644 index 00000000..6cd32cad --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyUnknown.h @@ -0,0 +1,24 @@ +// MyUnknown.h + +#ifndef __MYUNKNOWN_H +#define __MYUNKNOWN_H + +#ifdef _WIN32 + +#ifdef _WIN32_WCE +#if (_WIN32_WCE > 300) +#include +#else +#define MIDL_INTERFACE(x) struct +#endif +#else +#include +#endif + +#include + +#else +#include "MyWindows.h" +#endif + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyWindows.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyWindows.h new file mode 100644 index 00000000..65a4e9e7 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/MyWindows.h @@ -0,0 +1,183 @@ +// MyWindows.h + +#ifndef __MYWINDOWS_H +#define __MYWINDOWS_H + +#ifdef _WIN32 + +#include + +#else + +#include // for wchar_t +#include + +#include "MyGuidDef.h" + +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +typedef short SHORT; +typedef unsigned short USHORT; +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; +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_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 + +struct IUnknown +{ + STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE; + STDMETHOD_(ULONG, AddRef)() PURE; + STDMETHOD_(ULONG, Release)() PURE; +}; + +typedef IUnknown *LPUNKNOWN; + +#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; + +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 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 HRESULT VariantClear(VARIANTARG *prop); +MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src); +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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/NewHandler.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/NewHandler.cpp new file mode 100644 index 00000000..2f4e007b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/NewHandler.cpp @@ -0,0 +1,114 @@ +// NewHandler.cpp + +#include "StdAfx.h" + +#include + +#include "NewHandler.h" + +// #define DEBUG_MEMORY_LEAK + +#ifndef DEBUG_MEMORY_LEAK + +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); +} + +#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); +} +*/ diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/NewHandler.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/NewHandler.h new file mode 100644 index 00000000..b3a4f7e1 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/NewHandler.h @@ -0,0 +1,14 @@ +// Common/NewHandler.h + +#ifndef __COMMON_NEWHANDLER_H +#define __COMMON_NEWHANDLER_H + +class CNewException {}; + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw(); + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StdAfx.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StdAfx.h new file mode 100644 index 00000000..2547611b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +// #include "MyWindows.h" +#include "NewHandler.h" + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/String.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/String.cpp new file mode 100644 index 00000000..b6c12e99 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/String.cpp @@ -0,0 +1,198 @@ +// Common/String.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "StringConvert.h" +#else +#include +#endif + +#include "Common/String.h" + + +#ifdef _WIN32 + +#ifndef _UNICODE + +wchar_t MyCharUpper(wchar_t c) +{ + if (c == 0) + return 0; + wchar_t *res = CharUpperW((LPWSTR)(unsigned int)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned int)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)(unsigned int)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned int)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) +{ + while (true) + { + 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) +{ + while (true) + { + 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) +{ + while (true) + { + 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) +{ + while (true) + { + 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/String.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/String.h new file mode 100644 index 00000000..72a2c741 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/String.h @@ -0,0 +1,631 @@ +// Common/String.h + +#ifndef __COMMON_STRING_H +#define __COMMON_STRING_H + +#include +// #include + +#include "Vector.h" + +#ifdef _WIN32 +#include "MyWindows.h" +#endif + +static const char *kTrimDefaultCharSet = " \n\t"; + +template +inline int MyStringLen(const T *s) +{ + int i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +template +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)CharUpperA((LPSTR)(unsigned int)(unsigned char)c); } +#ifdef _UNICODE +inline wchar_t MyCharUpper(wchar_t c) + { return (wchar_t)CharUpperW((LPWSTR)c); } +#else +wchar_t MyCharUpper(wchar_t c); +#endif + +inline char MyCharLower(char c) + { return (char)(unsigned int)CharLowerA((LPSTR)(unsigned int)(unsigned char)c); } +#ifdef _UNICODE +inline wchar_t MyCharLower(wchar_t c) + { return (wchar_t)CharLowerW((LPWSTR)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 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 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 CompareNoCase(const CStringBase& s) const + { return MyStringCompareNoCase(_chars, s._chars); } + /* + 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; + while (true) + { + 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; + while (true) + { + 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 charSet; + for(int i = 0; i < (int)(sizeof(kTrimDefaultCharSet) / + sizeof(kTrimDefaultCharSet[0])); i++) + charSet += (T)kTrimDefaultCharSet[i]; + 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 +CStringBase operator+(const CStringBase& s1, const CStringBase& s2) +{ + CStringBase result(s1); + result += s2; + return result; +} + +template +CStringBase operator+(const CStringBase& s, T c) +{ + CStringBase result(s); + result += c; + return result; +} + +template +CStringBase operator+(T c, const CStringBase& s) +{ + CStringBase result(c); + result += s; + return result; +} + +template +CStringBase operator+(const CStringBase& s, const T * chars) +{ + CStringBase result(s); + result += chars; + return result; +} + +template +CStringBase operator+(const T * chars, const CStringBase& s) +{ + CStringBase result(chars); + result += s; + return result; +} + +template +bool operator==(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) == 0); } + +template +bool operator<(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) < 0); } + +template +bool operator==(const T *s1, const CStringBase& s2) + { return (s2.Compare(s1) == 0); } + +template +bool operator==(const CStringBase& s1, const T *s2) + { return (s1.Compare(s2) == 0); } + +template +bool operator!=(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) != 0); } + +template +bool operator!=(const T *s1, const CStringBase& s2) + { return (s2.Compare(s1) != 0); } + +template +bool operator!=(const CStringBase& s1, const T *s2) + { return (s1.Compare(s2) != 0); } + +typedef CStringBase AString; +typedef CStringBase UString; + +typedef CObjectVector AStringVector; +typedef CObjectVector UStringVector; + +#ifdef _UNICODE + typedef UString CSysString; +#else + typedef AString CSysString; +#endif + +typedef CObjectVector CSysStringVector; + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringConvert.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringConvert.cpp new file mode 100644 index 00000000..4b5913ad --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringConvert.cpp @@ -0,0 +1,93 @@ +// Common/StringConvert.cpp + +#include "StdAfx.h" + +#include "StringConvert.h" + +#ifndef _WIN32 +#include +#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; + int numChars = WideCharToMultiByte(codePage, 0, srcString, + srcString.Length(), resultString.GetBuffer(numRequiredBytes), + numRequiredBytes + 1, NULL, 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 + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringConvert.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringConvert.h new file mode 100644 index 00000000..921e33c7 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringConvert.h @@ -0,0 +1,71 @@ +// Common/StringConvert.h + +#ifndef __COMMON_STRINGCONVERT_H +#define __COMMON_STRINGCONVERT_H + +#include "MyWindows.h" +#include "Common/String.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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringToInt.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringToInt.cpp new file mode 100644 index 00000000..18ecad5a --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringToInt.cpp @@ -0,0 +1,68 @@ +// Common/StringToInt.cpp + +#include "StdAfx.h" + +#include "StringToInt.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + while(true) + { + 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; + while(true) + { + 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; + while(true) + { + 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); +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringToInt.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringToInt.h new file mode 100644 index 00000000..d5614ef5 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/StringToInt.h @@ -0,0 +1,17 @@ +// Common/StringToInt.h + +#ifndef __COMMON_STRINGTOINT_H +#define __COMMON_STRINGTOINT_H + +#include +#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 + + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Types.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Types.h new file mode 100644 index 00000000..52d07081 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Types.h @@ -0,0 +1,19 @@ +// Common/Types.h + +#ifndef __COMMON_TYPES_H +#define __COMMON_TYPES_H + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; +typedef int Int32; +typedef unsigned int UInt32; +#ifdef _MSC_VER +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +#endif + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Vector.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Vector.cpp new file mode 100644 index 00000000..f74d4c6c --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Vector.cpp @@ -0,0 +1,74 @@ +// Common/Vector.cpp + +#include "StdAfx.h" + +#include + +#include "Vector.h" + +CBaseRecordVector::~CBaseRecordVector() + { delete []((unsigned char *)_items); } +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; + /* + #ifndef _DEBUG + static const unsigned int kMaxVectorSize = 0xF0000000; + if(newCapacity < _size || + ((unsigned int )newCapacity * (unsigned int )_itemSize) > kMaxVectorSize) + throw 1052354; + #endif + */ + unsigned char *p = new unsigned char[newCapacity * _itemSize]; + 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; + } +} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Vector.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Vector.h new file mode 100644 index 00000000..0c7292a1 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Common/Vector.h @@ -0,0 +1,211 @@ +// 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(); + 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 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; + } + + void Sort(int left, int right) + { + if (right - left < 2) + return; + Swap(left, (left + right) / 2); + int last = left; + for (int i = left; i < right; i++) + if (operator[](i) < operator[](left)) + Swap(++last, i); + Swap(left, last); + Sort(left, last); + Sort(last + 1, right); + } + void Sort() { Sort(0, Size()); } + void Sort(int left, int right, int (*compare)(const T*, const T*, void *), void *param) + { + if (right - left < 2) + return; + Swap(left, (left + right) / 2); + int last = left; + for (int i = left; i < right; i++) + if (compare(&operator[](i), &operator[](left), param) < 0) + Swap(++last, i); + Swap(left, last); + Sort(left, last, compare, param); + Sort(last + 1, right, compare, param); + } + + void Sort(int (*compare)(const T*, const T*, void *), void *param) + { + Sort(0, Size(), compare, param); + } +}; + +typedef CRecordVector CIntVector; +typedef CRecordVector CUIntVector; +typedef CRecordVector CBoolVector; +typedef CRecordVector CByteVector; +typedef CRecordVector CPointerVector; + +template +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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/Defs.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/Defs.h new file mode 100644 index 00000000..1b0c97a5 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/Defs.h @@ -0,0 +1,18 @@ +// Windows/Defs.h + +#ifndef __WINDOWS_DEFS_H +#define __WINDOWS_DEFS_H + +inline bool BOOLToBool(BOOL value) + { return (value != FALSE); } + +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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/FileIO.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/FileIO.cpp new file mode 100644 index 00000000..20b5fc15 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/FileIO.cpp @@ -0,0 +1,245 @@ +// Windows/FileIO.cpp + +#include "StdAfx.h" + +#include "FileIO.h" +#include "Defs.h" +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { +namespace NIO { + +CFileBase::~CFileBase() { Close(); } + +bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + Close(); + _handle = ::CreateFile(fileName, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE) NULL); + return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE)); +} + +#ifndef _UNICODE +bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + if (g_IsNT) + { + Close(); + _handle = ::CreateFileW(fileName, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE) NULL); + return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE)); + } + return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP), + desiredAccess, shareMode, creationDisposition, flagsAndAttributes); +} +#endif + +bool CFileBase::Close() +{ + if(!_fileIsOpen) + return true; + bool result = BOOLToBool(::CloseHandle(_handle)); + _fileIsOpen = !result; + return result; +} + +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::Open(LPCTSTR fileName) + { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } + +#ifndef _UNICODE +bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); } + +bool CInFile::Open(LPCWSTR fileName) + { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } +#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). + +static UInt32 kChunkSizeMax = (1 << 24); + +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(); +} + +}}} diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/FileIO.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/FileIO.h new file mode 100644 index 00000000..de66d7f3 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/FileIO.h @@ -0,0 +1,98 @@ +// 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: + bool _fileIsOpen; + 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(): _fileIsOpen(false){}; + virtual ~CFileBase(); + + virtual 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 Open(LPCTSTR fileName); + #ifndef _UNICODE + bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + 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 diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/StdAfx.h b/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/StdAfx.h new file mode 100644 index 00000000..e0f76050 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/Windows/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../Common/MyWindows.h" +#include "../Common/NewHandler.h" + +#endif diff --git a/release/src/linux/linux/scripts/squashfs/lzma/CPL.html b/release/src/linux/linux/scripts/squashfs/lzma/CPL.html new file mode 100644 index 00000000..f1d3be11 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/CPL.html @@ -0,0 +1,224 @@ + +Common Public License - v 1.0 + + +

Common Public License - v 1.0 +

+

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER +THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR +DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS +AGREEMENT. +

+

1. DEFINITIONS +

"Contribution" means: +

    a) in the case of the initial Contributor, the initial code + and documentation distributed under this Agreement, and
    b) in + the case of each subsequent Contributor:
+
    i) changes to the Program, and
+
    ii) additions to the Program;
+
    where such changes and/or additions to the Program originate + from and are distributed by that particular Contributor. A + Contribution 'originates' from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include additions to the Program + which: (i) are separate modules of software distributed in conjunction with + the Program under their own license agreement, and (ii) are not derivative + works of the Program.
+

+

"Contributor" means any person or entity that distributes the +Program. +

+

"Licensed Patents " mean patent claims licensable by a +Contributor which are necessarily infringed by the use or sale of its +Contribution alone or when combined with the Program. +

+

"Program" means the Contributions +distributed in accordance with this Agreement. +

+

"Recipient" means anyone who receives the Program under this +Agreement, including all Contributors. +

+

2. GRANT OF RIGHTS +

    a) Subject to the + terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free copyright license + to reproduce, prepare + derivative works of, publicly display, publicly perform, distribute and + sublicense the Contribution of such Contributor, if any, and such derivative + works, in source code and object code form.
+
+
    b) Subject to the terms of this + Agreement, each Contributor hereby grants Recipient a + non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, + offer to sell, import and otherwise transfer the Contribution of such + Contributor, if any, in source code and object code form. This patent license + shall apply to the combination of the Contribution and the Program if, at the + time the Contribution is added by the Contributor, such addition of the + Contribution causes such combination to be covered by the Licensed Patents. + The patent license shall not apply to any other combinations which include the + Contribution. No hardware per se is licensed hereunder.
+
+
    c) Recipient understands that although each Contributor + grants the licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the patent or + other intellectual property rights of any other entity. Each Contributor + disclaims any liability to Recipient for claims brought by any other entity + based on infringement of intellectual property rights or otherwise. As a + condition to exercising the rights and licenses granted hereunder, each + Recipient hereby assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party patent license + is required to allow Recipient to distribute the Program, it is Recipient's + responsibility to acquire that license before distributing the +Program.
+
+
    d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant the + copyright license set forth in this Agreement.
+
+

3. REQUIREMENTS +

A Contributor may choose to distribute the Program in +object code form under its own license agreement, provided that: +

    a) it complies with the terms and conditions of this + Agreement; and
+
    b) its license agreement:
+
    i) effectively disclaims on behalf of all + Contributors all warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and implied warranties + or conditions of merchantability and fitness for a particular purpose; +
+
    ii) effectively excludes on behalf of all Contributors all + liability for damages, including direct, indirect, special, incidental and + consequential damages, such as lost profits;
+
    iii) states that any provisions which + differ from this Agreement are offered by that Contributor alone and not by + any other party; and
+
    iv) states that source code for the Program is available from + such Contributor, and informs licensees how to obtain it in a reasonable + manner on or through a medium customarily used for software + exchange.
+
+

When the Program is made available in source code form: +

    a) it must be made available under this Agreement; and +
+
    b) a copy of this Agreement must be included with each copy + of the Program.
+

+

Contributors +may not remove or alter any copyright notices contained within the Program. + +

+

Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent Recipients +to identify the originator of the Contribution. +

+

4. COMMERCIAL DISTRIBUTION +

Commercial distributors of software may accept certain +responsibilities with respect to end users, business partners and the like. +While this license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product offering should +do so in a manner which does not create potential liability for other +Contributors. Therefore, if a Contributor includes the Program in a commercial +product offering, such Contributor ("Commercial Contributor") hereby agrees to +defend and indemnify every other Contributor ("Indemnified Contributor") against +any losses, damages and costs (collectively "Losses") arising from claims, +lawsuits and other legal actions brought by a third party against the +Indemnified Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program in a +commercial product offering. The obligations in this section do not apply to any +claims or Losses relating to any actual or alleged intellectual property +infringement. In order to qualify, an Indemnified Contributor must: a) promptly +notify the Commercial Contributor in writing of such claim, and b) allow the +Commercial Contributor to control, and cooperate with the Commercial Contributor +in, the defense and any related settlement negotiations. The Indemnified +Contributor may participate in any such claim at its own expense. +

+

For example, a Contributor might include the Program in a +commercial product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance claims, or +offers warranties related to Product X, those performance claims and warranties +are such Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. +

+

5. NO WARRANTY +

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS +PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR +CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A +PARTICULAR PURPOSE. Each Recipient is solely responsible for +determining the appropriateness of using and distributing the Program and assumes all risks associated with its +exercise of rights under this Agreement, including but not +limited to the risks and costs of program errors, compliance with applicable +laws, damage to or loss of data, programs or equipment, and +unavailability or interruption of operations. +

+

6. DISCLAIMER OF LIABILITY +

EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +

+

7. GENERAL +

If any provision of this Agreement is +invalid or unenforceable under applicable law, it shall not affect the validity +or enforceability of the remainder of the terms of this Agreement, and without +further action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. +

+

If Recipient institutes patent litigation against a Contributor +with respect to a patent applicable to software (including a cross-claim or +counterclaim in a lawsuit), then any patent licenses granted by that Contributor +to such Recipient under this Agreement shall terminate as of the date such +litigation is filed. In addition, if Recipient institutes patent litigation +against any entity (including a cross-claim or counterclaim in a lawsuit) +alleging that the Program itself (excluding combinations of the Program with +other software or hardware) infringes such Recipient's patent(s), then such +Recipient's rights granted under Section 2(b) shall terminate as of the date +such litigation is filed. +

+

All Recipient's rights under this Agreement shall terminate if +it fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of time after +becoming aware of such noncompliance. If all Recipient's rights under this +Agreement terminate, Recipient agrees to cease use and distribution of the +Program as soon as reasonably practicable. However, Recipient's obligations +under this Agreement and any licenses granted by Recipient relating to the +Program shall continue and survive. +

+

Everyone is permitted to copy and distribute +copies of this Agreement, but in order to avoid inconsistency the Agreement is +copyrighted and may only be modified in the following manner. The Agreement +Steward reserves the right to publish new versions +(including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +IBM is the initial Agreement Steward. IBM may assign the responsibility to serve +as the Agreement Steward to a suitable separate entity. Each +new version of the Agreement will be given a distinguishing version number. The +Program (including Contributions) may always be distributed subject to the +version of the Agreement under which it was received. In addition, after a new +version of the Agreement is published, Contributor may elect to distribute the +Program (including its Contributions) under the new version. +Except as expressly stated in Sections 2(a) and 2(b) above, +Recipient receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by +implication, estoppel or otherwise. All +rights in the Program not expressly granted under this Agreement are +reserved. +

+

This Agreement is governed by the laws of the State of New York +and the intellectual property laws of the United States of America. No party to +this Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial in +any resulting litigation. +

+

diff --git a/release/src/linux/linux/scripts/squashfs/lzma/LGPL.txt b/release/src/linux/linux/scripts/squashfs/lzma/LGPL.txt new file mode 100644 index 00000000..f3926a61 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/LGPL.txt @@ -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. + + + Copyright (C) + + 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/release/src/linux/linux/scripts/squashfs/lzma/Methods.txt b/release/src/linux/linux/scripts/squashfs/lzma/Methods.txt new file mode 100644 index 00000000..5d1661e4 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/Methods.txt @@ -0,0 +1,114 @@ +Compression method IDs (4.27) +----------------------------- + +Each compression method in 7z has unique binary value (ID). +The length of ID in bytes is arbitrary but it can not exceed 15 bytes. + +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 + +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 + + +06 - Crypto + 00 - + 01 - AES + 0x - AES-128 + 4x - AES-192 + 8x - AES-256 + + x0 - ECB + x1 - CBC + x2 - CFB + x3 - OFB + + 07 - Reserved + 0F - Reserved + + F0 - Misc Ciphers (Real Ciphers without hashing algo) + + F1 - Misc Ciphers (Combine) + 01 - Zip + 01 - Main Zip crypto algo + 03 - RAR + 02 - + 03 - Rar29 AES-128 + (modified SHA-1) + 07 - 7z + 01 - AES-256 + SHA-256 + +07 - Hash (subject to change) + 00 - + 01 - CRC + 02 - SHA-1 + 03 - SHA-256 + 04 - SHA-384 + 05 - SHA-512 + + F0 - Misc Hash + + F1 - Misc + 03 - RAR + 03 - Rar29 Password Hashing (modified SHA1) + 07 - 7z + 01 - SHA-256 Password Hashing + + + + +--- +End of document diff --git a/release/src/linux/linux/scripts/squashfs/lzma/history.txt b/release/src/linux/linux/scripts/squashfs/lzma/history.txt new file mode 100644 index 00000000..167fdf1e --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/history.txt @@ -0,0 +1,147 @@ +HISTORY of the LZMA SDK +----------------------- + + Version 4.32 2005-12-09 + -------------------------------------- + - Java version of LZMA SDK was included + + + Version 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 + + + Version 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 + + + Version 4.27 2005-08-07 + -------------------------------------- + - Bug in LzmaDecodeSize.c was fixed: + if _LZMA_IN_CB and _LZMA_OUT_READ were defined, + decompressing worked incorrectly. + + + Version 4.26 2005-08-05 + -------------------------------------- + - Fixes in 7z_C code and LzmaTest.c: + previous versions could work incorrectly, + if malloc(0) returns 0 + + + Version 4.23 2005-06-29 + -------------------------------------- + - Small fixes in C++ code + + + Version 4.22 2005-06-10 + -------------------------------------- + - Small fixes + + + Version 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 + + + Version 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 + + + Version 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 + + + Version 4.06 2004-09-05 + -------------------------------------- + - Bug in v4.05 was fixed: + LZMA-Encoder didn't release output stream in some cases. + + + Version 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 + + + Version 4.04 2004-07-28 + -------------------------------------- + - More compatibility with some C++ compilers + + + Version 4.03 2004-06-18 + -------------------------------------- + - "Benchmark" command was added. It measures compressing + and decompressing speed and shows rating values. + Also it checks hardware errors. + + + Version 4.02 2004-06-10 + -------------------------------------- + - C++ LZMA Encoder/Decoder code now is more portable + and it can be compiled by GCC on Linux. + + + Version 4.01 2004-02-15 + -------------------------------------- + - Some detection of data corruption was enabled. + LzmaDecode.c / RangeDecoderReadByte + ..... + { + rd->ExtraBytes = 1; + return 0xFF; + } + + + Version 4.00 2004-02-13 + -------------------------------------- + - Original version of LZMA SDK + + + +HISTORY of the LZMA +------------------- + 2001-2004: Improvements to LZMA compressing/decompressing code, + keeping compatibility with original LZMA format + 1996-2001: Development of LZMA compression format + + Some milestones: + + 2001-08-30: LZMA compression was added to 7-Zip + 1999-01-02: First version of 7-Zip was released + + +End of document diff --git a/release/src/linux/linux/scripts/squashfs/lzma/lzma.txt b/release/src/linux/linux/scripts/squashfs/lzma/lzma.txt new file mode 100644 index 00000000..8b5825fb --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/lzma.txt @@ -0,0 +1,637 @@ +LZMA SDK 4.32 +------------- + +LZMA SDK 4.32 Copyright (C) 1999-2005 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 examples (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 / 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 / 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 + BinTree - Binary Tree Match Finder for LZ algorithm + HashChain - Hash Chain Match Finder for LZ algorithm + Patricia - Patricia Match Finder for LZ algorithm + RangeCoder - Range Coder (special code of compression/decompression) + LZMA - LZMA compression/decompression on C++ + LZMA_Alone - file->file LZMA compression/decompression + LZMA_C - 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 + 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 + +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_C +7-Zip doesn't use that ANSI-C LZMA code and that code was developed +specially for this SDK. And files from LZMA_C 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 Decompression features +--------------------------- + - Variable dictionary size (up to 256 MB) + - Estimated compressing speed: about 500 KB/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 inputFile outputFile [...] + + 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 XP 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. + + + + + -a{N}: set compression mode 0 = fast, 1 = normal, 2 = max + default: 2 (max) + + d{N}: Sets Dictionary size - [0, 28], default: 23 (8MB) + The maximum value for dictionary size is 256 MB = 2^28 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. + Compression ratio for all bt* and pat* almost the same. + Algorithms from hc* group doesn't provide good compression + ratio, but they often works pretty fast in combination with + fast mode (-a0). Methods from bt* group require less memory + than methods from pat* group. Usually bt4 works faster than + any pat*, but for some types of files pat* can work faster. + + Memory requirements depend from dictionary size + (parameter "d" in table below). + + MF_ID Memory Description + + bt2 d*9.5 + 1MB Binary Tree with 2 bytes hashing. + bt3 d*9.5 + 65MB Binary Tree with 2-3(full) bytes hashing. + bt4 d*9.5 + 6MB Binary Tree with 2-3-4 bytes hashing. + bt4b d*9.5 + 34MB Binary Tree with 2-3-4(big) bytes hashing. + pat2r d*26 + 1MB Patricia Tree with 2-bits nodes, removing. + pat2 d*38 + 1MB Patricia Tree with 2-bits nodes. + pat2h d*38 + 77MB Patricia Tree with 2-bits nodes, 2-3 bytes hashing. + pat3h d*62 + 85MB Patricia Tree with 3-bits nodes, 2-3 bytes hashing. + pat4h d*110 +101MB Patricia Tree with 4-bits nodes, 2-3 bytes hashing. + hc3 d*5.5 + 1MB Hash Chain with 2-3 bytes hashing. + hc4 d*5.5 + 6MB Hash Chain with 2-3-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 diff --git a/release/src/linux/linux/scripts/squashfs/mksquashfs.c b/release/src/linux/linux/scripts/squashfs/mksquashfs.c index fbe25e6d..e773f53c 100644 --- a/release/src/linux/linux/scripts/squashfs/mksquashfs.c +++ b/release/src/linux/linux/scripts/squashfs/mksquashfs.c @@ -1,7 +1,8 @@ /* * Create a squashfs filesystem. This is a highly compressed read only filesystem. * - * Copyright (c) 2002, 2003, 2004 Phillip Lougher + * Copyright (c) 2002, 2003, 2004, 2005, 2006 + * Phillip Lougher * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,7 +21,9 @@ * mksquashfs.c */ +#define FALSE 0 #define TRUE 1 + #include #include #include @@ -33,44 +36,70 @@ #include #include #include -#include #include #include #include #include -#include "mksquashfs.h" +#ifndef linux +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#else +#include +#endif + #include +#include "mksquashfs.h" +#include "global.h" +#include "sort.h" #ifdef SQUASHFS_TRACE -#define TRACE(s, args...) printf("mksquashfs: "s, ## args) +#define TRACE(s, args...) do { \ + printf("mksquashfs: "s, ## args); \ + } while(0) #else #define TRACE(s, args...) #endif -#define INFO(s, args...) do { if(!silent) printf("mksquashfs: "s, ## args); } while(0) -#define ERROR(s, args...) do { fprintf(stderr, s, ## args); } while(0) -#define EXIT_MKSQUASHFS() do { if(restore)\ - restorefs();\ - exit(1); } while(0) -#define BAD_ERROR(s, args...) do {\ +#define INFO(s, args...) do {\ + if(!silent)\ + printf("mksquashfs: "s, ## args);\ + } while(0) +#define ERROR(s, args...) do {\ + fprintf(stderr, s, ## args);\ + } while(0) +#define EXIT_MKSQUASHFS() do {\ + if(restore)\ + restorefs();\ + if(delete && destination_file && !block_device)\ + unlink(destination_file);\ + exit(1);\ + } while(0) +#define BAD_ERROR(s, args...) do {\ fprintf(stderr, "FATAL ERROR:" s, ##args);\ EXIT_MKSQUASHFS();\ - } while(0) - -int duplicate_checking = 1, noF = 0, no_fragments = 0, always_use_fragments = 0; -int total_compressed = 0, total_uncompressed = 0; + } while(0) +int delete = FALSE; +long long total_compressed = 0, total_uncompressed = 0; int fd; +/* filesystem flags for building */ +int duplicate_checking = 1, noF = 0, no_fragments = 0, always_use_fragments = 0; +int noI = 0, noD = 0, check_data = 0; +int swap, silent = TRUE; +long long global_uid = -1, global_gid = -1; + /* superblock attributes */ -int noI = 0, noD = 0, check_data = 0, block_size = SQUASHFS_FILE_SIZE, block_log; +int block_size = SQUASHFS_FILE_SIZE, block_log; unsigned short uid_count = 0, guid_count = 0; squashfs_uid uids[SQUASHFS_UIDS], guids[SQUASHFS_GUIDS]; int block_offset; +int file_count = 0, sym_count = 0, dev_count = 0, dir_count = 0, fifo_count = 0, sock_count = 0; /* write position within data section */ -unsigned int bytes = 0, total_bytes = 0; +long long bytes = 0, total_bytes = 0; /* in memory directory table - possibly compressed */ char *directory_table = NULL; @@ -88,22 +117,38 @@ unsigned int inode_bytes = 0, inode_size = 0, total_inode_bytes = 0; char *data_cache = NULL; unsigned int cache_bytes = 0, cache_size = 0, inode_count = 0; -/* in memory directory header */ +/* in memory directory data */ +#define I_COUNT_SIZE 128 +#define DIR_ENTRIES 32 +#define INODE_HASH_SIZE 65536 +#define INODE_HASH_MASK (INODE_HASH_SIZE - 1) +#define INODE_HASH(dev, ino) (ino & INODE_HASH_MASK) + +struct cached_dir_index { + squashfs_dir_index index; + char *name; +}; + struct directory { unsigned int start_block; unsigned int size; unsigned char *buff; unsigned char *p; unsigned int entry_count; - squashfs_dir_header *entry_count_p; + unsigned char *entry_count_p; + unsigned int i_count; + unsigned int i_size; + struct cached_dir_index *index; + unsigned char *index_count_p; + unsigned int inode_number; }; +struct inode_info *inode_info[INODE_HASH_SIZE]; + +/* hash tables used to do fast duplicate searches in duplicate check */ struct file_info *dupl[65536], *frag_dups[65536]; int dup_files = 0; -int swap, silent = TRUE; -int file_count = 0, sym_count = 0, dev_count = 0, dir_count = 0, fifo_count = 0, sock_count = 0; - /* list of exclude dirs/files */ struct exclude_info { dev_t st_dev; @@ -117,18 +162,22 @@ int excluded(char *filename, struct stat *buf); /* fragment block data structures */ int fragments = 0; -static char *fragment_data; -static int fragment_size = 0; +char fragment_data[SQUASHFS_FILE_SIZE]; +int fragment_size = 0; struct fragment { unsigned int index; int offset; int size; }; - - #define FRAG_SIZE 32768 squashfs_fragment_entry *fragment_table = NULL; + +/* current inode number for directories and non directories */ +unsigned int dir_inode_no = 1; +unsigned int inode_no = 0; +unsigned int root_inode_number = 0; + /* list of source dirs/files */ int source = 0; char **source_path; @@ -139,13 +188,15 @@ struct old_root_entry_info { char name[SQUASHFS_NAME_LEN + 1]; squashfs_inode inode; int type; + int inode_number; }; +struct old_root_entry_info *old_root_entry; /* in memory file info */ struct file_info { - unsigned int bytes; + long long bytes; unsigned short checksum; - unsigned int start; + long long start; unsigned int *block_list; struct file_info *next; struct fragment *fragment; @@ -158,46 +209,51 @@ int interrupted = 0; /* restore orignal filesystem state if appending to existing filesystem is cancelled */ jmp_buf env; char *sdata_cache, *sdirectory_data_cache; -unsigned int sbytes, sinode_bytes, scache_bytes, sdirectory_bytes, + +long long sbytes, stotal_bytes; + +unsigned int sinode_bytes, scache_bytes, sdirectory_bytes, sdirectory_cache_bytes, suid_count, sguid_count, - stotal_bytes, stotal_inode_bytes, stotal_directory_bytes, + stotal_inode_bytes, stotal_directory_bytes, sinode_count, sfile_count, ssym_count, sdev_count, - sdir_count, sdup_files; + sdir_count, sfifo_count, ssock_count, sdup_files; int sfragments; int restore = 0; -/*flag whether destination file is a block device */ +/* flag whether destination file is a block device */ int block_device = 0; /* flag indicating whether files are sorted using sort list(s) */ int sorted = 0; -long long global_uid = -1, global_gid = -1; +/* save destination file name for deleting on error */ +char *destination_file = NULL; /* structure to used to pass in a pointer or an integer * to duplicate buffer read helper functions. */ struct duplicate_buffer_handle { - unsigned char *ptr; - unsigned int start; + char *ptr; + long long start; }; -struct old_root_entry_info *old_root_entry; -void add_old_root_entry(char *name, squashfs_inode inode, int type); +void add_old_root_entry(char *name, squashfs_inode inode, int inode_number, int type); extern int read_super(int fd, squashfs_super_block *sBlk, int *be, char *source); -extern int read_filesystem(char *root_name, int fd, squashfs_super_block *sBlk, char **inode_table, int *inode_bytes, - char **data_cache, int *cache_bytes, int *cache_size, char **directory_table, int *directory_bytes, - char **directory_data_cache, int *directory_cache_bytes, int *directory_cache_size, - int *file_count, int *sym_count, int *dev_count, int *dir_count, int *fifo_count, int *sock_count, - squashfs_uid *uids, unsigned short *uid_count, squashfs_uid *guids, unsigned short *guid_count, - unsigned int *uncompressed_file, unsigned int *uncompressed_inode, unsigned int *uncompressed_directory, - void (push_directory_entry)(char *, squashfs_inode, int), squashfs_fragment_entry **fragment_table); -squashfs_inode get_sorted_inode(struct stat *buf); +extern long long read_filesystem(char *root_name, int fd, squashfs_super_block *sBlk, char **cinode_table, + char **data_cache, char **cdirectory_table, char **directory_data_cache, + unsigned int *last_directory_block, unsigned int *inode_dir_offset, unsigned int *inode_dir_file_size, + unsigned int *root_inode_size, unsigned int *inode_dir_start_block, int *file_count, int *sym_count, + int *dev_count, int *dir_count, int *fifo_count, int *sock_count, squashfs_uid *uids, + unsigned short *uid_count, squashfs_uid *guids, unsigned short *guid_count, + long long *uncompressed_file, unsigned int *uncompressed_inode, unsigned int *uncompressed_directory, + unsigned int *inode_dir_inode_number, unsigned int *inode_dir_parent_inode, + void (push_directory_entry)(char *, squashfs_inode, int, int), + squashfs_fragment_entry **fragment_table); +int get_sorted_inode(squashfs_inode *inode, struct stat *buf); int read_sort_file(char *filename, int source, char *source_path[]); -void sort_files_and_write(int source, char *source_path[]); -struct file_info *duplicate(unsigned char *(get_next_file_block)(struct duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle *file_start, int bytes, unsigned int **block_list, int *start, int blocks, struct fragment **fragment, char *frag_data, int frag_bytes); - -#define FALSE 0 +void sort_files_and_write(struct dir_info *dir); +struct file_info *duplicate(char *(get_next_file_block)(struct duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle *file_start, long long bytes, unsigned int **block_list, long long *start, int blocks, struct fragment **fragment, char *frag_data, int frag_bytes); +struct dir_info *dir_scan1(char *, int (_readdir)(char *, char *, struct dir_info *)); #define MKINODE(A) ((squashfs_inode)(((squashfs_inode) inode_bytes << 16) + (((char *)A) - data_cache))) @@ -220,6 +276,8 @@ void restorefs() sym_count = ssym_count; dev_count = sdev_count; dir_count = sdir_count; + fifo_count = sfifo_count; + sock_count = ssock_count; dup_files = sdup_files; fragments = sfragments; fragment_size = 0; @@ -239,12 +297,18 @@ void sighandler() } +void sighandler2() +{ + EXIT_MKSQUASHFS(); +} + + unsigned int mangle(char *d, char *s, int size, int block_size, int uncompressed, int data_block) { unsigned long c_byte = block_size << 1; unsigned int res; - if(!uncompressed && (res = compress2(d, &c_byte, s, size, 9)) != Z_OK) { + if(!uncompressed && (res = compress2((unsigned char *) d, &c_byte, (unsigned char *) s, size, 9)) != Z_OK) { if(res == Z_MEM_ERROR) BAD_ERROR("zlib::compress failed, not enough memory\n"); else if(res == Z_BUF_ERROR) @@ -281,7 +345,7 @@ squashfs_base_inode_header *get_inode(int req_size) SQUASHFS_METADATA_SIZE, SQUASHFS_METADATA_SIZE, noI, 0); TRACE("Inode block @ %x, size %d\n", inode_bytes, c_byte); if(!swap) - memcpy((void *) (inode_table + inode_bytes), (void *) &c_byte, sizeof(unsigned short)); + memcpy(inode_table + inode_bytes, &c_byte, sizeof(unsigned short)); else SQUASHFS_SWAP_SHORTS((&c_byte), (inode_table + inode_bytes), 1); if(check_data) @@ -311,7 +375,7 @@ failed: } -void read_bytes(int fd, unsigned int byte, int bytes, char *buff) +void read_bytes(int fd, long long byte, int bytes, char *buff) { off_t off = byte; @@ -327,13 +391,10 @@ void read_bytes(int fd, unsigned int byte, int bytes, char *buff) } -void write_bytes(int fd, unsigned int byte, int bytes, char *buff) +void write_bytes(int fd, long long byte, int bytes, char *buff) { off_t off = byte; - if(off + bytes > ((long long)1<<32) - 1 ) - BAD_ERROR("Filesystem greater than maximum size 2^32 - 1\n"); - if(lseek(fd, off, SEEK_SET) == -1) { perror("Lseek on destination failed"); EXIT_MKSQUASHFS(); @@ -346,12 +407,12 @@ void write_bytes(int fd, unsigned int byte, int bytes, char *buff) } -unsigned int write_inodes() +long long write_inodes() { unsigned short c_byte; int avail_bytes; char *datap = data_cache; - unsigned int start_bytes = bytes; + long long start_bytes = bytes; while(cache_bytes) { if(inode_size - inode_bytes < ((SQUASHFS_METADATA_SIZE << 1) + 2)) { @@ -364,7 +425,7 @@ unsigned int write_inodes() c_byte = mangle(inode_table + inode_bytes + block_offset, datap, avail_bytes, SQUASHFS_METADATA_SIZE, noI, 0); TRACE("Inode block @ %x, size %d\n", inode_bytes, c_byte); if(!swap) - memcpy((void *) (inode_table + inode_bytes), (void *) &c_byte, sizeof(unsigned short)); + memcpy(inode_table + inode_bytes, &c_byte, sizeof(unsigned short)); else SQUASHFS_SWAP_SHORTS((&c_byte), (inode_table + inode_bytes), 1); if(check_data) @@ -382,12 +443,12 @@ unsigned int write_inodes() } -unsigned int write_directories() +long long write_directories() { unsigned short c_byte; int avail_bytes; char *directoryp = directory_data_cache; - unsigned int start_bytes = bytes; + long long start_bytes = bytes; while(directory_cache_bytes) { if(directory_size - directory_bytes < ((SQUASHFS_METADATA_SIZE << 1) + 2)) { @@ -401,7 +462,7 @@ unsigned int write_directories() c_byte = mangle(directory_table + directory_bytes + block_offset, directoryp, avail_bytes, SQUASHFS_METADATA_SIZE, noI, 0); TRACE("Directory block @ %x, size %d\n", directory_bytes, c_byte); if(!swap) - memcpy((void *) (directory_table + directory_bytes), (void *) &c_byte, sizeof(unsigned short)); + memcpy(directory_table + directory_bytes, &c_byte, sizeof(unsigned short)); else SQUASHFS_SWAP_SHORTS((&c_byte), (directory_table + directory_bytes), 1); if(check_data) @@ -455,81 +516,132 @@ unsigned int get_guid(squashfs_uid uid, squashfs_uid guid) } -squashfs_inode create_inode(char *filename, int type, int byte_size, -squashfs_block start_block, unsigned int offset, unsigned int *block_list, struct fragment *fragment) +int create_inode(squashfs_inode *i_no, struct dir_ent *dir_ent, int type, long long byte_size, long long start_block, unsigned int offset, unsigned int *block_list, struct fragment *fragment, struct directory *dir_in) { - squashfs_inode i_no; - struct stat buf; + struct stat *buf = &dir_ent->inode->buf; squashfs_inode_header inode_header; squashfs_base_inode_header *inode, *base = &inode_header.base; + char *filename = dir_ent->pathname; + int nlink = dir_ent->inode->nlink; + int inode_number = (type == SQUASHFS_LDIR_TYPE || type == SQUASHFS_DIR_TYPE) ? dir_ent->inode->inode_number : dir_ent->inode->inode_number + dir_inode_no; - if(filename[0] == '\0') { - /* dummy top level directory, if multiple sources specified on command line */ - buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO; - buf.st_uid = getuid(); - buf.st_gid = getgid(); - buf.st_mtime = time(NULL); - } else if(lstat(filename, &buf) == -1) { - char buffer[8192]; - sprintf(buffer, "Cannot stat dir/file %s, ignoring", filename); - perror(buffer); - return SQUASHFS_INVALID; - } - - base->mode = SQUASHFS_MODE(buf.st_mode); - base->uid = get_uid((squashfs_uid) global_uid == -1 ? buf.st_uid : global_uid); + base->mode = SQUASHFS_MODE(buf->st_mode); + base->uid = get_uid((squashfs_uid) global_uid == -1 ? buf->st_uid : global_uid); base->inode_type = type; - base->guid = get_guid((squashfs_uid) global_uid == -1 ? buf.st_uid : global_uid, (squashfs_uid) global_gid == -1 ? buf.st_gid : global_gid); + base->guid = get_guid((squashfs_uid) global_uid == -1 ? buf->st_uid : global_uid, (squashfs_uid) global_gid == -1 ? buf->st_gid : global_gid); + base->mtime = buf->st_mtime; + base->inode_number = inode_number; if(type == SQUASHFS_FILE_TYPE) { int i; squashfs_reg_inode_header *reg = &inode_header.reg, *inodep; inode = get_inode(sizeof(*reg) + offset * sizeof(unsigned int)); - inodep = (squashfs_reg_inode_header *) inode ; - reg->mtime = buf.st_mtime; + inodep = (squashfs_reg_inode_header *) inode; reg->file_size = byte_size; reg->start_block = start_block; reg->fragment = fragment->index; reg->offset = fragment->offset; if(!swap) { - memcpy((void *) inodep, (void *) reg, sizeof(*reg)); - memcpy((void *) inodep->block_list, block_list, offset * sizeof(unsigned int)); + memcpy(inodep, reg, sizeof(*reg)); + memcpy(inodep->block_list, block_list, offset * sizeof(unsigned int)); } else { SQUASHFS_SWAP_REG_INODE_HEADER(reg, inodep); SQUASHFS_SWAP_INTS(block_list, inodep->block_list, offset); } - TRACE("File inode, file_size %d, start_block %x, blocks %d, fragment %d, offset %d, size %d\n", byte_size, + TRACE("File inode, file_size %d, start_block %llx, blocks %d, fragment %d, offset %d, size %d\n", (int) byte_size, start_block, offset, fragment->index, fragment->offset, fragment->size); for(i = 0; i < offset; i++) TRACE("Block %d, size %d\n", i, block_list[i]); } + else if(type == SQUASHFS_LREG_TYPE) { + int i; + squashfs_lreg_inode_header *reg = &inode_header.lreg, *inodep; + + inode = get_inode(sizeof(*reg) + offset * sizeof(unsigned int)); + inodep = (squashfs_lreg_inode_header *) inode; + reg->nlink = nlink; + reg->file_size = byte_size; + reg->start_block = start_block; + reg->fragment = fragment->index; + reg->offset = fragment->offset; + if(!swap) { + memcpy(inodep, reg, sizeof(*reg)); + memcpy(inodep->block_list, block_list, offset * sizeof(unsigned int)); + } else { + SQUASHFS_SWAP_LREG_INODE_HEADER(reg, inodep); + SQUASHFS_SWAP_INTS(block_list, inodep->block_list, offset); + } + TRACE("Long file inode, file_size %lld, start_block %llx, blocks %d, fragment %d, offset %d, size %d, nlink %d\n", byte_size, + start_block, offset, fragment->index, fragment->offset, fragment->size, nlink); + for(i = 0; i < offset; i++) + TRACE("Block %d, size %d\n", i, block_list[i]); + } + else if(type == SQUASHFS_LDIR_TYPE) { + int i; + unsigned char *p; + squashfs_ldir_inode_header *dir = &inode_header.ldir, *inodep; + struct cached_dir_index *index = dir_in->index; + unsigned int i_count = dir_in->i_count; + unsigned int i_size = dir_in->i_size; + + if(byte_size >= 1 << 27) + BAD_ERROR("directory greater than 2^27-1 bytes!\n"); + + inode = get_inode(sizeof(*dir) + i_size); + inodep = (squashfs_ldir_inode_header *) inode; + dir->inode_type = SQUASHFS_LDIR_TYPE; + dir->nlink = dir_ent->dir->directory_count + 2; + dir->file_size = byte_size; + dir->offset = offset; + dir->start_block = start_block; + dir->i_count = i_count; + dir->parent_inode = dir_ent->our_dir ? dir_ent->our_dir->dir_ent->inode->inode_number : dir_inode_no + inode_no; + + if(!swap) + memcpy(inode, dir, sizeof(*dir)); + else + SQUASHFS_SWAP_LDIR_INODE_HEADER(dir, inode); + p = (unsigned char *) inodep->index; + for(i = 0; i < i_count; i++) { + if(!swap) + memcpy(p, &index[i].index, sizeof(squashfs_dir_index)); + else + SQUASHFS_SWAP_DIR_INDEX(&index[i].index, p); + memcpy(((squashfs_dir_index *)p)->name, index[i].name, index[i].index.size + 1); + p += sizeof(squashfs_dir_index) + index[i].index.size + 1; + } + TRACE("Long directory inode, file_size %d, start_block %llx, offset %x, nlink %d\n", (int) byte_size, + start_block, offset, dir_ent->dir->directory_count + 2); + } else if(type == SQUASHFS_DIR_TYPE) { squashfs_dir_inode_header *dir = &inode_header.dir; inode = get_inode(sizeof(*dir)); - dir->mtime = buf.st_mtime; + dir->nlink = dir_ent->dir->directory_count + 2; dir->file_size = byte_size; dir->offset = offset; dir->start_block = start_block; + dir->parent_inode = dir_ent->our_dir ? dir_ent->our_dir->dir_ent->inode->inode_number : dir_inode_no + inode_no; if(!swap) - memcpy((void *) inode, (void *) dir, sizeof(*dir)); + memcpy(inode, dir, sizeof(*dir)); else SQUASHFS_SWAP_DIR_INODE_HEADER(dir, inode); - TRACE("Directory inode, file_size %d, start_block %x, offset %x\n", byte_size, - start_block, offset); + TRACE("Directory inode, file_size %d, start_block %llx, offset %x, nlink %d\n", (int) byte_size, + start_block, offset, dir_ent->dir->directory_count + 2); } else if(type == SQUASHFS_CHRDEV_TYPE || type == SQUASHFS_BLKDEV_TYPE) { squashfs_dev_inode_header *dev = &inode_header.dev; inode = get_inode(sizeof(*dev)); - dev->rdev = (unsigned short) ((major(buf.st_rdev) << 8) | - (minor(buf.st_rdev) & 0xff)); + dev->nlink = nlink; + dev->rdev = (unsigned short) ((major(buf->st_rdev) << 8) | + (minor(buf->st_rdev) & 0xff)); if(!swap) - memcpy((void *) inode, (void *) dev, sizeof(*dev)); + memcpy(inode, dev, sizeof(*dev)); else SQUASHFS_SWAP_DEV_INODE_HEADER(dev, inode); - TRACE("Device inode, rdev %x\n", dev->rdev); + TRACE("Device inode, rdev %x, nlink %d\n", dev->rdev, nlink); } else if(type == SQUASHFS_SYMLINK_TYPE) { squashfs_symlink_inode_header *symlink = &inode_header.symlink, *inodep; @@ -538,61 +650,65 @@ squashfs_block start_block, unsigned int offset, unsigned int *block_list, struc if((byte = readlink(filename, buff, 65536)) == -1) { perror("Error in reading symbolic link, skipping..."); - return SQUASHFS_INVALID; + return FALSE; } if(byte == 65536) { ERROR("Symlink is greater than 65536 bytes! skipping..."); - return SQUASHFS_INVALID; + return FALSE; } inode = get_inode(sizeof(*symlink) + byte); - inodep = (squashfs_symlink_inode_header *) inode ; + symlink->nlink = nlink; + inodep = (squashfs_symlink_inode_header *) inode; symlink->symlink_size = byte; if(!swap) - memcpy((void *) inode, symlink, sizeof(*symlink)); + memcpy(inode, symlink, sizeof(*symlink)); else SQUASHFS_SWAP_SYMLINK_INODE_HEADER(symlink, inode); strncpy(inodep->symlink, buff, byte); - TRACE("Symbolic link inode, symlink_size %d\n", byte); + TRACE("Symbolic link inode, symlink_size %d, nlink %d\n", byte, nlink); } else if(type == SQUASHFS_FIFO_TYPE || type == SQUASHFS_SOCKET_TYPE) { squashfs_ipc_inode_header *ipc = &inode_header.ipc; inode = get_inode(sizeof(*ipc)); + ipc->nlink = nlink; if(!swap) - memcpy((void *) inode, (void *) ipc, sizeof(*ipc)); + memcpy(inode, ipc, sizeof(*ipc)); else SQUASHFS_SWAP_IPC_INODE_HEADER(ipc, inode); - TRACE("ipc inode, type %s %d\n", type == SQUASHFS_FIFO_TYPE ? "fifo" : "socket"); + TRACE("ipc inode, type %s, nlink %d\n", type == SQUASHFS_FIFO_TYPE ? "fifo" : "socket", nlink); } else - return SQUASHFS_INVALID; + return FALSE; - i_no = MKINODE(inode); + *i_no = MKINODE(inode); inode_count ++; - TRACE("Created inode 0x%Lx, type %d, uid %d, guid %d\n", i_no, type, base->uid, base->guid); + TRACE("Created inode 0x%llx, type %d, uid %d, guid %d\n", *i_no, type, base->uid, base->guid); - return i_no; + return TRUE; } -void init_dir(struct directory *dir) +void scan2_init_dir(struct directory *dir) { - if((dir->buff = (char *)malloc(SQUASHFS_METADATA_SIZE)) == NULL) { + if((dir->buff = malloc(SQUASHFS_METADATA_SIZE)) == NULL) { BAD_ERROR("Out of memory allocating directory buffer\n"); } dir->size = SQUASHFS_METADATA_SIZE; - dir->p = dir->buff; + dir->p = dir->index_count_p = dir->buff; dir->entry_count = 256; dir->entry_count_p = NULL; + dir->index = NULL; + dir->i_count = dir->i_size = 0; } -void add_dir(squashfs_inode inode, char *name, int type, struct directory *dir) +void add_dir(squashfs_inode inode, unsigned int inode_number, char *name, int type, struct directory *dir) { - char *buff; + unsigned char *buff; squashfs_dir_entry idir, *idirp; unsigned int start_block = inode >> 16; unsigned int offset = inode & 0xffff; @@ -603,33 +719,48 @@ void add_dir(squashfs_inode inode, char *name, int type, struct directory *dir) ERROR("Filename is greater than %d characters, truncating! ...\n", SQUASHFS_NAME_LEN); } - if(dir->p + sizeof(squashfs_dir_entry) + size + 6 >= dir->buff + dir->size) { - if((buff = (char *) realloc(dir->buff, dir->size += SQUASHFS_METADATA_SIZE)) == NULL) { + if(dir->p + sizeof(squashfs_dir_entry) + size + sizeof(squashfs_dir_header) >= dir->buff + dir->size) { + if((buff = realloc(dir->buff, dir->size += SQUASHFS_METADATA_SIZE)) == NULL) { BAD_ERROR("Out of memory reallocating directory buffer\n"); } dir->p = (dir->p - dir->buff) + buff; if(dir->entry_count_p) - dir->entry_count_p = (squashfs_dir_header *) (((unsigned char *) dir->entry_count_p) - - dir->buff + buff); + dir->entry_count_p = (dir->entry_count_p - dir->buff + buff); + dir->index_count_p = dir->index_count_p - dir->buff + buff; dir->buff = buff; } - if(dir->entry_count == 256 || start_block != dir->start_block) { + if(dir->entry_count == 256 || start_block != dir->start_block || ((dir->entry_count_p != NULL) && ((dir->p + sizeof(squashfs_dir_entry) + size - dir->index_count_p) > SQUASHFS_METADATA_SIZE)) || ((long long) inode_number - dir->inode_number) > 32767 || ((long long) inode_number - dir->inode_number) < - 32768) { if(dir->entry_count_p) { squashfs_dir_header dir_header; + if((dir->p + sizeof(squashfs_dir_entry) + size - dir->index_count_p) > SQUASHFS_METADATA_SIZE) { + if(dir->i_count % I_COUNT_SIZE == 0) + if((dir->index = realloc(dir->index, (dir->i_count + I_COUNT_SIZE) * sizeof(struct cached_dir_index))) == NULL) + BAD_ERROR("Out of memory in directory index table reallocation!\n"); + dir->index[dir->i_count].index.index = dir->p - dir->buff; + dir->index[dir->i_count].index.size = size - 1; + dir->index[dir->i_count++].name = name; + dir->i_size += sizeof(squashfs_dir_index) + size; + dir->index_count_p = dir->p; + } + dir_header.count = dir->entry_count - 1; dir_header.start_block = dir->start_block; + dir_header.inode_number = dir->inode_number; if(!swap) - memcpy((void *) dir->entry_count_p, (void *) &dir_header, sizeof(dir_header)); + memcpy(dir->entry_count_p, &dir_header, sizeof(dir_header)); else - SQUASHFS_SWAP_DIR_HEADER((&dir_header), dir->entry_count_p); + SQUASHFS_SWAP_DIR_HEADER((&dir_header), (squashfs_dir_header *) dir->entry_count_p); + } - dir->entry_count_p = (squashfs_dir_header *) dir->p; + + dir->entry_count_p = dir->p; dir->start_block = start_block; dir->entry_count = 0; + dir->inode_number = inode_number; dir->p += sizeof(squashfs_dir_header); } @@ -637,8 +768,9 @@ void add_dir(squashfs_inode inode, char *name, int type, struct directory *dir) idir.offset = offset; idir.type = type; idir.size = size - 1; + idir.inode_number = ((long long) inode_number - dir->inode_number); if(!swap) - memcpy((void *) idirp, (void *) &idir, sizeof(idir)); + memcpy(idirp, &idir, sizeof(idir)); else SQUASHFS_SWAP_DIR_ENTRY((&idir), idirp); strncpy(idirp->name, name, size); @@ -647,14 +779,48 @@ void add_dir(squashfs_inode inode, char *name, int type, struct directory *dir) } -squashfs_inode write_dir(char *filename, struct directory *dir) +int write_dir(squashfs_inode *inode, struct dir_info *dir_info, struct directory *dir) { - squashfs_inode inode; - unsigned int dir_size; - int data_space; + unsigned int dir_size = dir->p - dir->buff; + int data_space = (directory_cache_size - directory_cache_bytes); + unsigned int directory_block, directory_offset, i_count, index; unsigned short c_byte; - while(directory_cache_bytes >= SQUASHFS_METADATA_SIZE) { + if(data_space < dir_size) { + int realloc_size = directory_cache_size == 0 ? ((dir_size + SQUASHFS_METADATA_SIZE) & ~(SQUASHFS_METADATA_SIZE - 1)) : dir_size - data_space; + + if((directory_data_cache = (char *) realloc(directory_data_cache, directory_cache_size + realloc_size)) == NULL) { + goto failed; + } + directory_cache_size += realloc_size; + } + + if(dir_size) { + squashfs_dir_header dir_header; + + dir_header.count = dir->entry_count - 1; + dir_header.start_block = dir->start_block; + dir_header.inode_number = dir->inode_number; + if(!swap) + memcpy(dir->entry_count_p, &dir_header, sizeof(dir_header)); + else + SQUASHFS_SWAP_DIR_HEADER((&dir_header), (squashfs_dir_header *) dir->entry_count_p); + memcpy(directory_data_cache + directory_cache_bytes, dir->buff, dir_size); + } + directory_offset = directory_cache_bytes; + directory_block = directory_bytes; + directory_cache_bytes += dir_size; + i_count = 0; + index = SQUASHFS_METADATA_SIZE - directory_offset; + + while(1) { + while(i_count < dir->i_count && dir->index[i_count].index.index < index) + dir->index[i_count++].index.start_block = directory_bytes; + index += SQUASHFS_METADATA_SIZE; + + if(directory_cache_bytes < SQUASHFS_METADATA_SIZE) + break; + if((directory_size - directory_bytes) < ((SQUASHFS_METADATA_SIZE << 1) + 2)) { if((directory_table = (char *) realloc(directory_table, directory_size + (SQUASHFS_METADATA_SIZE << 1) + 2)) == NULL) { @@ -667,7 +833,7 @@ squashfs_inode write_dir(char *filename, struct directory *dir) SQUASHFS_METADATA_SIZE, SQUASHFS_METADATA_SIZE, noI, 0); TRACE("Directory block @ %x, size %d\n", directory_bytes, c_byte); if(!swap) - memcpy((void *) directory_table + directory_bytes, (void *) &c_byte, sizeof(unsigned short)); + memcpy(directory_table + directory_bytes, &c_byte, sizeof(unsigned short)); else SQUASHFS_SWAP_SHORTS((&c_byte), (directory_table + directory_bytes), 1); if(check_data) @@ -678,39 +844,20 @@ squashfs_inode write_dir(char *filename, struct directory *dir) directory_cache_bytes -= SQUASHFS_METADATA_SIZE; } - dir_size = dir->p - dir->buff; - data_space = (directory_cache_size - directory_cache_bytes); - if(data_space < dir_size) { - int realloc_size = directory_cache_size == 0 ? ((dir_size + SQUASHFS_METADATA_SIZE) & ~(SQUASHFS_METADATA_SIZE - 1)) : dir_size - data_space; - - if((directory_data_cache = (char *) realloc(directory_data_cache, directory_cache_size + realloc_size)) == NULL) { - goto failed; - } - directory_cache_size += realloc_size; - } - - if(dir_size) { - squashfs_dir_header dir_header; - - dir_header.count = dir->entry_count - 1; - dir_header.start_block = dir->start_block; - if(!swap) - memcpy((void *) dir->entry_count_p, (void *) &dir_header, sizeof(dir_header)); - else - SQUASHFS_SWAP_DIR_HEADER((&dir_header), dir->entry_count_p); - memcpy(directory_data_cache + directory_cache_bytes, dir->buff, dir_size); + if(dir_info->dir_is_ldir) { + if(create_inode(inode, dir_info->dir_ent, SQUASHFS_LDIR_TYPE, dir_size + 3, directory_block, directory_offset, NULL, NULL, dir) == FALSE) + return FALSE; + } else { + if(create_inode(inode, dir_info->dir_ent, SQUASHFS_DIR_TYPE, dir_size + 3, directory_block, directory_offset, NULL, NULL, NULL) == FALSE) + return FALSE; } - inode = create_inode(filename, SQUASHFS_DIR_TYPE, dir_size, directory_bytes, directory_cache_bytes, NULL, NULL); - - directory_cache_bytes += dir_size; - #ifdef SQUASHFS_TRACE if(!swap) { unsigned char *dirp; int count; - TRACE("Directory contents of inode 0x%Lx\n", inode); + TRACE("Directory contents of inode 0x%llx\n", *inode); dirp = dir->buff; while(dirp < dir->p) { char buffer[SQUASHFS_NAME_LEN + 1]; @@ -735,7 +882,7 @@ squashfs_inode write_dir(char *filename, struct directory *dir) #endif dir_count ++; - return inode; + return TRUE; failed: BAD_ERROR("Out of memory in directory table reallocation!\n"); @@ -744,37 +891,35 @@ failed: char *get_fragment(char *buffer, struct fragment *fragment) { - if(fragment->index == fragments || fragment->index == SQUASHFS_INVALID_BLK) - return fragment_data + fragment->offset; - else { - squashfs_fragment_entry *disk_fragment = &fragment_table[fragment->index]; - int size = SQUASHFS_COMPRESSED_SIZE_BLOCK(disk_fragment->size), res; - long bytes = block_size; - - if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) { - char cbuffer[block_size]; - - read_bytes(fd, disk_fragment->start_block, size, cbuffer); - - if((res = uncompress(buffer, &bytes, (const char *) cbuffer, size)) != Z_OK) { - if(res == Z_MEM_ERROR) - BAD_ERROR("zlib::uncompress failed, not enough memory\n"); - else if(res == Z_BUF_ERROR) - BAD_ERROR("zlib::uncompress failed, not enough room in output buffer\n"); - else - BAD_ERROR("zlib::uncompress failed, unknown error %d\n", res); - } - } else - read_bytes(fd, disk_fragment->start_block, size, buffer); - return buffer + fragment->offset; - } + squashfs_fragment_entry *disk_fragment = &fragment_table[fragment->index]; + int size = SQUASHFS_COMPRESSED_SIZE_BLOCK(disk_fragment->size); + + if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) { + int res; + unsigned long bytes = block_size; + char cbuffer[block_size]; + + read_bytes(fd, disk_fragment->start_block, size, cbuffer); + + if((res = uncompress((unsigned char *) buffer, &bytes, (const unsigned char *) cbuffer, size)) != Z_OK) { + if(res == Z_MEM_ERROR) + BAD_ERROR("zlib::uncompress failed, not enough memory\n"); + else if(res == Z_BUF_ERROR) + BAD_ERROR("zlib::uncompress failed, not enough room in output buffer\n"); + else + BAD_ERROR("zlib::uncompress failed, unknown error %d\n", res); + } + } else + read_bytes(fd, disk_fragment->start_block, size, buffer); + + return buffer + fragment->offset; } void write_fragment() { int compressed_size; - unsigned char buffer[block_size << 1]; + char buffer[block_size << 1]; if(fragment_size == 0) return; @@ -795,7 +940,7 @@ void write_fragment() } -static struct fragment empty_fragment = {SQUASHFS_INVALID_BLK, 0, 0}; +static struct fragment empty_fragment = {SQUASHFS_INVALID_FRAG, 0, 0}; struct fragment *get_and_fill_fragment(char *buff, int size) { struct fragment *ffrg; @@ -819,9 +964,10 @@ struct fragment *get_and_fill_fragment(char *buff, int size) } -unsigned int write_fragment_table() +long long write_fragment_table() { - unsigned int start_bytes, frag_bytes = SQUASHFS_FRAGMENT_BYTES(fragments), + long long start_bytes; + unsigned int frag_bytes = SQUASHFS_FRAGMENT_BYTES(fragments), meta_blocks = SQUASHFS_FRAGMENT_INDEXES(fragments); char cbuffer[(SQUASHFS_METADATA_SIZE << 2) + 2], buffer[frag_bytes]; squashfs_fragment_entry *p = (squashfs_fragment_entry *) buffer; @@ -831,9 +977,9 @@ unsigned int write_fragment_table() TRACE("write_fragment_table: fragments %d, frag_bytes %d, meta_blocks %d\n", fragments, frag_bytes, meta_blocks); for(i = 0; i < fragments; i++, p++) { - TRACE("write_fragment_table: fragment %d, start_block %x, size %d\n", i, fragment_table[i].start_block, fragment_table[i].size); + TRACE("write_fragment_table: fragment %d, start_block %llx, size %d\n", i, fragment_table[i].start_block, fragment_table[i].size); if(!swap) - memcpy((void *) p, &fragment_table[i], sizeof(squashfs_fragment_entry)); + memcpy(p, &fragment_table[i], sizeof(squashfs_fragment_entry)); else SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_table[i], p); } @@ -842,7 +988,7 @@ unsigned int write_fragment_table() int avail_bytes = i == meta_blocks - 1 ? frag_bytes % SQUASHFS_METADATA_SIZE : SQUASHFS_METADATA_SIZE; c_byte = mangle(cbuffer + block_offset, buffer + i * SQUASHFS_METADATA_SIZE , avail_bytes, SQUASHFS_METADATA_SIZE, noF, 0); if(!swap) - memcpy((void *) cbuffer, (void *) &c_byte, sizeof(unsigned short)); + memcpy(cbuffer, &c_byte, sizeof(unsigned short)); else SQUASHFS_SWAP_SHORTS((&c_byte), cbuffer, 1); if(check_data) @@ -868,16 +1014,16 @@ unsigned int write_fragment_table() } -unsigned char *read_from_buffer(struct duplicate_buffer_handle *handle, unsigned int avail_bytes) +char *read_from_buffer(struct duplicate_buffer_handle *handle, unsigned int avail_bytes) { - unsigned char *v = handle->ptr; + char *v = handle->ptr; handle->ptr += avail_bytes; return v; } char read_from_file_buffer[SQUASHFS_FILE_MAX_SIZE]; -unsigned char *read_from_file(struct duplicate_buffer_handle *handle, unsigned int avail_bytes) +char *read_from_file(struct duplicate_buffer_handle *handle, unsigned int avail_bytes) { read_bytes(fd, handle->start, avail_bytes, read_from_file_buffer); handle->start += avail_bytes; @@ -888,7 +1034,7 @@ unsigned char *read_from_file(struct duplicate_buffer_handle *handle, unsigned i /* * Compute 16 bit BSD checksum over the data */ -unsigned short get_checksum(unsigned char *(get_next_file_block)(struct duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle *handle, int l) +unsigned short get_checksum(char *(get_next_file_block)(struct duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle *handle, long long l) { unsigned short chksum = 0; unsigned int bytes = 0; @@ -898,7 +1044,7 @@ unsigned short get_checksum(unsigned char *(get_next_file_block)(struct duplicat while(l) { bytes = l > SQUASHFS_FILE_MAX_SIZE ? SQUASHFS_FILE_MAX_SIZE : l; l -= bytes; - b = get_next_file_block(&position, bytes); + b = (unsigned char *) get_next_file_block(&position, bytes); while(bytes--) { chksum = (chksum & 1) ? (chksum >> 1) | 0x8000 : chksum >> 1; chksum += *b++; @@ -909,14 +1055,15 @@ unsigned short get_checksum(unsigned char *(get_next_file_block)(struct duplicat } -static unsigned int cached_frag = -1; -void add_file(int start, int file_bytes, unsigned int *block_listp, int blocks, unsigned int fragment, int offset, int bytes) +int cached_frag = -1; +void add_file(long long start, long long file_bytes, unsigned int *block_listp, int blocks, unsigned int fragment, int offset, int bytes) { struct fragment *frg; struct file_info *dupl_ptr; char *datap; struct duplicate_buffer_handle handle; - + unsigned int *block_list = block_listp; + if(!duplicate_checking) return; @@ -926,18 +1073,23 @@ void add_file(int start, int file_bytes, unsigned int *block_listp, int blocks, frg->index = fragment; frg->offset = offset; frg->size = bytes; - if(cached_frag == fragment) + if(fragment == cached_frag || fragment == SQUASHFS_INVALID_FRAG) datap = fragment_data + offset; else datap = get_fragment(fragment_data, frg); handle.start = start; if((dupl_ptr = duplicate(read_from_file, &handle, file_bytes, &block_listp, &start, blocks, &frg, datap, bytes)) != NULL) dupl_ptr->fragment = frg; + else + free(block_list); cached_frag = fragment; } -struct file_info *duplicate(unsigned char *(get_next_file_block)(struct duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle *file_start, int bytes, unsigned int **block_list, int *start, int blocks, struct fragment **fragment, char *frag_data, int frag_bytes) +char cached_fragment[SQUASHFS_FILE_SIZE]; +int cached_frag1 = -1; + +struct file_info *duplicate(char *(get_next_file_block)(struct duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle *file_start, long long bytes, unsigned int **block_list, long long *start, int blocks, struct fragment **fragment, char *frag_data, int frag_bytes) { unsigned short checksum = get_checksum(get_next_file_block, file_start, bytes); struct duplicate_buffer_handle handle = { frag_data, 0 }; @@ -947,10 +1099,11 @@ struct file_info *duplicate(unsigned char *(get_next_file_block)(struct duplicat for(; dupl_ptr; dupl_ptr = dupl_ptr->next) if(bytes == dupl_ptr->bytes && frag_bytes == dupl_ptr->fragment->size && fragment_checksum == dupl_ptr->fragment_checksum) { - unsigned char buffer1[SQUASHFS_FILE_MAX_SIZE]; - unsigned int dup_bytes = dupl_ptr->bytes, dup_start = dupl_ptr->start; + char buffer1[SQUASHFS_FILE_MAX_SIZE]; + long long dup_bytes = dupl_ptr->bytes; + long long dup_start = dupl_ptr->start; struct duplicate_buffer_handle position = *file_start; - unsigned char *buffer; + char *buffer; while(dup_bytes) { int avail_bytes = dup_bytes > SQUASHFS_FILE_MAX_SIZE ? SQUASHFS_FILE_MAX_SIZE : dup_bytes; @@ -962,10 +1115,19 @@ struct file_info *duplicate(unsigned char *(get_next_file_block)(struct duplicat dup_start += avail_bytes; } if(dup_bytes == 0) { - char frag_buffer1[block_size]; - char *fragment_buffer1 = get_fragment(frag_buffer1, dupl_ptr->fragment); + char *fragment_buffer1; + + if(dupl_ptr->fragment->index == fragments || dupl_ptr->fragment->index == SQUASHFS_INVALID_FRAG) + fragment_buffer1 = fragment_data + dupl_ptr->fragment->offset; + else if(dupl_ptr->fragment->index == cached_frag1) + fragment_buffer1 = cached_fragment + dupl_ptr->fragment->offset; + else { + fragment_buffer1 = get_fragment(cached_fragment, dupl_ptr->fragment); + cached_frag1 = dupl_ptr->fragment->index; + } + if(frag_bytes == 0 || memcmp(frag_data, fragment_buffer1, frag_bytes) == 0) { - TRACE("Found duplicate file, start 0x%x, size %d, checksum 0x%x, fragment %d, size %d, offset %d, checksum 0x%x\n", dupl_ptr->start, + TRACE("Found duplicate file, start 0x%llx, size %lld, checksum 0x%x, fragment %d, size %d, offset %d, checksum 0x%x\n", dupl_ptr->start, dupl_ptr->bytes, dupl_ptr->checksum, dupl_ptr->fragment->index, frag_bytes, dupl_ptr->fragment->offset, fragment_checksum); *block_list = dupl_ptr->block_list; *start = dupl_ptr->start; @@ -984,11 +1146,8 @@ struct file_info *duplicate(unsigned char *(get_next_file_block)(struct duplicat dupl_ptr->checksum = checksum; dupl_ptr->start = *start; dupl_ptr->fragment_checksum = fragment_checksum; - if((dupl_ptr->block_list = (unsigned int *) malloc(blocks * sizeof(unsigned int))) == NULL) { - BAD_ERROR("Out of memory allocating block_list\n"); - } - - memcpy(dupl_ptr->block_list, *block_list, blocks * sizeof(unsigned int)); + dupl_ptr->block_list = *block_list; + dup_files ++; if(bytes) { dupl_ptr->next = dupl[checksum]; @@ -1003,18 +1162,22 @@ struct file_info *duplicate(unsigned char *(get_next_file_block)(struct duplicat #define MINALLOCBYTES (1024 * 1024) -squashfs_inode write_file(char *filename, long long size, int *duplicate_file) +int write_file(squashfs_inode *inode, struct dir_ent *dir_ent, long long size, int *duplicate_file) { - unsigned int frag_bytes, file, start, file_bytes = 0, block = 0; - unsigned int c_byte; - long long read_size = (size > SQUASHFS_MAX_FILE_SIZE) ? SQUASHFS_MAX_FILE_SIZE : size; - unsigned int blocks = (read_size + block_size - 1) >> block_log; - unsigned int block_list[blocks], *block_listp = block_list; - char buff[block_size], *c_buffer; - int allocated_blocks = blocks, i, bbytes, whole_file = 1; + int block = 0, i, file, whole_file = 1, status; + unsigned int c_byte, frag_bytes; + long long bbytes, file_bytes = 0, start; + char buff[block_size], *c_buffer = NULL, *filename = dir_ent->pathname; struct fragment *fragment; - struct file_info *dupl_ptr; + struct file_info *dupl_ptr = NULL; struct duplicate_buffer_handle handle; + long long read_size = (size > SQUASHFS_MAX_FILE_SIZE) ? SQUASHFS_MAX_FILE_SIZE : size; + int blocks = (read_size + block_size - 1) >> block_log, allocated_blocks = blocks; + unsigned int *block_list, *block_listp; + + if((block_list = malloc(blocks * sizeof(unsigned int))) == NULL) + BAD_ERROR("Out of memory allocating block_list\n"); + block_listp = block_list; if(!no_fragments && (read_size < block_size || always_use_fragments)) { allocated_blocks = blocks = read_size >> block_log; @@ -1023,20 +1186,19 @@ squashfs_inode write_file(char *filename, long long size, int *duplicate_file) frag_bytes = 0; if(size > read_size) - ERROR("file %s truncated to %Ld bytes\n", filename, SQUASHFS_MAX_FILE_SIZE); + ERROR("file %s truncated to %lld bytes\n", filename, SQUASHFS_MAX_FILE_SIZE); total_bytes += read_size; - if((file = open(filename, O_RDONLY)) == -1) { - perror("Error in opening file, skipping..."); - return SQUASHFS_INVALID; - } + if((file = open(filename, O_RDONLY)) == -1) + goto read_err; do { - if((c_buffer = (char *) malloc((allocated_blocks + 1) << block_log)) == NULL) { - TRACE("Out of memory allocating write_file buffer, allocated_blocks %d, blocks %d\n", allocated_blocks, blocks); + long long bytes = (((long long) allocated_blocks) + 1) << block_log; + if(bytes != ((size_t) bytes) || (c_buffer = (char *) malloc(bytes)) == NULL) { + TRACE("Out of memory allocating write_file buffer, allocated_blocks %ld, blocks %d\n", allocated_blocks, blocks); whole_file = 0; - if((allocated_blocks << (block_log - 1)) < MINALLOCBYTES) - BAD_ERROR("Out of memory allocating write_file buffer, could not allocate %d blocks (%d Kbytes)\n", allocated_blocks, allocated_blocks << (block_log - 10)); + if(bytes < MINALLOCBYTES) + BAD_ERROR("Out of memory allocating write_file buffer, could not allocate %ld blocks (%d Kbytes)\n", allocated_blocks, allocated_blocks << (block_log - 10)); allocated_blocks >>= 1; } } while(!c_buffer); @@ -1089,54 +1251,19 @@ squashfs_inode write_file(char *filename, long long size, int *duplicate_file) wr_inode: free(c_buffer); file_count ++; - return create_inode(filename, SQUASHFS_FILE_TYPE, read_size, start, blocks, block_listp, fragment); + if(dir_ent->inode->nlink == 1 && read_size < ((long long) (1<<30) - 1)) + status = create_inode(inode, dir_ent, SQUASHFS_FILE_TYPE, read_size, start, blocks, block_listp, fragment, NULL); + else + status = create_inode(inode, dir_ent, SQUASHFS_LREG_TYPE, read_size, start, blocks, block_listp, fragment, NULL); + if(duplicate_checking == FALSE || *duplicate_file == TRUE) + free(block_list); + return status; read_err: perror("Error in reading file, skipping..."); free(c_buffer); - return SQUASHFS_INVALID; -} - - -struct linuxdir { - DIR *linuxdir; - char pathname[8192]; -}; - - -void *linux_opendir(char *pathname, struct directory *dir) -{ - struct linuxdir *linuxdir; - if((linuxdir = malloc(sizeof(struct linuxdir))) == NULL) - return NULL; - if((linuxdir->linuxdir = opendir(pathname)) == NULL) { - free(linuxdir); - return NULL; - } - strcpy(linuxdir->pathname, pathname); - return (void *) linuxdir; -} - - -int linux_readdir(void *l, char *filename, char *dir_name) -{ - struct dirent *d_name; - struct linuxdir *linuxdir = (struct linuxdir *)l; - - do { - if((d_name = readdir(linuxdir->linuxdir)) == NULL) - return FALSE; - } while(strcmp(d_name->d_name, ".") == 0 || strcmp(d_name->d_name, "..") == 0); - strcat(strcat(strcpy(filename, linuxdir->pathname), "/"), d_name->d_name); - strcpy(dir_name, d_name->d_name); - return TRUE; -} - - -void linux_closedir(void *linuxdir) -{ - closedir(((struct linuxdir *)linuxdir)->linuxdir); - free(linuxdir); + free(block_list); + return FALSE; } @@ -1189,100 +1316,265 @@ char *basename_r() } -char encomp_pathname[8192]; -int encomp_entry = 0; +struct inode_info *lookup_inode(struct stat *buf) +{ + int inode_hash = INODE_HASH(buf->st_dev, buf->st_ino); + struct inode_info *inode = inode_info[inode_hash]; + + while(inode != NULL) { + if(memcmp(buf, &inode->buf, sizeof(struct stat)) == 0) { + inode->nlink ++; + return inode; + } + inode = inode->next; + } + + if((inode = malloc(sizeof(struct inode_info))) == NULL) + BAD_ERROR("Out of memory in inode hash table entry allocation\n"); + + memcpy(&inode->buf, buf, sizeof(struct stat)); + inode->inode = SQUASHFS_INVALID_BLK; + inode->nlink = 1; + if((buf->st_mode & S_IFMT) == S_IFDIR) + inode->inode_number = dir_inode_no ++; + else + inode->inode_number = inode_no ++; + + inode->next = inode_info[inode_hash]; + inode_info[inode_hash] = inode; + + return inode; +} + + +inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, struct inode_info *inode_info, void *data, struct dir_info *dir) +{ + if((dir->count % DIR_ENTRIES) == 0) + if((dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) * sizeof(struct dir_ent *))) == NULL) + BAD_ERROR("Out of memory in add_dir_entry\n"); + + if((dir->list[dir->count] = malloc(sizeof(struct dir_ent))) == NULL) + BAD_ERROR("Out of memory in linux_opendir\n"); + + if(sub_dir) + sub_dir->dir_ent = dir->list[dir->count]; + dir->list[dir->count]->name = strdup(name); + dir->list[dir->count]->pathname = pathname != NULL ? strdup(pathname) : NULL; + dir->list[dir->count]->inode = inode_info; + dir->list[dir->count]->dir = sub_dir; + dir->list[dir->count]->our_dir = dir; + dir->list[dir->count++]->data = data; + dir->byte_count += strlen(name) + sizeof(squashfs_dir_entry); +} + -void *encomp_opendir(char *pathname, struct directory *dir) +int compare_name(const void *ent1_ptr, const void *ent2_ptr) { - int i; + struct dir_ent *ent1 = *((struct dir_ent **) ent1_ptr); + struct dir_ent *ent2 = *((struct dir_ent **) ent2_ptr); + + return strcmp(ent1->name, ent2->name); +} + + +void sort_directory(struct dir_info *dir) +{ + qsort(dir->list, dir->count, sizeof(struct dir_ent *), compare_name); + + if((dir->count < 257 && dir->byte_count < SQUASHFS_METADATA_SIZE)) + dir->dir_is_ldir = FALSE; +} + + +struct dir_info *scan1_opendir(char *pathname) +{ + DIR *linuxdir; + struct dirent *d_name; + struct dir_info *dir; - for(i = 0; i < old_root_entries; i++) - add_dir(old_root_entry[i].inode, old_root_entry[i].name, old_root_entry[i].type, dir); + if((dir = malloc(sizeof(struct dir_info))) == NULL) + return NULL; + + if(pathname[0] != '\0' && (dir->linuxdir = opendir(pathname)) == NULL) { + free(dir); + return NULL; + } + dir->pathname = strdup(pathname); + dir->count = dir->directory_count = dir->current_count = dir->byte_count = 0; + dir->dir_is_ldir = TRUE; + dir->list = NULL; - return (void *)source_path; + return dir; } -int encomp_readdir(void *l, char *filename, char *dir_name) +int scan1_encomp_readdir(char *pathname, char *dir_name, struct dir_info *dir) { + int i, n, pass; char *basename; - int n, pass = 1; + static int index = 0; + + if(dir->count < old_root_entries) + for(i = 0; i < old_root_entries; i++) { + if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) + dir->directory_count ++; + add_dir_entry(old_root_entry[i].name, "", NULL, NULL, &old_root_entry[i], dir); + } - while(encomp_entry < source) { - if((basename = getbase(source_path[encomp_entry])) == NULL) { - ERROR("Bad source directory %s - skipping ...\n", source_path[encomp_entry]); - encomp_entry++; + while(index < source) { + if((basename = getbase(source_path[index])) == NULL) { + ERROR("Bad source directory %s - skipping ...\n", source_path[index]); + index ++; continue; } - strcpy(filename, source_path[encomp_entry]); strcpy(dir_name, basename); + pass = 1; for(;;) { - for(n = 0; n < old_root_entries && strcmp(old_root_entry[n].name, dir_name) != 0; n++); - if(n == old_root_entries) { - add_old_root_entry(dir_name, 0, 0); - encomp_entry++; - return TRUE; - } + for(n = 0; n < dir->count && strcmp(dir->list[n]->name, dir_name) != 0; n++); + if(n == dir->count) + break; ERROR("Source directory entry %s already used! - trying ", dir_name); sprintf(dir_name, "%s_%d", basename, pass++); ERROR("%s\n", dir_name); } + strcpy(pathname, source_path[index ++]); + return 1; } - return FALSE; + return 0; +} + + +int scan1_single_readdir(char *pathname, char *dir_name, struct dir_info *dir) +{ + struct dirent *d_name; + int i, pass; + + if(dir->count < old_root_entries) + for(i = 0; i < old_root_entries; i++) { + if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) + dir->directory_count ++; + add_dir_entry(old_root_entry[i].name, "", NULL, NULL, &old_root_entry[i], dir); + } + + if((d_name = readdir(dir->linuxdir)) != NULL) { + strcpy(dir_name, d_name->d_name); + pass = 1; + for(;;) { + for(i = 0; i < dir->count && strcmp(dir->list[i]->name, dir_name) != 0; i++); + if(i == dir->count) + break; + ERROR("Source directory entry %s already used! - trying ", dir_name); + sprintf(dir_name, "%s_%d", d_name->d_name, pass++); + ERROR("%s\n", dir_name); + } + strcat(strcat(strcpy(pathname, dir->pathname), "/"), d_name->d_name); + return 1; + } + + return 0; } -void encomp_closedir(void *linuxdir) +int scan1_readdir(char *pathname, char *dir_name, struct dir_info *dir) { + struct dirent *d_name; + + if((d_name = readdir(dir->linuxdir)) != NULL) { + strcpy(dir_name, d_name->d_name); + strcat(strcat(strcpy(pathname, dir->pathname), "/"), d_name->d_name); + return 1; + } + + return 0; } -void *single_opendir(char *pathname, struct directory *dir) +struct dir_ent *scan2_readdir(struct directory *dir, struct dir_info *dir_info) { - encomp_opendir(pathname, dir); - return linux_opendir(pathname, dir); + int current_count; + + while((current_count = dir_info->current_count++) < dir_info->count) + if(dir_info->list[current_count]->data) + add_dir(dir_info->list[current_count]->data->inode, dir_info->list[current_count]->data->inode_number, + dir_info->list[current_count]->name, dir_info->list[current_count]->data->type, dir); + else + return dir_info->list[current_count]; + return FALSE; } -int single_readdir(void *l, char *filename, char *dir_name) +void scan1_freedir(struct dir_info *dir) { - int i, pass = 1; - char name[SQUASHFS_NAME_LEN + 1]; + if(dir->pathname[0] != '\0') + closedir(dir->linuxdir); +} - if(linux_readdir(l, filename, dir_name) == FALSE) - return FALSE; - strcpy(name, dir_name); - for(;;) { - for(i = 0; i < old_root_entries && strcmp(old_root_entry[i].name, dir_name) != 0; i++); - if(i == old_root_entries) { - add_old_root_entry(dir_name, 0, 0); - return TRUE; - } - ERROR("Source directory entry %s already used! - trying ", dir_name); - sprintf(dir_name, "%s_%d", name, pass++); - ERROR("%s\n", dir_name); +void scan2_freedir(struct directory *dir) +{ + if(dir->index) + free(dir->index); + free(dir->buff); +} + + +void dir_scan(squashfs_inode *inode, char *pathname, int (_readdir)(char *, char *, struct dir_info *)) +{ + struct dir_info *dir_info = dir_scan1(pathname, _readdir); + struct dir_ent *dir_ent; + struct inode_info *inode_info; + + if(dir_info == NULL) + return; + + if((dir_ent = malloc(sizeof(struct dir_ent))) == NULL) + BAD_ERROR("Out of memory in dir_scan\n"); + + if((inode_info = malloc(sizeof(struct inode_info))) == NULL) + BAD_ERROR("Out of memory in dir_scan\n"); + + dir_ent->name = dir_ent->pathname = strdup(pathname); + dir_ent->dir = dir_info; + dir_ent->inode = inode_info; + dir_ent->our_dir = NULL; + dir_ent->data = NULL; + inode_info->nlink = 1; + inode_info->inode_number = root_inode_number ? root_inode_number : dir_inode_no++; + dir_info->dir_ent = dir_ent; + + if(pathname[0] == '\0') { + /* dummy top level directory, if multiple sources specified on command line */ + inode_info->buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO; + inode_info->buf.st_uid = getuid(); + inode_info->buf.st_gid = getgid(); + inode_info->buf.st_mtime = time(NULL); + } else if(lstat(pathname, &inode_info->buf) == -1) { + char buffer[8192]; + sprintf(buffer, "Cannot stat dir/file %s, ignoring", pathname); + perror(buffer); + return; } + if(sorted) + sort_files_and_write(dir_info); + dir_scan2(inode, dir_info); } -squashfs_inode dir_scan(char *pathname, void* (_opendir)(char *, struct directory *), int (_readdir)(void *, char *, char *), - void (_closedir)(void *)) +struct dir_info *dir_scan1(char *pathname, int (_readdir)(char *, char *, struct dir_info *)) { - void *linuxdir; + struct dir_info *dir, *sub_dir; struct stat buf; char filename[8192], dir_name[8192]; - int squashfs_type; - squashfs_inode inode = SQUASHFS_INVALID; - struct directory dir; - - init_dir(&dir); - if((linuxdir = _opendir(pathname, &dir)) == NULL) { + + if((dir = scan1_opendir(pathname)) == NULL) { ERROR("Could not open %s, skipping...\n", pathname); goto error; } - - while(_readdir(linuxdir, filename, dir_name) != FALSE) { + + while(_readdir(filename, dir_name, dir) != FALSE) { + + if(strcmp(dir_name, ".") == 0 || strcmp(dir_name, "..") == 0) + continue; if(lstat(filename, &buf) == -1) { char buffer[8192]; @@ -1293,75 +1585,135 @@ squashfs_inode dir_scan(char *pathname, void* (_opendir)(char *, struct director if(excluded(filename, &buf)) continue; - switch(buf.st_mode & S_IFMT) { - case S_IFREG: { - int duplicate_file; + if((buf.st_mode & S_IFMT) == S_IFDIR) { + if((sub_dir = dir_scan1(filename, scan1_readdir)) == NULL) + continue; + dir->directory_count ++; + } else + sub_dir = NULL; - squashfs_type = SQUASHFS_FILE_TYPE; - if(!sorted) { - inode = write_file(filename, buf.st_size, &duplicate_file); - INFO("file %s, uncompressed size %Ld bytes, %s\n", filename, buf.st_size, duplicate_file ? "DUPLICATE" : ""); - } else - inode = get_sorted_inode(&buf); - break; - } - case S_IFDIR: - squashfs_type = SQUASHFS_DIR_TYPE; - inode = dir_scan(filename, linux_opendir, linux_readdir, linux_closedir); - break; + add_dir_entry(dir_name, filename, sub_dir, lookup_inode(&buf), NULL, dir); + } - case S_IFLNK: - squashfs_type = SQUASHFS_SYMLINK_TYPE; - inode = create_inode(filename, squashfs_type, 0, 0, 0, NULL, NULL); - INFO("symbolic link %s inode 0x%Lx\n", dir_name, inode); - sym_count ++; - break; + scan1_freedir(dir); + sort_directory(dir); - case S_IFCHR: - squashfs_type = SQUASHFS_CHRDEV_TYPE; - inode = create_inode(filename, squashfs_type, 0, 0, 0, NULL, NULL); - INFO("character device %s inode 0x%Lx\n", dir_name, inode); - dev_count ++; - break; +error: + return dir; +} - case S_IFBLK: - squashfs_type = SQUASHFS_BLKDEV_TYPE; - inode = create_inode(filename, squashfs_type, 0, 0, 0, NULL, NULL); - INFO("block device %s inode 0x%Lx\n", dir_name, inode); - dev_count ++; - break; - case S_IFIFO: - squashfs_type = SQUASHFS_FIFO_TYPE; - inode = create_inode(filename, squashfs_type, 0, 0, 0, NULL, NULL); - INFO("fifo %s inode 0x%Lx\n", dir_name, inode); - fifo_count ++; - break; +int dir_scan2(squashfs_inode *inode, struct dir_info *dir_info) +{ + int squashfs_type; + int result = FALSE; + int duplicate_file; + char *pathname = dir_info->pathname; + struct directory dir; + struct dir_ent *dir_ent; + + scan2_init_dir(&dir); + + while((dir_ent = scan2_readdir(&dir, dir_info)) != NULL) { + struct inode_info *inode_info = dir_ent->inode; + struct stat *buf = &inode_info->buf; + char *filename = dir_ent->pathname; + char *dir_name = dir_ent->name; + unsigned int inode_number = ((buf->st_mode & S_IFMT) == S_IFDIR) ? dir_ent->inode->inode_number : dir_ent->inode->inode_number + dir_inode_no; + + if(dir_ent->inode->inode == SQUASHFS_INVALID_BLK) { + switch(buf->st_mode & S_IFMT) { + case S_IFREG: + squashfs_type = SQUASHFS_FILE_TYPE; + result = write_file(inode, dir_ent, buf->st_size, &duplicate_file); + INFO("file %s, uncompressed size %lld bytes %s\n", filename, buf->st_size, duplicate_file ? "DUPLICATE" : ""); + break; - case S_IFSOCK: - squashfs_type = SQUASHFS_SOCKET_TYPE; - inode = create_inode(filename, squashfs_type, 0, 0, 0, NULL, NULL); - INFO("unix domain socket %s inode 0x%Lx\n", dir_name, inode); - sock_count ++; - break; + case S_IFDIR: + squashfs_type = SQUASHFS_DIR_TYPE; + result = dir_scan2(inode, dir_ent->dir); + break; - default: - ERROR("%s unrecognised file type, mode is %x\n", filename, buf.st_mode); - continue; + case S_IFLNK: + squashfs_type = SQUASHFS_SYMLINK_TYPE; + result = create_inode(inode, dir_ent, squashfs_type, 0, 0, 0, NULL, NULL, NULL); + INFO("symbolic link %s inode 0x%llx\n", dir_name, *inode); + sym_count ++; + break; + + case S_IFCHR: + squashfs_type = SQUASHFS_CHRDEV_TYPE; + result = create_inode(inode, dir_ent, squashfs_type, 0, 0, 0, NULL, NULL, NULL); + INFO("character device %s inode 0x%llx\n", dir_name, *inode); + dev_count ++; + break; + + case S_IFBLK: + squashfs_type = SQUASHFS_BLKDEV_TYPE; + result = create_inode(inode, dir_ent, squashfs_type, 0, 0, 0, NULL, NULL, NULL); + INFO("block device %s inode 0x%llx\n", dir_name, *inode); + dev_count ++; + break; + + case S_IFIFO: + squashfs_type = SQUASHFS_FIFO_TYPE; + result = create_inode(inode, dir_ent, squashfs_type, 0, 0, 0, NULL, NULL, NULL); + INFO("fifo %s inode 0x%llx\n", dir_name, *inode); + fifo_count ++; + break; + + case S_IFSOCK: + squashfs_type = SQUASHFS_SOCKET_TYPE; + result = create_inode(inode, dir_ent, squashfs_type, 0, 0, 0, NULL, NULL, NULL); + INFO("unix domain socket %s inode 0x%llx\n", dir_name, *inode); + sock_count ++; + break; + + default: + ERROR("%s unrecognised file type, mode is %x\n", filename, buf->st_mode); + result = FALSE; + } + if(result) + dir_ent->inode->inode = *inode; + dir_ent->inode->type = squashfs_type; + } else { + *inode = dir_ent->inode->inode; + squashfs_type = dir_ent->inode->type; + switch(squashfs_type) { + case SQUASHFS_FILE_TYPE: + if(!sorted) + INFO("file %s, uncompressed size %lld bytes LINK\n", filename, buf->st_size); + break; + case SQUASHFS_SYMLINK_TYPE: + INFO("symbolic link %s inode 0x%llx LINK\n", dir_name, *inode); + break; + case SQUASHFS_CHRDEV_TYPE: + INFO("character device %s inode 0x%llx LINK\n", dir_name, *inode); + break; + caseSQUASHFS_BLKDEV_TYPE: + INFO("block device %s inode 0x%llx LINK\n", dir_name, *inode); + break; + case SQUASHFS_FIFO_TYPE: + INFO("fifo %s inode 0x%llx LINK\n", dir_name, *inode); + break; + case SQUASHFS_SOCKET_TYPE: + INFO("unix domain socket %s inode 0x%llx LINK\n", dir_name, *inode); + break; } + result = TRUE; + } + - if(inode != SQUASHFS_INVALID) - add_dir(inode, dir_name, squashfs_type, &dir); + if(result) + add_dir(*inode, inode_number, dir_name, squashfs_type, &dir); } - _closedir(linuxdir); - inode = write_dir(pathname, &dir); - INFO("directory %s inode 0x%Lx\n", pathname, inode); + result = write_dir(inode, dir_info, &dir); + INFO("directory %s inode 0x%llx\n", pathname, *inode); -error: - free(dir.buff); + scan2_freedir(&dir); - return inode; + return result; } @@ -1369,7 +1721,7 @@ unsigned int slog(unsigned int block) { int i; - for(i = 9; i <= 16; i++) + for(i = 12; i <= 16; i++) if(block == (1 << i)) return i; return 0; @@ -1425,7 +1777,7 @@ int add_exclude(char *path) } -void add_old_root_entry(char *name, squashfs_inode inode, int type) +void add_old_root_entry(char *name, squashfs_inode inode, int inode_number, int type) { if((old_root_entry = (struct old_root_entry_info *) realloc(old_root_entry, sizeof(struct old_root_entry_info) * (old_root_entries + 1))) == NULL) @@ -1433,13 +1785,14 @@ void add_old_root_entry(char *name, squashfs_inode inode, int type) strcpy(old_root_entry[old_root_entries].name, name); old_root_entry[old_root_entries].inode = inode; + old_root_entry[old_root_entries].inode_number = inode_number; old_root_entry[old_root_entries++].type = type; } #define VERSION() \ - printf("mksquashfs version 2.0\n");\ - printf("copyright (C) 2004 Phillip Lougher (plougher@users.sourceforge.net)\n\n"); \ + printf("mksquashfs version 3.0 (2006/03/15)\n");\ + printf("copyright (C) 2006 Phillip Lougher \n\n"); \ printf("This program is free software; you can redistribute it and/or\n");\ printf("modify it under the terms of the GNU General Public License\n");\ printf("as published by the Free Software Foundation; either version 2,\n");\ @@ -1450,11 +1803,12 @@ void add_old_root_entry(char *name, squashfs_inode inode, int type) printf("GNU General Public License for more details.\n"); int main(int argc, char *argv[]) { - struct stat buf; + struct stat buf, source_buf; int i; squashfs_super_block sBlk; char *b, *root_name = NULL; - int be, nopad = FALSE, delete = FALSE, keep_as_directory = FALSE, orig_be; + int be, nopad = FALSE, keep_as_directory = FALSE, orig_be; + squashfs_inode inode; #if __BYTE_ORDER == __BIG_ENDIAN be = TRUE; @@ -1480,7 +1834,7 @@ int main(int argc, char *argv[]) } if((block_log = slog(block_size)) == 0) { - ERROR("%s: -b block size not power of two or not between 512 and 64K\n", argv[0]); + ERROR("%s: -b block size not power of two or not between 4096 and 64K\n", argv[0]); exit(1); } } else if(strcmp(argv[i], "-ef") == 0) { @@ -1591,40 +1945,51 @@ int main(int argc, char *argv[]) } else { ERROR("%s: invalid option\n\n", argv[0]); printOptions: - ERROR("SYNTAX:%s source1 source2 ... dest [options] [-e list of exclude dirs/files]\n", argv[0]); + ERROR("SYNTAX:%s source1 source2 ... dest [options] [-e list of exclude\ndirs/files]\n", argv[0]); ERROR("\nOptions are\n"); - ERROR("\t-info\t\t\t\tprint files written to filesystem\n"); - ERROR("\t-sort sort file\t\t\tsort files according to priorities in sort file. One file or dir\n"); - ERROR("\t\t\t\t\twith priority per line. Priority -32768 to 32767, default priority 0\n"); - ERROR("\t-b block size\t\t\tsize of blocks in "); - ERROR("filesystem, default %d\n", SQUASHFS_FILE_SIZE); - ERROR("\t-noappend\t\t\tDo not append to existing filesystem on dest, write a new filesystem\n"); - ERROR("\t\t\t\t\tThis is the default action if dest does not exist, or if no filesystem is on it\n"); - ERROR("\t-keep-as-directory\t\tIf one source directory is specified, create a root directory\n"); - ERROR("\t\t\t\t\tcontaining that directory, rather than the contents of the directory\n"); - ERROR("\t-root-becomes name\t\tWhen appending source files/directories, make the original\n"); - ERROR("\t\t\t\t\troot become a subdirectory in the new root called name, rather\n"); - ERROR("\t\t\t\t\tthan adding the new source items to the original root\n"); - ERROR("\t-noI -noInodeCompression\tdo not compress inode table\n"); - ERROR("\t-noD -noDataCompression\t\tdo not compress data blocks\n"); - ERROR("\t-noF -noFragmentCompression\tdo not compress fragment blocks\n"); - ERROR("\t-no-duplicates\t\t\tdo not perform duplicate checking\n"); - ERROR("\t-no-fragments\t\t\tdo not use fragments\n"); - ERROR("\t-always-use-fragments\t\tuse fragment blocks for files larger than block size\n"); - ERROR("\t-nopad\t\t\t\tdo not pad filesystem to a multiple of 4K\n"); - ERROR("\t-check_data\t\t\tadd checkdata for greater filesystem checks\n"); - ERROR("\t-le\t\t\t\tcreate a little endian filesystem\n"); - ERROR("\t-be\t\t\t\tcreate a big endian filesystem\n"); - ERROR("\t-ef exclude file\t\tfile is a list of exclude dirs/files - one per line\n"); - ERROR("\t-all-root\t\t\toverride file uid/gid and make all file uid/gids owned by root\n"); - ERROR("\t-root-owned\t\t\talternative name for -all-root\n"); - ERROR("\t-force-uid uid\t\t\tset all file uids to uid\n"); - ERROR("\t-force-gid gid\t\t\tset all file gids to gid\n"); - ERROR("\t-version\t\t\tprint version, licence and copyright message\n"); + ERROR("-version\t\tprint version, licence and copyright message\n"); + ERROR("-info\t\t\tprint files written to filesystem\n"); + ERROR("-b \t\tset data block to . Default %d bytes\n", SQUASHFS_FILE_SIZE); + ERROR("-noI\t\t\tdo not compress inode table\n"); + ERROR("-noD\t\t\tdo not compress data blocks\n"); + ERROR("-noF\t\t\tdo not compress fragment blocks\n"); + ERROR("-no-fragments\t\tdo not use fragments\n"); + ERROR("-always-use-fragments\tuse fragment blocks for files larger than block size\n"); + ERROR("-no-duplicates\t\tdo not perform duplicate checking\n"); + ERROR("-noappend\t\tdo not append to existing filesystem\n"); + ERROR("-keep-as-directory\tif one source directory is specified, create a root\n"); + ERROR("\t\t\tdirectory containing that directory, rather than the\n"); + ERROR("\t\t\tcontents of the directory\n"); + ERROR("-root-becomes \twhen appending source files/directories, make the\n"); + ERROR("\t\t\toriginal root become a subdirectory in the new root\n"); + ERROR("\t\t\tcalled , rather than adding the new source items\n"); + ERROR("\t\t\tto the original root\n"); + ERROR("-all-root\t\tmake all files owned by root\n"); + ERROR("-force-uid uid\t\tset all file uids to uid\n"); + ERROR("-force-gid gid\t\tset all file gids to gid\n"); + ERROR("-le\t\t\tcreate a little endian filesystem\n"); + ERROR("-be\t\t\tcreate a big endian filesystem\n"); + ERROR("-nopad\t\t\tdo not pad filesystem to a multiple of 4K\n"); + ERROR("-check_data\t\tadd checkdata for greater filesystem checks\n"); + ERROR("-root-owned\t\talternative name for -all-root\n"); + ERROR("-noInodeCompression\talternative name for -noI\n"); + ERROR("-noDataCompression\talternative name for -noD\n"); + ERROR("-noFragmentCompression\talternative name for -noF\n"); + ERROR("-sort \tsort files according to priorities in . One\n"); + ERROR("\t\t\tfile or dir with priority per line. Priority -32768 to\n"); + ERROR("\t\t\t32767, default priority 0\n"); + ERROR("-ef \tlist of exclude dirs/files. One per line\n"); exit(1); } } + for(i = 0; i < source; i++) + if(stat(source_path[i], &source_buf) == -1) { + fprintf(stderr, "Cannot stat source directory \"%s\" because %s\n", source_path[i], strerror(errno)); + EXIT_MKSQUASHFS(); + } + + destination_file = argv[source + 1]; if(stat(argv[source + 1], &buf) == -1) { if(errno == ENOENT) { /* Does not exist */ if((fd = open(argv[source + 1], O_CREAT | O_TRUNC | O_RDWR, S_IRWXU)) == -1) { @@ -1656,19 +2021,16 @@ printOptions: exit(1); } - if(!delete) { - if(read_super(fd, &sBlk, &orig_be, argv[source + 1]) == 0) { - if(S_ISREG(buf.st_mode)) { /* reopen truncating file */ - close(fd); - if((fd = open(argv[source + 1], O_TRUNC | O_RDWR)) == -1) { - perror("Could not open regular file for writing as destination"); - exit(1); - } - } - delete = TRUE; - } + } + if(!delete) { + if(read_super(fd, &sBlk, &orig_be, argv[source + 1]) == 0) { + ERROR("Failed to read existing filesystem - will not overwrite - ABORTING!\n"); + EXIT_MKSQUASHFS(); } + } else { + signal(SIGTERM, sighandler2); + signal(SIGINT, sighandler2); } /* process the exclude files - must be done afer destination file has been possibly created */ @@ -1678,7 +2040,7 @@ printOptions: char filename[16385]; if((fd = fopen(argv[++i], "r")) == NULL) { perror("Could not open exclude file..."); - exit(1); + EXIT_MKSQUASHFS(); } while(fscanf(fd, "%16384[^\n]\n", filename) != EOF) add_exclude(filename); @@ -1691,7 +2053,7 @@ printOptions: if(i != argc) { if(++i == argc) { ERROR("%s: -e missing arguments\n", argv[0]); - exit(1); + EXIT_MKSQUASHFS(); } while(i < argc && add_exclude(argv[i++])); } @@ -1706,14 +2068,17 @@ printOptions: else if(strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "-root-becomes") == 0 || strcmp(argv[i], "-ef") == 0) i++; - if((fragment_data = (char *) malloc(block_size)) == NULL) - BAD_ERROR("Out of memory allocating fragment_data"); - if(delete) { - printf("Creating %s filesystem on %s, block size %d.\n", - be ? "big endian" : "little endian", argv[source + 1], block_size); + printf("Creating %s %d.%d filesystem on %s, block size %d.\n", + be ? "big endian" : "little endian", SQUASHFS_MAJOR, SQUASHFS_MINOR, argv[source + 1], block_size); bytes = sizeof(squashfs_super_block); } else { + unsigned int last_directory_block, inode_dir_offset, inode_dir_file_size, root_inode_size, + inode_dir_start_block, uncompressed_data, compressed_data, inode_dir_inode_number, + inode_dir_parent_inode; + unsigned int root_inode_start = SQUASHFS_INODE_BLK(sBlk.root_inode), root_inode_offset = + SQUASHFS_INODE_OFFSET(sBlk.root_inode); + be = orig_be; block_log = slog(block_size = sBlk.block_size); noI = SQUASHFS_UNCOMPRESSED_INODES(sBlk.flags); @@ -1724,47 +2089,48 @@ printOptions: always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags); duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags); - fragments = SQUASHFS_INVALID_BLK; - if((bytes = read_filesystem(root_name, fd, &sBlk, &inode_table, &inode_bytes, &data_cache, - &cache_bytes, &cache_size, &directory_table, &directory_bytes, - &directory_data_cache, &directory_cache_bytes, &directory_cache_size, - &file_count, &sym_count, &dev_count, &dir_count, &fifo_count, &sock_count, (squashfs_uid *) uids, &uid_count, - (squashfs_uid *) guids, &guid_count, - &total_bytes, &total_inode_bytes, &total_directory_bytes, add_old_root_entry, &fragment_table)) == 0) { + if((bytes = read_filesystem(root_name, fd, &sBlk, &inode_table, &data_cache, + &directory_table, &directory_data_cache, &last_directory_block, &inode_dir_offset, + &inode_dir_file_size, &root_inode_size, &inode_dir_start_block, + &file_count, &sym_count, &dev_count, &dir_count, &fifo_count, &sock_count, + (squashfs_uid *) uids, &uid_count, (squashfs_uid *) guids, &guid_count, + &total_bytes, &total_inode_bytes, &total_directory_bytes, &inode_dir_inode_number, + &inode_dir_parent_inode, add_old_root_entry, &fragment_table)) == 0) { ERROR("Failed to read existing filesystem - will not overwrite - ABORTING!\n"); - exit(1); + EXIT_MKSQUASHFS(); } if((fragments = sBlk.fragments)) fragment_table = (squashfs_fragment_entry *) realloc((char *) fragment_table, ((fragments + FRAG_SIZE - 1) & ~(FRAG_SIZE - 1)) * sizeof(squashfs_fragment_entry)); - printf("Appending to existing %s squashfs filesystem on %s, block size %d\n", be ? "big endian" : - "little endian", argv[source + 1], block_size); - printf("All -be, -le, -b, -noI, noD, noF, -check_data, no-duplicates, no-fragments and always-use-fragments options ignored\n"); + printf("Appending to existing %s %d.%d filesystem on %s, block size %d\n", be ? "big endian" : + "little endian", SQUASHFS_MAJOR, SQUASHFS_MINOR, argv[source + 1], block_size); + printf("All -be, -le, -b, -noI, -noD, -noF, -check_data, no-duplicates, no-fragments, -always-use-fragments and -2.0 options ignored\n"); printf("\nIf appending is not wanted, please re-run with -noappend specified!\n\n"); - inode_size = inode_bytes; - directory_size = directory_bytes; - + compressed_data = inode_dir_offset + inode_dir_file_size & ~(SQUASHFS_METADATA_SIZE - 1); + uncompressed_data = inode_dir_offset + inode_dir_file_size & (SQUASHFS_METADATA_SIZE - 1); + /* save original filesystem state for restoring ... */ sfragments = fragments; sbytes = bytes; sinode_count = sBlk.inodes; - inode_count = file_count + dir_count + sym_count + dev_count; - sdata_cache = (char *)malloc(scache_bytes = cache_size); - sdirectory_data_cache = (char *)malloc(sdirectory_cache_bytes = directory_cache_size); + sdata_cache = (char *)malloc(scache_bytes = root_inode_offset + root_inode_size); + sdirectory_data_cache = (char *)malloc(sdirectory_cache_bytes = uncompressed_data); memcpy(sdata_cache, data_cache, scache_bytes); - memcpy(sdirectory_data_cache, directory_data_cache, sdirectory_cache_bytes); - sinode_bytes = inode_bytes; - sdirectory_bytes = directory_bytes; + memcpy(sdirectory_data_cache, directory_data_cache + compressed_data, sdirectory_cache_bytes); + sinode_bytes = root_inode_start; + sdirectory_bytes = last_directory_block; suid_count = uid_count; sguid_count = guid_count; stotal_bytes = total_bytes; stotal_inode_bytes = total_inode_bytes; - stotal_directory_bytes = total_directory_bytes; + stotal_directory_bytes = total_directory_bytes + compressed_data; sfile_count = file_count; ssym_count = sym_count; sdev_count = dev_count; - sdir_count = dir_count; + sdir_count = dir_count + 1; + sfifo_count = fifo_count; + ssock_count = sock_count; sdup_files = dup_files; restore = TRUE; if(setjmp(env)) @@ -1772,6 +2138,34 @@ printOptions: signal(SIGTERM, sighandler); signal(SIGINT, sighandler); write_bytes(fd, SQUASHFS_START, 4, "\0\0\0\0"); + + /* set the filesystem state up to be able to append to the original filesystem. The filesystem state + * differs depending on whether we're appending to the original root directory, or if the original + * root directory becomes a sub-directory (root-becomes specified on command line, here root_name != NULL) + */ + inode_bytes = inode_size = root_inode_start; + directory_size = last_directory_block; + cache_size = root_inode_offset + root_inode_size; + directory_cache_size = inode_dir_offset + inode_dir_file_size; + if(root_name) { + root_inode_number = inode_dir_parent_inode; + dir_inode_no = sBlk.inodes + 2; + directory_bytes = last_directory_block; + directory_cache_bytes = uncompressed_data; + memmove(directory_data_cache, directory_data_cache + compressed_data, uncompressed_data); + cache_bytes = root_inode_offset + root_inode_size; + add_old_root_entry(root_name, sBlk.root_inode, inode_dir_inode_number, SQUASHFS_DIR_TYPE); + total_directory_bytes += compressed_data; + dir_count ++; + } else { + root_inode_number = inode_dir_inode_number; + dir_inode_no = sBlk.inodes + 1; + directory_bytes = inode_dir_start_block; + directory_cache_bytes = inode_dir_offset; + cache_bytes = root_inode_offset; + } + + inode_count = file_count + dir_count + sym_count + dev_count + fifo_count + sock_count; } #if __BYTE_ORDER == __BIG_ENDIAN @@ -1782,20 +2176,13 @@ printOptions: block_offset = check_data ? 3 : 2; - if(stat(source_path[0], &buf) == -1) { - perror("Cannot stat source directory"); - EXIT_MKSQUASHFS(); - } - - if(sorted) - sort_files_and_write(source, source_path); - - if(delete && !keep_as_directory && source == 1 && S_ISDIR(buf.st_mode)) - sBlk.root_inode = dir_scan(source_path[0], linux_opendir, linux_readdir, linux_closedir); - else if(!keep_as_directory && source == 1 && S_ISDIR(buf.st_mode)) - sBlk.root_inode = dir_scan(source_path[0], single_opendir, single_readdir, linux_closedir); + if(delete && !keep_as_directory && source == 1 && S_ISDIR(source_buf.st_mode)) + dir_scan(&inode, source_path[0], scan1_readdir); + else if(!keep_as_directory && source == 1 && S_ISDIR(source_buf.st_mode)) + dir_scan(&inode, source_path[0], scan1_single_readdir); else - sBlk.root_inode = dir_scan("", encomp_opendir, encomp_readdir, encomp_closedir); + dir_scan(&inode, "", scan1_encomp_readdir); + sBlk.root_inode = inode; sBlk.inodes = inode_count; sBlk.s_magic = SQUASHFS_MAGIC; sBlk.s_major = SQUASHFS_MAJOR; @@ -1846,6 +2233,8 @@ restore_filesystem: sBlk.bytes_used = bytes; + sBlk.unused = SQUASHFS_INVALID_BLK; + if(!swap) write_bytes(fd, SQUASHFS_START, sizeof(squashfs_super_block), (char *) &sBlk); else { @@ -1856,7 +2245,7 @@ restore_filesystem: } if(!nopad && (i = bytes & (4096 - 1))) { - unsigned char temp[4096] = {0}; + char temp[4096] = {0}; write_bytes(fd, bytes, 4096 - i, temp); } @@ -1865,7 +2254,7 @@ restore_filesystem: sizeof(squashfs_super_block); printf("\n%s filesystem, data block size %d, %s data, %s metadata, %s fragments\n", be ? - "Big endian" : "Little endian", block_size, noI ? "uncompressed" : "compressed", noD ? + "Big endian" : "Little endian", block_size, noD ? "uncompressed" : "compressed", noI ? "uncompressed" : "compressed", no_fragments ? "no" : noF ? "uncompressed" : "compressed"); printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", bytes / 1024.0, bytes / (1024.0 * 1024.0)); printf("\t%.2f%% of uncompressed filesystem size (%.2f Kbytes)\n", diff --git a/release/src/linux/linux/scripts/squashfs/mksquashfs.h b/release/src/linux/linux/scripts/squashfs/mksquashfs.h index b3d2e441..680bb388 100644 --- a/release/src/linux/linux/scripts/squashfs/mksquashfs.h +++ b/release/src/linux/linux/scripts/squashfs/mksquashfs.h @@ -3,7 +3,8 @@ * endian and vice versa. These are needed when creating a filesystem on a * machine with different byte ordering to the target architecture. * - * Copyright (c) 2002, 2003, 2004 Phillip Lougher + * Copyright (c) 2002, 2003, 2004, 2005, 2006 + * Phillip Lougher * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/release/src/linux/linux/scripts/squashfs/read_fs.c b/release/src/linux/linux/scripts/squashfs/read_fs.c index cdb62a75..46f4a4e4 100644 --- a/release/src/linux/linux/scripts/squashfs/read_fs.c +++ b/release/src/linux/linux/scripts/squashfs/read_fs.c @@ -1,7 +1,8 @@ /* * Read a squashfs filesystem. This is a highly compressed read only filesystem. * - * Copyright (c) 2002, 2003, 2004 Phillip Lougher + * Copyright (c) 2002, 2003, 2004, 2005, 2006 + * Phillip Lougher * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,8 +21,8 @@ * read_fs.c */ -extern void read_bytes(int, unsigned int, int, char *); -extern int add_file(int, int, unsigned int *, int, unsigned int, int, int); +extern void read_bytes(int, long long, int, char *); +extern int add_file(long long, long long, unsigned int *, int, unsigned int, int, int); #define TRUE 1 #define FALSE 0 @@ -34,29 +35,41 @@ extern int add_file(int, int, unsigned int *, int, unsigned int, int, int); #include #include +#ifndef linux +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#else #include -#include "read_fs.h" +#endif + #include +#include "read_fs.h" +#include "global.h" #include #ifdef SQUASHFS_TRACE -#define TRACE(s, args...) printf("mksquashfs: "s, ## args) +#define TRACE(s, args...) do { \ + printf("mksquashfs: "s, ## args); \ + } while(0) #else #define TRACE(s, args...) #endif -#define ERROR(s, args...) fprintf(stderr, s, ## args) +#define ERROR(s, args...) do { \ + fprintf(stderr, s, ## args); \ + } while(0) int swap; -int read_block(int fd, int start, int *next, unsigned char *block, squashfs_super_block *sBlk) +int read_block(int fd, long long start, long long *next, unsigned char *block, squashfs_super_block *sBlk) { unsigned short c_byte; int offset = 2; if(swap) { - read_bytes(fd, start, 2, block); + read_bytes(fd, start, 2, (char *) block); ((unsigned char *) &c_byte)[1] = block[0]; ((unsigned char *) &c_byte)[0] = block[1]; } else @@ -65,14 +78,14 @@ int read_block(int fd, int start, int *next, unsigned char *block, squashfs_supe if(SQUASHFS_CHECK_DATA(sBlk->flags)) offset = 3; if(SQUASHFS_COMPRESSED(c_byte)) { - unsigned char buffer[SQUASHFS_METADATA_SIZE]; + char buffer[SQUASHFS_METADATA_SIZE]; int res; - long bytes = SQUASHFS_METADATA_SIZE; + unsigned long bytes = SQUASHFS_METADATA_SIZE; c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); read_bytes(fd, start + offset, c_byte, buffer); - if((res = uncompress(block, &bytes, (const char *) buffer, c_byte)) != Z_OK) { + if((res = uncompress(block, &bytes, (const unsigned char *) buffer, c_byte)) != Z_OK) { if(res == Z_MEM_ERROR) ERROR("zlib::uncompress failed, not enough memory\n"); else if(res == Z_BUF_ERROR) @@ -86,7 +99,7 @@ int read_block(int fd, int start, int *next, unsigned char *block, squashfs_supe return bytes; } else { c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); - read_bytes(fd, start + offset, c_byte, block); + read_bytes(fd, start + offset, c_byte, (char *) block); if(next) *next = start + offset + c_byte; return c_byte; @@ -94,30 +107,32 @@ int read_block(int fd, int start, int *next, unsigned char *block, squashfs_supe } -int scan_inode_table(int fd, int start, int end, int root_inode_start, squashfs_super_block *sBlk, - squashfs_dir_inode_header *dir_inode, unsigned char **inode_table, unsigned int *root_inode_block, - unsigned int *uncompressed_file, unsigned int *uncompressed_directory, int *file_count, int *sym_count, - int *dev_count, int *dir_count, int *fifo_count, int *sock_count) +int scan_inode_table(int fd, long long start, long long end, long long root_inode_start, int root_inode_offset, + squashfs_super_block *sBlk, + squashfs_inode_header *dir_inode, unsigned char **inode_table, unsigned int *root_inode_block, + unsigned int *root_inode_size, long long *uncompressed_file, unsigned int *uncompressed_directory, + int *file_count, int *sym_count, int *dev_count, int *dir_count, int *fifo_count, int *sock_count) { unsigned char *cur_ptr; - int bytes = 0, size = 0, files = 0; + int byte, bytes = 0, size = 0, files = 0; squashfs_reg_inode_header inode; unsigned int directory_start_block; - TRACE("scan_inode_table: start 0x%x, end 0x%x, root_inode_start 0x%x\n", start, end, root_inode_start); + TRACE("scan_inode_table: start 0x%llx, end 0x%llx, root_inode_start 0x%llx\n", start, end, root_inode_start); while(start < end) { if(start == root_inode_start) { - TRACE("scan_inode_table: read compressed block 0x%x containing root inode\n", start); + TRACE("scan_inode_table: read compressed block 0x%llx containing root inode\n", start); *root_inode_block = bytes; } if((size - bytes < SQUASHFS_METADATA_SIZE) && ((*inode_table = realloc(*inode_table, size += SQUASHFS_METADATA_SIZE)) == NULL)) return FALSE; - TRACE("scan_inode_table: reading block 0x%x\n", start); - if((bytes += read_block(fd, start, &start, *inode_table + bytes, sBlk)) == 0) { + TRACE("scan_inode_table: reading block 0x%llx\n", start); + if((byte = read_block(fd, start, &start, *inode_table + bytes, sBlk)) == 0) { free(*inode_table); return FALSE; } + bytes += byte; } /* @@ -128,43 +143,112 @@ int scan_inode_table(int fd, int start, int end, int root_inode_start, squashfs_ * The root inode is ignored in the inode scan. This ensures there is * always enough bytes left to read a regular file inode entry */ - bytes -= sizeof(squashfs_dir_inode_header); + *root_inode_size = bytes - (*root_inode_block + root_inode_offset); + bytes = *root_inode_block + root_inode_offset; if(swap) { - squashfs_dir_inode_header sinode; - memcpy((void *)&sinode, (void *)(*inode_table + bytes), sizeof(*dir_inode)); - SQUASHFS_SWAP_DIR_INODE_HEADER(dir_inode, &sinode); + squashfs_base_inode_header sinode; + memcpy(&sinode, *inode_table + bytes, sizeof(dir_inode->base)); + SQUASHFS_SWAP_BASE_INODE_HEADER(&dir_inode->base, &sinode, sizeof(squashfs_base_inode_header)); } else - memcpy((void *)dir_inode, (void *)(*inode_table + bytes), sizeof(*dir_inode)); - directory_start_block = dir_inode->start_block; + memcpy(&dir_inode->base, *inode_table + bytes, sizeof(dir_inode->base)); + if(dir_inode->base.inode_type == SQUASHFS_DIR_TYPE) { + if(swap) { + squashfs_dir_inode_header sinode; + memcpy(&sinode, *inode_table + bytes, sizeof(dir_inode->dir)); + SQUASHFS_SWAP_DIR_INODE_HEADER(&dir_inode->dir, &sinode); + } else + memcpy(&dir_inode->dir, *inode_table + bytes, sizeof(dir_inode->dir)); + directory_start_block = dir_inode->dir.start_block; + } else { + if(swap) { + squashfs_ldir_inode_header sinode; + memcpy(&sinode, *inode_table + bytes, sizeof(dir_inode->ldir)); + SQUASHFS_SWAP_LDIR_INODE_HEADER(&dir_inode->ldir, &sinode); + } else + memcpy(&dir_inode->ldir, *inode_table + bytes, sizeof(dir_inode->ldir)); + directory_start_block = dir_inode->ldir.start_block; + } for(cur_ptr = *inode_table; cur_ptr < *inode_table + bytes; files ++) { if(swap) { squashfs_reg_inode_header sinode; - memcpy((void *)&sinode, (void *)cur_ptr, sizeof(inode)); + memcpy(&sinode, cur_ptr, sizeof(inode)); SQUASHFS_SWAP_REG_INODE_HEADER(&inode, &sinode); } else - memcpy((void *)&inode, (void *)cur_ptr, sizeof(inode)); + memcpy(&inode, cur_ptr, sizeof(inode)); TRACE("scan_inode_table: processing inode @ byte position 0x%x, type 0x%x\n", cur_ptr - *inode_table, inode.inode_type); switch(inode.inode_type) { case SQUASHFS_FILE_TYPE: { - int frag_bytes = inode.fragment == SQUASHFS_INVALID_BLK ? 0 : inode.file_size % sBlk->block_size; - int blocks = inode.fragment == SQUASHFS_INVALID_BLK ? (inode.file_size + int frag_bytes = inode.fragment == SQUASHFS_INVALID_FRAG ? 0 : inode.file_size % sBlk->block_size; + int blocks = inode.fragment == SQUASHFS_INVALID_FRAG ? (inode.file_size + sBlk->block_size - 1) >> sBlk->block_log : inode.file_size >> sBlk->block_log; - int file_bytes = 0, i, start = inode.start_block; - unsigned int block_list[blocks]; + long long file_bytes = 0; + int i, start = inode.start_block; + unsigned int *block_list; + + TRACE("scan_inode_table: regular file, file_size %lld, blocks %d\n", inode.file_size, blocks); + + if((block_list = malloc(blocks * sizeof(unsigned int))) == NULL) { + ERROR("Out of memory in block list malloc\n"); + goto failed; + } + + cur_ptr += sizeof(inode); + if(swap) { + unsigned int sblock_list[blocks]; + memcpy(sblock_list, cur_ptr, blocks * sizeof(unsigned int)); + SQUASHFS_SWAP_INTS(block_list, sblock_list, blocks); + } else + memcpy(block_list, cur_ptr, blocks * sizeof(unsigned int)); + + *uncompressed_file += inode.file_size; + (*file_count) ++; + + for(i = 0; i < blocks; i++) + file_bytes += SQUASHFS_COMPRESSED_SIZE_BLOCK(block_list[i]); + + add_file(start, file_bytes, block_list, blocks, inode.fragment, inode.offset, frag_bytes); + cur_ptr += blocks * sizeof(unsigned int); + break; + } + case SQUASHFS_LREG_TYPE: { + squashfs_lreg_inode_header inode; + int frag_bytes; + int blocks; + long long file_bytes = 0; + int i, start; + unsigned int *block_list; - TRACE("scan_inode_table: regular file, file_size %d, blocks %d\n", inode.file_size, blocks); + if(swap) { + squashfs_lreg_inode_header sinodep; + memcpy(&sinodep, cur_ptr, sizeof(sinodep)); + SQUASHFS_SWAP_LREG_INODE_HEADER(&inode, &sinodep); + } else + memcpy(&inode, cur_ptr, sizeof(inode)); + + TRACE("scan_inode_table: extended regular file, file_size %lld, blocks %d\n", inode.file_size, blocks); cur_ptr += sizeof(inode); + frag_bytes = inode.fragment == SQUASHFS_INVALID_FRAG ? 0 : inode.file_size % sBlk->block_size; + blocks = inode.fragment == SQUASHFS_INVALID_FRAG ? (inode.file_size + + sBlk->block_size - 1) >> sBlk->block_log : inode.file_size >> + sBlk->block_log; + start = inode.start_block; + + if((block_list = malloc(blocks * sizeof(unsigned int))) == NULL) { + ERROR("Out of memory in block list malloc\n"); + goto failed; + } + if(swap) { unsigned int sblock_list[blocks]; - memcpy((void *)sblock_list, (void *)cur_ptr, blocks * sizeof(unsigned int)); + memcpy(sblock_list, cur_ptr, blocks * sizeof(unsigned int)); SQUASHFS_SWAP_INTS(block_list, sblock_list, blocks); } else - memcpy((void *)block_list, (void *)cur_ptr, blocks * sizeof(unsigned int)); + memcpy(block_list, cur_ptr, blocks * sizeof(unsigned int)); *uncompressed_file += inode.file_size; (*file_count) ++; @@ -181,10 +265,10 @@ int scan_inode_table(int fd, int start, int end, int root_inode_start, squashfs_ if(swap) { squashfs_symlink_inode_header sinodep; - memcpy((void *)&sinodep, (void *)cur_ptr, sizeof(sinodep)); + memcpy(&sinodep, cur_ptr, sizeof(sinodep)); SQUASHFS_SWAP_SYMLINK_INODE_HEADER(&inodep, &sinodep); } else - memcpy((void *)&inodep, (void *)cur_ptr, sizeof(inodep)); + memcpy(&inodep, cur_ptr, sizeof(inodep)); (*sym_count) ++; cur_ptr += sizeof(inodep) + inodep.symlink_size; break; @@ -194,16 +278,42 @@ int scan_inode_table(int fd, int start, int end, int root_inode_start, squashfs_ if(swap) { squashfs_dir_inode_header sinode; - memcpy((void *)&sinode, (void *)cur_ptr, sizeof(dir_inode)); + memcpy(&sinode, cur_ptr, sizeof(dir_inode)); SQUASHFS_SWAP_DIR_INODE_HEADER(&dir_inode, &sinode); } else - memcpy((void *)&dir_inode, (void *)cur_ptr, sizeof(dir_inode)); + memcpy(&dir_inode, cur_ptr, sizeof(dir_inode)); if(dir_inode.start_block < directory_start_block) *uncompressed_directory += dir_inode.file_size; (*dir_count) ++; cur_ptr += sizeof(squashfs_dir_inode_header); break; } + case SQUASHFS_LDIR_TYPE: { + squashfs_ldir_inode_header dir_inode; + int i; + + if(swap) { + squashfs_ldir_inode_header sinode; + memcpy(&sinode, cur_ptr, sizeof(dir_inode)); + SQUASHFS_SWAP_LDIR_INODE_HEADER(&dir_inode, &sinode); + } else + memcpy(&dir_inode, cur_ptr, sizeof(dir_inode)); + if(dir_inode.start_block < directory_start_block) + *uncompressed_directory += dir_inode.file_size; + (*dir_count) ++; + cur_ptr += sizeof(squashfs_ldir_inode_header); + for(i = 0; i < dir_inode.i_count; i++) { + squashfs_dir_index index; + if(swap) { + squashfs_dir_index sindex; + memcpy(&sindex, cur_ptr, sizeof(squashfs_dir_index)); + SQUASHFS_SWAP_DIR_INDEX(&index, &sindex); + } else + memcpy(&index, cur_ptr, sizeof(squashfs_dir_index)); + cur_ptr += sizeof(squashfs_dir_index) + index.size + 1; + } + break; + } case SQUASHFS_BLKDEV_TYPE: case SQUASHFS_CHRDEV_TYPE: (*dev_count) ++; @@ -220,12 +330,16 @@ int scan_inode_table(int fd, int start, int end, int root_inode_start, squashfs_ break; default: ERROR("Unknown inode type %d in scan_inode_table!\n", inode.inode_type); - free(*inode_table); - return FALSE; + goto failed; } } return files; + + +failed: + free(*inode_table); + return FALSE; } @@ -250,11 +364,11 @@ int read_super(int fd, squashfs_super_block *sBlk, int *be, char *source) /* Check the MAJOR & MINOR versions */ if(sBlk->s_major != SQUASHFS_MAJOR || sBlk->s_minor > SQUASHFS_MINOR) { - if(sBlk->s_major == 1) - ERROR("Filesystem on %s is a SQUASHFS 1.x filesystem. Appending\nto SQUASHFS 1.x filesystems is not supported. Please convert it to a SQUASHFS 2.0 filesystem...n", source); + if(sBlk->s_major < 3) + ERROR("Filesystem on %s is a SQUASHFS %d.%d filesystem. Appending\nto SQUASHFS %d.%d filesystems is not supported. Please convert it to a SQUASHFS 3.0 filesystem\n", source, sBlk->s_major, sBlk->s_minor, sBlk->s_major, sBlk->s_minor); else - ERROR("Major/Minor mismatch, filesystem on %s is (%d:%d), I support (%d: <= %d)\n", - source, sBlk->s_major, sBlk->s_minor, SQUASHFS_MAJOR, SQUASHFS_MINOR); + ERROR("Major/Minor mismatch, filesystem on %s is %d.%d, I support 3.0\n", + source, sBlk->s_major, sBlk->s_minor); goto failed_mount; } @@ -272,16 +386,16 @@ int read_super(int fd, squashfs_super_block *sBlk, int *be, char *source) printf("\tFragments are %s present in the filesystem\n", SQUASHFS_NO_FRAGMENTS(sBlk->flags) ? "not" : ""); printf("\tAlways_use_fragments option is %s specified\n", SQUASHFS_ALWAYS_FRAGMENTS(sBlk->flags) ? "" : "not"); printf("\tDuplicates are %s removed\n", SQUASHFS_DUPLICATES(sBlk->flags) ? "" : "not"); - printf("\tFilesystem size %d bytes\n", sBlk->bytes_used); + printf("\tFilesystem size %.2f Kbytes (%.2f Mbytes)\n", sBlk->bytes_used / 1024.0, sBlk->bytes_used / (1024.0 * 1024.0)); printf("\tBlock size %d\n", sBlk->block_size); printf("\tNumber of fragments %d\n", sBlk->fragments); printf("\tNumber of inodes %d\n", sBlk->inodes); printf("\tNumber of uids %d\n", sBlk->no_uids); printf("\tNumber of gids %d\n", sBlk->no_guids); - TRACE("sBlk->inode_table_start %x\n", sBlk->inode_table_start); - TRACE("sBlk->directory_table_start %x\n", sBlk->directory_table_start); - TRACE("sBlk->uid_start %x\n", sBlk->uid_start); - TRACE("sBlk->fragment_table_start %x\n", sBlk->fragment_table_start); + TRACE("sBlk->inode_table_start %llx\n", sBlk->inode_table_start); + TRACE("sBlk->directory_table_start %llx\n", sBlk->directory_table_start); + TRACE("sBlk->uid_start %llx\n", sBlk->uid_start); + TRACE("sBlk->fragment_table_start %llx\n", sBlk->fragment_table_start); printf("\n"); return TRUE; @@ -291,24 +405,27 @@ failed_mount: } -unsigned char *squashfs_readdir(int fd, int root_entries, int start, int offset, int size, squashfs_super_block *sBlk, - void (push_directory_entry)(char *, squashfs_inode, int)) +unsigned char *squashfs_readdir(int fd, int root_entries, unsigned int directory_start_block, int offset, int size, + unsigned int *last_directory_block, squashfs_super_block *sBlk, void (push_directory_entry)(char *, squashfs_inode, int, int)) { squashfs_dir_header dirh; char buffer[sizeof(squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1]; squashfs_dir_entry *dire = (squashfs_dir_entry *) buffer; unsigned char *directory_table = NULL; - int bytes = 0, dir_count; + int byte, bytes = 0, dir_count; + long long start = sBlk->directory_table_start + directory_start_block, last_start_block; size += offset; if((directory_table = malloc((size + SQUASHFS_METADATA_SIZE * 2 - 1) & ~(SQUASHFS_METADATA_SIZE - 1))) == NULL) return NULL; while(bytes < size) { - TRACE("squashfs_readdir: reading block 0x%x, bytes read so far %d\n", start, bytes); - if((bytes += read_block(fd, start, &start, directory_table + bytes, sBlk)) == 0) { + TRACE("squashfs_readdir: reading block 0x%llx, bytes read so far %d\n", start, bytes); + last_start_block = start; + if((byte = read_block(fd, start, &start, directory_table + bytes, sBlk)) == 0) { free(directory_table); return NULL; } + bytes += byte; } if(!root_entries) @@ -318,10 +435,10 @@ unsigned char *squashfs_readdir(int fd, int root_entries, int start, int offset, while(bytes < size) { if(swap) { squashfs_dir_header sdirh; - memcpy((void *)&sdirh, directory_table + bytes, sizeof(sdirh)); + memcpy(&sdirh, directory_table + bytes, sizeof(sdirh)); SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); } else - memcpy((void *)&dirh, directory_table + bytes, sizeof(dirh)); + memcpy(&dirh, directory_table + bytes, sizeof(dirh)); dir_count = dirh.count + 1; TRACE("squashfs_readdir: Read directory header @ byte position 0x%x, 0x%x directory entries\n", bytes, dir_count); @@ -330,21 +447,22 @@ unsigned char *squashfs_readdir(int fd, int root_entries, int start, int offset, while(dir_count--) { if(swap) { squashfs_dir_entry sdire; - memcpy((void *)&sdire, directory_table + bytes, sizeof(sdire)); + memcpy(&sdire, directory_table + bytes, sizeof(sdire)); SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); } else - memcpy((void *)dire, directory_table + bytes, sizeof(dire)); + memcpy(dire, directory_table + bytes, sizeof(dire)); bytes += sizeof(*dire); - memcpy((void *)dire->name, directory_table + bytes, dire->size + 1); + memcpy(dire->name, directory_table + bytes, dire->size + 1); dire->name[dire->size + 1] = '\0'; TRACE("squashfs_readdir: pushing directory entry %s, inode %x:%x, type 0x%x\n", dire->name, dirh.start_block, dire->offset, dire->type); - push_directory_entry(dire->name, SQUASHFS_MKINODE(dirh.start_block, dire->offset), dire->type); + push_directory_entry(dire->name, SQUASHFS_MKINODE(dirh.start_block, dire->offset), dire->inode_number, dire->type); bytes += dire->size + 1; } } all_done: + *last_directory_block = (unsigned int) last_start_block - sBlk->directory_table_start; return directory_table; } @@ -354,7 +472,7 @@ int read_fragment_table(int fd, squashfs_super_block *sBlk, squashfs_fragment_en int i, indexes = SQUASHFS_FRAGMENT_INDEXES(sBlk->fragments); squashfs_fragment_index fragment_table_index[indexes]; - TRACE("read_fragment_table: %d fragments, reading %d fragment indexes from 0x%x\n", sBlk->fragments, indexes, sBlk->fragment_table_start); + TRACE("read_fragment_table: %d fragments, reading %d fragment indexes from 0x%llx\n", sBlk->fragments, indexes, sBlk->fragment_table_start); if(sBlk->fragments == 0) return 1; @@ -372,11 +490,10 @@ int read_fragment_table(int fd, squashfs_super_block *sBlk, squashfs_fragment_en read_bytes(fd, sBlk->fragment_table_start, SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments), (char *) fragment_table_index); for(i = 0; i < indexes; i++) { - int length = read_block(fd, fragment_table_index[i], NULL, ((char *) *fragment_table) + (i * SQUASHFS_METADATA_SIZE), sBlk); - TRACE("Read fragment table block %d, from 0x%x, length %d\n", i, fragment_table_index[i], length); + int length = read_block(fd, fragment_table_index[i], NULL, ((unsigned char *) *fragment_table) + (i * SQUASHFS_METADATA_SIZE), sBlk); + TRACE("Read fragment table block %d, from 0x%llx, length %d\n", i, fragment_table_index[i], length); } - if(swap) { squashfs_fragment_entry sfragment; for(i = 0; i < sBlk->fragments; i++) { @@ -389,29 +506,30 @@ int read_fragment_table(int fd, squashfs_super_block *sBlk, squashfs_fragment_en } -int read_filesystem(char *root_name, int fd, squashfs_super_block *sBlk, char **cinode_table, int *inode_bytes, - char **data_cache, int *cache_bytes, int *cache_size, - char **cdirectory_table, int *directory_bytes, - char **directory_data_cache, int *directory_cache_bytes, int *directory_cache_size, - int *file_count, int *sym_count, int *dev_count, int *dir_count, int *fifo_count, int *sock_count, - squashfs_uid *uids, unsigned short *uid_count, squashfs_uid *guids, unsigned short *guid_count, - unsigned int *uncompressed_file, unsigned int *uncompressed_inode, unsigned int *uncompressed_directory, - void (push_directory_entry)(char *, squashfs_inode, int), squashfs_fragment_entry **fragment_table) +long long read_filesystem(char *root_name, int fd, squashfs_super_block *sBlk, char **cinode_table, + char **data_cache, char **cdirectory_table, char **directory_data_cache, + unsigned int *last_directory_block, unsigned int *inode_dir_offset, unsigned int *inode_dir_file_size, + unsigned int *root_inode_size, unsigned int *inode_dir_start_block, int *file_count, int *sym_count, + int *dev_count, int *dir_count, int *fifo_count, int *sock_count, squashfs_uid *uids, + unsigned short *uid_count, squashfs_uid *guids, unsigned short *guid_count, + long long *uncompressed_file, unsigned int *uncompressed_inode, unsigned int *uncompressed_directory, + unsigned int *inode_dir_inode_number, unsigned int *inode_dir_parent_inode, + void (push_directory_entry)(char *, squashfs_inode, int, int), squashfs_fragment_entry **fragment_table) { unsigned char *inode_table = NULL, *directory_table; - unsigned int start = sBlk->inode_table_start, end = sBlk->directory_table_start, - root_inode_start = start + SQUASHFS_INODE_BLK(sBlk->root_inode), - root_inode_offset = SQUASHFS_INODE_OFFSET(sBlk->root_inode), root_directory_offset; - squashfs_dir_inode_header inode; - unsigned int files, root_inode_block; + long long start = sBlk->inode_table_start, end = sBlk->directory_table_start, root_inode_start = start + + SQUASHFS_INODE_BLK(sBlk->root_inode); + unsigned int root_inode_offset = SQUASHFS_INODE_OFFSET(sBlk->root_inode), root_inode_block, files; + squashfs_inode_header inode; printf("Scanning existing filesystem...\n"); - if(read_fragment_table(fd, sBlk, fragment_table) == 0) + if(read_fragment_table(fd, sBlk, fragment_table) == 0) goto error; - if((files = scan_inode_table(fd, start, end, root_inode_start, sBlk, &inode, &inode_table, &root_inode_block, - uncompressed_file, uncompressed_directory, file_count, sym_count, dev_count, dir_count, fifo_count, sock_count)) == 0) { + if((files = scan_inode_table(fd, start, end, root_inode_start, root_inode_offset, sBlk, &inode, &inode_table, + &root_inode_block, root_inode_size, uncompressed_file, uncompressed_directory, file_count, sym_count, + dev_count, dir_count, fifo_count, sock_count)) == 0) { ERROR("read_filesystem: inode table read failed\n"); goto error; } @@ -420,53 +538,51 @@ int read_filesystem(char *root_name, int fd, squashfs_super_block *sBlk, char ** printf("Read existing filesystem, %d inodes scanned\n", files); - if(inode.inode_type == SQUASHFS_DIR_TYPE) { - if((directory_table = squashfs_readdir(fd, !root_name, sBlk->directory_table_start + inode.start_block, - inode.offset, inode.file_size, sBlk, push_directory_entry)) == NULL) { + if(inode.base.inode_type == SQUASHFS_DIR_TYPE || inode.base.inode_type == SQUASHFS_LDIR_TYPE) { + if(inode.base.inode_type == SQUASHFS_DIR_TYPE) { + *inode_dir_start_block = inode.dir.start_block; + *inode_dir_offset = inode.dir.offset; + *inode_dir_file_size = inode.dir.file_size - 3; + *inode_dir_inode_number = inode.dir.inode_number; + *inode_dir_parent_inode = inode.dir.parent_inode; + } else { + *inode_dir_start_block = inode.ldir.start_block; + *inode_dir_offset = inode.ldir.offset; + *inode_dir_file_size = inode.ldir.file_size - 3; + *inode_dir_inode_number = inode.ldir.inode_number; + *inode_dir_parent_inode = inode.ldir.parent_inode; + } + + if((directory_table = squashfs_readdir(fd, !root_name, *inode_dir_start_block, *inode_dir_offset, + *inode_dir_file_size, last_directory_block, sBlk, push_directory_entry)) == NULL) { ERROR("read_filesystem: Could not read root directory\n"); goto error; } - if((*cinode_table = (char *) malloc(root_inode_start - start)) == NULL) { + root_inode_start -= start; + if((*cinode_table = (char *) malloc(root_inode_start)) == NULL) { ERROR("read_filesystem: failed to alloc space for existing filesystem inode table\n"); goto error; } + read_bytes(fd, start, root_inode_start, *cinode_table); - read_bytes(fd, start, root_inode_start - start, *cinode_table); - - if((*cdirectory_table = (char *) malloc(inode.start_block)) == NULL) { - ERROR("read_filesystem: failed to alloc space for existing filesystem inode table\n"); + if((*cdirectory_table = (char *) malloc(*last_directory_block)) == NULL) { + ERROR("read_filesystem: failed to alloc space for existing filesystem directory table\n"); goto error; } + read_bytes(fd, sBlk->directory_table_start, *last_directory_block, *cdirectory_table); - read_bytes(fd, sBlk->directory_table_start, inode.start_block, *cdirectory_table); - - *inode_bytes = root_inode_start - start; - *directory_bytes = inode.start_block; - - root_inode_offset += sizeof(inode); - root_directory_offset = inode.offset + inode.file_size; - (*dir_count) ++; - - if(((*data_cache = (char *) malloc(root_inode_offset)) == NULL) || - ((*directory_data_cache = (char *) malloc(root_directory_offset)) == NULL)) { - ERROR("read_filesystem: failed to alloc inode/directory caches\n"); + if((*data_cache = (char *) malloc(root_inode_offset + *root_inode_size)) == NULL) { + ERROR("read_filesystem: failed to alloc inode cache\n"); goto error; } + memcpy(*data_cache, inode_table + root_inode_block, root_inode_offset + *root_inode_size); - memcpy(*data_cache, inode_table + root_inode_block, root_inode_offset); - memcpy(*directory_data_cache, directory_table, root_directory_offset); - *cache_size = root_inode_offset; - *directory_cache_size = root_directory_offset; - - if(root_name) { - push_directory_entry(root_name, sBlk->root_inode, SQUASHFS_DIR_TYPE); - *cache_bytes = root_inode_offset; - *directory_cache_bytes = root_directory_offset; - } else { - *cache_bytes = root_inode_offset - sizeof(inode); - *directory_cache_bytes = inode.offset; + if((*directory_data_cache = (char *) malloc(*inode_dir_offset + *inode_dir_file_size)) == NULL) { + ERROR("read_filesystem: failed to alloc directory cache\n"); + goto error; } + memcpy(*directory_data_cache, directory_table, *inode_dir_offset + *inode_dir_file_size); if(!swap) read_bytes(fd, sBlk->uid_start, sBlk->no_uids * sizeof(squashfs_uid), (char *) uids); diff --git a/release/src/linux/linux/scripts/squashfs/read_fs.h b/release/src/linux/linux/scripts/squashfs/read_fs.h index fcc39c35..1b35aed2 100644 --- a/release/src/linux/linux/scripts/squashfs/read_fs.h +++ b/release/src/linux/linux/scripts/squashfs/read_fs.h @@ -3,7 +3,8 @@ * endian and vice versa. These are needed when creating a filesystem on a * machine with different byte ordering to the target architecture. * - * Copyright (c) 2002, 2003, 2004 Phillip Lougher + * Copyright (c) 2002, 2003, 2004, 2005, 2006 + * Phillip Lougher * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/release/src/linux/linux/scripts/squashfs/sort.c b/release/src/linux/linux/scripts/squashfs/sort.c index b5371280..c30093fa 100644 --- a/release/src/linux/linux/scripts/squashfs/sort.c +++ b/release/src/linux/linux/scripts/squashfs/sort.c @@ -1,7 +1,8 @@ /* * Create a squashfs filesystem. This is a highly compressed read only filesystem. * - * Copyright (c) 2002, 2003, 2004 Phillip Lougher + * Copyright (c) 2002, 2003, 2004, 2005 + * Phillip Lougher * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,20 +35,32 @@ #include #include +#include "global.h" +#include "sort.h" #ifdef SQUASHFS_TRACE -#define TRACE(s, args...) printf("mksquashfs: "s, ## args) +#define TRACE(s, args...) do { \ + printf("mksquashfs: "s, ## args); \ + } while(0) #else #define TRACE(s, args...) #endif -#define INFO(s, args...) if(!silent) printf("mksquashfs: "s, ## args) -#define ERROR(s, args...) fprintf(stderr, s, ## args) -#define EXIT_MKSQUASHFS() exit(1) -#define BAD_ERROR(s, args...) {\ - fprintf(stderr, "FATAL ERROR:" s, ##args);\ - EXIT_MKSQUASHFS();\ - } +#define INFO(s, args...) do { \ + if(!silent) printf("mksquashfs: "s, ## args); \ + } while(0) +#define ERROR(s, args...) do { \ + fprintf(stderr, s, ## args); \ + } while(0) +#define EXIT_MKSQUASHFS() do { \ + exit(1); \ + } while(0) +#define BAD_ERROR(s, args...) do {\ + fprintf(stderr, "FATAL ERROR:" s, ##args);\ + EXIT_MKSQUASHFS();\ + } while(0); + +int mkisofs_style = -1; struct sort_info { dev_t st_dev; @@ -59,66 +72,17 @@ struct sort_info { struct sort_info *sort_info_list[65536]; struct priority_entry { - char *filename; - long long size; - ino_t st_ino; - dev_t st_dev; + struct dir_ent *dir; struct priority_entry *next; }; struct priority_entry *priority_list[65536]; -struct sorted_inode_entry { - squashfs_inode inode; - ino_t st_ino; - dev_t st_dev; - struct sorted_inode_entry *next; -}; - -struct sorted_inode_entry *sorted_inode_list[65536]; - extern int silent; -extern int excluded(char *filename, struct stat *buf); -extern squashfs_inode write_file(char *filename, long long size, int *c_size); - - -int add_to_sorted_inode_list(squashfs_inode inode, dev_t st_dev, ino_t st_ino) -{ - int hash = st_ino & 0xffff; - struct sorted_inode_entry *new_sorted_inode_entry; - - if((new_sorted_inode_entry = malloc(sizeof(struct sorted_inode_entry))) == NULL) { - ERROR("Out of memory allocating sorted inode entry\n"); - return FALSE; - } - - new_sorted_inode_entry->inode = inode; - new_sorted_inode_entry->st_ino = st_ino; - new_sorted_inode_entry->st_dev = st_dev; - new_sorted_inode_entry->next = sorted_inode_list[hash]; - sorted_inode_list[hash] = new_sorted_inode_entry; - - return TRUE; -} - - -squashfs_inode get_sorted_inode(struct stat *buf) -{ - int hash = buf->st_ino & 0xffff; - struct sorted_inode_entry *sorted_inode_entry; - - for(sorted_inode_entry = sorted_inode_list[hash]; sorted_inode_entry; sorted_inode_entry = sorted_inode_entry->next) - if(buf->st_ino == sorted_inode_entry->st_ino && buf->st_dev == sorted_inode_entry->st_dev) - break; - - if(sorted_inode_entry) - return sorted_inode_entry->inode; - else - return (squashfs_inode) 0; -} +extern squashfs_inode write_file(squashfs_inode *inode, struct dir_ent *dir_ent, long long size, int *c_size); -int add_priority_list(char *filename, struct stat *buf, int priority) +int add_priority_list(struct dir_ent *dir, int priority) { struct priority_entry *new_priority_entry; @@ -128,10 +92,7 @@ int add_priority_list(char *filename, struct stat *buf, int priority) return FALSE; } - new_priority_entry->filename = strdup(filename); - new_priority_entry->size = buf->st_size; - new_priority_entry->st_dev = buf->st_dev; - new_priority_entry->st_ino = buf->st_ino; + new_priority_entry->dir = dir;; new_priority_entry->next = priority_list[priority]; priority_list[priority] = new_priority_entry; return TRUE; @@ -168,8 +129,8 @@ int get_priority(char *filename, struct stat *buf, int priority) } int add_sort_list(char *path, int priority, int source, char *source_path[]) { - int i; - char buffer[4096], filename[4096]; + int i, n; + char filename[4096]; struct stat buf; TRACE("add_sort_list: filename %s, priority %d\n", path, priority); @@ -177,71 +138,73 @@ int add_sort_list(char *path, int priority, int source, char *source_path[]) path[strlen(path) - 2] = '\0'; TRACE("add_sort_list: filename %s, priority %d\n", path, priority); - if(path[0] == '/' || strncmp(path, "./", 2) == 0 || strncmp(path, "../", 3) == 0) { - if(lstat(path, &buf) == -1) { - sprintf(buffer, "Cannot stat sort_list dir/file %s, ignoring", path); - perror(buffer); - return TRUE; - } - TRACE("adding filename %s, priority %d, st_dev %Lx, st_ino %Lx\n", path, priority, buf.st_dev, buf.st_ino); +re_read: + if(path[0] == '/' || strncmp(path, "./", 2) == 0 || strncmp(path, "../", 3) == 0 || mkisofs_style == 1) { + if(lstat(path, &buf) == -1) + goto error; + TRACE("adding filename %s, priority %d, st_dev %llx, st_ino %llx\n", path, priority, buf.st_dev, buf.st_ino); ADD_ENTRY(buf, priority); return TRUE; } - for(i = 0; i < source; i++) { + for(i = 0, n = 0; i < source; i++) { strcat(strcat(strcpy(filename, source_path[i]), "/"), path); if(lstat(filename, &buf) == -1) { - if(!(errno == ENOENT || errno == ENOTDIR)) { - sprintf(buffer, "Cannot stat sort_list dir/file %s, ignoring", filename); - perror(buffer); - } + if(!(errno == ENOENT || errno == ENOTDIR)) + goto error; continue; } ADD_ENTRY(buf, priority); + n ++; } - return TRUE; + + if(n == 0 && mkisofs_style == -1 && lstat(path, &buf) != -1) { + ERROR("WARNING: Mkisofs style sortlist detected! This is supported but please\n"); + ERROR("convert to mksquashfs style sortlist! A sortlist entry "); + ERROR("should be\neither absolute (starting with "); + ERROR("'/') start with './' or '../' (taken to be\nrelative to $PWD), otherwise it "); + ERROR("is assumed the entry is relative to one\nof the source directories, i.e. with "); + ERROR("\"mksquashfs test test.sqsh\",\nthe sortlist "); + ERROR("entry \"file\" is assumed to be inside the directory test.\n\n"); + mkisofs_style = 1; + goto re_read; + } + + mkisofs_style = 0; + + if(n == 1) + return TRUE; + if(n > 1) + BAD_ERROR(" Ambiguous sortlist entry \"%s\"\n\nIt maps to more than one source entry! Please use an absolute path.\n", path); + +error: + fprintf(stderr, "Cannot stat sortlist entry \"%s\"\n", path); + fprintf(stderr, "This is probably because you're using the wrong file\n"); + fprintf(stderr, "path relative to the source directories\n"); + return FALSE; } -void generate_file_priorities(char *pathname, int priority, struct stat *buf) +void generate_file_priorities(struct dir_info *dir, int priority, struct stat *buf) { - char filename[8192]; - DIR *linuxdir; - struct dirent *d_name; - - priority = get_priority(pathname, buf, priority); - - if((linuxdir = opendir(pathname)) == NULL) { - ERROR("Could not open %s, skipping...\n", pathname); - return; - } - - while((d_name = readdir(linuxdir)) != NULL) { - if(strcmp(d_name->d_name, ".") == 0 || strcmp(d_name->d_name, "..") == 0) - continue; - strcat(strcat(strcpy(filename, pathname), "/"), d_name->d_name); + priority = get_priority(dir->pathname, buf, priority); - if(lstat(filename, buf) == -1) { - char buffer[8192]; - sprintf(buffer, "Cannot stat dir/file %s, ignoring", filename); - perror(buffer); - continue; - } - - if(excluded(filename, buf)) + while(dir->current_count < dir->count) { + struct dir_ent *dir_ent = dir->list[dir->current_count++]; + struct stat *buf = &dir_ent->inode->buf; + if(dir_ent->data) continue; switch(buf->st_mode & S_IFMT) { case S_IFREG: - add_priority_list(filename, buf, get_priority(filename, buf, priority)); + add_priority_list(dir_ent, get_priority(dir_ent->pathname, buf, priority)); break; case S_IFDIR: - generate_file_priorities(filename, priority, buf); + generate_file_priorities(dir_ent->dir, priority, buf); break; } } - - closedir(linuxdir); + dir->current_count = 0; } @@ -265,40 +228,30 @@ int read_sort_file(char *filename, int source, char *source_path[]) } -void sort_files_and_write(int source, char *source_path[]) +void sort_files_and_write(struct dir_info *dir) { - struct stat buf; - int i, c_size; + int i; struct priority_entry *entry; squashfs_inode inode; + int duplicate_file; - for(i = 0; i < source; i++) { - if(lstat(source_path[i], &buf) == -1) { - char buffer[8192]; - sprintf(buffer, "Cannot stat dir/file %s, ignoring", source_path[i]); - perror(buffer); - continue; - } - - if(excluded(source_path[i], &buf)) - continue; - - switch(buf.st_mode & S_IFMT) { - case S_IFREG: - add_priority_list(source_path[i], &buf, get_priority(source_path[i], &buf, 0)); - break; - case S_IFDIR: - generate_file_priorities(source_path[i], 0, &buf); - break; - } - } + generate_file_priorities(dir, 0, &dir->dir_ent->inode->buf); - for(i = 0; i < 65536; i++) + for(i = 65535; i >= 0; i--) for(entry = priority_list[i]; entry; entry = entry->next) { - TRACE("%d: %s\n", i - 32768, entry->filename); - inode = write_file(entry->filename, entry->size, &c_size); - INFO("file %s, size %d bytes, inode 0x%Lx\n", entry->filename, c_size, inode); - INFO("\t%.2f%% of uncompressed file size (%Ld bytes)\n", ((float) c_size / entry->size) * 100.0, entry->size); - add_to_sorted_inode_list(inode, entry->st_dev, entry->st_ino); + TRACE("%d: %s\n", i - 32768, entry->dir->pathname); + if(entry->dir->inode->inode == SQUASHFS_INVALID_BLK) { + if(write_file(&inode, entry->dir, entry->dir->inode->buf.st_size, + &duplicate_file)) { + INFO("file %s, uncompressed size %lld bytes %s\n", + entry->dir->pathname, + entry->dir->inode->buf.st_size, + duplicate_file ? "DUPLICATE" : ""); + entry->dir->inode->inode = inode; + entry->dir->inode->type = SQUASHFS_FILE_TYPE; + } + } else + INFO("file %s, uncompressed size %lld bytes LINK\n", + entry->dir->pathname, entry->dir->inode->buf.st_size); } } diff --git a/release/src/linux/linux/scripts/squashfs/sort.h b/release/src/linux/linux/scripts/squashfs/sort.h new file mode 100644 index 00000000..561c320b --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/sort.h @@ -0,0 +1,56 @@ +#ifndef SORT_H +#define SORT_H + +/* + * Squashfs + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006 + * Phillip Lougher + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * sort.h + */ + +struct dir_info { + char *pathname; + unsigned int count; + unsigned int directory_count; + unsigned int current_count; + unsigned int byte_count; + char dir_is_ldir; + struct dir_ent *dir_ent; + struct dir_ent **list; + DIR *linuxdir; +}; + +struct dir_ent { + char *name; + char *pathname; + struct inode_info *inode; + struct dir_info *dir; + struct dir_info *our_dir; + struct old_root_entry_info *data; +}; + +struct inode_info { + unsigned int nlink; + struct stat buf; + squashfs_inode inode; + unsigned int type; + unsigned int inode_number; + struct inode_info *next; +}; +#endif diff --git a/release/src/linux/linux/scripts/squashfs/squashfs_fs.h b/release/src/linux/linux/scripts/squashfs/squashfs_fs.h index d810c596..fbbb53c1 100644 --- a/release/src/linux/linux/scripts/squashfs/squashfs_fs.h +++ b/release/src/linux/linux/scripts/squashfs/squashfs_fs.h @@ -1,9 +1,11 @@ #ifndef SQUASHFS_FS #define SQUASHFS_FS + /* * Squashfs * - * Copyright (c) 2002, 2003, 2004 Phillip Lougher + * Copyright (c) 2002, 2003, 2004, 2005, 2006 + * Phillip Lougher * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,7 +24,7 @@ * squashfs_fs.h */ -#define SQUASHFS_MAJOR 2 +#define SQUASHFS_MAJOR 3 #define SQUASHFS_MINOR 0 #define SQUASHFS_MAGIC 0x73717368 #define SQUASHFS_MAGIC_SWAP 0x68737173 @@ -46,8 +48,9 @@ #define SQUASHFS_NAME_LEN 256 #define SQUASHFS_INVALID ((long long) 0xffffffffffff) -#define SQUASHFS_INVALID_BLK ((long long) 0xffffffff) -#define SQUASHFS_USED_BLK ((long long) 0xfffffffe) +#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff) +#define SQUASHFS_INVALID_BLK ((long long) -1) +#define SQUASHFS_USED_BLK ((long long) -2) /* Filesystem flags */ #define SQUASHFS_NOI 0 @@ -57,15 +60,34 @@ #define SQUASHFS_NO_FRAG 4 #define SQUASHFS_ALWAYS_FRAG 5 #define SQUASHFS_DUPLICATE 6 + #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) -#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, SQUASHFS_NOI) -#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, SQUASHFS_NOD) -#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_NOF) -#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_NO_FRAG) -#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_ALWAYS_FRAG) -#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, SQUASHFS_DUPLICATE) -#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, SQUASHFS_CHECK) -#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, duplicate_checking) (noi | (nod << 1) | (check_data << 2) | (nof << 3) | (no_frag << 4) | (always_frag << 5) | (duplicate_checking << 6)) + +#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOI) + +#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOD) + +#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOF) + +#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NO_FRAG) + +#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_ALWAYS_FRAG) + +#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_DUPLICATE) + +#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_CHECK) + +#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \ + duplicate_checking) (noi | (nod << 1) | (check_data << 2) \ + | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \ + (duplicate_checking << 6)) /* Max number of types and file types */ #define SQUASHFS_DIR_TYPE 1 @@ -75,53 +97,74 @@ #define SQUASHFS_CHRDEV_TYPE 5 #define SQUASHFS_FIFO_TYPE 6 #define SQUASHFS_SOCKET_TYPE 7 +#define SQUASHFS_LDIR_TYPE 8 +#define SQUASHFS_LREG_TYPE 9 /* 1.0 filesystem type definitions */ #define SQUASHFS_TYPES 5 #define SQUASHFS_IPC_TYPE 0 -/* Flag whether block is compressed or uncompressed, bit is set if block is uncompressed */ +/* Flag whether block is compressed or uncompressed, bit is set if block is + * uncompressed */ #define SQUASHFS_COMPRESSED_BIT (1 << 15) + #define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ - (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) + (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) #define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) #define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) -#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? \ - (B) & ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK) -#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) +#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \ + ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \ + ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK) + +#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) /* - * Inode number ops. Inodes consist of a compressed block number, and an uncompressed - * offset within that block + * Inode number ops. Inodes consist of a compressed block number, and an + * uncompressed offset within that block */ #define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16)) + #define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff)) -#define SQUASHFS_MKINODE(A, B) ((squashfs_inode)(((squashfs_inode) (A) << 16)\ - + (B))) + +#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\ + << 16) + (B))) /* Compute 32 bit VFS inode number from squashfs inode number */ -#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + ((b) >> 2) + 1)) +#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \ + ((b) >> 2) + 1)) +/* XXX */ /* Translate between VFS mode and squashfs mode */ #define SQUASHFS_MODE(a) ((a) & 0xfff) /* fragment and fragment table defines */ -typedef unsigned int squashfs_fragment_index; -#define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(squashfs_fragment_entry)) -#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / SQUASHFS_METADATA_SIZE) -#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % SQUASHFS_METADATA_SIZE) -#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + SQUASHFS_METADATA_SIZE - 1) / SQUASHFS_METADATA_SIZE) -#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) * sizeof(squashfs_fragment_index)) +#define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(struct squashfs_fragment_entry)) + +#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\ + sizeof(long long)) + #define SQUASHFS_CACHED_FRAGMENTS 3 /* cached data constants for filesystem */ #define SQUASHFS_CACHED_BLKS 8 -#define SQUASHFS_MAX_FILE_SIZE_LOG 32 -#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << (SQUASHFS_MAX_FILE_SIZE_LOG - 1)) +#define SQUASHFS_MAX_FILE_SIZE_LOG 64 + +#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \ + (SQUASHFS_MAX_FILE_SIZE_LOG - 2)) #define SQUASHFS_MARKER_BYTE 0xff @@ -129,19 +172,17 @@ typedef unsigned int squashfs_fragment_index; * definitions for structures on disk */ -typedef unsigned int squashfs_block; -typedef long long squashfs_inode; - -typedef unsigned int squashfs_uid; +typedef long long squashfs_block_t; +typedef long long squashfs_inode_t; -typedef struct squashfs_super_block { +struct squashfs_super_block { unsigned int s_magic; unsigned int inodes; - unsigned int bytes_used; - unsigned int uid_start; - unsigned int guid_start; - unsigned int inode_table_start; - unsigned int directory_table_start; + unsigned int bytes_used_2; + unsigned int uid_start_2; + unsigned int guid_start_2; + unsigned int inode_table_start_2; + unsigned int directory_table_start_2; unsigned int s_major:16; unsigned int s_minor:16; unsigned int block_size_1:16; @@ -150,88 +191,125 @@ typedef struct squashfs_super_block { unsigned int no_uids:8; unsigned int no_guids:8; unsigned int mkfs_time /* time of filesystem creation */; - squashfs_inode root_inode; + squashfs_inode_t root_inode; unsigned int block_size; unsigned int fragments; - unsigned int fragment_table_start; -} __attribute__ ((packed)) squashfs_super_block; - -typedef struct { - unsigned int inode_type:4; - unsigned int mode:12; /* protection */ - unsigned int uid:8; /* index into uid table */ - unsigned int guid:8; /* index into guid table */ -} __attribute__ ((packed)) squashfs_base_inode_header; - -typedef squashfs_base_inode_header squashfs_ipc_inode_header; - -typedef struct { - unsigned int inode_type:4; - unsigned int mode:12; /* protection */ - unsigned int uid:8; /* index into uid table */ - unsigned int guid:8; /* index into guid table */ + unsigned int fragment_table_start_2; + long long bytes_used; + long long uid_start; + long long guid_start; + long long inode_table_start; + long long directory_table_start; + long long fragment_table_start; + long long unused; +} __attribute__ ((packed)); + +struct squashfs_dir_index { + unsigned int index; + unsigned int start_block; + unsigned char size; + unsigned char name[0]; +} __attribute__ ((packed)); + +#define SQUASHFS_BASE_INODE_HEADER \ + unsigned int inode_type:4; \ + unsigned int mode:12; \ + unsigned int uid:8; \ + unsigned int guid:8; \ + unsigned int mtime; \ + unsigned int inode_number; + +struct squashfs_base_inode_header { + SQUASHFS_BASE_INODE_HEADER; +} __attribute__ ((packed)); + +struct squashfs_ipc_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; +} __attribute__ ((packed)); + +struct squashfs_dev_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; unsigned short rdev; -} __attribute__ ((packed)) squashfs_dev_inode_header; +} __attribute__ ((packed)); -typedef struct { - unsigned int inode_type:4; - unsigned int mode:12; /* protection */ - unsigned int uid:8; /* index into uid table */ - unsigned int guid:8; /* index into guid table */ +struct squashfs_symlink_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; unsigned short symlink_size; char symlink[0]; -} __attribute__ ((packed)) squashfs_symlink_inode_header; +} __attribute__ ((packed)); -typedef struct { - unsigned int inode_type:4; - unsigned int mode:12; /* protection */ - unsigned int uid:8; /* index into uid table */ - unsigned int guid:8; /* index into guid table */ - unsigned int mtime; - squashfs_block start_block; +struct squashfs_reg_inode_header { + SQUASHFS_BASE_INODE_HEADER; + squashfs_block_t start_block; unsigned int fragment; unsigned int offset; - unsigned int file_size:SQUASHFS_MAX_FILE_SIZE_LOG; + unsigned int file_size; unsigned short block_list[0]; -} __attribute__ ((packed)) squashfs_reg_inode_header; +} __attribute__ ((packed)); -typedef struct { - unsigned int inode_type:4; - unsigned int mode:12; /* protection */ - unsigned int uid:8; /* index into uid table */ - unsigned int guid:8; /* index into guid table */ +struct squashfs_lreg_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + squashfs_block_t start_block; + unsigned int fragment; + unsigned int offset; + long long file_size; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; unsigned int file_size:19; unsigned int offset:13; - unsigned int mtime; - unsigned int start_block:24; -} __attribute__ ((packed)) squashfs_dir_inode_header; - -typedef union { - squashfs_base_inode_header base; - squashfs_dev_inode_header dev; - squashfs_symlink_inode_header symlink; - squashfs_reg_inode_header reg; - squashfs_dir_inode_header dir; - squashfs_ipc_inode_header ipc; -} squashfs_inode_header; + unsigned int start_block; + unsigned int parent_inode; +} __attribute__ ((packed)); + +struct squashfs_ldir_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned int file_size:27; + unsigned int offset:13; + unsigned int start_block; + unsigned int i_count:16; + unsigned int parent_inode; + struct squashfs_dir_index index[0]; +} __attribute__ ((packed)); + +union squashfs_inode_header { + struct squashfs_base_inode_header base; + struct squashfs_dev_inode_header dev; + struct squashfs_symlink_inode_header symlink; + struct squashfs_reg_inode_header reg; + struct squashfs_lreg_inode_header lreg; + struct squashfs_dir_inode_header dir; + struct squashfs_ldir_inode_header ldir; + struct squashfs_ipc_inode_header ipc; +}; -typedef struct { +struct squashfs_dir_entry { unsigned int offset:13; unsigned int type:3; unsigned int size:8; + int inode_number:16; char name[0]; -} __attribute__ ((packed)) squashfs_dir_entry; +} __attribute__ ((packed)); -typedef struct { +struct squashfs_dir_header { unsigned int count:8; - unsigned int start_block:24; -} __attribute__ ((packed)) squashfs_dir_header; - - -typedef struct { unsigned int start_block; + unsigned int inode_number; +} __attribute__ ((packed)); + +struct squashfs_fragment_entry { + long long start_block; unsigned int size; -} __attribute__ ((packed)) squashfs_fragment_entry; + unsigned int unused; +} __attribute__ ((packed)); extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); extern int squashfs_uncompress_init(void); @@ -239,20 +317,28 @@ extern int squashfs_uncompress_exit(void); /* * macros to convert each packed bitfield structure from little endian to big - * endian and vice versa. These are needed when creating or using a filesystem on a - * machine with different byte ordering to the target architecture. + * endian and vice versa. These are needed when creating or using a filesystem + * on a machine with different byte ordering to the target architecture. * */ +#define SQUASHFS_SWAP_START \ + int bits;\ + int b_pos;\ + unsigned long long val;\ + unsigned char *s;\ + unsigned char *d; + #define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ - SQUASHFS_MEMSET(s, d, sizeof(squashfs_super_block));\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ - SQUASHFS_SWAP((s)->bytes_used, d, 64, 32);\ - SQUASHFS_SWAP((s)->uid_start, d, 96, 32);\ - SQUASHFS_SWAP((s)->guid_start, d, 128, 32);\ - SQUASHFS_SWAP((s)->inode_table_start, d, 160, 32);\ - SQUASHFS_SWAP((s)->directory_table_start, d, 192, 32);\ + SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\ + SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\ + SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\ + SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\ + SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ @@ -264,137 +350,218 @@ extern int squashfs_uncompress_exit(void); SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ - SQUASHFS_SWAP((s)->fragment_table_start, d, 472, 32);\ + SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\ + SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\ + SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\ + SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\ + SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\ + SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\ + SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\ + SQUASHFS_SWAP((s)->unused, d, 888, 64);\ } -#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ +#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ SQUASHFS_MEMSET(s, d, n);\ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ + SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ + SQUASHFS_SWAP((s)->inode_number, d, 64, 32); + +#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ } -#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_ipc_inode_header)) +#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_ipc_inode_header))\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ +} #define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dev_inode_header));\ - SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_dev_inode_header)); \ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->rdev, d, 128, 16);\ } #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_symlink_inode_header));\ - SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_symlink_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\ } #define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_reg_inode_header));\ - SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ - SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ - SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ - SQUASHFS_SWAP((s)->offset, d, 128, 32);\ - SQUASHFS_SWAP((s)->file_size, d, 160, SQUASHFS_MAX_FILE_SIZE_LOG);\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_reg_inode_header));\ + SQUASHFS_SWAP((s)->start_block, d, 96, 64);\ + SQUASHFS_SWAP((s)->fragment, d, 160, 32);\ + SQUASHFS_SWAP((s)->offset, d, 192, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 224, 32);\ +} + +#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_lreg_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 128, 64);\ + SQUASHFS_SWAP((s)->fragment, d, 192, 32);\ + SQUASHFS_SWAP((s)->offset, d, 224, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 256, 64);\ } #define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dir_inode_header));\ - SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ - SQUASHFS_SWAP((s)->offset, d, 51, 13);\ - SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ - SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_dir_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 128, 19);\ + SQUASHFS_SWAP((s)->offset, d, 147, 13);\ + SQUASHFS_SWAP((s)->start_block, d, 160, 32);\ + SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\ +} + +#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_ldir_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 128, 27);\ + SQUASHFS_SWAP((s)->offset, d, 155, 13);\ + SQUASHFS_SWAP((s)->start_block, d, 168, 32);\ + SQUASHFS_SWAP((s)->i_count, d, 200, 16);\ + SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\ +} + +#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\ + SQUASHFS_SWAP((s)->index, d, 0, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 32, 32);\ + SQUASHFS_SWAP((s)->size, d, 64, 8);\ } #define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ - SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_header));\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\ SQUASHFS_SWAP((s)->count, d, 0, 8);\ - SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ + SQUASHFS_SWAP((s)->start_block, d, 8, 32);\ + SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\ } #define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ - SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_entry));\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ SQUASHFS_SWAP((s)->type, d, 13, 3);\ SQUASHFS_SWAP((s)->size, d, 16, 8);\ + SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\ } #define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ - SQUASHFS_MEMSET(s, d, sizeof(squashfs_fragment_entry));\ - SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ - SQUASHFS_SWAP((s)->size, d, 32, 32);\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\ + SQUASHFS_SWAP((s)->start_block, d, 0, 64);\ + SQUASHFS_SWAP((s)->size, d, 64, 32);\ } #define SQUASHFS_SWAP_SHORTS(s, d, n) {\ int entry;\ int bit_position;\ + SQUASHFS_SWAP_START\ SQUASHFS_MEMSET(s, d, n * 2);\ - for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += 16)\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 16)\ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ } #define SQUASHFS_SWAP_INTS(s, d, n) {\ int entry;\ int bit_position;\ + SQUASHFS_SWAP_START\ SQUASHFS_MEMSET(s, d, n * 4);\ - for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += 32)\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 32)\ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ } +#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * 8);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 64)\ + SQUASHFS_SWAP(s[entry], d, bit_position, 64);\ +} + #define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ int entry;\ int bit_position;\ + SQUASHFS_SWAP_START\ SQUASHFS_MEMSET(s, d, n * bits / 8);\ - for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += bits)\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + bits)\ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ } -#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) +#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) + +#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY -#ifdef SQUASHFS_1_0_COMPATIBILITY -typedef struct { +struct squashfs_base_inode_header_1 { unsigned int inode_type:4; unsigned int mode:12; /* protection */ unsigned int uid:4; /* index into uid table */ unsigned int guid:4; /* index into guid table */ -} __attribute__ ((packed)) squashfs_base_inode_header_1; +} __attribute__ ((packed)); -typedef struct { +struct squashfs_ipc_inode_header_1 { unsigned int inode_type:4; unsigned int mode:12; /* protection */ unsigned int uid:4; /* index into uid table */ unsigned int guid:4; /* index into guid table */ unsigned int type:4; unsigned int offset:4; -} __attribute__ ((packed)) squashfs_ipc_inode_header_1; +} __attribute__ ((packed)); -typedef struct { +struct squashfs_dev_inode_header_1 { unsigned int inode_type:4; unsigned int mode:12; /* protection */ unsigned int uid:4; /* index into uid table */ unsigned int guid:4; /* index into guid table */ unsigned short rdev; -} __attribute__ ((packed)) squashfs_dev_inode_header_1; +} __attribute__ ((packed)); -typedef struct { +struct squashfs_symlink_inode_header_1 { unsigned int inode_type:4; unsigned int mode:12; /* protection */ unsigned int uid:4; /* index into uid table */ unsigned int guid:4; /* index into guid table */ unsigned short symlink_size; char symlink[0]; -} __attribute__ ((packed)) squashfs_symlink_inode_header_1; +} __attribute__ ((packed)); -typedef struct { +struct squashfs_reg_inode_header_1 { unsigned int inode_type:4; unsigned int mode:12; /* protection */ unsigned int uid:4; /* index into uid table */ unsigned int guid:4; /* index into guid table */ unsigned int mtime; - squashfs_block start_block; - unsigned int file_size:SQUASHFS_MAX_FILE_SIZE_LOG; + unsigned int start_block; + unsigned int file_size:32; unsigned short block_list[0]; -} __attribute__ ((packed)) squashfs_reg_inode_header_1; +} __attribute__ ((packed)); -typedef struct { +struct squashfs_dir_inode_header_1 { unsigned int inode_type:4; unsigned int mode:12; /* protection */ unsigned int uid:4; /* index into uid table */ @@ -403,72 +570,308 @@ typedef struct { unsigned int offset:13; unsigned int mtime; unsigned int start_block:24; -} __attribute__ ((packed)) squashfs_dir_inode_header_1; +} __attribute__ ((packed)); -#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ +#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \ SQUASHFS_MEMSET(s, d, n);\ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ SQUASHFS_SWAP((s)->uid, d, 16, 4);\ - SQUASHFS_SWAP((s)->guid, d, 20, 4);\ + SQUASHFS_SWAP((s)->guid, d, 20, 4); + +#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\ } #define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, sizeof(squashfs_ipc_inode_header_1));\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_ipc_inode_header_1));\ SQUASHFS_SWAP((s)->type, d, 24, 4);\ SQUASHFS_SWAP((s)->offset, d, 28, 4);\ } #define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, sizeof(squashfs_dev_inode_header_1));\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_dev_inode_header_1));\ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ } #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_symlink_inode_header_1));\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_symlink_inode_header_1));\ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ } #define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_reg_inode_header_1));\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_reg_inode_header_1));\ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ SQUASHFS_SWAP((s)->file_size, d, 88, SQUASHFS_MAX_FILE_SIZE_LOG);\ } #define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ - SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dir_inode_header_1));\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_dir_inode_header_1));\ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ SQUASHFS_SWAP((s)->offset, d, 43, 13);\ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ } + +#endif + +#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY + +struct squashfs_dir_index_2 { + unsigned int index:27; + unsigned int start_block:29; + unsigned char size; + unsigned char name[0]; +} __attribute__ ((packed)); + +struct squashfs_base_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ +} __attribute__ ((packed)); + +struct squashfs_ipc_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ +} __attribute__ ((packed)); + +struct squashfs_dev_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned short rdev; +} __attribute__ ((packed)); + +struct squashfs_symlink_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned short symlink_size; + char symlink[0]; +} __attribute__ ((packed)); + +struct squashfs_reg_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int mtime; + unsigned int start_block; + unsigned int fragment; + unsigned int offset; + unsigned int file_size:32; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int file_size:19; + unsigned int offset:13; + unsigned int mtime; + unsigned int start_block:24; +} __attribute__ ((packed)); + +struct squashfs_ldir_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int file_size:27; + unsigned int offset:13; + unsigned int mtime; + unsigned int start_block:24; + unsigned int i_count:16; + struct squashfs_dir_index_2 index[0]; +} __attribute__ ((packed)); + +union squashfs_inode_header_2 { + struct squashfs_base_inode_header_2 base; + struct squashfs_dev_inode_header_2 dev; + struct squashfs_symlink_inode_header_2 symlink; + struct squashfs_reg_inode_header_2 reg; + struct squashfs_dir_inode_header_2 dir; + struct squashfs_ldir_inode_header_2 ldir; + struct squashfs_ipc_inode_header_2 ipc; +}; + +struct squashfs_dir_header_2 { + unsigned int count:8; + unsigned int start_block:24; +} __attribute__ ((packed)); + +struct squashfs_dir_entry_2 { + unsigned int offset:13; + unsigned int type:3; + unsigned int size:8; + char name[0]; +} __attribute__ ((packed)); + +struct squashfs_fragment_entry_2 { + unsigned int start_block; + unsigned int size; +} __attribute__ ((packed)); + +#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ + SQUASHFS_MEMSET(s, d, n);\ + SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ + SQUASHFS_SWAP((s)->mode, d, 4, 12);\ + SQUASHFS_SWAP((s)->uid, d, 16, 8);\ + SQUASHFS_SWAP((s)->guid, d, 24, 8);\ + +#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ +} + +#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \ + SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2)) + +#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_dev_inode_header_2)); \ + SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ +} + +#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_symlink_inode_header_2));\ + SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ +} + +#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_reg_inode_header_2));\ + SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ + SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ + SQUASHFS_SWAP((s)->offset, d, 128, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 160, SQUASHFS_MAX_FILE_SIZE_LOG);\ +} + +#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_dir_inode_header_2));\ + SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ + SQUASHFS_SWAP((s)->offset, d, 51, 13);\ + SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ +} + +#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_ldir_inode_header_2));\ + SQUASHFS_SWAP((s)->file_size, d, 32, 27);\ + SQUASHFS_SWAP((s)->offset, d, 59, 13);\ + SQUASHFS_SWAP((s)->mtime, d, 72, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 104, 24);\ + SQUASHFS_SWAP((s)->i_count, d, 128, 16);\ +} + +#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\ + SQUASHFS_SWAP((s)->index, d, 0, 27);\ + SQUASHFS_SWAP((s)->start_block, d, 27, 29);\ + SQUASHFS_SWAP((s)->size, d, 56, 8);\ +} +#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\ + SQUASHFS_SWAP((s)->count, d, 0, 8);\ + SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ +} + +#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\ + SQUASHFS_SWAP((s)->offset, d, 0, 13);\ + SQUASHFS_SWAP((s)->type, d, 13, 3);\ + SQUASHFS_SWAP((s)->size, d, 16, 8);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\ + SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ + SQUASHFS_SWAP((s)->size, d, 32, 32);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) + +/* fragment and fragment table defines */ +#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2)) + +#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\ + sizeof(int)) + #endif #ifdef __KERNEL__ + /* * macros used to swap each structure entry, taking into account - * bitfields and different bitfield placing conventions on differing architectures + * bitfields and different bitfield placing conventions on differing + * architectures */ + #include + #ifdef __BIG_ENDIAN /* convert from little endian to big endian */ -#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, b_pos) +#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ + tbits, b_pos) #else /* convert from big endian to little endian */ -#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, 64 - tbits - b_pos) +#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ + tbits, 64 - tbits - b_pos) #endif #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ - int bits;\ - int b_pos = pos % 8;\ - unsigned long long val = 0;\ - unsigned char *s = (unsigned char *)p + (pos / 8);\ - unsigned char *d = ((unsigned char *) &val) + 7;\ + b_pos = pos % 8;\ + val = 0;\ + s = (unsigned char *)p + (pos / 8);\ + d = ((unsigned char *) &val) + 7;\ for(bits = 0; bits < (tbits + b_pos); bits += 8) \ *d-- = *s++;\ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ } + #define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); + #endif #endif diff --git a/release/src/linux/linux/scripts/squashfs/unsquashfs.c b/release/src/linux/linux/scripts/squashfs/unsquashfs.c new file mode 100644 index 00000000..dae8fd62 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/unsquashfs.c @@ -0,0 +1,946 @@ +/* + * Unsquash a squashfs filesystem. This is a highly compressed read only filesystem. + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006 + * Phillip Lougher + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * unsquash.c + */ + +#define TRUE 1 +#define FALSE 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef linux +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#else +#include +#endif + +#include +#include "read_fs.h" +#include "global.h" + +#include + +#ifdef SQUASHFS_TRACE +#define TRACE(s, args...) do { \ + printf("mksquashfs: "s, ## args); \ + } while(0) +#else +#define TRACE(s, args...) +#endif + +#define ERROR(s, args...) do { \ + fprintf(stderr, s, ## args); \ + } while(0) + +#define EXIT_UNSQUASH(s, args...) do { \ + fprintf(stderr, "FATAL ERROR aborting: "s, ## args); \ + } while(0) + +struct hash_table_entry { + int start; + int bytes; + struct hash_table_entry *next; +}; + +int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0, dev_count = 0, fifo_count = 0; +char *inode_table = NULL, *directory_table = NULL; +struct hash_table_entry *inode_table_hash[65536], *directory_table_hash[65536]; +int fd; +squashfs_fragment_entry *fragment_table; +unsigned int *uid_table, *guid_table; +unsigned int cached_frag = SQUASHFS_INVALID_FRAG; +char *fragment_data; +char *file_data; +char *data; +unsigned int block_size; +int lsonly = FALSE, info = FALSE; +char **created_inode; + +#define CALCULATE_HASH(start) (start & 0xffff) + +int add_entry(struct hash_table_entry *hash_table[], int start, int bytes) +{ + int hash = CALCULATE_HASH(start); + struct hash_table_entry *hash_table_entry; + + if((hash_table_entry = malloc(sizeof(struct hash_table_entry))) == NULL) { + ERROR("add_hash: out of memory in malloc\n"); + return FALSE; + } + + hash_table_entry->start = start; + hash_table_entry->bytes = bytes; + hash_table_entry->next = hash_table[hash]; + hash_table[hash] = hash_table_entry; + + return TRUE; +} + + +int lookup_entry(struct hash_table_entry *hash_table[], int start) +{ + int hash = CALCULATE_HASH(start); + struct hash_table_entry *hash_table_entry; + + for(hash_table_entry = hash_table[hash]; hash_table_entry; hash_table_entry = hash_table_entry->next) + if(hash_table_entry->start == start) + return hash_table_entry->bytes; + + return -1; +} + + +int read_bytes(long long byte, int bytes, char *buff) +{ + off_t off = byte; + + TRACE("read_bytes: reading from position 0x%llx, bytes %d\n", byte, bytes); + + if(lseek(fd, off, SEEK_SET) == -1) { + ERROR("Lseek failed because %s\b", strerror(errno)); + return FALSE; + } + + if(read(fd, buff, bytes) == -1) { + ERROR("Read on destination failed because %s\n", strerror(errno)); + return FALSE; + } + + return TRUE; +} + + +int read_block(long long start, long long *next, char *block, squashfs_super_block *sBlk) +{ + unsigned short c_byte; + int offset = 2; + + if(swap) { + if(read_bytes(start, 2, block) == FALSE) + goto failed; + ((unsigned char *) &c_byte)[1] = block[0]; + ((unsigned char *) &c_byte)[0] = block[1]; + } else + if(read_bytes(start, 2, (char *)&c_byte) == FALSE) + goto failed; + + TRACE("read_block: block @0x%llx, %d %s bytes\n", start, SQUASHFS_COMPRESSED_SIZE(c_byte), SQUASHFS_COMPRESSED(c_byte) ? "compressed" : "uncompressed"); + + if(SQUASHFS_CHECK_DATA(sBlk->flags)) + offset = 3; + if(SQUASHFS_COMPRESSED(c_byte)) { + char buffer[SQUASHFS_METADATA_SIZE]; + int res; + unsigned long bytes = SQUASHFS_METADATA_SIZE; + + c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); + if(read_bytes(start + offset, c_byte, buffer) == FALSE) + goto failed; + + if((res = uncompress((unsigned char *) block, &bytes, (const unsigned char *) buffer, c_byte)) != Z_OK) { + if(res == Z_MEM_ERROR) + ERROR("zlib::uncompress failed, not enough memory\n"); + else if(res == Z_BUF_ERROR) + ERROR("zlib::uncompress failed, not enough room in output buffer\n"); + else + ERROR("zlib::uncompress failed, unknown error %d\n", res); + goto failed; + } + if(next) + *next = start + offset + c_byte; + return bytes; + } else { + c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); + if(read_bytes(start + offset, c_byte, block) == FALSE) + goto failed; + if(next) + *next = start + offset + c_byte; + return c_byte; + } + +failed: + return FALSE; +} + + +int read_data_block(long long start, unsigned int size, char *block) +{ + int res; + unsigned long bytes = block_size; + int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size); + + TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start, SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte), SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" : "uncompressed"); + + if(SQUASHFS_COMPRESSED_BLOCK(size)) { + if(read_bytes(start, c_byte, data) == FALSE) + return 0; + + if((res = uncompress((unsigned char *) block, &bytes, (const unsigned char *) data, c_byte)) != Z_OK) { + if(res == Z_MEM_ERROR) + ERROR("zlib::uncompress failed, not enough memory\n"); + else if(res == Z_BUF_ERROR) + ERROR("zlib::uncompress failed, not enough room in output buffer\n"); + else + ERROR("zlib::uncompress failed, unknown error %d\n", res); + return 0; + } + + return bytes; + } else { + if(read_bytes(start, c_byte, block) == FALSE) + return 0; + + return c_byte; + } +} + + +void uncompress_inode_table(long long start, long long end, squashfs_super_block *sBlk) +{ + int size = 0, bytes = 0, res; + + while(start < end) { + if((size - bytes < SQUASHFS_METADATA_SIZE) && + ((inode_table = realloc(inode_table, size += SQUASHFS_METADATA_SIZE)) == NULL)) + EXIT_UNSQUASH("uncompress_inode_table: out of memory in realloc\n"); + TRACE("uncompress_inode_table: reading block 0x%llx\n", start); + add_entry(inode_table_hash, start, bytes); + if((res = read_block(start, &start, inode_table + bytes, sBlk)) == 0) { + free(inode_table); + EXIT_UNSQUASH("uncompress_inode_table: failed to read block\n"); + } + bytes += res; + } +} + + +int set_attributes(char *pathname, unsigned int mode, unsigned int uid, unsigned int guid, +unsigned int mtime, unsigned int set_mode) +{ + struct utimbuf times = { (time_t) mtime, (time_t) mtime }; + + if(utime(pathname, ×) == -1) { + ERROR("set_attributes: failed to set time on %s, because %s\n", pathname, strerror(errno)); + return FALSE; + } + + if(set_mode && chmod(pathname, (mode_t) mode) == -1) { + ERROR("set_attributes: failed to change mode %s, because %s\n", pathname, strerror(errno)); + return FALSE; + } + + if(geteuid() == 0) { + uid_t uid_value = (uid_t) uid_table[uid]; + uid_t guid_value = guid == SQUASHFS_GUIDS ? uid_value : (uid_t) guid_table[guid]; + + if(chown(pathname, uid_value, guid_value) == -1) { + ERROR("set_attributes: failed to change uid and gids on %s, because %s\n", pathname, strerror(errno)); + return FALSE; + } + } + + return TRUE; +} + + +void read_uids_guids(squashfs_super_block *sBlk) +{ + if((uid_table = malloc((sBlk->no_uids + sBlk->no_guids) * sizeof(unsigned int))) == NULL) + EXIT_UNSQUASH("read_uids_guids: failed to allocate uid/gid table\n"); + + guid_table = uid_table + sBlk->no_uids; + + if(read_bytes(sBlk->uid_start, (sBlk->no_uids + sBlk->no_guids) * sizeof(unsigned int), (char *) uid_table) == + FALSE) + EXIT_UNSQUASH("read_uids_guids: failed to read uid/gid table\n"); +} + + +void read_fragment_table(squashfs_super_block *sBlk) +{ + int i, indexes = SQUASHFS_FRAGMENT_INDEXES(sBlk->fragments); + squashfs_fragment_index fragment_table_index[indexes]; + + TRACE("read_fragment_table: %d fragments, reading %d fragment indexes from 0x%llx\n", sBlk->fragments, indexes, sBlk->fragment_table_start); + if(sBlk->fragments == 0) + return; + + if((fragment_table = (squashfs_fragment_entry *) malloc(sBlk->fragments * sizeof(squashfs_fragment_entry))) == NULL) + EXIT_UNSQUASH("read_fragment_table: failed to allocate fragment table\n"); + + if(swap) { + squashfs_fragment_index sfragment_table_index[indexes]; + + read_bytes(sBlk->fragment_table_start, SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments), (char *) sfragment_table_index); + SQUASHFS_SWAP_FRAGMENT_INDEXES(fragment_table_index, sfragment_table_index, indexes); + } else + read_bytes(sBlk->fragment_table_start, SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments), (char *) fragment_table_index); + + for(i = 0; i < indexes; i++) { + int length = read_block(fragment_table_index[i], NULL, ((char *) fragment_table) + (i * SQUASHFS_METADATA_SIZE), sBlk); + TRACE("Read fragment table block %d, from 0x%llx, length %d\n", i, fragment_table_index[i], length); + } + + if(swap) { + squashfs_fragment_entry sfragment; + for(i = 0; i < sBlk->fragments; i++) { + SQUASHFS_SWAP_FRAGMENT_ENTRY((&sfragment), (&fragment_table[i])); + memcpy((char *) &fragment_table[i], (char *) &sfragment, sizeof(squashfs_fragment_entry)); + } + } +} + + +char *read_fragment(unsigned int fragment) +{ + TRACE("read_fragment: reading fragment %d\n", fragment); + + if(cached_frag == SQUASHFS_INVALID_FRAG || fragment != cached_frag) { + squashfs_fragment_entry *fragment_entry = &fragment_table[fragment]; + if(read_data_block(fragment_entry->start_block, fragment_entry->size, fragment_data) == 0) { + ERROR("read_fragment: failed to read fragment %d\n", fragment); + cached_frag = SQUASHFS_INVALID_FRAG; + return NULL; + } + cached_frag = fragment; + } + + return fragment_data; +} + + +int write_file(char *pathname, unsigned int fragment, unsigned int frag_bytes, unsigned int offset, +unsigned int blocks, long long start, char *block_ptr, unsigned int mode) +{ + unsigned int file_fd, bytes, i; + unsigned int *block_list; + + TRACE("write_file: regular file, blocks %d\n", blocks); + + if((block_list = malloc(blocks * sizeof(unsigned int))) == NULL) { + ERROR("write_file: unable to malloc block list\n"); + return FALSE; + } + + if(swap) { + unsigned int sblock_list[blocks]; + memcpy(sblock_list, block_ptr, blocks * sizeof(unsigned int)); + SQUASHFS_SWAP_INTS(block_list, sblock_list, blocks); + } else + memcpy(block_list, block_ptr, blocks * sizeof(unsigned int)); + + if((file_fd = open(pathname, O_CREAT | O_WRONLY, (mode_t) mode)) == -1) { + ERROR("write_file: failed to create file %s, because %s\n", pathname, + strerror(errno)); + free(block_list); + return FALSE; + } + + for(i = 0; i < blocks; i++) { + if((bytes = read_data_block(start, block_list[i], file_data)) == 0) { + ERROR("write_file: failed to read data block 0x%llx\n", start); + goto failure; + } + + if(write(file_fd, file_data, bytes) < bytes) { + ERROR("write_file: failed to write data block 0x%llx\n", start); + goto failure; + } + + start += SQUASHFS_COMPRESSED_SIZE_BLOCK(block_list[i]); + } + + if(frag_bytes != 0) { + char *fragment_data = read_fragment(fragment); + + if(fragment_data == NULL) + goto failure; + + if(write(file_fd, fragment_data + offset, frag_bytes) < frag_bytes) { + ERROR("write_file: failed to write fragment %d\n", fragment); + goto failure; + } + } + + close(file_fd); + return TRUE; + +failure: + close(file_fd); + free(block_list); + return FALSE; +} + + +int create_inode(char *pathname, unsigned int start_block, unsigned int offset, squashfs_super_block *sBlk) +{ + long long start = sBlk->inode_table_start + start_block; + squashfs_inode_header header; + char *block_ptr; + int bytes = lookup_entry(inode_table_hash, start), file_fd; + + TRACE("create_inode: pathname %s, start 0x%llx, offset %d\n", pathname, start, offset); + + if(bytes == -1) { + ERROR("create_inode: inode block 0x%llx out of range!\n", start); + return FALSE; + } + block_ptr = inode_table + bytes + offset; + + if(swap) { + squashfs_base_inode_header sinode; + memcpy(&sinode, block_ptr, sizeof(header.base)); + SQUASHFS_SWAP_BASE_INODE_HEADER(&header.base, &sinode, sizeof(squashfs_base_inode_header)); + } else + memcpy(&header.base, block_ptr, sizeof(header.base)); + + if(created_inode[header.base.inode_number - 1]) { + TRACE("create_inode: hard link\n"); + if(link(created_inode[header.base.inode_number - 1], pathname) == -1) { + ERROR("create_inode: failed to create hardlink, because %s\n", strerror(errno)); + return FALSE; + } + + return TRUE; + } + + switch(header.base.inode_type) { + case SQUASHFS_FILE_TYPE: { + unsigned int frag_bytes; + unsigned int blocks; + unsigned int offset; + long long start; + squashfs_reg_inode_header *inode = &header.reg; + + if(swap) { + squashfs_reg_inode_header sinode; + memcpy(&sinode, block_ptr, sizeof(sinode)); + SQUASHFS_SWAP_REG_INODE_HEADER(inode, &sinode); + } else + memcpy(inode, block_ptr, sizeof(*inode)); + + frag_bytes = inode->fragment == SQUASHFS_INVALID_FRAG ? 0 : inode->file_size % sBlk->block_size; + offset = inode->offset; + blocks = inode->fragment == SQUASHFS_INVALID_FRAG ? (inode->file_size + + sBlk->block_size - 1) >> sBlk->block_log : inode->file_size >> + sBlk->block_log; + start = inode->start_block; + + TRACE("create_inode: regular file, file_size %lld, blocks %d\n", inode->file_size, blocks); + + if(write_file(pathname, inode->fragment, frag_bytes, offset, blocks, start, + block_ptr + sizeof(*inode), inode->mode)) { + set_attributes(pathname, inode->mode, inode->uid, inode->guid, inode->mtime, FALSE); + file_count ++; + } + break; + } + case SQUASHFS_LREG_TYPE: { + unsigned int frag_bytes; + unsigned int blocks; + unsigned int offset; + long long start; + squashfs_lreg_inode_header *inode = &header.lreg; + + if(swap) { + squashfs_lreg_inode_header sinode; + memcpy(&sinode, block_ptr, sizeof(sinode)); + SQUASHFS_SWAP_LREG_INODE_HEADER(inode, &sinode); + } else + memcpy(inode, block_ptr, sizeof(*inode)); + + frag_bytes = inode->fragment == SQUASHFS_INVALID_FRAG ? 0 : inode->file_size % sBlk->block_size; + offset = inode->offset; + blocks = inode->fragment == SQUASHFS_INVALID_FRAG ? (inode->file_size + + sBlk->block_size - 1) >> sBlk->block_log : inode->file_size >> + sBlk->block_log; + start = inode->start_block; + + TRACE("create_inode: regular file, file_size %lld, blocks %d\n", inode->file_size, blocks); + + if(write_file(pathname, inode->fragment, frag_bytes, offset, blocks, start, + block_ptr + sizeof(*inode), inode->mode)) { + set_attributes(pathname, inode->mode, inode->uid, inode->guid, inode->mtime, FALSE); + file_count ++; + } + break; + } + case SQUASHFS_SYMLINK_TYPE: { + squashfs_symlink_inode_header *inodep = &header.symlink; + char name[65536]; + + if(swap) { + squashfs_symlink_inode_header sinodep; + memcpy(&sinodep, block_ptr, sizeof(sinodep)); + SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, &sinodep); + } else + memcpy(inodep, block_ptr, sizeof(*inodep)); + + TRACE("create_inode: symlink, symlink_size %d\n", inodep->symlink_size); + + strncpy(name, block_ptr + sizeof(squashfs_symlink_inode_header), inodep->symlink_size); + name[inodep->symlink_size] = '\0'; + + if(symlink(name, pathname) == -1) { + ERROR("create_inode: failed to create symlink %s, because %s\n", pathname, + strerror(errno)); + break; + } + + if(geteuid() == 0) { + uid_t uid_value = (uid_t) uid_table[inodep->uid]; + uid_t guid_value = inodep->guid == SQUASHFS_GUIDS ? uid_value : (uid_t) guid_table[inodep->guid]; + + if(lchown(pathname, uid_value, guid_value) == -1) + ERROR("create_inode: failed to change uid and gids on %s, because %s\n", pathname, strerror(errno)); + } + + sym_count ++; + break; + } + case SQUASHFS_BLKDEV_TYPE: + case SQUASHFS_CHRDEV_TYPE: { + squashfs_dev_inode_header *inodep = &header.dev; + + if(swap) { + squashfs_dev_inode_header sinodep; + memcpy(&sinodep, block_ptr, sizeof(sinodep)); + SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, &sinodep); + } else + memcpy(inodep, block_ptr, sizeof(*inodep)); + + TRACE("create_inode: dev, rdev 0x%x\n", inodep->rdev); + + if(geteuid() == 0) { + if(mknod(pathname, inodep->inode_type == SQUASHFS_CHRDEV_TYPE ? S_IFCHR : S_IFBLK, + makedev((inodep->rdev >> 8) & 0xff, inodep->rdev & 0xff)) + == -1) { + ERROR("create_inode: failed to create %s device %s, because %s\n", + inodep->inode_type == SQUASHFS_CHRDEV_TYPE ? "character" : "block", + pathname, strerror(errno)); + break; + } + set_attributes(pathname, inodep->mode, inodep->uid, inodep->guid, inodep->mtime, TRUE); + dev_count ++; + } else + ERROR("create_inode: could not create %s device %s, because you're not superuser!\n", + inodep->inode_type == SQUASHFS_CHRDEV_TYPE ? "character" : "block", + pathname, strerror(errno)); + break; + } + case SQUASHFS_FIFO_TYPE: + TRACE("create_inode: fifo\n"); + + if(mknod(pathname, S_IFIFO, 0) == -1) { + ERROR("create_inode: failed to create fifo %s, because %s\n", + pathname, strerror(errno)); + break; + } + set_attributes(pathname, header.base.mode, header.base.uid, header.base.guid, + header.base.mtime, TRUE); + fifo_count ++; + break; + case SQUASHFS_SOCKET_TYPE: + TRACE("create_inode: socket\n"); + ERROR("create_inode: socket %s ignored\n", pathname); + break; + default: + ERROR("Unknown inode type %d in create_inode_table!\n", header.base.inode_type); + return FALSE; + } + + created_inode[header.base.inode_number - 1] = strdup(pathname); + + return TRUE; +} + + +void uncompress_directory_table(long long start, long long end, squashfs_super_block *sBlk) +{ + int bytes = 0, size = 0, res; + + while(start < end) { + if(size - bytes < SQUASHFS_METADATA_SIZE && (directory_table = realloc(directory_table, size += SQUASHFS_METADATA_SIZE)) == NULL) + EXIT_UNSQUASH("uncompress_directory_table: out of memory in realloc\n"); + TRACE("uncompress_directory_table: reading block 0x%llx\n", start); + add_entry(directory_table_hash, start, bytes); + if((res = read_block(start, &start, directory_table + bytes, sBlk)) == 0) + EXIT_UNSQUASH("uncompress_directory_table: failed to read block\n"); + bytes += res; + } +} + + +#define DIR_ENT_SIZE 16 + +struct dir_ent { + char name[SQUASHFS_NAME_LEN + 1]; + unsigned int start_block; + unsigned int offset; + unsigned int type; +}; + +struct dir { + int dir_count; + int cur_entry; + unsigned int mode; + unsigned int uid; + unsigned int guid; + unsigned int mtime; + struct dir_ent *dirs; +}; + + +struct dir *squashfs_openddir(unsigned int block_start, unsigned int offset, squashfs_super_block *sBlk) +{ + squashfs_dir_header dirh; + char buffer[sizeof(squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1]; + squashfs_dir_entry *dire = (squashfs_dir_entry *) buffer; + long long start = sBlk->inode_table_start + block_start; + char *block_ptr; + int bytes = lookup_entry(inode_table_hash, start); + squashfs_inode_header header; + int dir_count, size; + struct dir_ent *new_dir; + struct dir *dir; + + TRACE("squashfs_opendir: inode start block %d, offset %d\n", block_start, offset); + + if(bytes == -1) { + ERROR("squashfs_opendir: inode block %d not found!\n", block_start); + return NULL; + } + block_ptr = inode_table + bytes + offset; + + if(swap) { + squashfs_dir_inode_header sinode; + memcpy(&sinode, block_ptr, sizeof(header.dir)); + SQUASHFS_SWAP_DIR_INODE_HEADER(&header.dir, &sinode); + } else + memcpy(&header.dir, block_ptr, sizeof(header.dir)); + + switch(header.dir.inode_type) { + case SQUASHFS_DIR_TYPE: + block_start = header.dir.start_block; + offset = header.dir.offset; + size = header.dir.file_size; + break; + case SQUASHFS_LDIR_TYPE: + if(swap) { + squashfs_ldir_inode_header sinode; + memcpy(&sinode, block_ptr, sizeof(header.ldir)); + SQUASHFS_SWAP_LDIR_INODE_HEADER(&header.ldir, &sinode); + } else + memcpy(&header.ldir, block_ptr, sizeof(header.ldir)); + block_start = header.ldir.start_block; + offset = header.ldir.offset; + size = header.ldir.file_size; + break; + default: + ERROR("squashfs_opendir: inode not a directory\n"); + return NULL; + } + + start = sBlk->directory_table_start + block_start; + bytes = lookup_entry(directory_table_hash, start); + + if(bytes == -1) { + ERROR("squashfs_opendir: directory block %d not found!\n", block_start); + return NULL; + } + bytes += offset; + size += bytes - 3; + + if((dir = malloc(sizeof(struct dir))) == NULL) { + ERROR("squashfs_opendir: malloc failed!\n"); + return NULL; + } + + dir->dir_count = 0; + dir->cur_entry = 0; + dir->mode = header.dir.mode; + dir->uid = header.dir.uid; + dir->guid = header.dir.guid; + dir->mtime = header.dir.mtime; + dir->dirs = NULL; + + while(bytes < size) { + if(swap) { + squashfs_dir_header sdirh; + memcpy(&sdirh, directory_table + bytes, sizeof(sdirh)); + SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); + } else + memcpy(&dirh, directory_table + bytes, sizeof(dirh)); + + dir_count = dirh.count + 1; + TRACE("squashfs_opendir: Read directory header @ byte position %d, %d directory entries\n", bytes, dir_count); + bytes += sizeof(dirh); + + while(dir_count--) { + if(swap) { + squashfs_dir_entry sdire; + memcpy(&sdire, directory_table + bytes, sizeof(sdire)); + SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); + } else + memcpy(dire, directory_table + bytes, sizeof(dire)); + bytes += sizeof(*dire); + + memcpy(dire->name, directory_table + bytes, dire->size + 1); + dire->name[dire->size + 1] = '\0'; + TRACE("squashfs_opendir: directory entry %s, inode %d:%d, type %d\n", dire->name, dirh.start_block, dire->offset, dire->type); + if((dir->dir_count % DIR_ENT_SIZE) == 0) { + if((new_dir = realloc(dir->dirs, (dir->dir_count + DIR_ENT_SIZE) * sizeof(struct dir_ent))) == NULL) { + ERROR("squashfs_opendir: realloc failed!\n"); + free(dir->dirs); + free(dir); + return NULL; + } + dir->dirs = new_dir; + } + strcpy(dir->dirs[dir->dir_count].name, dire->name); + dir->dirs[dir->dir_count].start_block = dirh.start_block; + dir->dirs[dir->dir_count].offset = dire->offset; + dir->dirs[dir->dir_count].type = dire->type; + dir->dir_count ++; + bytes += dire->size + 1; + } + } + + return dir; +} + + +int squashfs_readdir(struct dir *dir, char **name, unsigned int *start_block, unsigned int *offset, unsigned int *type) +{ + if(dir->cur_entry == dir->dir_count) + return FALSE; + + *name = dir->dirs[dir->cur_entry].name; + *start_block = dir->dirs[dir->cur_entry].start_block; + *offset = dir->dirs[dir->cur_entry].offset; + *type = dir->dirs[dir->cur_entry].type; + dir->cur_entry ++; + + return TRUE; +} + + +void squashfs_closedir(struct dir *dir) +{ + free(dir->dirs); + free(dir); +} + + +int dir_scan(char *parent_name, unsigned int start_block, unsigned int offset, squashfs_super_block *sBlk) +{ + struct dir *dir = squashfs_openddir(start_block, offset, sBlk); + unsigned int type; + char *name, pathname[1024]; + + if(dir == NULL) { + ERROR("dir_scan: Failed to read directory %s (%x:%x)\n", parent_name, start_block, offset); + return FALSE; + } + + if(!lsonly && mkdir(parent_name, (mode_t) dir->mode) == -1) { + ERROR("dir_scan: failed to open directory %s, because %s\n", parent_name, strerror(errno)); + return FALSE; + } + + while(squashfs_readdir(dir, &name, &start_block, &offset, &type)) { + TRACE("dir_scan: name %s, start_block %d, offset %d, type %d\n", name, start_block, offset, type); + + strcat(strcat(strcpy(pathname, parent_name), "/"), name); + + if(lsonly || info) + printf("%s\n", pathname); + + if(type == SQUASHFS_DIR_TYPE) + dir_scan(pathname, start_block, offset, sBlk); + else + if(!lsonly) + create_inode(pathname, start_block, offset, sBlk); + } + + !lsonly && set_attributes(parent_name, dir->mode, dir->uid, dir->guid, dir->mtime, TRUE); + + squashfs_closedir(dir); + dir_count ++; + + return TRUE; +} + + +int read_super(squashfs_super_block *sBlk, char *source) +{ + read_bytes(SQUASHFS_START, sizeof(squashfs_super_block), (char *) sBlk); + + /* Check it is a SQUASHFS superblock */ + swap = 0; + if(sBlk->s_magic != SQUASHFS_MAGIC) { + if(sBlk->s_magic == SQUASHFS_MAGIC_SWAP) { + squashfs_super_block sblk; + ERROR("Reading a different endian SQUASHFS filesystem on %s\n", source); + SQUASHFS_SWAP_SUPER_BLOCK(&sblk, sBlk); + memcpy(sBlk, &sblk, sizeof(squashfs_super_block)); + swap = 1; + } else { + ERROR("Can't find a SQUASHFS superblock on %s\n", source); + goto failed_mount; + } + } + + /* Check the MAJOR & MINOR versions */ + if(sBlk->s_major != SQUASHFS_MAJOR || sBlk->s_minor > SQUASHFS_MINOR) { + ERROR("Major/Minor mismatch, filesystem on %s is (%d:%d)\n", + source, sBlk->s_major, sBlk->s_minor); + ERROR("I only support Squashfs 3.0 filesystems! Later releases will support older Squashfs filesystems\n"); + goto failed_mount; + } + +#if __BYTE_ORDER == __BIG_ENDIAN + TRACE("Found a valid %s endian SQUASHFS superblock on %s.\n", swap ? "little" : "big", source); +#else + TRACE("Found a valid %s endian SQUASHFS superblock on %s.\n", swap ? "big" : "little", source); +#endif + + TRACE("\tInodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : ""); + TRACE("\tData is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sBlk->flags) ? "un" : ""); + TRACE("\tFragments are %scompressed\n", SQUASHFS_UNCOMPRESSED_FRAGMENTS(sBlk->flags) ? "un" : ""); + TRACE("\tCheck data is %s present in the filesystem\n", SQUASHFS_CHECK_DATA(sBlk->flags) ? "" : "not"); + TRACE("\tFragments are %s present in the filesystem\n", SQUASHFS_NO_FRAGMENTS(sBlk->flags) ? "not" : ""); + TRACE("\tAlways_use_fragments option is %s specified\n", SQUASHFS_ALWAYS_FRAGMENTS(sBlk->flags) ? "" : "not"); + TRACE("\tDuplicates are %s removed\n", SQUASHFS_DUPLICATES(sBlk->flags) ? "" : "not"); + TRACE("\tFilesystem size %.2f Kbytes (%.2f Mbytes)\n", sBlk->bytes_used / 1024.0, sBlk->bytes_used / (1024.0 * 1024.0)); + TRACE("\tBlock size %d\n", sBlk->block_size); + TRACE("\tNumber of fragments %d\n", sBlk->fragments); + TRACE("\tNumber of inodes %d\n", sBlk->inodes); + TRACE("\tNumber of uids %d\n", sBlk->no_uids); + TRACE("\tNumber of gids %d\n", sBlk->no_guids); + TRACE("sBlk->inode_table_start 0x%llx\n", sBlk->inode_table_start); + TRACE("sBlk->directory_table_start 0x%llx\n", sBlk->directory_table_start); + TRACE("sBlk->uid_start 0x%llx\n", sBlk->uid_start); + TRACE("sBlk->fragment_table_start 0x%llx\n", sBlk->fragment_table_start); + TRACE("\n"); + + return TRUE; + +failed_mount: + return FALSE; +} + + +#define VERSION() \ + printf("unsquashfs version 1.0 (2006/03/15)\n");\ + printf("copyright (C) 2006 Phillip Lougher \n\n"); \ + printf("This program is free software; you can redistribute it and/or\n");\ + printf("modify it under the terms of the GNU General Public License\n");\ + printf("as published by the Free Software Foundation; either version 2,\n");\ + printf("or (at your option) any later version.\n\n");\ + printf("This program is distributed in the hope that it will be useful,\n");\ + printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");\ + printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");\ + printf("GNU General Public License for more details.\n"); +int main(int argc, char *argv[]) +{ + squashfs_super_block sBlk; + char *dest = "squashfs-root"; + int i, version = FALSE; + + for(i = 1; i < argc; i++) { + if(*argv[i] != '-') + break; + if(strcmp(argv[i], "-version") == 0) { + VERSION(); + version = TRUE; + } else if(strcmp(argv[i], "-info") == 0) + info = TRUE; + else if(strcmp(argv[i], "-ls") == 0) + lsonly = TRUE; + else if(strcmp(argv[i], "-dest") == 0) { + if(++i == argc) + goto options; + dest = argv[i]; + } + } + + if(i == argc) { + if(!version) { +options: + ERROR("SYNTAX: %s [-ls | -dest] filesystem\n", argv[0]); + ERROR("\t-version\t\tprint version, licence and copyright information\n"); + ERROR("\t-info\t\t\tprint files as they are unsquashed\n"); + ERROR("\t-ls\t\t\tlist filesystem only\n"); + ERROR("\t-dest \tunsquash to , default \"squashfs-root\"\n"); + } + exit(1); + } + + if((fd = open(argv[i], O_RDONLY)) == -1) { + ERROR("Could not open %s, because %s\n", argv[i], strerror(errno)); + exit(1); + } + + if(read_super(&sBlk, argv[i]) == FALSE) + exit(1); + + block_size = sBlk.block_size; + if((fragment_data = malloc(block_size)) == NULL) + EXIT_UNSQUASH("failed to allocate fragment_data\n"); + + if((file_data = malloc(block_size)) == NULL) + EXIT_UNSQUASH("failed to allocate file_data"); + + if((data = malloc(block_size)) == NULL) + EXIT_UNSQUASH("failed to allocate datan\n"); + + if((created_inode = malloc(sBlk.inodes * sizeof(char *))) == NULL) + EXIT_UNSQUASH("failed to allocate created_inode\n"); + + memset(created_inode, 0, sBlk.inodes * sizeof(char *)); + + read_uids_guids(&sBlk); + read_fragment_table(&sBlk); + uncompress_inode_table(sBlk.inode_table_start, sBlk.directory_table_start, &sBlk); + uncompress_directory_table(sBlk.directory_table_start, sBlk.fragment_table_start, &sBlk); + + dir_scan(dest, SQUASHFS_INODE_BLK(sBlk.root_inode), SQUASHFS_INODE_OFFSET(sBlk.root_inode), &sBlk); + + if(!lsonly) { + printf("\n"); + printf("created %d files\n", file_count); + printf("created %d directories\n", dir_count); + printf("created %d symlinks\n", sym_count); + printf("created %d devices\n", dev_count); + printf("created %d fifos\n", fifo_count); + } + +} -- cgit v1.2.3-54-g00ecf