⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 suballocator.java

📁 java下操作rar文件,创建,压缩/解压缩等等.
💻 JAVA
字号:
/*
 * 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 de.innosystec.unrar.unpack.ppm;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.List;

import de.innosystec.unrar.Archive;
import de.innosystec.unrar.io.ReadOnlyAccessFile;
import de.innosystec.unrar.rarfile.BaseBlock;

/**
 * DOCUMENT ME
 * 
 * @author $LastChangedBy$
 * @version $LastChangedRevision$
 */
public class SubAllocator
{
	public static final int N1 = 4, N2 = 4, N3 = 4, N4 = (128 + 3 - 1 * N1 - 2
			* N2 - 3 * N3) / 4;

	public static final int N_INDEXES = N1 + N2 + N3 + N4;

	public static final int UNIT_SIZE = Math.max(PPMContext.size,
			RarMemBlock.size);

	public static final int FIXED_UNIT_SIZE = 12;

	private int subAllocatorSize;

	private short[] indx2Units = new short[N_INDEXES];

	private short[] units2Indx = new short[128];

	private short glueCount;

	private int heapStart, loUnit, hiUnit;

	private RarNode[] FreeList = new RarNode[N_INDEXES];

	//
	private int pText, unitsStart, heapEnd, fakeUnitsStart;

	private byte[] heap;

	private int freeListPos;

	private int tempMemBlockPos;

	public SubAllocator()
	{
		clean();
	}

	public void clean()
	{
		subAllocatorSize = 0;
	}

	private void insertNode(int p/* rarnode ptr */, int indx)
	{
		RarNode temp = new RarNode(heap);
		temp.setAddress(p);
		temp.setNext(FreeList[indx].getNext());
		FreeList[indx].setNext(temp);
	}

	public void incPText(){
		pText++;
	}
	
	private int removeNode(int indx)
	{
		int retVal = FreeList[indx].getNext();
		RarNode temp = new RarNode(heap);
		temp.setAddress(retVal);
		FreeList[indx].setNext(temp.getNext());
		return retVal;
	}

	private int U2B(int NU)
	{
		return /* 8*NU+4*NU */UNIT_SIZE * NU;
	}

	/* memblockptr */
	private int MBPtr(int BasePtr, int Items)
	{
		return (BasePtr + U2B(Items));
	}

	private void splitBlock(int pv/* ptr */, int oldIndx, int newIndx)
	{
		int i, uDiff = indx2Units[oldIndx] - indx2Units[newIndx];
		int p = pv + U2B(indx2Units[newIndx]);
		if (indx2Units[i = units2Indx[uDiff - 1]] != uDiff) {
			insertNode(p, --i);
			p += U2B(i = indx2Units[i]);
			uDiff -= i;
		}
		insertNode(p, units2Indx[uDiff - 1]);
	}

	public void stopSubAllocator()
	{
		if (subAllocatorSize != 0) {
			subAllocatorSize = 0;
			heap = null;
			heapStart = 1;
			// rarfree(HeapStart);
		}
	}

	public int GetAllocatedMemory()
	{
		return subAllocatorSize;
	};

	public boolean startSubAllocator(int SASize)
	{
		int t = SASize << 20;
		if (subAllocatorSize == t) {
			return true;
		}
		stopSubAllocator();
		int allocSize = t / FIXED_UNIT_SIZE * UNIT_SIZE + UNIT_SIZE;

		// adding space for freelist (needed for poiters)
		//1+ for null pointer
		int realAllocSize = 1+allocSize + 4 * N_INDEXES;
		// adding space for an additional memblock
		tempMemBlockPos = realAllocSize;
		realAllocSize += RarMemBlock.size;

		freeListPos = allocSize;

		heap = new byte[(int) realAllocSize];
		heapStart = 1;
		heapEnd = heapStart + allocSize - UNIT_SIZE;
		subAllocatorSize = t;
		return true;
	}

	private void glueFreeBlocks()
	{
		RarMemBlock s0 = new RarMemBlock(heap);
		s0.setAddress((int) tempMemBlockPos);
		RarMemBlock p = new RarMemBlock(heap);
		RarMemBlock p1 = new RarMemBlock(heap);
		int i, k, sz;
		if (loUnit != hiUnit) {
			heap[(int) loUnit] = 0;
		}
		for (i = 0, s0.setPrev(s0), s0.setNext(s0); i < N_INDEXES; i++) {
			while (FreeList[i].getNext() == 0) {

				p.setAddress(removeNode(i));// =(RAR_MEM_BLK*)RemoveNode(i);
				p.insertAt(s0);// p->insertAt(&s0);
				p.setStamp((short) 0xFFFF);// p->Stamp=0xFFFF;
				p.setNU(indx2Units[i]);// p->NU=Indx2Units[i];

			}
		}

		for (p.setAddress(s0.getNext()); p.getAddress() != s0.getAddress(); p
				.setAddress(p.getNext())) {
			// while ((p1=MBPtr(p,p->NU))->Stamp == 0xFFFF && int(p->NU)+p1->NU
			// < 0x10000)
			for (p1.setAddress(MBPtr(p.getAddress(), p.getNU())); p1.getStamp() == (short) 0xFFFF
					&& (int) (p.getNU() + p1.getNU()) < 0x10000;) {
				p1.remove();
				p.setNU((short) (p.getNU() + p1.getNU()));// ->NU += p1->NU;
			}
		}
		// while ((p=s0.next) != &s0)
		for (p.setAddress(s0.getNext()); p.getAddress() != s0.getAddress();) {
			for (p.remove(), sz = p.getNU(); sz > 128; sz -= 128, p
					.setAddress(MBPtr(p.getAddress(), 128))) {
				insertNode(p.getAddress(), N_INDEXES - 1);
			}
			if (indx2Units[i = units2Indx[sz - 1]] != sz) {
				k = sz - indx2Units[--i];
				insertNode(MBPtr(p.getAddress(), sz - k), k - 1);
			}
			insertNode(p.getAddress(), i);
		}
	}

	private int allocUnitsRare(int indx)
	{
		if (glueCount == 0) {
			glueCount = 255;
			glueFreeBlocks();
			if (FreeList[indx].getNext() != 0) {
				return removeNode(indx);
			}
		}
		int i = indx;
		do {
			if (++i == N_INDEXES) {
				glueCount--;
				i = U2B(indx2Units[indx]);
				int j = FIXED_UNIT_SIZE * indx2Units[indx];
				if (fakeUnitsStart - pText > j) {
					fakeUnitsStart -= j;
					unitsStart -= i;
					return ((int) unitsStart);
				}
				return (0);
			}
		} while (FreeList[i].getNext() == 0);
		int retVal = removeNode(i);
		splitBlock(retVal, i, indx);
		return retVal;
	}

	public int allocUnits(int NU)
	{
		int indx = units2Indx[NU - 1];
		if (FreeList[indx].getNext() != 0) {
			return removeNode(indx);
		}
		int retVal = loUnit;
		loUnit += U2B(indx2Units[indx]);
		if (loUnit <= hiUnit) {
			return retVal;
		}
		loUnit -= U2B(indx2Units[indx]);
		return allocUnitsRare(indx);
	}

	public int allocContext()
	{
		if (hiUnit != loUnit)
			return (hiUnit -= UNIT_SIZE);
		if (FreeList[0].getNext() != 0) {
			return removeNode(0);
		}
		return allocUnitsRare(0);
	}

	public int expandUnits(int OldPtr, int OldNU)
	{
		int i0 = units2Indx[OldNU - 1]; 
		int i1 = units2Indx[OldNU - 1 + 1];
		if (i0 == i1) {
			return OldPtr;
		}
		int ptr = allocUnits(OldNU + 1);
		if (ptr != 0) {
			// memcpy(ptr,OldPtr,U2B(OldNU));
			for (int i = 0; i < U2B(OldNU); i++) {
				heap[ptr + i] = heap[OldPtr + i];
			}
			insertNode(OldPtr, i0);
		}
		return ptr;
	}

	public int shrinkUnits(int OldPtr, int OldNU, int NewNU)
	{
		int i0 = units2Indx[OldNU - 1], i1 = units2Indx[NewNU - 1];
		if (i0 == i1) {
			return OldPtr;
		}
		if (FreeList[i1].getNext() != 0) {
			int ptr = removeNode(i1);
			// memcpy(ptr,OldPtr,U2B(NewNU));
			for (int i = 0; i < U2B(NewNU); i++) {
				heap[ptr + i] = heap[OldPtr + i];
			}
			insertNode(OldPtr, i0);
			return ptr;
		} else {
			splitBlock(OldPtr, i0, i1);
			return OldPtr;
		}
	}
	
	public void freeUnits(int ptr, int OldNU)
	{
		insertNode(ptr, units2Indx[OldNU - 1]);
	}

	
	public int getFakeUnitsStart()
	{
		return fakeUnitsStart;
	}

	public void setFakeUnitsStart(int fakeUnitsStart)
	{
		this.fakeUnitsStart = fakeUnitsStart;
	}

	public int getHeapEnd()
	{
		return heapEnd;
	}

	public void setHeapEnd(int heapEnd)
	{
		this.heapEnd = heapEnd;
	}

	public int getPText()
	{
		return pText;
	}

	public void setPText(int text)
	{
		pText = text;
	}

	public int getUnitsStart()
	{
		return unitsStart;
	}

	public void setUnitsStart(int unitsStart)
	{
		this.unitsStart = unitsStart;
	}

	public void initSubAllocator()
	{
		int i, k;

		for (int j = 0; j < FreeList.length; j++) {
			FreeList[j] = new RarNode(heap);
		}
		for (int j = (int) freeListPos; j < heap.length; j++) {
			heap[j] = 0;
		}
		for (int j = (int) freeListPos, l = 0; j < tempMemBlockPos-1; j += 4, l++) {
			FreeList[l].setAddress(j);
		}
		pText = heapStart;

		int size2 = FIXED_UNIT_SIZE
				* (subAllocatorSize / 8 / FIXED_UNIT_SIZE * 7);
		int realSize2 = size2 / FIXED_UNIT_SIZE * UNIT_SIZE;
		int size1 = subAllocatorSize - size2;
		int realSize1 = size1 / FIXED_UNIT_SIZE * UNIT_SIZE + size1
				% FIXED_UNIT_SIZE;
		hiUnit = heapStart + subAllocatorSize;
		loUnit = unitsStart = heapStart + realSize1;
		fakeUnitsStart = heapStart + size1;
		hiUnit = loUnit + realSize2;

		for (i = 0, k = 1; i < N1; i++, k += 1) {
			indx2Units[i] = (short) k;
		}
		for (k++; i < N1 + N2; i++, k += 2) {
			indx2Units[i] = (short) k;
		}
		for (k++; i < N1 + N2 + N3; i++, k += 3) {
			indx2Units[i] = (short) k;
		}
		for (k++; i < (N1 + N2 + N3 + N4); i++, k += 4) {
			indx2Units[i] = (short) k;
		}

		for (glueCount = (short) 0, k = 0, i = 0; k < 128; k++) {

			i += ((indx2Units[i] < (k + 1)) ? 1 : 0);
			units2Indx[k] = (short) i;
		}

	}

	public byte[] getHeap()
	{
		return heap;
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -