Write deserialization code

This commit is contained in:
Lonami Exo 2018-07-23 19:28:23 +02:00
parent 389cdae3ec
commit 2f22e74eca
4 changed files with 196 additions and 3 deletions

View File

@ -54,7 +54,7 @@ public class Generator {
writer.write("import io.github.lonamiwebs.overgram.utils.BinaryReader;\n"); writer.write("import io.github.lonamiwebs.overgram.utils.BinaryReader;\n");
writer.write("import io.github.lonamiwebs.overgram.utils.BinaryWriter;\n"); writer.write("import io.github.lonamiwebs.overgram.utils.BinaryWriter;\n");
writer.write("import java.util.List;\n"); writer.write("import java.util.List;\n");
writer.write("@SuppressWarnings(\"unused\")\n"); writer.write("@SuppressWarnings(\"ALL\")\n");
writer.write("public class "); writer.write("public class ");
writer.write(className); writer.write(className);
writer.write(" {\n"); writer.write(" {\n");
@ -95,7 +95,7 @@ public class Generator {
// TODO // TODO
writeSerialize(writer, object); writeSerialize(writer, object);
writer.write("public void deserialize(final BinaryReader reader) {}\n"); writeDeserialize(writer, object);
writer.write("}\n"); writer.write("}\n");
} }
@ -149,6 +149,95 @@ public class Generator {
writer.write("}\n"); writer.write("}\n");
} }
private static void writeDeserialize(final Writer writer, final TLObject object) throws IOException {
writer.write("public void deserialize(final BinaryReader reader) {\n");
for (int i = 0; i < object.args.size(); ++i) {
final TLArg arg = object.args.get(i);
if (arg.flags) {
writer.write("int ");
writer.write(arg.name);
writer.write(" = reader.readInt();\n");
continue;
}
if (arg.flag != null) {
writer.write("if ((");
writer.write(arg.flag.flagName);
writer.write(" & " + (1 << arg.flag.flagIndex));
writer.write(") != 0) { ");
}
// TODO The only nested type we handle is Vector<>, avoid that
// TODO We don't handle boxed vs. unboxed here, either
writer.write(VARIABLE_SUFFIX + i);
writer.write(" = ");
if (arg.types.get(0).equalsIgnoreCase("vector")) {
switch (arg.types.get(1)) {
case "int":
writer.write("reader.readIntList();");
break;
case "long":
writer.write("reader.readLongList();");
break;
case "string":
writer.write("reader.readStringList();");
break;
case "bytes":
writer.write("reader.readBytesList();");
break;
case "int128":
case "int256":
case "double":
case "Bool":
case "true":
throw new UnsupportedOperationException("vector of " + arg.types.get(1));
default:
writer.write("(");
writer.write(arg.javaType());
writer.write(") reader.readTlList();");
break;
}
} else {
switch (arg.types.get(0)) {
case "int":
writer.write("reader.readInt();");
break;
case "long":
// TODO handle int128 and int256 properly
case "int128":
case "int256":
writer.write("reader.readLong();");
break;
case "double":
writer.write("reader.readDouble();");
break;
case "Bool":
case "true":
writer.write("reader.readBoolean();");
break;
case "string":
writer.write("reader.readString();");
break;
case "bytes":
writer.write("reader.readBytes();");
break;
default:
writer.write("(");
writer.write(arg.javaType());
writer.write(") reader.readTl();");
break;
}
}
if (arg.flag != null) {
writer.write(" }\n");
} else {
writer.write('\n');
}
}
writer.write("}\n");
}
private static Map<String, List<TLObject>> byNamespace(final Iterable<TLObject> objects) { private static Map<String, List<TLObject>> byNamespace(final Iterable<TLObject> objects) {
final Map<String, List<TLObject>> result = new HashMap<>(); final Map<String, List<TLObject>> result = new HashMap<>();
for (final TLObject object : objects) { for (final TLObject object : objects) {

View File

@ -5,5 +5,6 @@ import io.github.lonamiwebs.overgram.utils.BinaryWriter;
public abstract class TLObject { public abstract class TLObject {
public abstract void serialize(final BinaryWriter writer); public abstract void serialize(final BinaryWriter writer);
public abstract void deserialize(final BinaryReader reader); public abstract void deserialize(final BinaryReader reader);
} }

View File

@ -1,4 +1,107 @@
package io.github.lonamiwebs.overgram.utils; package io.github.lonamiwebs.overgram.utils;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class BinaryReader { public class BinaryReader {
private final ByteBuffer buffer;
public BinaryReader(final ByteBuffer buffer) {
this.buffer = buffer;
}
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 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);
buffer.position(buffer.position() + 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 Object readTl() {
return null;
}
public List<?> readTlList() {
buffer.position(buffer.position() + 4); // vector code
final int size = buffer.getInt();
final List<Object> result = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
result.add(readTl());
}
return result;
}
} }

View File

@ -34,7 +34,7 @@ public class BinaryWriter {
public void write(final byte[] bytes) { public void write(final byte[] bytes) {
int padding; int padding;
if (bytes.length < 254) { if (bytes.length < 0xfe) {
padding = (bytes.length + 1) % 4; padding = (bytes.length + 1) % 4;
buffer.put((byte) bytes.length); buffer.put((byte) bytes.length);
buffer.put(bytes); buffer.put(bytes);