Write serialization code

This commit is contained in:
Lonami Exo 2018-07-23 18:45:58 +02:00
parent 19b976807e
commit 1836837245
3 changed files with 145 additions and 12 deletions

View File

@ -7,6 +7,9 @@ import java.io.*;
import java.util.*; import java.util.*;
public class Generator { public class Generator {
private static final String VARIABLE_SUFFIX = "$";
public static void generateJava( public static void generateJava(
final List<TLObject> types, final List<TLObject> functions, final List<TLObject> types, final List<TLObject> functions,
final File abstractsFile, final File typesFile, final File functionsFile) throws IOException { final File abstractsFile, final File typesFile, final File functionsFile) throws IOException {
@ -68,16 +71,13 @@ public class Generator {
writer.write(extendsName); writer.write(extendsName);
writer.write(" {\n"); writer.write(" {\n");
int n = 0; for (int i = 0; i < object.args.size(); ++i) {
for (TLArg arg : object.args) { if (object.args.get(i).flags) {
if (arg.flags) {
continue; continue;
} }
writer.write("private "); writer.write("private ");
writer.write(arg.javaType()); writer.write(object.args.get(i).javaType());
writer.write(" var" + n); writer.write(" " + VARIABLE_SUFFIX + i);
++n;
writer.write(";\n"); writer.write(";\n");
} }
@ -89,7 +89,7 @@ public class Generator {
// Objects will be created with nothing set and the arguments set with .argument(value). // Objects will be created with nothing set and the arguments set with .argument(value).
// TODO // TODO
writer.write("public void serialize(final BinaryWriter writer) {}\n"); writeSerialize(writer, object);
writer.write("public void deserialize(final BinaryReader reader) {}\n"); writer.write("public void deserialize(final BinaryReader reader) {}\n");
writer.write("}\n"); writer.write("}\n");
@ -101,6 +101,49 @@ public class Generator {
writer.write("}\n"); writer.write("}\n");
} }
private static void writeSerialize(final Writer writer, final TLObject object) throws IOException {
writer.write("public void serialize(final BinaryWriter writer) {\n");
for (final TLArg arg : object.args) {
if (arg.flags) {
writer.write("int ");
writer.write(arg.name);
writer.write(" = 0;\n");
}
}
for (int i = 0; i < object.args.size(); ++i) {
final TLArg arg = object.args.get(i);
if (arg.flag != null) {
writer.write("if (" + VARIABLE_SUFFIX + i);
writer.write(arg.javaSetCheck());
writer.write(") { ");
writer.write(arg.flag.flagName);
writer.write(" |= " + (1 << arg.flag.flagIndex));
writer.write("; }\n");
}
}
for (int i = 0; i < object.args.size(); ++i) {
final TLArg arg = object.args.get(i);
if (arg.flag != null) {
writer.write("if (" + VARIABLE_SUFFIX + i);
writer.write(arg.javaSetCheck());
writer.write(") { ");
}
if (!arg.flags) {
writer.write("writer.write(" + VARIABLE_SUFFIX + i + ");");
} else {
writer.write("writer.write(");
writer.write(arg.name);
writer.write(");");
}
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

@ -61,7 +61,7 @@ public class TLArg {
} }
break; break;
case "long": case "long":
// TODO handle int128 and int256 properly // TODO handle int128 and int256 properly
case "int128": case "int128":
case "int256": case "int256":
if (flag == null && !nested) { if (flag == null && !nested) {
@ -110,6 +110,10 @@ public class TLArg {
return builder.toString(); return builder.toString();
} }
public String javaSetCheck() {
return types.size() == 1 && types.get(0).equals("true") ? "" : " != null";
}
@Override @Override
public String toString() { public String toString() {
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
@ -134,9 +138,9 @@ public class TLArg {
return builder.toString(); return builder.toString();
} }
private static final class Flag { public static final class Flag {
private final String flagName; public final String flagName;
private final int flagIndex; public final int flagIndex;
private Flag(final String flagName, final int flagIndex) { private Flag(final String flagName, final int flagIndex) {
this.flagName = flagName; this.flagName = flagName;

View File

@ -1,5 +1,91 @@
package io.github.lonamiwebs.overgram.utils; 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 { 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 < 254) {
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<TLObject>) objects) {
write(obj);
}
} else if (first instanceof Integer) {
for (final Integer obj : (List<Integer>) objects) {
write(obj);
}
} else if (first instanceof Long) {
for (final Long obj : (List<Long>) objects) {
write(obj);
}
} else if (first instanceof byte[]) {
for (final byte[] obj : (List<byte[]>) objects) {
write(obj);
}
} else {
throw new UnsupportedOperationException();
}
}
} }