MoparScape/MoparScape/src/main/java/org/moparscape/cacheutils/v317/CacheIndex.java

245 lines
8.1 KiB
Java

/*
* Copyright (C) 2009-2013 moparisthebest
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Official forums are http://www.moparscape.org/smf/
* Email me at admin@moparisthebest.com.
*/
package org.moparscape.cacheutils.v317;
/**
* Created by Silabsoft
* Date: Sep 14, 2008
* Time: 11:05:10 AM
*/
import java.io.*;
public class CacheIndex {
public CacheIndex(RandomAccessFile randomaccessfile, RandomAccessFile randomaccessfile1, int j) {
indexID = j;
dataFile = randomaccessfile;
indexFile = randomaccessfile1;
}
public synchronized byte[] read(int i) {
try {
seekTo(indexFile, i * 6);
int l;
for (int j = 0; j < 6; j += l) {
l = indexFile.read(buffer, j, 6 - j);
if (l == -1)
return null;
}
int fileSize = ((buffer[0] & 0xff) << 16) + ((buffer[1] & 0xff) << 8) + (buffer[2] & 0xff);
int offset = ((buffer[3] & 0xff) << 16) + ((buffer[4] & 0xff) << 8) + (buffer[5] & 0xff);
if (fileSize < 0 || fileSize > 0x7a120)
return null;
if (offset <= 0 || (long) offset > dataFile.length() / 520L)
return null;
byte data[] = new byte[fileSize];
int readBytes = 0;
for (int l1 = 0; readBytes < fileSize; l1++) {
if (offset == 0)
return null;
seekTo(dataFile, offset * 520);
int k = 0;
int left = fileSize - readBytes;
if (left > 512)
left = 512;
int j2;
for (; k < left + 8; k += j2) {
j2 = dataFile.read(buffer, k, (left + 8) - k);
if (j2 == -1)
return null;
}
//Start of chunk header
int fileNumber = ((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff);
int bufferChunkNumber = ((buffer[2] & 0xff) << 8) + (buffer[3] & 0xff);
int bufferChunkHash = ((buffer[4] & 0xff) << 16) + ((buffer[5] & 0xff) << 8) + (buffer[6] & 0xff);
int indexNumber = buffer[7] & 0xff;
//end of chunk header
if (fileNumber != i || bufferChunkNumber != l1 || indexNumber != indexID)
return null;
if (bufferChunkHash < 0 || (long) bufferChunkHash > dataFile.length() / 520L)
return null;
for (int k3 = 0; k3 < left; k3++)
data[readBytes++] = buffer[k3 + 8];
offset = bufferChunkHash;
}
return data;
}
catch (IOException _ex) {
return null;
}
}
public synchronized boolean write(int i, byte abyte0[], int j)
{
boolean flag = method235(true, j, i, abyte0);
if(!flag)
flag = method235(false, j, i, abyte0);
return flag;
}
private synchronized boolean method235(boolean flag, int j, int k, byte abyte0[])
{
try
{
int l;
if(flag)
{
seekTo(indexFile, j * 6);
int k1;
for(int i1 = 0; i1 < 6; i1 += k1)
{
k1 = indexFile.read(buffer, i1, 6 - i1);
if(k1 == -1)
return false;
}
l = ((buffer[3] & 0xff) << 16) + ((buffer[4] & 0xff) << 8) + (buffer[5] & 0xff);
if(l <= 0 || (long)l > dataFile.length() / 520L)
return false;
} else
{
l = (int)((dataFile.length() + 519L) / 520L);
if(l == 0)
l = 1;
}
buffer[0] = (byte)(k >> 16);
buffer[1] = (byte)(k >> 8);
buffer[2] = (byte)k;
buffer[3] = (byte)(l >> 16);
buffer[4] = (byte)(l >> 8);
buffer[5] = (byte)l;
seekTo(indexFile, j * 6);
indexFile.write(buffer, 0, 6);
int j1 = 0;
for(int l1 = 0; j1 < k; l1++)
{
int i2 = 0;
if(flag)
{
seekTo(dataFile, l * 520);
int j2;
int l2;
for(j2 = 0; j2 < 8; j2 += l2)
{
l2 = dataFile.read(buffer, j2, 8 - j2);
if(l2 == -1)
break;
}
if(j2 == 8)
{
int i3 = ((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff);
int j3 = ((buffer[2] & 0xff) << 8) + (buffer[3] & 0xff);
i2 = ((buffer[4] & 0xff) << 16) + ((buffer[5] & 0xff) << 8) + (buffer[6] & 0xff);
int k3 = buffer[7] & 0xff;
if(i3 != j || j3 != l1 || k3 != indexID)
return false;
if(i2 < 0 || (long)i2 > dataFile.length() / 520L)
return false;
}
}
if(i2 == 0)
{
flag = false;
i2 = (int)((dataFile.length() + 519L) / 520L);
if(i2 == 0)
i2++;
if(i2 == l)
i2++;
}
if(k - j1 <= 512)
i2 = 0;
buffer[0] = (byte)(j >> 8);
buffer[1] = (byte)j;
buffer[2] = (byte)(l1 >> 8);
buffer[3] = (byte)l1;
buffer[4] = (byte)(i2 >> 16);
buffer[5] = (byte)(i2 >> 8);
buffer[6] = (byte)i2;
buffer[7] = (byte)indexID;
seekTo(dataFile, l * 520);
dataFile.write(buffer, 0, 8);
int k2 = k - j1;
if(k2 > 512)
k2 = 512;
dataFile.write(abyte0, j1, k2);
j1 += k2;
l = i2;
}
return true;
}
catch(IOException _ex)
{
return false;
}
}
private synchronized void seekTo(RandomAccessFile randomaccessfile, int j)
throws IOException {
if (j < 0 || j > 0x3c00000) {
System.out.println("Badseek - pos:" + j + " len:" + randomaccessfile.length());
j = 0x3c00000;
try {
Thread.sleep(1000L);
}
catch (Exception _ex) {
}
}
randomaccessfile.seek(j);
}
public int fileCount() {
try {
return (int) (indexFile.length() / 6);
} catch (Exception e) {
return 0;
}
}
public void saveFiles(){
for(int i = 0; i < fileCount(); i++){
try{
byte[] data = read(i);
if(data != null){
long hash = (((indexID-1) << 16)+i);
FileOutputStream out = new FileOutputStream("ondemand/"+hash);
out.write(data);
}
else{
}
}catch(Exception e){
e.printStackTrace();
}
}
}
private static final byte[] buffer = new byte[520];
private final RandomAccessFile dataFile;
private final RandomAccessFile indexFile;
public final int indexID;
}