📄 unpack.java
字号:
}
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)
{
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.maxSize, 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);
}
}
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.maxSize - 30) {
unpReadBuf();
}
return (inBuf[inAddr++]&0xff);
}
public int getPpmEscChar()
{
return ppmEscChar;
}
public void setPpmEscChar(int ppmEscChar)
{
this.ppmEscChar = ppmEscChar;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -