Files
2006RebottedClient/src/main/java/org/rebotted/cache/FileArchive.java
T
2019-12-15 20:35:23 -06:00

102 lines
2.5 KiB
Java

package org.rebotted.cache;
import org.rebotted.cache.bzip.BZip2Decompressor;
import org.rebotted.io.Buffer;
public final class FileArchive {
/**
* The buffer containing the decompressed data in this Archive.
*/
private final byte[] buffer;
/**
* The amount of entries in this Archive.
*/
private final int entries;
/**
* The identifiers (i.e. hashed names) of each of the entries in this Archive.
*/
private final int[] identifiers;
/**
* The raw (i.e. decompressed) sizes of each of the entries in this Archive.
*/
private final int[] extractedSizes;
/**
* The compressed sizes of each of the entries in this Archive.
*/
private final int[] sizes;
private final int[] indices;
/**
* Whether or not this Archive was compressed as a whole: if false, decompression will be performed on each of the
* individual entries.
*/
private final boolean extracted;
public FileArchive(byte data[]) {
Buffer buffer = new Buffer(data);
int decompressedLength = buffer.readTriByte();
int compressedLength = buffer.readTriByte();
if (compressedLength != decompressedLength) {
byte output[] = new byte[decompressedLength];
BZip2Decompressor.decompress(output, decompressedLength, data, compressedLength, 6);
this.buffer = output;
buffer = new Buffer(this.buffer);
extracted = true;
} else {
this.buffer = data;
extracted = false;
}
entries = buffer.readUShort();
identifiers = new int[entries];
extractedSizes = new int[entries];
sizes = new int[entries];
indices = new int[entries];
int offset = buffer.currentPosition + entries * 10;
for (int file = 0; file < entries; file++) {
identifiers[file] = buffer.readInt();
extractedSizes[file] = buffer.readTriByte();
sizes[file] = buffer.readTriByte();
indices[file] = offset;
offset += sizes[file];
}
}
public byte[] readFile(String name) {
byte output[] = null;
int hash = 0;
name = name.toUpperCase();
for (int index = 0; index < name.length(); index++) {
hash = (hash * 61 + name.charAt(index)) - 32;
}
for (int file = 0; file < entries; file++) {
if (identifiers[file] == hash) {
if (output == null) {
output = new byte[extractedSizes[file]];
}
if (!extracted) {
BZip2Decompressor.decompress(output, extractedSizes[file], this.buffer,
sizes[file], indices[file]);
} else {
System.arraycopy(this.buffer, indices[file], output,
0, extractedSizes[file]);
}
return output;
}
}
return null;
}
}