Commit db907cb9 authored by Hengwen Zhang's avatar Hengwen Zhang
Browse files

Merge branch 'master' into ltl-components

# Conflicts:
#	src/main/java/de/rwth/montisim/commons/utils/json/Json.java
parents 6ece7edb ac277d96
package de.rwth.montisim.commons.dynamicinterface;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import de.rwth.montisim.commons.utils.*;
import de.rwth.montisim.commons.utils.json.*;
@Typed(BasicType.TYPE)
public class BasicType extends DataType {
public static final String TYPE = "basic";
public static final BasicType DOUBLE = new BasicType(Type.DOUBLE);
public static final BasicType FLOAT = new BasicType(Type.FLOAT);
public static final BasicType INT = new BasicType(Type.INT);
public static final BasicType Q = new BasicType(Type.Q);
public static final BasicType Z = new BasicType(Type.Z);
public static final BasicType N = new BasicType(Type.N);
public static final BasicType N1 = new BasicType(Type.N1);
public static final BasicType C = new BasicType(Type.C);
public static final BasicType BOOLEAN = new BasicType(Type.BOOLEAN);
public static final BasicType BYTE = new BasicType(Type.BYTE);
public static final BasicType DOUBLE = Q;
public static final BasicType INT = Z;
// public static final BasicType FLOAT = new BasicType(Type.FLOAT);
// public static final BasicType BYTE = new BasicType(Type.BYTE);
public static final BasicType EMPTY = new BasicType(Type.EMPTY);
public static final BasicType VEC2 = new BasicType(Type.VEC2);
......@@ -20,26 +29,21 @@ public class BasicType extends DataType {
this.base_type = basic_type;
}
private BasicType(){}
private BasicType() {
}
public Type base_type;
private Type base_type;
public static enum Type {
@JsonEntry("double")
DOUBLE(Double.class, double[].class, 8),
@JsonEntry("float")
FLOAT(Float.class, float[].class, 4),
@JsonEntry("int")
INT(Integer.class, int[].class, 4),
@JsonEntry("byte")
BYTE(Byte.class, byte[].class, 1),
@JsonEntry("boolean")
BOOLEAN(Boolean.class, boolean[].class, 1),
@JsonEntry("void")
// @JsonEntry("float")
// FLOAT(Float.class, float[].class, 4),
Q(Double.class, double[].class, 8), Z(Integer.class, int[].class, 4), N(Integer.class, int[].class, 4),
N1(Integer.class, int[].class, 4), C(Vec2.class, Object[].class, 16), @JsonEntry("boolean")
BOOLEAN(Boolean.class, boolean[].class, 1), @JsonEntry("void")
EMPTY(null, null, 0),
// Vec2 and Vec3 are special cases of VectorType with length 2/3
@JsonEntry("vec2")
VEC2(Vec2.class, Object[].class, 16),
@JsonEntry("vec3")
VEC2(Vec2.class, Object[].class, 16), @JsonEntry("vec3")
VEC3(Vec3.class, Object[].class, 24);
Type(Class<?> c, Class<?> array_c, int size) {
......@@ -83,7 +87,8 @@ public class BasicType extends DataType {
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
if (base_type.c == null) return null;
if (base_type.c == null)
return null;
return Json.instantiateFromJson(j, base_type.c, context);
}
......@@ -92,5 +97,80 @@ public class BasicType extends DataType {
return base_type.array_c;
}
public Type getType() {
return base_type;
}
@Override
public void toBinary(DataOutputStream os, Object o) throws IOException {
switch (base_type) {
case BOOLEAN:
if ((Boolean)o){
os.writeByte(1);
} else {
os.writeByte(0);
}
break;
case C:
throw new IllegalArgumentException("Unimplemented");
case EMPTY:
break;
case N:
case N1:
case Z:
os.writeInt((Integer) o);
break;
case Q:
os.writeDouble((Double) o);
break;
case VEC2:
Vec2 v2 = (Vec2) o;
os.writeDouble(v2.x);
os.writeDouble(v2.y);
break;
case VEC3:
Vec3 v3 = (Vec3) o;
os.writeDouble(v3.x);
os.writeDouble(v3.y);
os.writeDouble(v3.z);
break;
default:
throw new IllegalArgumentException("Missing case");
}
}
@Override
public Object fromBinary(DataInputStream is) throws IOException {
switch (base_type) {
case BOOLEAN:
return is.readByte() != 0;
case C:
throw new IllegalArgumentException("Unimplemented");
case EMPTY:
return null;
case N:
case N1:
case Z:
return is.readInt();
case Q:
return is.readDouble();
case VEC2:
double x1 = is.readDouble();
double y1 = is.readDouble();
return new Vec2(x1, y1);
case VEC3:
double x2 = is.readDouble();
double y2 = is.readDouble();
double z2 = is.readDouble();
return new Vec3(x2, y2, z2);
default:
throw new IllegalArgumentException("Missing case");
}
}
@Override
public String toString() {
return base_type.name();
}
}
\ No newline at end of file
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.dynamicinterface;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import de.rwth.montisim.commons.utils.json.*;
/**
......@@ -8,15 +12,10 @@ import de.rwth.montisim.commons.utils.json.*;
*/
public abstract class DataType {
static {
try {
Json.registerType(BasicType.class);
Json.registerType(VectorType.class);
Json.registerType(ArrayType.class);
Json.registerType(StructType.class);
} catch (SerializationException e) {
e.printStackTrace();
System.exit(-1);
}
Json.registerType(BasicType.class);
Json.registerType(DynVectorType.class);
Json.registerType(VectorType.class);
Json.registerType(StructType.class);
}
public abstract int getDataSize(Object o);
......@@ -29,5 +28,8 @@ public abstract class DataType {
public abstract void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException;
public abstract Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException;
public abstract void toBinary(DataOutputStream os, Object o) throws IOException;
public abstract Object fromBinary(DataInputStream is) throws IOException;
public abstract Class<?> getArrayType();
}
\ No newline at end of file
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.dynamicinterface;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import de.rwth.montisim.commons.utils.ParsingException;
import de.rwth.montisim.commons.utils.json.*;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ArrayIterable;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ValueType;
@Typed("array")
public class ArrayType extends DataType {
@Typed("dyn_vector")
public class DynVectorType extends DataType {
public DataType base_type;
public int size;
public int max_size;
public ArrayType(DataType base_type, int size) {
public DynVectorType(DataType base_type, int max_size) {
this.base_type = base_type;
this.size = size;
this.max_size = max_size;
}
private ArrayType() {}
private DynVectorType() {
}
@Override
public int getDataSize(Object o) {
// TODO optimize size calls
int size = 0;
Object arr[] = (Object[]) o;
for (Object oi : arr) size += base_type.getDataSize(oi);
return size;
for (Object oi : arr)
size += base_type.getDataSize(oi);
return size + 4;
}
@Override
public String toString() {
return "[" + base_type.toString() + "; " + size + "]";
//return "<" + base_type.toString() + "; " + size + ">";
return "<" + base_type.toString() + "; " + max_size + ">";
}
// Implement hashCode & equals to be able to perform hashmap lookup by type &
......@@ -37,10 +43,10 @@ public class ArrayType extends DataType {
@Override
public int hashCode() {
final int prime = 31;
final int prime = 13;
int result = 1;
result = prime * result + ((base_type == null) ? 0 : base_type.hashCode());
result = prime * result + Integer.valueOf(size).hashCode();
result = prime * result + Integer.valueOf(max_size).hashCode();
return result;
}
......@@ -52,25 +58,32 @@ public class ArrayType extends DataType {
return true;
if (this.getClass() != o.getClass())
return false;
ArrayType a = ((ArrayType) o);
return this.base_type.equals(a.base_type) && this.size == a.size;
DynVectorType a = ((DynVectorType) o);
return this.base_type.equals(a.base_type) && this.max_size == a.max_size;
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
Class<?> array_c = base_type.getArrayType();
if (array_c == null) return null;
if (array_c == null)
return null;
if (array_c != Object[].class)
return Json.instantiateFromJson(j, array_c, context);
ArrayIterable it = j.streamArray();
if (!it.iterator().hasNext())
throw new ParsingException("Missing length entry in VectorType serialization.");
it.iterator().next();
int size = (int) j.getLong();
Object o[] = new Object[size];
int i = 0;
for (ValueType t : j.streamArray()){
if (i >= size) throw new ParsingException("Too much entries in Array serialization.");
for (ValueType t : it) {
if (i >= size)
throw new ParsingException("Too much entries in VectorType serialization.");
o[i] = base_type.fromJson(j, context);
i++;
}
if (i < size) throw new ParsingException("Missing entries in Array serialization.");
if (i < size)
throw new ParsingException("Missing entries in VectorType serialization.");
return o;
}
......@@ -79,16 +92,19 @@ public class ArrayType extends DataType {
if (o == null)
return;
Class<?> array_c = base_type.getArrayType();
if (array_c == null) return;
if (array_c != Object[].class){
if (array_c == null)
return;
if (array_c != Object[].class) {
Json.toJson(j, o, context);
return;
}
Object arr[] = (Object[]) o;
j.startArray();
if (arr.length != size) throw new IllegalArgumentException("Array length does not match its ArrayType length");
for (Object oi : arr){
if (arr.length > max_size)
throw new IllegalArgumentException("Vector length above VectorType limit.");
j.writeValue(arr.length);
for (Object oi : arr) {
base_type.toJson(j, oi, context);
}
j.endArray();
......@@ -99,4 +115,14 @@ public class ArrayType extends DataType {
return Object[].class;
}
@Override
public void toBinary(DataOutputStream os, Object o) throws IOException {
throw new IllegalArgumentException("Unimplemented");
}
@Override
public Object fromBinary(DataInputStream is) throws IOException {
throw new IllegalArgumentException("Unimplemented");
}
}
\ No newline at end of file
package de.rwth.montisim.commons.dynamicinterface;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;
import de.rwth.montisim.commons.utils.json.Json;
import de.rwth.montisim.commons.utils.json.JsonTraverser;
import de.rwth.montisim.commons.utils.json.JsonWriter;
import de.rwth.montisim.commons.utils.json.SerializationContext;
import de.rwth.montisim.commons.utils.json.SerializationException;
import de.rwth.montisim.commons.utils.json.Typed;
/**
* Represents a named Enum with named variants. The corresponding object type
* must be a string with the specified variant name. The serialization format
* for enum types is the variant name as JSON string.
*/
@Typed(EnumType.TYPE)
public class EnumType extends DataType {
public static final String TYPE = "enum";
private String name;
private Vector<String> variants = new Vector<>();
private int size = 0;
public void addVariant(String name) {
variants.add(name);
// Compute the required number of bytes to store the variants
double bits = Math.log(variants.size());
double bytes = bits / 8;
size = (int) Math.ceil(bytes - 0.000001);
}
public String getName() {
return name;
}
public int getVariantCount() {
return variants.size();
}
public String getVariant(int i) {
return variants.elementAt(i);
}
@Override
public int getDataSize(Object o) {
return size;
}
@Override
public int hashCode() {
final int prime = 31;
int result = name.hashCode();
for (String v : variants) {
result = prime * result + v.hashCode();
}
return result;
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (this.getClass() != o.getClass())
return false;
EnumType s = ((EnumType) o);
if (!this.name.equals(s.name))
return false;
if (this.variants.size() != s.variants.size())
return false;
for (int i = 0; i < variants.size(); ++i) {
if (!variants.elementAt(i).equals(s.variants.elementAt(i)))
return false;
}
return true;
}
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
Json.toJson(j, o, context);
}
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
return Json.instantiateFromJson(j, String.class, context);
}
@Override
public Class<?> getArrayType() {
return Object[].class;
}
@Override
public void toBinary(DataOutputStream os, Object o) throws IOException {
throw new IllegalArgumentException("Unimplemented");
}
@Override
public Object fromBinary(DataInputStream is) throws IOException {
throw new IllegalArgumentException("Unimplemented");
}
}
/* (c) https://github.com/MontiCore/monticore */
package de.rwth.montisim.commons.dynamicinterface;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import de.rwth.montisim.commons.utils.ParsingException;
import de.rwth.montisim.commons.utils.json.*;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ArrayIterable;
import de.rwth.montisim.commons.utils.json.JsonTraverser.ValueType;
@Typed("matrix")
public class MatrixType extends DataType {
private DataType base_type;
private int rows;
private int columns;
public MatrixType(DataType baseType, int rows, int columns) {
this.base_type = baseType;
this.rows = rows;
this.columns = columns;
}
private MatrixType() {
}
@Override
public int getDataSize(Object o) {
// TODO optimize size calls
int size = 0;
Object arr[] = (Object[]) o;
for (Object oi : arr)
size += base_type.getDataSize(oi);
return size;
}
@Override
public String toString() {
return "[" + base_type.toString() + "; " + rows + "x" + columns + "]";
}
// Implement hashCode & equals to be able to perform hashmap lookup by type &
// type comparison
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((base_type == null) ? 0 : base_type.hashCode());
result = prime * result + Integer.valueOf(rows).hashCode();
result = prime * result + Integer.valueOf(columns).hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (this.getClass() != o.getClass())
return false;
MatrixType a = ((MatrixType) o);
return this.base_type.equals(a.base_type) && this.rows == a.rows && this.columns == a.columns;
}
//
@Override
public Object fromJson(JsonTraverser j, SerializationContext context) throws SerializationException {
Class<?> array_c = base_type.getArrayType();
if (array_c == null)
return null;
if (array_c != Object[].class)
return Json.instantiateFromJson(j, array_c, context);
Object o[][] = new Object[rows][columns];
ArrayIterable it = j.streamArray();
// if (!it.iterator().hasNext()) throw new ParsingException("Missing row count
// in serialized matrix array.");
// it.iterator().next();
// if (j.getLong() != rows) throw new IllegalArgumentException("Matrix row count
// does not match the MatrixType.");
// if (!it.iterator().hasNext()) throw new ParsingException("Missing column
// count in serialized matrix array.");
// it.iterator().next();
// if (j.getLong() != columns) throw new IllegalArgumentException("Matrix column
// count does not match the MatrixType.");
int i = 0;
for (ValueType t : it) {
if (i >= rows)
throw new ParsingException("Too many rows in Matrix serialization.");
int i2 = 0;
for (ValueType t2 : j.streamArray()) {
o[i][i2] = base_type.fromJson(j, context);
i2++;
}
if (i2 < columns)
throw new ParsingException("Missing column entries in Matrix serialization.");
i++;
}
if (i < rows)
throw new ParsingException("Missing row entries in Matrix serialization.");
return o;
}
// Writes in an array: the row count then colum count then a series of row
// arrays
@Override
public void toJson(JsonWriter j, Object o, SerializationContext context) throws SerializationException {
if (o == null)
return;
Class<?> array_c = base_type.getArrayType();
if (array_c == null)
return;
if (array_c != Object[].class) {
Json.toJson(j, o, context);
return;
}
Object[] arr[] = (Object[][]) o;
j.startArray();
// j.writeValue(rows);
// j.writeValue(columns);
if (arr.length != rows)