From 1512bf490aef66c8a5b0b69e6a9c754579352b25 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Wed, 10 Mar 2021 03:37:09 +0100 Subject: [PATCH] Add int52 --- .../data/generator/SourcesGenerator.java | 28 ++++- .../nativedata/ArrayInt52Serializer.java | 28 +++++ .../data/generator/nativedata/Int52.java | 74 +++++++++++++ .../generator/nativedata/Int52Serializer.java | 47 ++++++++ .../generator/nativedata/NullableInt52.java | 102 ++++++++++++++++++ .../nativedata/NullableInt52Serializer.java | 37 +++++++ 6 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 src/main/java/it/cavallium/data/generator/nativedata/ArrayInt52Serializer.java create mode 100644 src/main/java/it/cavallium/data/generator/nativedata/Int52.java create mode 100644 src/main/java/it/cavallium/data/generator/nativedata/Int52Serializer.java create mode 100644 src/main/java/it/cavallium/data/generator/nativedata/NullableInt52.java create mode 100644 src/main/java/it/cavallium/data/generator/nativedata/NullableInt52Serializer.java diff --git a/src/main/java/it/cavallium/data/generator/SourcesGenerator.java b/src/main/java/it/cavallium/data/generator/SourcesGenerator.java index 9be4a2b..e4b856e 100644 --- a/src/main/java/it/cavallium/data/generator/SourcesGenerator.java +++ b/src/main/java/it/cavallium/data/generator/SourcesGenerator.java @@ -15,6 +15,7 @@ import com.squareup.javapoet.TypeSpec.Builder; import com.squareup.javapoet.TypeVariableName; import com.squareup.javapoet.WildcardTypeName; import it.cavallium.data.generator.nativedata.IGenericNullable; +import it.cavallium.data.generator.nativedata.Int52Serializer; import it.cavallium.data.generator.nativedata.StringSerializer; import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; @@ -471,7 +472,8 @@ public class SourcesGenerator { "long", "float", "double", - "byte" + "byte", + "Int52" ); // Generate the type statements @@ -479,9 +481,9 @@ public class SourcesGenerator { // Generate the native types for (String specialNativeType : specialNativeTypes) { if (Character.isUpperCase(specialNativeType.charAt(0))) { - typeTypes.put(specialNativeType, ClassName.get("java.lang", specialNativeType)); + typeTypes.put(specialNativeType, ClassName.get(getSpecialNativePackage(specialNativeType), specialNativeType)); if (nextVersion.isPresent()) { - nextVersionTypeTypes.put(specialNativeType, ClassName.get("java.lang", specialNativeType)); + nextVersionTypeTypes.put(specialNativeType, ClassName.get(getSpecialNativePackage(specialNativeType), specialNativeType)); } if (specialNativeType.equals("String")) { typeSerializeStatement.put(specialNativeType, @@ -493,6 +495,16 @@ public class SourcesGenerator { typeDeserializeStatement.put(specialNativeType, CodeBlock.builder().add("$T.INSTANCE.deserialize(dataInput)", StringSerializer.class).build() ); + } else if (specialNativeType.equals("Int52")) { + typeSerializeStatement.put(specialNativeType, + new SerializeCodeBlockGenerator(CodeBlock + .builder() + .add("$T.INSTANCE.serialize(dataOutput, ", Int52Serializer.class) + .build(), CodeBlock.builder().add(")").build()) + ); + typeDeserializeStatement.put(specialNativeType, + CodeBlock.builder().add("$T.INSTANCE.deserialize(dataInput)", Int52Serializer.class).build() + ); } else { typeSerializeStatement.put(specialNativeType, new SerializeCodeBlockGenerator(CodeBlock @@ -1943,6 +1955,16 @@ public class SourcesGenerator { } } + private static String getSpecialNativePackage(String specialNativeType) { + //noinspection SwitchStatementWithTooFewBranches + switch (specialNativeType) { + case "Int52": + return "it.cavallium.data.generator.nativedata"; + default: + return "java.lang"; + } + } + private void registerArrayType(String versionPackage, ClassName versionClassType, HashMap typeOptionalSerializers, diff --git a/src/main/java/it/cavallium/data/generator/nativedata/ArrayInt52Serializer.java b/src/main/java/it/cavallium/data/generator/nativedata/ArrayInt52Serializer.java new file mode 100644 index 0000000..1facc01 --- /dev/null +++ b/src/main/java/it/cavallium/data/generator/nativedata/ArrayInt52Serializer.java @@ -0,0 +1,28 @@ +package it.cavallium.data.generator.nativedata; + +import it.cavallium.data.generator.DataSerializer; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import org.jetbrains.annotations.NotNull; + +public class ArrayInt52Serializer implements DataSerializer { + + @Override + public void serialize(DataOutput dataOutput, @NotNull Int52[] data) throws IOException { + dataOutput.writeInt(data.length); + for (int i = 0; i < data.length; i++) { + Int52Serializer.INSTANCE.serialize(dataOutput, data[i]); + } + } + + @NotNull + @Override + public Int52[] deserialize(DataInput dataInput) throws IOException { + var data = new Int52[dataInput.readInt()]; + for (int i = 0; i < data.length; i++) { + data[i] = Int52Serializer.INSTANCE.deserialize(dataInput); + } + return data; + } +} diff --git a/src/main/java/it/cavallium/data/generator/nativedata/Int52.java b/src/main/java/it/cavallium/data/generator/nativedata/Int52.java new file mode 100644 index 0000000..2a594e4 --- /dev/null +++ b/src/main/java/it/cavallium/data/generator/nativedata/Int52.java @@ -0,0 +1,74 @@ +package it.cavallium.data.generator.nativedata; + +import java.util.Objects; +import org.jetbrains.annotations.NotNull; + +public class Int52 extends Number implements Comparable { + + private final long value; + + private Int52(long value) { + this.value = value; + } + + public static Int52 fromLong(long value) { + if (value < 0) { + throw new IllegalArgumentException("Only positive values are supported"); + } + if (value > 0x0F_FF_FF_FF_FF_FF_FFL) { + throw new IllegalArgumentException("Only values below or equal to " + 0xFFFFFFFFFFFFFL + " are supported"); + } + return new Int52(value); + } + + long getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Int52 int52 = (Int52) o; + return value == int52.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return Long.toString(value); + } + + @Override + public int intValue() { + return (int) value; + } + + @Override + public long longValue() { + return value; + } + + @Override + public float floatValue() { + return (float) value; + } + + @Override + public double doubleValue() { + return (double) value; + } + + @Override + public int compareTo(@NotNull Int52 o) { + return Long.compareUnsigned(this.value, o.value); + } +} diff --git a/src/main/java/it/cavallium/data/generator/nativedata/Int52Serializer.java b/src/main/java/it/cavallium/data/generator/nativedata/Int52Serializer.java new file mode 100644 index 0000000..1f183f2 --- /dev/null +++ b/src/main/java/it/cavallium/data/generator/nativedata/Int52Serializer.java @@ -0,0 +1,47 @@ +package it.cavallium.data.generator.nativedata; + +import it.cavallium.data.generator.DataSerializer; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import org.jetbrains.annotations.NotNull; + +public class Int52Serializer implements DataSerializer { + + public static final Int52Serializer INSTANCE = new Int52Serializer(); + + @Override + public void serialize(DataOutput dataOutput, @NotNull Int52 data) throws IOException { + dataOutput.write(toByteArray(data.getValue())); + } + + @NotNull + @Override + public Int52 deserialize(DataInput dataInput) throws IOException { + byte[] bytes = new byte[7]; + dataInput.readFully(bytes); + return Int52.fromLong(fromByteArray(bytes)); + } + + public static byte[] toByteArray(long value) { + byte[] result = new byte[7]; + + for(int i = 6; i >= 0; --i) { + result[i] = (byte)((int)(value & (i == 6 ? 0b00001111L : 255L))); + value >>= 8; + } + + return result; + } + + public static long fromByteArray(byte[] bytes) { + if (bytes.length != 8) { + throw new IllegalArgumentException("Size must be 7, got " + bytes.length + " instead"); + } + return fromBytes((byte) (bytes[0] & 0b00001111), bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6]); + } + + public static long fromBytes(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) { + return ((long)b1 & 0b00001111) << 48 | ((long)b2 & 255L) << 40 | ((long)b3 & 255L) << 32 | ((long)b4 & 255L) << 24 | ((long)b5 & 255L) << 16 | ((long)b6 & 255L) << 8 | (long)b7 & 255L; + } +} diff --git a/src/main/java/it/cavallium/data/generator/nativedata/NullableInt52.java b/src/main/java/it/cavallium/data/generator/nativedata/NullableInt52.java new file mode 100644 index 0000000..d38e1d4 --- /dev/null +++ b/src/main/java/it/cavallium/data/generator/nativedata/NullableInt52.java @@ -0,0 +1,102 @@ +package it.cavallium.data.generator.nativedata; + +import java.io.Serializable; +import java.util.Objects; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class NullableInt52 implements Serializable, IGenericNullable { + + private static final long serialVersionUID = 1L; + + private final Int52 value; + + public NullableInt52(Int52 value) { + this.value = value; + } + + public static NullableInt52 of(@NotNull Int52 value) { + return new NullableInt52(value); + } + + public static NullableInt52 ofNullable(@Nullable Int52 value) { + return new NullableInt52(value); + } + + public static NullableInt52 empty() { + return new NullableInt52(null); + } + + public boolean isEmpty() { + return value == null; + } + + public boolean isPresent() { + return value != null; + } + + @NotNull + public Int52 get() { + if (value == null) { + throw new NullPointerException(); + } else { + return value; + } + } + + public Int52 orElse(Int52 defaultValue) { + if (value == null) { + return defaultValue; + } else { + return value; + } + } + + @Override + public Object $getNullable() { + return this.getNullable(); + } + + @Nullable + public Int52 getNullable() { + return value; + } + + @Nullable + public Int52 getNullable(Int52 defaultValue) { + return value == null ? defaultValue : value; + } + + @NotNull + @Override + public NullableInt52 clone() { + if (value != null) { + return NullableInt52.of(value); + } else { + return NullableInt52.empty(); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + var that = (NullableInt52) o; + return Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + if (value == null) return "null"; + return "" + value; + } +} diff --git a/src/main/java/it/cavallium/data/generator/nativedata/NullableInt52Serializer.java b/src/main/java/it/cavallium/data/generator/nativedata/NullableInt52Serializer.java new file mode 100644 index 0000000..dcb22eb --- /dev/null +++ b/src/main/java/it/cavallium/data/generator/nativedata/NullableInt52Serializer.java @@ -0,0 +1,37 @@ +package it.cavallium.data.generator.nativedata; + +import it.cavallium.data.generator.DataSerializer; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import org.jetbrains.annotations.NotNull; + +public class NullableInt52Serializer implements DataSerializer { + + public static final NullableInt52Serializer INSTANCE = new NullableInt52Serializer(); + + @Override + public void serialize(DataOutput dataOutput, @NotNull NullableInt52 data) throws IOException { + // 0b10000000 = empty, 0b00000000 = with value + if (data.isEmpty()) { + dataOutput.writeByte(0b10000000); + } else { + dataOutput.write(Int52Serializer.toByteArray(data.get().getValue())); + } + } + + @NotNull + @Override + public NullableInt52 deserialize(DataInput dataInput) throws IOException { + // 0b10000000 = empty, 0b00000000 = with value + byte firstByteAndIsPresent = dataInput.readByte(); + if ((firstByteAndIsPresent & 0b10000000) != 0) { + return NullableInt52.empty(); + } else { + byte[] secondPart = new byte[7]; + secondPart[0] = (byte) (firstByteAndIsPresent & 0b00001111); + dataInput.readFully(secondPart, 1, secondPart.length - 1); + return NullableInt52.of(Int52.fromLong(Int52Serializer.fromByteArray(secondPart))); + } + } +}