Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class TSO1IO {
- public static <T> T read (DataInput di, Class<T> clazz) {
- if (clazz.getDeclaredAnnotation(TSOSerialized.class) == null) throw new IllegalArgumentException("class is not TSO serializable");
- TSOObject o = read(di);
- return readObject(o, clazz);
- }
- private static <T> T readObject (TSOObject obj, Class<T> clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException {
- if (clazz.isEnum()) {
- for (T t : clazz.getEnumConstants())
- if (t.toString().equalsIgnoreCase(obj.getAnyString()))
- return t;
- throw new TSOFormatException("could not map TSO data to enum");
- } else if (clazz.isRecord()) {
- TSO1Array a = obj.getAnyArray();
- ArrayList<Class<?>> clazzes = new ArrayList<Class<?>>();
- ArrayList<Object> objects = new ArrayList<Object>();
- for (Field f : clazz.getDeclaredFields()) {
- if (!f.accessFlags().contains(AccessFlag.STATIC)) {
- clazzes.add(f.getType());
- objects.add(getObject(obj, f.getName(), f.getType()));
- }
- }
- Constructor<T> constructor = clazz.getDeclaredConstructor(clazzes.toArray(new Class<?>[clazzes.size()]));
- return constructor.newInstance(objects.toArray());
- } else if (clazz.isInterface() || clazz.accessFlags().contains(AccessFlag.ABSTRACT))
- throw new IllegalArgumentException("class is abstract");
- else {
- TSO1Object a = obj.getAnyObject();
- HashMap<String, Class<?>> clazzes = new HashMap<String, Class<?>>();
- ArrayList<Object> objects = new ArrayList<Object>();
- for (Field f : clazz.getDeclaredFields()) {
- if (!f.accessFlags().contains(AccessFlag.STATIC)) {
- clazzes.add(f.getType());
- objects.add(getObject(obj, f.getName(), f.getType()));
- }
- }
- Constructor<T> constructor = clazz.getDeclaredConstructor(clazzes.toArray(new Class<?>[clazzes.size()]));
- return constructor.newInstance(objects.toArray());
- }
- }
- public static TSO1Object read (DataInput di) throws IOException {
- byte[] sig = new byte[4];
- di.readFully(sig);
- String sigs = new String(sig);
- if (sigs.matches("T[sS][oO]1")) return readObject(di);
- else if (sigs.matches("t[sS][oO]1")) return readObject(new LittleEndianDataInput(di));
- throw new TSOFormatException("not a TSO object");
- }
- private static TSO1Object readObject (DataInput di) throws IOException {
- int length = di.readUnsignedShort();
- HashMap<String, Object> tags = new HashMap<String, Object>();
- for (int i = 0; i < length; i++) {
- int type = di.readUnsignedByte();
- String key = di.readUTF();
- switch (type) {
- case 0:
- tags.put(key, di.readUTF());
- break;
- case 1:
- tags.put(key, readObject(di));
- break;
- case 2:
- tags.put(key, readArray(di));
- break;
- case 3:
- tags.put(key, Byte.valueOf(di.readByte()));
- break;
- case 4:
- tags.put(key, Short.valueOf(di.readShort()));
- break;
- case 5:
- tags.put(key, Integer.valueOf(di.readInt()));
- break;
- case 6:
- tags.put(key, Long.valueOf(di.readLong()));
- break;
- case 7:
- tags.put(key, Float.valueOf(di.readFloat()));
- break;
- case 8:
- tags.put(key, Double.valueOf(di.readDouble()));
- break;
- default:
- throw new TSOFormatException("invalid tag type {" + key + ":" + type + "}");
- }
- }
- return new TSOObject(tags);
- }
- private static TSO1Array readObject (DataInput di) throws IOException {
- int length = di.readUnsignedShort();
- Object[] tags = new Object[length];
- for (int i = 0; i < length; i++) {
- int type = di.readUnsignedByte();
- switch (type) {
- case 0:
- tags[i] = (key, di.readUTF());
- break;
- case 1:
- tags[i] = (key, readObject(di));
- break;
- case 2:
- tags[i] = (key, readArray(di));
- break;
- case 3:
- tags[i] = (key, Byte.valueOf(di.readByte()));
- break;
- case 4:
- tags[i] = (key, Short.valueOf(di.readShort()));
- break;
- case 5:
- tags[i] = (key, Integer.valueOf(di.readInt()));
- break;
- case 6:
- tags[i] = (key, Long.valueOf(di.readLong()));
- break;
- case 7:
- tags[i] = (key, Float.valueOf(di.readFloat()));
- break;
- case 8:
- tags[i] = (key, Double.valueOf(di.readDouble()));
- break;
- default:
- throw new TSOFormatException("invalid tag type {" + key + ":" + type + "}");
- }
- }
- return new TSOObject(tags);
- }
- }
- public class LittleEndianDataInput implements DataInput {
- private final DataInput input;
- public LittleEndianDataInput (DataInput input) {
- this.input = input;
- }
- public boolean readBoolean () {
- return this.input.readBoolean();
- }
- public byte readByte () {
- return this.input.readByte();
- }
- public char readChar () {
- return (char) Short.reverseBytes(this.input.readShort());
- }
- public double readDouble () {
- return Double.longBitsToDouble(Long.reverseBytes(this.input.readLong()));
- }
- public float readFloat () {
- return Float.longBitsToDouble(Integer.reverseBytes(this.input.readInt()));
- }
- public void readFully (byte[] array) {
- this.input.readFully(array);
- }
- public void readFully (byte[] array, int off, int len) {
- this.input.readFully(array, off, len);
- }
- public int readInt () {
- return Integer.reverseBytes(this.input.readInt());
- }
- public String readLine () {
- return this.input.readLine();
- }
- public long readLong () {
- return Long.reverseBytes(this.input.readLong());
- }
- public short readShort () {
- return Short.reverseBytes(this.input.readShort());
- }
- public int readUnsignedByte () {
- return Integer.compress(this.input.readByte(), 0x8000007F);
- }
- public int readUnsignedShort () {
- return Integer.compress(Short.reverseBytes(this.input.readShort()), 0x80007FFF);
- }
- public String readUTF () {
- return this.input.readUTF();
- }
- public int skipBytes (int n) {
- return this.input.skipBytes(n);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment