Overgram/lib/src/main/java/io/github/lonamiwebs/overgram/utils/BinaryReader.java

167 lines
4.5 KiB
Java

package io.github.lonamiwebs.overgram.utils;
import io.github.lonamiwebs.overgram.tl.*;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class BinaryReader {
private final ByteBuffer buffer;
public BinaryReader(final ByteBuffer buffer) {
this.buffer = buffer.order(ByteOrder.LITTLE_ENDIAN);
}
public int readInt() {
return buffer.getInt();
}
public List<Integer> readIntList() {
buffer.position(buffer.position() + 4); // vector code
final int size = buffer.getInt();
final List<Integer> result = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
result.add(buffer.getInt());
}
return result;
}
public long readLong() {
return buffer.getLong();
}
public List<Long> readLongList() {
buffer.position(buffer.position() + 4); // vector code
final int size = buffer.getInt();
final List<Long> result = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
result.add(buffer.getLong());
}
return result;
}
public BigInteger readInt128() {
final byte[] bytes = new byte[16];
buffer.get(bytes);
return new BigInteger(Utils.reversed(bytes));
}
public BigInteger readInt256() {
final byte[] bytes = new byte[32];
buffer.get(bytes);
return new BigInteger(Utils.reversed(bytes));
}
public double readDouble() {
return buffer.getDouble();
}
public boolean readBoolean() {
return buffer.getInt() == 0x997275b5;
}
public byte[] readBytes() {
int length;
int padding;
final byte first = buffer.get();
if (first == (byte) 0xfe) {
buffer.position(buffer.position() - 1);
length = buffer.getInt() >> 8;
padding = length % 4;
} else {
length = first;
padding = (length + 1) % 4;
}
final byte[] data = new byte[length];
buffer.get(data);
if (padding > 0) {
buffer.position(buffer.position() + 4 - padding);
}
return data;
}
public List<byte[]> readBytesList() {
buffer.position(buffer.position() + 4); // vector code
final int size = buffer.getInt();
final List<byte[]> result = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
result.add(readBytes());
}
return result;
}
public String readString() {
return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(readBytes())).toString();
}
public List<String> readStringList() {
buffer.position(buffer.position() + 4); // vector code
final int size = buffer.getInt();
final List<String> result = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
result.add(readString());
}
return result;
}
public TLObject readTl() throws ClassNotFoundException {
final int id = readInt();
final TLObject object;
switch (id) {
case RPCResult.CONSTRUCTOR_ID:
object = new RPCResult();
break;
case GzipPacked.CONSTRUCTOR_ID:
object = new GzipPacked();
break;
case MessageContainer.CONSTRUCTOR_ID:
object = new MessageContainer();
break;
default:
object = Types.getFromId(id);
break;
}
object.deserialize(this);
return object;
}
public List<?> readTlList() throws ClassNotFoundException {
buffer.position(buffer.position() + 4); // vector code
final int size = buffer.getInt();
final List<TLObject> result = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
result.add(readTl());
}
return result;
}
public int tell() {
return buffer.position();
}
public void seek(final int delta) {
buffer.position(buffer.position() + delta);
}
public void set(final int position) {
buffer.position(position);
}
public byte[] read(final int size) {
final byte[] result = new byte[size];
buffer.get(result);
return result;
}
public byte[] read() {
final byte[] result = new byte[buffer.remaining()];
buffer.get(result);
return result;
}
}