package clientdata;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import org.apache.mina.core.buffer.IoBuffer;
public class IffFile {
/**
*
* Reads in a client file, and uses the given interpreter to interpret the data.
* See {@link VisitorInterface}
*
* @param file the file to read
* @param i the interpreter to use
*/
public static void readFile(String file, VisitorInterface i) {
IoBuffer buffer;
try {
File input = new File(file);
input.setReadable(true);
input.setWritable(true);
java.io.FileInputStream fis = new java.io.FileInputStream(file);
buffer = IoBuffer.allocate(fis.available(), false);
buffer.setAutoExpand(true);
buffer.order(ByteOrder.LITTLE_ENDIAN);
byte[] buf = new byte[1024];
int count = fis.read(buf);
while(count != -1) {
buffer.put(buf, 0, count);
count = fis.read(buf);
}
buffer.flip();
parseIffStructure(buffer, i, 0, file);
fis.close();
} catch (FileNotFoundException e) {
System.out.println("!File not found: " + file.toString());
} catch (IOException e) {
System.out.println("!IO Error: " + file.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
private static int getNameLength(byte[] data) {
int count = 0;
for(byte b : data) {
if(!((b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9') || b == ' ')) {
break;
} else {
count++;
}
}
if(count < 4) {
return 0;
} else if(count < 8) {
return 4;
} else {
return 8;
}
}
private static boolean childIsData(IoBuffer buf) {
byte[] nameBuf = new byte[8];
int length;
if(buf.remaining() >= 8) {
buf.mark();
buf.get(nameBuf);
buf.reset();
length = getNameLength(nameBuf);
} else {
length = 0;
}
return length == 0;
}
private static boolean isFolderNode(String name) {
if(name.startsWith("FORM") || name.endsWith("FORM"))
return true;
return false;
}
private static void parseIffStructure(IoBuffer buf, VisitorInterface i, int depth, String fileName) throws Exception {
byte[] nameBuf = new byte[8];
//Get the length of the Name
int length;
if(buf.remaining() >= 8) {
buf.mark();
buf.get(nameBuf);
buf.reset();
length = getNameLength(nameBuf);
} else {
length = 0;
}
String name = buf.getString(length, Charset.forName("US-ASCII").newDecoder());
int size = Integer.reverseBytes(buf.getInt());
if(size > buf.remaining()) {
if(name.length() > 0)
System.out.println("Bad client file: " + fileName + " remaining buffer size: " + buf.remaining() + " parsed size: " + size + " parsed Name: " + name);
return;
}
if(size < 0)
return;
if(!isFolderNode(name)) {
IoBuffer dataBuf = buf.getSlice(size);
dataBuf.order(ByteOrder.LITTLE_ENDIAN);
i.parseData(name, dataBuf, depth, size);
} else {
i.notifyFolder(name, depth);
IoBuffer folderBuffer = buf.getSlice(size);
folderBuffer.order(ByteOrder.LITTLE_ENDIAN);
while(folderBuffer.remaining() > 0) {
parseIffStructure(folderBuffer, i, depth+1, name);
}
}
}
}