SforzandoCF

TSO1

Feb 12th, 2026
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.41 KB | None | 0 0
  1. public class TSO1IO {
  2.     public static <T> T read (DataInput di, Class<T> clazz) {
  3.         if (clazz.getDeclaredAnnotation(TSOSerialized.class) == null) throw new IllegalArgumentException("class is not TSO serializable");
  4.         TSOObject o = read(di);
  5.         return readObject(o, clazz);
  6.     }
  7.    
  8.     private static <T> T readObject (TSOObject obj, Class<T> clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException {
  9.         if (clazz.isEnum()) {
  10.             for (T t : clazz.getEnumConstants())
  11.                 if (t.toString().equalsIgnoreCase(obj.getAnyString()))
  12.                     return t;
  13.             throw new TSOFormatException("could not map TSO data to enum");
  14.         } else if (clazz.isRecord()) {
  15.             TSO1Array a = obj.getAnyArray();
  16.             ArrayList<Class<?>> clazzes = new ArrayList<Class<?>>();
  17.             ArrayList<Object> objects = new ArrayList<Object>();
  18.             for (Field f : clazz.getDeclaredFields()) {
  19.                 if (!f.accessFlags().contains(AccessFlag.STATIC)) {
  20.                     clazzes.add(f.getType());
  21.                     objects.add(getObject(obj, f.getName(), f.getType()));
  22.                 }
  23.             }
  24.             Constructor<T> constructor = clazz.getDeclaredConstructor(clazzes.toArray(new Class<?>[clazzes.size()]));
  25.             return constructor.newInstance(objects.toArray());
  26.         } else if (clazz.isInterface() || clazz.accessFlags().contains(AccessFlag.ABSTRACT))
  27.             throw new IllegalArgumentException("class is abstract");
  28.         else {
  29.             TSO1Object a = obj.getAnyObject();
  30.             HashMap<String, Class<?>> clazzes = new HashMap<String, Class<?>>();
  31.             ArrayList<Object> objects = new ArrayList<Object>();
  32.             for (Field f : clazz.getDeclaredFields()) {
  33.                 if (!f.accessFlags().contains(AccessFlag.STATIC)) {
  34.                     clazzes.add(f.getType());
  35.                     objects.add(getObject(obj, f.getName(), f.getType()));
  36.                 }
  37.             }
  38.             Constructor<T> constructor = clazz.getDeclaredConstructor(clazzes.toArray(new Class<?>[clazzes.size()]));
  39.             return constructor.newInstance(objects.toArray());
  40.         }
  41.     }
  42.    
  43.     public static TSO1Object read (DataInput di) throws IOException {
  44.         byte[] sig = new byte[4];
  45.         di.readFully(sig);
  46.         String sigs = new String(sig);
  47.         if (sigs.matches("T[sS][oO]1")) return readObject(di);
  48.         else if (sigs.matches("t[sS][oO]1")) return readObject(new LittleEndianDataInput(di));
  49.         throw new TSOFormatException("not a TSO object");
  50.     }
  51.    
  52.     private static TSO1Object readObject (DataInput di) throws IOException {
  53.         int length = di.readUnsignedShort();
  54.         HashMap<String, Object> tags = new HashMap<String, Object>();
  55.         for (int i = 0; i < length; i++) {
  56.             int type = di.readUnsignedByte();
  57.             String key = di.readUTF();
  58.             switch (type) {
  59.                 case 0:
  60.                     tags.put(key, di.readUTF());
  61.                     break;
  62.                 case 1:
  63.                     tags.put(key, readObject(di));
  64.                     break;
  65.                 case 2:
  66.                     tags.put(key, readArray(di));
  67.                     break;
  68.                 case 3:
  69.                     tags.put(key, Byte.valueOf(di.readByte()));
  70.                     break;
  71.                 case 4:
  72.                     tags.put(key, Short.valueOf(di.readShort()));
  73.                     break;
  74.                 case 5:
  75.                     tags.put(key, Integer.valueOf(di.readInt()));
  76.                     break;
  77.                 case 6:
  78.                     tags.put(key, Long.valueOf(di.readLong()));
  79.                     break;
  80.                 case 7:
  81.                     tags.put(key, Float.valueOf(di.readFloat()));
  82.                     break;
  83.                 case 8:
  84.                     tags.put(key, Double.valueOf(di.readDouble()));
  85.                     break;
  86.                 default:
  87.                     throw new TSOFormatException("invalid tag type {" + key + ":" + type + "}");
  88.             }
  89.         }
  90.         return new TSOObject(tags);
  91.     }
  92.    
  93.     private static TSO1Array readObject (DataInput di) throws IOException {
  94.         int length = di.readUnsignedShort();
  95.         Object[] tags = new Object[length];
  96.         for (int i = 0; i < length; i++) {
  97.             int type = di.readUnsignedByte();
  98.             switch (type) {
  99.                 case 0:
  100.                     tags[i] = (key, di.readUTF());
  101.                     break;
  102.                 case 1:
  103.                     tags[i] = (key, readObject(di));
  104.                     break;
  105.                 case 2:
  106.                     tags[i] = (key, readArray(di));
  107.                     break;
  108.                 case 3:
  109.                     tags[i] = (key, Byte.valueOf(di.readByte()));
  110.                     break;
  111.                 case 4:
  112.                     tags[i] = (key, Short.valueOf(di.readShort()));
  113.                     break;
  114.                 case 5:
  115.                     tags[i] = (key, Integer.valueOf(di.readInt()));
  116.                     break;
  117.                 case 6:
  118.                     tags[i] = (key, Long.valueOf(di.readLong()));
  119.                     break;
  120.                 case 7:
  121.                     tags[i] = (key, Float.valueOf(di.readFloat()));
  122.                     break;
  123.                 case 8:
  124.                     tags[i] = (key, Double.valueOf(di.readDouble()));
  125.                     break;
  126.                 default:
  127.                     throw new TSOFormatException("invalid tag type {" + key + ":" + type + "}");
  128.             }
  129.         }
  130.         return new TSOObject(tags);
  131.     }
  132. }
  133.  
  134. public class LittleEndianDataInput implements DataInput {
  135.     private final DataInput input;
  136.    
  137.     public LittleEndianDataInput (DataInput input) {
  138.         this.input = input;
  139.     }
  140.    
  141.     public boolean readBoolean () {
  142.         return this.input.readBoolean();
  143.     }
  144.    
  145.     public byte readByte () {
  146.         return this.input.readByte();
  147.     }
  148.    
  149.     public char readChar () {
  150.         return (char) Short.reverseBytes(this.input.readShort());
  151.     }
  152.    
  153.     public double readDouble () {
  154.         return Double.longBitsToDouble(Long.reverseBytes(this.input.readLong()));
  155.     }
  156.    
  157.     public float readFloat () {
  158.         return Float.longBitsToDouble(Integer.reverseBytes(this.input.readInt()));
  159.     }
  160.    
  161.     public void readFully (byte[] array) {
  162.         this.input.readFully(array);
  163.     }
  164.    
  165.     public void readFully (byte[] array, int off, int len) {
  166.         this.input.readFully(array, off, len);
  167.     }
  168.    
  169.     public int readInt () {
  170.         return Integer.reverseBytes(this.input.readInt());
  171.     }
  172.    
  173.     public String readLine () {
  174.         return this.input.readLine();
  175.     }
  176.    
  177.     public long readLong () {
  178.         return Long.reverseBytes(this.input.readLong());
  179.     }
  180.    
  181.     public short readShort () {
  182.         return Short.reverseBytes(this.input.readShort());
  183.     }
  184.    
  185.     public int readUnsignedByte () {
  186.         return Integer.compress(this.input.readByte(), 0x8000007F);
  187.     }
  188.    
  189.     public int readUnsignedShort () {
  190.         return Integer.compress(Short.reverseBytes(this.input.readShort()), 0x80007FFF);
  191.     }
  192.    
  193.     public String readUTF () {
  194.         return this.input.readUTF();
  195.     }
  196.    
  197.     public int skipBytes (int n) {
  198.         return this.input.skipBytes(n);
  199.     }
  200. }
Advertisement
Add Comment
Please, Sign In to add comment