summaryrefslogtreecommitdiff
path: root/src/com/github/junrar/unpack/Unpack.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/github/junrar/unpack/Unpack.java')
-rw-r--r--src/com/github/junrar/unpack/Unpack.java1051
1 files changed, 0 insertions, 1051 deletions
diff --git a/src/com/github/junrar/unpack/Unpack.java b/src/com/github/junrar/unpack/Unpack.java
deleted file mode 100644
index fdf5eb4..0000000
--- a/src/com/github/junrar/unpack/Unpack.java
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
- * Original author: Edmund Wagner
- * Creation date: 31.05.2007
- *
- * Source: $HeadURL$
- * Last changed: $LastChangedDate$
- *
- * the unrar licence applies to all junrar source and binary distributions
- * you are not allowed to use this source to re-create the RAR compression algorithm
- *
- * Here some html entities which can be used for escaping javadoc tags:
- * "&": "&" or "&"
- * "<": "&#060;" or "&lt;"
- * ">": "&#062;" or "&gt;"
- * "@": "&#064;"
- */
-package com.github.junrar.unpack;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Vector;
-
-import com.github.junrar.exception.RarException;
-import com.github.junrar.unpack.decode.Compress;
-import com.github.junrar.unpack.ppm.BlockTypes;
-import com.github.junrar.unpack.ppm.ModelPPM;
-import com.github.junrar.unpack.ppm.SubAllocator;
-import com.github.junrar.unpack.vm.BitInput;
-import com.github.junrar.unpack.vm.RarVM;
-import com.github.junrar.unpack.vm.VMPreparedProgram;
-
-
-/**
- * DOCUMENT ME
- *
- * @author $LastChangedBy$
- * @version $LastChangedRevision$
- */
-public final class Unpack extends Unpack20 {
-
- private final ModelPPM ppm = new ModelPPM();
-
- private int ppmEscChar;
-
- private RarVM rarVM = new RarVM();
-
- /* Filters code, one entry per filter */
- private List<UnpackFilter> filters = new ArrayList<UnpackFilter>();
-
- /* Filters stack, several entrances of same filter are possible */
- private List<UnpackFilter> prgStack = new ArrayList<UnpackFilter>();
-
- /*
- * lengths of preceding blocks, one length per filter. Used to reduce size
- * required to write block length if lengths are repeating
- */
- private List<Integer> oldFilterLengths = new ArrayList<Integer>();
-
- private int lastFilter;
-
- private boolean tablesRead;
-
- private byte[] unpOldTable = new byte[Compress.HUFF_TABLE_SIZE];
-
- private BlockTypes unpBlockType;
-
- private boolean externalWindow;
-
- private long writtenFileSize;
-
- private boolean fileExtracted;
-
- private boolean ppmError;
-
- private int prevLowDist;
-
- private int lowDistRepCount;
-
- public static int[] DBitLengthCounts = { 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 14, 0, 12 };
-
- public Unpack(ComprDataIO DataIO) {
- unpIO = DataIO;
- window = null;
- externalWindow = false;
- suspended = false;
- unpAllBuf = false;
- unpSomeRead = false;
- }
-
- public void init(byte[] window) {
- if (window == null) {
- this.window = new byte[Compress.MAXWINSIZE];
- } else {
- this.window = window;
- externalWindow = true;
- }
- inAddr = 0;
- unpInitData(false);
- }
-
- public void doUnpack(int method, boolean solid) throws IOException,
- RarException {
- if (unpIO.getSubHeader().getUnpMethod() == 0x30) {
- unstoreFile();
- }
- switch (method) {
- case 15: // rar 1.5 compression
- unpack15(solid);
- break;
- case 20: // rar 2.x compression
- case 26: // files larger than 2GB
- unpack20(solid);
- break;
- case 29: // rar 3.x compression
- case 36: // alternative hash
- unpack29(solid);
- break;
- }
- }
-
- private void unstoreFile() throws IOException, RarException {
- byte[] buffer = new byte[0x10000];
- while (true) {
- int code = unpIO.unpRead(buffer, 0, (int) Math.min(buffer.length,
- destUnpSize));
- if (code == 0 || code == -1)
- break;
- code = code < destUnpSize ? code : (int) destUnpSize;
- unpIO.unpWrite(buffer, 0, code);
- if (destUnpSize >= 0)
- destUnpSize -= code;
- }
-
- }
-
- private void unpack29(boolean solid) throws IOException, RarException {
-
- int[] DDecode = new int[Compress.DC];
- byte[] DBits = new byte[Compress.DC];
-
- int Bits;
-
- if (DDecode[1] == 0) {
- int Dist = 0, BitLength = 0, Slot = 0;
- for (int I = 0; I < DBitLengthCounts.length; I++, BitLength++) {
- int count = DBitLengthCounts[I];
- for (int J = 0; J < count; J++, Slot++, Dist += (1 << BitLength)) {
- DDecode[Slot] = Dist;
- DBits[Slot] = (byte) BitLength;
- }
- }
- }
-
- fileExtracted = true;
-
- if (!suspended) {
- unpInitData(solid);
- if (!unpReadBuf()) {
- return;
- }
- if ((!solid || !tablesRead) && !readTables()) {
- return;
- }
- }
-
- if (ppmError) {
- return;
- }
-
- while (true) {
- unpPtr &= Compress.MAXWINMASK;
-
- if (inAddr > readBorder) {
- if (!unpReadBuf()) {
- break;
- }
- }
- // System.out.println(((wrPtr - unpPtr) &
- // Compress.MAXWINMASK)+":"+wrPtr+":"+unpPtr);
- if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 260
- && wrPtr != unpPtr) {
-
- UnpWriteBuf();
- if (writtenFileSize > destUnpSize) {
- return;
- }
- if (suspended) {
- fileExtracted = false;
- return;
- }
- }
- if (unpBlockType == BlockTypes.BLOCK_PPM) {
- int Ch = ppm.decodeChar();
- if (Ch == -1) {
- ppmError = true;
- break;
- }
- if (Ch == ppmEscChar) {
- int NextCh = ppm.decodeChar();
- if (NextCh == 0) {
- if (!readTables()) {
- break;
- }
- continue;
- }
- if (NextCh == 2 || NextCh == -1) {
- break;
- }
- if (NextCh == 3) {
- if (!readVMCodePPM()) {
- break;
- }
- continue;
- }
- if (NextCh == 4) {
- int Distance = 0, Length = 0;
- boolean failed = false;
- for (int I = 0; I < 4 && !failed; I++) {
- int ch = ppm.decodeChar();
- if (ch == -1) {
- failed = true;
- } else {
- if (I == 3) {
- // Bug fixed
- Length = ch & 0xff;
- } else {
- // Bug fixed
- Distance = (Distance << 8) + (ch & 0xff);
- }
- }
- }
- if (failed) {
- break;
- }
- copyString(Length + 32, Distance + 2);
- continue;
- }
- if (NextCh == 5) {
- int Length = ppm.decodeChar();
- if (Length == -1) {
- break;
- }
- copyString(Length + 4, 1);
- continue;
- }
- }
- window[unpPtr++] = (byte) Ch;
- continue;
- }
-
- int Number = decodeNumber(LD);
- if (Number < 256) {
- window[unpPtr++] = (byte) Number;
- continue;
- }
- if (Number >= 271) {
- int Length = LDecode[Number -= 271] + 3;
- if ((Bits = LBits[Number]) > 0) {
- Length += getbits() >>> (16 - Bits);
- addbits(Bits);
- }
-
- int DistNumber = decodeNumber(DD);
- int Distance = DDecode[DistNumber] + 1;
- if ((Bits = DBits[DistNumber]) > 0) {
- if (DistNumber > 9) {
- if (Bits > 4) {
- Distance += ((getbits() >>> (20 - Bits)) << 4);
- addbits(Bits - 4);
- }
- if (lowDistRepCount > 0) {
- lowDistRepCount--;
- Distance += prevLowDist;
- } else {
- int LowDist = decodeNumber(LDD);
- if (LowDist == 16) {
- lowDistRepCount = Compress.LOW_DIST_REP_COUNT - 1;
- Distance += prevLowDist;
- } else {
- Distance += LowDist;
- prevLowDist = LowDist;
- }
- }
- } else {
- Distance += getbits() >>> (16 - Bits);
- addbits(Bits);
- }
- }
-
- if (Distance >= 0x2000) {
- Length++;
- if (Distance >= 0x40000L) {
- Length++;
- }
- }
-
- insertOldDist(Distance);
- insertLastMatch(Length, Distance);
-
- copyString(Length, Distance);
- continue;
- }
- if (Number == 256) {
- if (!readEndOfBlock()) {
- break;
- }
- continue;
- }
- if (Number == 257) {
- if (!readVMCode()) {
- break;
- }
- continue;
- }
- if (Number == 258) {
- if (lastLength != 0) {
- copyString(lastLength, lastDist);
- }
- continue;
- }
- if (Number < 263) {
- int DistNum = Number - 259;
- int Distance = oldDist[DistNum];
- for (int I = DistNum; I > 0; I--) {
- oldDist[I] = oldDist[I - 1];
- }
- oldDist[0] = Distance;
-
- int LengthNumber = decodeNumber(RD);
- int Length = LDecode[LengthNumber] + 2;
- if ((Bits = LBits[LengthNumber]) > 0) {
- Length += getbits() >>> (16 - Bits);
- addbits(Bits);
- }
- insertLastMatch(Length, Distance);
- copyString(Length, Distance);
- continue;
- }
- if (Number < 272) {
- int Distance = SDDecode[Number -= 263] + 1;
- if ((Bits = SDBits[Number]) > 0) {
- Distance += getbits() >>> (16 - Bits);
- addbits(Bits);
- }
- insertOldDist(Distance);
- insertLastMatch(2, Distance);
- copyString(2, Distance);
- continue;
- }
- }
- UnpWriteBuf();
-
- }
-
- private void UnpWriteBuf() throws IOException {
- int WrittenBorder = wrPtr;
- int WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;
- for (int I = 0; I < prgStack.size(); I++) {
- UnpackFilter flt = prgStack.get(I);
- if (flt == null) {
- continue;
- }
- if (flt.isNextWindow()) {
- flt.setNextWindow(false);// ->NextWindow=false;
- continue;
- }
- int BlockStart = flt.getBlockStart();// ->BlockStart;
- int BlockLength = flt.getBlockLength();// ->BlockLength;
- if (((BlockStart - WrittenBorder) & Compress.MAXWINMASK) < WriteSize) {
- if (WrittenBorder != BlockStart) {
- UnpWriteArea(WrittenBorder, BlockStart);
- WrittenBorder = BlockStart;
- WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;
- }
- if (BlockLength <= WriteSize) {
- int BlockEnd = (BlockStart + BlockLength)
- & Compress.MAXWINMASK;
- if (BlockStart < BlockEnd || BlockEnd == 0) {
- // VM.SetMemory(0,Window+BlockStart,BlockLength);
- rarVM.setMemory(0, window, BlockStart, BlockLength);
- } else {
- int FirstPartLength = Compress.MAXWINSIZE - BlockStart;
- // VM.SetMemory(0,Window+BlockStart,FirstPartLength);
- rarVM.setMemory(0, window, BlockStart, FirstPartLength);
- // VM.SetMemory(FirstPartLength,Window,BlockEnd);
- rarVM.setMemory(FirstPartLength, window, 0, BlockEnd);
-
- }
-
- VMPreparedProgram ParentPrg = filters.get(
- flt.getParentFilter()).getPrg();
- VMPreparedProgram Prg = flt.getPrg();
-
- if (ParentPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) {
- // copy global data from previous script execution if
- // any
- // Prg->GlobalData.Alloc(ParentPrg->GlobalData.Size());
- // memcpy(&Prg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
- Prg.getGlobalData().setSize(
- ParentPrg.getGlobalData().size());
- for (int i = 0; i < ParentPrg.getGlobalData().size()
- - RarVM.VM_FIXEDGLOBALSIZE; i++) {
- Prg.getGlobalData().set(
- RarVM.VM_FIXEDGLOBALSIZE + i,
- ParentPrg.getGlobalData().get(
- RarVM.VM_FIXEDGLOBALSIZE + i));
- }
- }
-
- ExecuteCode(Prg);
-
- if (Prg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) {
- // save global data for next script execution
- if (ParentPrg.getGlobalData().size() < Prg
- .getGlobalData().size()) {
- ParentPrg.getGlobalData().setSize(
- Prg.getGlobalData().size());// ->GlobalData.Alloc(Prg->GlobalData.Size());
- }
- // memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&Prg->GlobalData[VM_FIXEDGLOBALSIZE],Prg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
- for (int i = 0; i < Prg.getGlobalData().size()
- - RarVM.VM_FIXEDGLOBALSIZE; i++) {
- ParentPrg.getGlobalData().set(
- RarVM.VM_FIXEDGLOBALSIZE + i,
- Prg.getGlobalData().get(
- RarVM.VM_FIXEDGLOBALSIZE + i));
- }
- } else {
- ParentPrg.getGlobalData().clear();
- }
-
- int FilteredDataOffset = Prg.getFilteredDataOffset();
- int FilteredDataSize = Prg.getFilteredDataSize();
- byte[] FilteredData = new byte[FilteredDataSize];
-
- for (int i = 0; i < FilteredDataSize; i++) {
- FilteredData[i] = rarVM.getMem()[FilteredDataOffset + i];// Prg.getGlobalData().get(FilteredDataOffset
- // +
- // i);
- }
-
- prgStack.set(I, null);
- while (I + 1 < prgStack.size()) {
- UnpackFilter NextFilter = prgStack.get(I + 1);
- if (NextFilter == null
- || NextFilter.getBlockStart() != BlockStart
- || NextFilter.getBlockLength() != FilteredDataSize
- || NextFilter.isNextWindow()) {
- break;
- }
- // apply several filters to same data block
-
- rarVM.setMemory(0, FilteredData, 0, FilteredDataSize);// .SetMemory(0,FilteredData,FilteredDataSize);
-
- VMPreparedProgram pPrg = filters.get(
- NextFilter.getParentFilter()).getPrg();
- VMPreparedProgram NextPrg = NextFilter.getPrg();
-
- if (pPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) {
- // copy global data from previous script execution
- // if any
- // NextPrg->GlobalData.Alloc(ParentPrg->GlobalData.Size());
- NextPrg.getGlobalData().setSize(
- pPrg.getGlobalData().size());
- // memcpy(&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
- for (int i = 0; i < pPrg.getGlobalData().size()
- - RarVM.VM_FIXEDGLOBALSIZE; i++) {
- NextPrg.getGlobalData().set(
- RarVM.VM_FIXEDGLOBALSIZE + i,
- pPrg.getGlobalData().get(
- RarVM.VM_FIXEDGLOBALSIZE + i));
- }
- }
-
- ExecuteCode(NextPrg);
-
- if (NextPrg.getGlobalData().size() > RarVM.VM_FIXEDGLOBALSIZE) {
- // save global data for next script execution
- if (pPrg.getGlobalData().size() < NextPrg
- .getGlobalData().size()) {
- pPrg.getGlobalData().setSize(
- NextPrg.getGlobalData().size());
- }
- // memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],NextPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
- for (int i = 0; i < NextPrg.getGlobalData().size()
- - RarVM.VM_FIXEDGLOBALSIZE; i++) {
- pPrg.getGlobalData().set(
- RarVM.VM_FIXEDGLOBALSIZE + i,
- NextPrg.getGlobalData().get(
- RarVM.VM_FIXEDGLOBALSIZE + i));
- }
- } else {
- pPrg.getGlobalData().clear();
- }
- FilteredDataOffset = NextPrg.getFilteredDataOffset();
- FilteredDataSize = NextPrg.getFilteredDataSize();
-
- FilteredData = new byte[FilteredDataSize];
- for (int i = 0; i < FilteredDataSize; i++) {
- FilteredData[i] = NextPrg.getGlobalData().get(
- FilteredDataOffset + i);
- }
-
- I++;
- prgStack.set(I, null);
- }
- unpIO.unpWrite(FilteredData, 0, FilteredDataSize);
- unpSomeRead = true;
- writtenFileSize += FilteredDataSize;
- WrittenBorder = BlockEnd;
- WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;
- } else {
- for (int J = I; J < prgStack.size(); J++) {
- UnpackFilter filt = prgStack.get(J);
- if (filt != null && filt.isNextWindow()) {
- filt.setNextWindow(false);
- }
- }
- wrPtr = WrittenBorder;
- return;
- }
- }
- }
-
- UnpWriteArea(WrittenBorder, unpPtr);
- wrPtr = unpPtr;
-
- }
-
- private void UnpWriteArea(int startPtr, int endPtr) throws IOException {
- if (endPtr != startPtr) {
- unpSomeRead = true;
- }
- if (endPtr < startPtr) {
- UnpWriteData(window, startPtr, -startPtr & Compress.MAXWINMASK);
- UnpWriteData(window, 0, endPtr);
- unpAllBuf = true;
- } else {
- UnpWriteData(window, startPtr, endPtr - startPtr);
- }
- }
-
- private void UnpWriteData(byte[] data, int offset, int size)
- throws IOException {
- if (writtenFileSize >= destUnpSize) {
- return;
- }
- int writeSize = size;
- long leftToWrite = destUnpSize - writtenFileSize;
- if (writeSize > leftToWrite) {
- writeSize = (int) leftToWrite;
- }
- unpIO.unpWrite(data, offset, writeSize);
-
- writtenFileSize += size;
-
- }
-
- private void insertOldDist(int distance) {
- oldDist[3] = oldDist[2];
- oldDist[2] = oldDist[1];
- oldDist[1] = oldDist[0];
- oldDist[0] = distance;
- }
-
- private void insertLastMatch(int length, int distance) {
- lastDist = distance;
- lastLength = length;
- }
-
- private void copyString(int length, int distance) {
- // System.out.println("copyString(" + length + ", " + distance + ")");
-
- int destPtr = unpPtr - distance;
- // System.out.println(unpPtr+":"+distance);
- if (destPtr >= 0 && destPtr < Compress.MAXWINSIZE - 260
- && unpPtr < Compress.MAXWINSIZE - 260) {
-
- window[unpPtr++] = window[destPtr++];
-
- while (--length > 0)
-
- window[unpPtr++] = window[destPtr++];
- } else
- while (length-- != 0) {
- window[unpPtr] = window[destPtr++ & Compress.MAXWINMASK];
- unpPtr = (unpPtr + 1) & Compress.MAXWINMASK;
- }
- }
-
- protected void unpInitData(boolean solid) {
- if (!solid) {
- tablesRead = false;
- Arrays.fill(oldDist, 0); // memset(oldDist,0,sizeof(OldDist));
-
- oldDistPtr = 0;
- lastDist = 0;
- lastLength = 0;
-
- Arrays.fill(unpOldTable, (byte) 0);// memset(UnpOldTable,0,sizeof(UnpOldTable));
-
- unpPtr = 0;
- wrPtr = 0;
- ppmEscChar = 2;
-
- initFilters();
- }
- InitBitInput();
- ppmError = false;
- writtenFileSize = 0;
- readTop = 0;
- readBorder = 0;
- unpInitData20(solid);
- }
-
- private void initFilters() {
- oldFilterLengths.clear();
- lastFilter = 0;
-
- filters.clear();
-
- prgStack.clear();
- }
-
- private boolean readEndOfBlock() throws IOException, RarException {
- int BitField = getbits();
- boolean NewTable, NewFile = false;
- if ((BitField & 0x8000) != 0) {
- NewTable = true;
- addbits(1);
- } else {
- NewFile = true;
- NewTable = (BitField & 0x4000) != 0 ? true : false;
- addbits(2);
- }
- tablesRead = !NewTable;
- return !(NewFile || NewTable && !readTables());
- }
-
- private boolean readTables() throws IOException, RarException {
- byte[] bitLength = new byte[Compress.BC];
-
- byte[] table = new byte[Compress.HUFF_TABLE_SIZE];
- if (inAddr > readTop - 25) {
- if (!unpReadBuf()) {
- return (false);
- }
- }
- faddbits((8 - inBit) & 7);
- long bitField = fgetbits() & 0xffFFffFF;
- if ((bitField & 0x8000) != 0) {
- unpBlockType = BlockTypes.BLOCK_PPM;
- return (ppm.decodeInit(this, ppmEscChar));
- }
- unpBlockType = BlockTypes.BLOCK_LZ;
-
- prevLowDist = 0;
- lowDistRepCount = 0;
-
- if ((bitField & 0x4000) == 0) {
- Arrays.fill(unpOldTable, (byte) 0);// memset(UnpOldTable,0,sizeof(UnpOldTable));
- }
- faddbits(2);
-
- for (int i = 0; i < Compress.BC; i++) {
- int length = (fgetbits() >>> 12) & 0xFF;
- faddbits(4);
- if (length == 15) {
- int zeroCount = (fgetbits() >>> 12) & 0xFF;
- faddbits(4);
- if (zeroCount == 0) {
- bitLength[i] = 15;
- } else {
- zeroCount += 2;
- while (zeroCount-- > 0 && i < bitLength.length) {
- bitLength[i++] = 0;
- }
- i--;
- }
- } else {
- bitLength[i] = (byte) length;
- }
- }
-
- makeDecodeTables(bitLength, 0, BD, Compress.BC);
-
- int TableSize = Compress.HUFF_TABLE_SIZE;
-
- for (int i = 0; i < TableSize;) {
- if (inAddr > readTop - 5) {
- if (!unpReadBuf()) {
- return (false);
- }
- }
- int Number = decodeNumber(BD);
- if (Number < 16) {
- table[i] = (byte) ((Number + unpOldTable[i]) & 0xf);
- i++;
- } else if (Number < 18) {
- int N;
- if (Number == 16) {
- N = (fgetbits() >>> 13) + 3;
- faddbits(3);
- } else {
- N = (fgetbits() >>> 9) + 11;
- faddbits(7);
- }
- while (N-- > 0 && i < TableSize) {
- table[i] = table[i - 1];
- i++;
- }
- } else {
- int N;
- if (Number == 18) {
- N = (fgetbits() >>> 13) + 3;
- faddbits(3);
- } else {
- N = (fgetbits() >>> 9) + 11;
- faddbits(7);
- }
- while (N-- > 0 && i < TableSize) {
- table[i++] = 0;
- }
- }
- }
- tablesRead = true;
- if (inAddr > readTop) {
- return (false);
- }
- makeDecodeTables(table, 0, LD, Compress.NC);
- makeDecodeTables(table, Compress.NC, DD, Compress.DC);
- makeDecodeTables(table, Compress.NC + Compress.DC, LDD, Compress.LDC);
- makeDecodeTables(table, Compress.NC + Compress.DC + Compress.LDC, RD,
- Compress.RC);
-
- // memcpy(unpOldTable,table,sizeof(unpOldTable));
- for (int i = 0; i < unpOldTable.length; i++) {
- unpOldTable[i] = table[i];
- }
- return (true);
-
- }
-
- private boolean readVMCode() throws IOException, RarException {
- int FirstByte = getbits() >> 8;
- addbits(8);
- int Length = (FirstByte & 7) + 1;
- if (Length == 7) {
- Length = (getbits() >> 8) + 7;
- addbits(8);
- } else if (Length == 8) {
- Length = getbits();
- addbits(16);
- }
- List<Byte> vmCode = new ArrayList<Byte>();
- for (int I = 0; I < Length; I++) {
- if (inAddr >= readTop - 1 && !unpReadBuf() && I < Length - 1) {
- return (false);
- }
- vmCode.add(Byte.valueOf((byte) (getbits() >> 8)));
- addbits(8);
- }
- return (addVMCode(FirstByte, vmCode, Length));
- }
-
- private boolean readVMCodePPM() throws IOException, RarException {
- int FirstByte = ppm.decodeChar();
- if ((int) FirstByte == -1) {
- return (false);
- }
- int Length = (FirstByte & 7) + 1;
- if (Length == 7) {
- int B1 = ppm.decodeChar();
- if (B1 == -1) {
- return (false);
- }
- Length = B1 + 7;
- } else if (Length == 8) {
- int B1 = ppm.decodeChar();
- if (B1 == -1) {
- return (false);
- }
- int B2 = ppm.decodeChar();
- if (B2 == -1) {
- return (false);
- }
- Length = B1 * 256 + B2;
- }
- List<Byte> vmCode = new ArrayList<Byte>();
- for (int I = 0; I < Length; I++) {
- int Ch = ppm.decodeChar();
- if (Ch == -1) {
- return (false);
- }
- vmCode.add(Byte.valueOf((byte) Ch));// VMCode[I]=Ch;
- }
- return (addVMCode(FirstByte, vmCode, Length));
- }
-
- private boolean addVMCode(int firstByte, List<Byte> vmCode, int length) {
- BitInput Inp = new BitInput();
- Inp.InitBitInput();
- // memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));
- for (int i = 0; i < Math.min(BitInput.MAX_SIZE, vmCode.size()); i++) {
- Inp.getInBuf()[i] = vmCode.get(i);
- }
- rarVM.init();
-
- int FiltPos;
- if ((firstByte & 0x80) != 0) {
- FiltPos = RarVM.ReadData(Inp);
- if (FiltPos == 0) {
- initFilters();
- } else {
- FiltPos--;
- }
- } else
- FiltPos = lastFilter; // use the same filter as last time
-
- if (FiltPos > filters.size() || FiltPos > oldFilterLengths.size()) {
- return (false);
- }
- lastFilter = FiltPos;
- boolean NewFilter = (FiltPos == filters.size());
-
- UnpackFilter StackFilter = new UnpackFilter(); // new filter for
- // PrgStack
-
- UnpackFilter Filter;
- if (NewFilter) // new filter code, never used before since VM reset
- {
- // too many different filters, corrupt archive
- if (FiltPos > 1024) {
- return (false);
- }
-
- // Filters[Filters.Size()-1]=Filter=new UnpackFilter;
- Filter = new UnpackFilter();
- filters.add(Filter);
- StackFilter.setParentFilter(filters.size() - 1);
- oldFilterLengths.add(0);
- Filter.setExecCount(0);
- } else // filter was used in the past
- {
- Filter = filters.get(FiltPos);
- StackFilter.setParentFilter(FiltPos);
- Filter.setExecCount(Filter.getExecCount() + 1);// ->ExecCount++;
- }
-
- prgStack.add(StackFilter);
- StackFilter.setExecCount(Filter.getExecCount());// ->ExecCount;
-
- int BlockStart = RarVM.ReadData(Inp);
- if ((firstByte & 0x40) != 0) {
- BlockStart += 258;
- }
- StackFilter.setBlockStart((BlockStart + unpPtr) & Compress.MAXWINMASK);
- if ((firstByte & 0x20) != 0) {
- StackFilter.setBlockLength(RarVM.ReadData(Inp));
- } else {
- StackFilter
- .setBlockLength(FiltPos < oldFilterLengths.size() ? oldFilterLengths
- .get(FiltPos)
- : 0);
- }
- StackFilter.setNextWindow((wrPtr != unpPtr)
- && ((wrPtr - unpPtr) & Compress.MAXWINMASK) <= BlockStart);
-
- // DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x
- // BlockStart=%08x",UnpPtr,WrPtr,BlockStart);
-
- oldFilterLengths.set(FiltPos, StackFilter.getBlockLength());
-
- // memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));
- Arrays.fill(StackFilter.getPrg().getInitR(), 0);
- StackFilter.getPrg().getInitR()[3] = RarVM.VM_GLOBALMEMADDR;// StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;
- StackFilter.getPrg().getInitR()[4] = StackFilter.getBlockLength();// StackFilter->Prg.InitR[4]=StackFilter->BlockLength;
- StackFilter.getPrg().getInitR()[5] = StackFilter.getExecCount();// StackFilter->Prg.InitR[5]=StackFilter->ExecCount;
-
- if ((firstByte & 0x10) != 0) // set registers to optional parameters
- // if any
- {
- int InitMask = Inp.fgetbits() >>> 9;
- Inp.faddbits(7);
- for (int I = 0; I < 7; I++) {
- if ((InitMask & (1 << I)) != 0) {
- // StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp);
- StackFilter.getPrg().getInitR()[I] = RarVM.ReadData(Inp);
- }
- }
- }
-
- if (NewFilter) {
- int VMCodeSize = RarVM.ReadData(Inp);
- if (VMCodeSize >= 0x10000 || VMCodeSize == 0) {
- return (false);
- }
- byte[] VMCode = new byte[VMCodeSize];
- for (int I = 0; I < VMCodeSize; I++) {
- if (Inp.Overflow(3)) {
- return (false);
- }
- VMCode[I] = (byte) (Inp.fgetbits() >> 8);
- Inp.faddbits(8);
- }
- // VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
- rarVM.prepare(VMCode, VMCodeSize, Filter.getPrg());
- }
- StackFilter.getPrg().setAltCmd(Filter.getPrg().getCmd());// StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];
- StackFilter.getPrg().setCmdCount(Filter.getPrg().getCmdCount());// StackFilter->Prg.CmdCount=Filter->Prg.CmdCount;
-
- int StaticDataSize = Filter.getPrg().getStaticData().size();
- if (StaticDataSize > 0 && StaticDataSize < RarVM.VM_GLOBALMEMSIZE) {
- // read statically defined data contained in DB commands
- // StackFilter->Prg.StaticData.Add(StaticDataSize);
- StackFilter.getPrg().setStaticData(Filter.getPrg().getStaticData());
- // memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);
- }
-
- if (StackFilter.getPrg().getGlobalData().size() < RarVM.VM_FIXEDGLOBALSIZE) {
- // StackFilter->Prg.GlobalData.Reset();
- // StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE);
- StackFilter.getPrg().getGlobalData().clear();
- StackFilter.getPrg().getGlobalData().setSize(
- RarVM.VM_FIXEDGLOBALSIZE);
- }
-
- // byte *GlobalData=&StackFilter->Prg.GlobalData[0];
- Vector<Byte> globalData = StackFilter.getPrg().getGlobalData();
- for (int I = 0; I < 7; I++) {
- rarVM.setLowEndianValue(globalData, I * 4, StackFilter.getPrg()
- .getInitR()[I]);
- }
-
- // VM.SetLowEndianValue((uint
- // *)&GlobalData[0x1c],StackFilter->BlockLength);
- rarVM.setLowEndianValue(globalData, 0x1c, StackFilter.getBlockLength());
- // VM.SetLowEndianValue((uint *)&GlobalData[0x20],0);
- rarVM.setLowEndianValue(globalData, 0x20, 0);
- rarVM.setLowEndianValue(globalData, 0x24, 0);
- rarVM.setLowEndianValue(globalData, 0x28, 0);
-
- // VM.SetLowEndianValue((uint
- // *)&GlobalData[0x2c],StackFilter->ExecCount);
- rarVM.setLowEndianValue(globalData, 0x2c, StackFilter.getExecCount());
- // memset(&GlobalData[0x30],0,16);
- for (int i = 0; i < 16; i++) {
- globalData.set(0x30 + i, Byte.valueOf((byte) (0)));
- }
- if ((firstByte & 8) != 0) // put data block passed as parameter if any
- {
- if (Inp.Overflow(3)) {
- return (false);
- }
- int DataSize = RarVM.ReadData(Inp);
- if (DataSize > RarVM.VM_GLOBALMEMSIZE - RarVM.VM_FIXEDGLOBALSIZE) {
- return (false);
- }
- int CurSize = StackFilter.getPrg().getGlobalData().size();
- if (CurSize < DataSize + RarVM.VM_FIXEDGLOBALSIZE) {
- // StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);
- StackFilter.getPrg().getGlobalData().setSize(
- DataSize + RarVM.VM_FIXEDGLOBALSIZE - CurSize);
- }
- int offset = RarVM.VM_FIXEDGLOBALSIZE;
- globalData = StackFilter.getPrg().getGlobalData();
- for (int I = 0; I < DataSize; I++) {
- if (Inp.Overflow(3)) {
- return (false);
- }
- globalData.set(offset + I, Byte
- .valueOf((byte) (Inp.fgetbits() >>> 8)));
- Inp.faddbits(8);
- }
- }
- return (true);
- }
-
- private void ExecuteCode(VMPreparedProgram Prg) {
- if (Prg.getGlobalData().size() > 0) {
- // Prg->InitR[6]=int64to32(WrittenFileSize);
- Prg.getInitR()[6] = (int) (writtenFileSize);
- // rarVM.SetLowEndianValue((uint
- // *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));
- rarVM.setLowEndianValue(Prg.getGlobalData(), 0x24,
- (int) writtenFileSize);
- // rarVM.SetLowEndianValue((uint
- // *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32));
- rarVM.setLowEndianValue(Prg.getGlobalData(), 0x28,
- (int) (writtenFileSize >>> 32));
- rarVM.execute(Prg);
- }
- }
-
- // Duplicate method
- // private boolean ReadEndOfBlock() throws IOException, RarException
- // {
- // int BitField = getbits();
- // boolean NewTable, NewFile = false;
- // if ((BitField & 0x8000) != 0) {
- // NewTable = true;
- // addbits(1);
- // } else {
- // NewFile = true;
- // NewTable = (BitField & 0x4000) != 0;
- // addbits(2);
- // }
- // tablesRead = !NewTable;
- // return !(NewFile || NewTable && !readTables());
- // }
-
- public boolean isFileExtracted() {
- return fileExtracted;
- }
-
- public void setDestSize(long destSize) {
- this.destUnpSize = destSize;
- this.fileExtracted = false;
- }
-
- public void setSuspended(boolean suspended) {
- this.suspended = suspended;
- }
-
- public int getChar() throws IOException, RarException {
- if (inAddr > BitInput.MAX_SIZE - 30) {
- unpReadBuf();
- }
- return (inBuf[inAddr++] & 0xff);
- }
-
- public int getPpmEscChar() {
- return ppmEscChar;
- }
-
- public void setPpmEscChar(int ppmEscChar) {
- this.ppmEscChar = ppmEscChar;
- }
-
- public void cleanUp() {
- if (ppm != null) {
- SubAllocator allocator = ppm.getSubAlloc();
- if (allocator != null) {
- allocator.stopSubAllocator();
- }
- }
- }
-}