add SOD
parent
3ac06e30b1
commit
a76bd342e5
|
@ -0,0 +1,64 @@
|
|||
package tk.valoeghese.sod;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import tk.valoeghese.sod.exception.SODParseException;
|
||||
|
||||
public class BinaryData implements Iterable<Map.Entry<String, DataSection>> {
|
||||
public BinaryData() {
|
||||
this.sections = new HashMap<>();
|
||||
}
|
||||
|
||||
private final Map<String, DataSection> sections;
|
||||
|
||||
public DataSection get(String name) {
|
||||
return this.sections.get(name);
|
||||
}
|
||||
|
||||
public DataSection getOrCreate(String name) {
|
||||
return this.sections.computeIfAbsent(name, k -> new DataSection());
|
||||
}
|
||||
|
||||
public void put(String name, DataSection section) {
|
||||
this.sections.put(name, section);
|
||||
}
|
||||
|
||||
public boolean write(File file) {
|
||||
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) {
|
||||
Parser.write(this, dos);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Map.Entry<String, DataSection>> iterator() {
|
||||
return this.sections.entrySet().iterator();
|
||||
}
|
||||
|
||||
public static BinaryData read(File file) throws SODParseException {
|
||||
try (DataInputStream dis = new DataInputStream(new FileInputStream(file))) {
|
||||
long magic = dis.readLong();
|
||||
|
||||
if (magic != 0xA77D1E) {
|
||||
throw new SODParseException("Not a valid SOD file!");
|
||||
}
|
||||
|
||||
return Parser.parse(dis);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
//throw new SODParseException("Error in parsing file " + file.toString());
|
||||
return new BinaryData();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package tk.valoeghese.sod;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a section of SOD data.
|
||||
* @author Valoeghese
|
||||
*/
|
||||
public class DataSection implements Iterable<Object> {
|
||||
public DataSection() {
|
||||
this.data = new ArrayList<>();
|
||||
}
|
||||
|
||||
private final List<Object> data;
|
||||
|
||||
public void writeByte(byte data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
|
||||
public void writeShort(short data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
|
||||
public void writeInt(int data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
|
||||
public void writeLong(long data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
|
||||
public void writeFloat(float data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
|
||||
public void writeDouble(double data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
|
||||
public void writeString(String data) {
|
||||
this.data.add(data);
|
||||
}
|
||||
|
||||
public void writeBoolean(boolean data) {
|
||||
this.data.add(data ? (byte) 1 : (byte) 0);
|
||||
}
|
||||
|
||||
public <T extends Enum<?>> void writeEnum(T enumValue) {
|
||||
this.data.add(enumValue.ordinal());
|
||||
}
|
||||
|
||||
public <T extends Enum<?>> void writeEnumAsString(T enumValue) {
|
||||
this.data.add(enumValue.toString());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.data.size();
|
||||
}
|
||||
|
||||
public byte readByte(int index) {
|
||||
return (byte) this.data.get(index);
|
||||
}
|
||||
|
||||
public short readShort(int index) {
|
||||
return (short) this.data.get(index);
|
||||
}
|
||||
|
||||
public int readInt(int index) {
|
||||
return (int) this.data.get(index);
|
||||
}
|
||||
|
||||
public long readLong(int index) {
|
||||
return (long) this.data.get(index);
|
||||
}
|
||||
|
||||
public float readFloat(int index) {
|
||||
return (float) this.data.get(index);
|
||||
}
|
||||
|
||||
public double readDouble(int index) {
|
||||
return (double) this.data.get(index);
|
||||
}
|
||||
|
||||
public String readString(int index) {
|
||||
return (String) this.data.get(index);
|
||||
}
|
||||
|
||||
public boolean readBoolean(int index) {
|
||||
return ((byte) this.data.get(index)) != 0;
|
||||
}
|
||||
|
||||
public <T extends Enum<T>> T readEnumString(int index, Class<T> type) {
|
||||
return Enum.valueOf(type, (String) this.data.get(index));
|
||||
}
|
||||
|
||||
public <T extends Enum<?>> T readEnum(int index, T[] values) {
|
||||
return values[(int) this.data.get(index)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Object> iterator() {
|
||||
return this.data.iterator();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package tk.valoeghese.sod;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import tk.valoeghese.sod.exception.SODParseException;
|
||||
|
||||
final class Parser {
|
||||
static BinaryData parse(DataInputStream input) throws IOException, SODParseException {
|
||||
BinaryData data = new BinaryData();
|
||||
|
||||
DataType dataType;
|
||||
dataType = DataType.of(input.readByte());
|
||||
|
||||
if (dataType != DataType.SECTION) {
|
||||
throw new SODParseException("Data must be segregated into sections!");
|
||||
}
|
||||
|
||||
DataSection currentSection = new DataSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
|
||||
while (input.available() > 0) {
|
||||
dataType = DataType.of(input.readByte());
|
||||
|
||||
switch (dataType) {
|
||||
case BYTE:
|
||||
currentSection.writeByte(input.readByte());
|
||||
break;
|
||||
case DOUBLE:
|
||||
currentSection.writeDouble(input.readDouble());
|
||||
break;
|
||||
case FLOAT:
|
||||
currentSection.writeFloat(input.readFloat());
|
||||
break;
|
||||
case INT:
|
||||
currentSection.writeInt(input.readInt());
|
||||
break;
|
||||
case LONG:
|
||||
currentSection.writeLong(input.readLong());
|
||||
break;
|
||||
case SECTION:
|
||||
currentSection = new DataSection();
|
||||
data.put(input.readUTF(), currentSection);
|
||||
break;
|
||||
case SHORT:
|
||||
currentSection.writeShort(input.readShort());
|
||||
break;
|
||||
case STRING:
|
||||
currentSection.writeString(input.readUTF());
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("This error should never be thrown! If this error occurs, the parser is not properly dealing with a most-likely-invalid data type.");
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void write(BinaryData data, DataOutputStream dos) throws IOException {
|
||||
dos.writeLong(0xA77D1E);
|
||||
|
||||
Iterator<Map.Entry<String, DataSection>> sectionStream = data.iterator();
|
||||
|
||||
while (sectionStream.hasNext()) {
|
||||
Map.Entry<String, DataSection> section = sectionStream.next();
|
||||
dos.writeByte(DataType.SECTION.id);
|
||||
dos.writeUTF(section.getKey());
|
||||
|
||||
Iterator<Object> dataStream = section.getValue().iterator();
|
||||
|
||||
while (dataStream.hasNext()) {
|
||||
Object o = dataStream.next();
|
||||
|
||||
if (o instanceof Byte) {
|
||||
dos.writeByte(DataType.BYTE.id);
|
||||
dos.writeByte((byte) o);
|
||||
} else if (o instanceof Short) {
|
||||
dos.writeByte(DataType.SHORT.id);
|
||||
dos.writeShort((short) o);
|
||||
} else if (o instanceof Integer) {
|
||||
dos.writeByte(DataType.INT.id);
|
||||
dos.writeInt((int) o);
|
||||
} else if (o instanceof Long) {
|
||||
dos.writeByte(DataType.LONG.id);
|
||||
dos.writeLong((long) o);
|
||||
} else if (o instanceof Float) {
|
||||
dos.writeByte(DataType.FLOAT.id);
|
||||
dos.writeFloat((float) o);
|
||||
} else if (o instanceof Double) {
|
||||
dos.writeByte(DataType.DOUBLE.id);
|
||||
dos.writeDouble((double) o);
|
||||
} else if (o instanceof String) {
|
||||
dos.writeByte(DataType.STRING.id);
|
||||
dos.writeUTF((String) o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum DataType {
|
||||
SECTION(0),
|
||||
BYTE(1),
|
||||
SHORT(2),
|
||||
INT(3),
|
||||
LONG(4),
|
||||
FLOAT(5),
|
||||
DOUBLE(6),
|
||||
STRING(7);
|
||||
|
||||
private DataType(int id) {
|
||||
this.id = (byte) id;
|
||||
}
|
||||
|
||||
public final byte id;
|
||||
|
||||
public static DataType of(byte id) throws SODParseException {
|
||||
switch (id) {
|
||||
case 0:
|
||||
return SECTION;
|
||||
case 1:
|
||||
return BYTE;
|
||||
case 2:
|
||||
return SHORT;
|
||||
case 3:
|
||||
return INT;
|
||||
case 4:
|
||||
return LONG;
|
||||
case 5:
|
||||
return FLOAT;
|
||||
case 6:
|
||||
return DOUBLE;
|
||||
case 7:
|
||||
return STRING;
|
||||
default:
|
||||
throw new SODParseException("Unknown data type " + String.valueOf(id));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package tk.valoeghese.sod;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class TestMain {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
//writeTest()
|
||||
readTest();
|
||||
}
|
||||
|
||||
static void readTest() throws IOException {
|
||||
File f = new File("../test.sod");
|
||||
|
||||
if (!f.createNewFile()) {
|
||||
BinaryData bd = BinaryData.read(f);
|
||||
|
||||
DataSection ds1 = bd.get("DS1");
|
||||
|
||||
for (Object i : ds1) {
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
DataSection ds2 = bd.get("yeet");
|
||||
|
||||
for (Object i : ds2) {
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void writeTest() throws IOException {
|
||||
File f = new File("../test.sod");
|
||||
f.createNewFile();
|
||||
BinaryData bd = new BinaryData();
|
||||
|
||||
DataSection ds1 = bd.getOrCreate("DS1");
|
||||
ds1.writeBoolean(false);
|
||||
ds1.writeDouble(0.666D);
|
||||
ds1.writeLong(69696969);
|
||||
ds1.writeString("yaY33T");
|
||||
|
||||
DataSection ds2 = bd.getOrCreate("yeet");
|
||||
ds2.writeByte((byte) 4);
|
||||
ds2.writeFloat(1.3F);
|
||||
ds2.writeString("e");
|
||||
ds2.writeString("ff");
|
||||
|
||||
bd.write(f);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package tk.valoeghese.sod.exception;
|
||||
|
||||
public class SODParseException extends RuntimeException {
|
||||
private static final long serialVersionUID = -3337517517501006140L;
|
||||
|
||||
public SODParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue