Skip to content

Instantly share code, notes, and snippets.

@gsrunion
Created April 19, 2022 15:12
Show Gist options
  • Save gsrunion/5626658b5112b70fb71a2bebee1dfb9c to your computer and use it in GitHub Desktop.
Save gsrunion/5626658b5112b70fb71a2bebee1dfb9c to your computer and use it in GitHub Desktop.
Struct 4 Java
public class Struct {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Unsigned {
}
public void encode(ByteBuffer buffer) {
for (Field field : this.getClass().getDeclaredFields()) {
try {
Object value = field.get(this);
boolean signed = field.getAnnotation(Unsigned.class) != null;
if (value instanceof Byte b) buffer.put(b);
else if (value instanceof byte[] b) buffer.put(b);
else if (value instanceof Boolean b) buffer.put((byte) (b ? 0x01 : 0x00));
else if (value instanceof Short s && !signed) buffer.putShort(s);
else if (value instanceof Short s) buffer.put(s.byteValue());
else if (value instanceof Integer i && !signed) buffer.putInt(i);
else if (value instanceof Integer i) buffer.putShort(i.shortValue());
else if (value instanceof Long l && !signed) buffer.putLong(l);
else if (value instanceof Long l) buffer.putInt(l.intValue());
else if (value instanceof Float f) buffer.putFloat(f);
else if (value instanceof Double d) buffer.putDouble(d);
else if (value instanceof Character c) buffer.putChar(c);
else if (value instanceof Struct s) s.encode(buffer);
else throw new IllegalArgumentException();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
public void decode(ByteBuffer buffer) {
for (Field field : this.getClass().getDeclaredFields()) {
try {
Object value = field.get(this);
boolean signed = field.getAnnotation(Unsigned.class) != null;
if (value instanceof Byte b) field.set(this, buffer.get(b));
else if (value instanceof byte[] b) buffer.get(b);
else if (value instanceof Boolean b) field.set(this, buffer.get() != 0 ? true : false);
else if (value instanceof Short && !signed) field.set(this, buffer.getShort());
else if (value instanceof Short) field.set(this, (short)Byte.toUnsignedInt(buffer.get()));
else if (value instanceof Integer && !signed) field.set(this, buffer.getInt());
else if (value instanceof Integer) field.set(this, Short.toUnsignedInt(buffer.getShort()));
else if (value instanceof Long && !signed) field.set(this, buffer.getLong());
else if (value instanceof Long) field.set(this, Integer.toUnsignedLong(buffer.getInt()));
else if (value instanceof Float) field.set(this, buffer.getFloat());
else if (value instanceof Double) field.set(this, buffer.getDouble());
else if (value instanceof Character) field.set(this, buffer.getChar());
else if (value instanceof Struct s) s.decode(buffer);
else throw new IllegalArgumentException();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment