package io.github.lonamiwebs.overgram.utils; import io.github.lonamiwebs.overgram.tl.TLObject; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.List; public class BinaryWriter { private final ByteBuffer buffer; public BinaryWriter() { buffer = ByteBuffer.allocate(128); buffer.order(ByteOrder.LITTLE_ENDIAN); } public void write(final int value) { buffer.putInt(value); } public void write(final long value) { buffer.putLong(value); } public void write(final double value) { buffer.putDouble(value); } public void write(final boolean value) { buffer.putInt(value ? 0x997275b5 : 0xbc799737); } public void write(final byte[] bytes) { int padding; if (bytes.length < 0xfe) { padding = (bytes.length + 1) % 4; buffer.put((byte) bytes.length); buffer.put(bytes); } else { padding = bytes.length % 4; buffer.putInt(bytes.length << 8 | 0xfe); buffer.put(bytes); } if (padding != 0) { for (padding = 4 - padding; padding-- != 0; ) { buffer.put((byte) 0); } } } public void write(final String string) { buffer.put(StandardCharsets.UTF_8.encode(string)); } // TODO Handle boxed vs unboxed types (and vector<>) public void write(final TLObject object) { object.serialize(this); } @SuppressWarnings("unchecked") public void write(final List objects) { write(0x1cb5c415); write(objects.size()); if (objects.isEmpty()) { return; } final Object first = objects.get(0); if (first instanceof TLObject) { for (final TLObject obj : (List) objects) { write(obj); } } else if (first instanceof Integer) { for (final Integer obj : (List) objects) { write(obj); } } else if (first instanceof Long) { for (final Long obj : (List) objects) { write(obj); } } else if (first instanceof byte[]) { for (final byte[] obj : (List) objects) { write(obj); } } else { throw new UnsupportedOperationException(); } } }