Compare commits

...

38 Commits

Author SHA1 Message Date
Andrea Cavalli 73d24bf13f Fix rebuild bug 2024-02-20 16:38:24 +01:00
Andrea Cavalli bf2cd90acf Fix missing cast 2023-11-29 18:09:24 +01:00
Andrea Cavalli b224157c53 Improve immutable wrapped array list performance 2023-11-29 15:50:42 +01:00
Andrea Cavalli 4654b690fe Improve immutable wrapped array list performance 2023-11-29 15:49:09 +01:00
Andrea Cavalli 87f31652d7 Extend nullable utils to native nullables 2023-11-11 22:19:04 +01:00
Andrea Cavalli f836a26001 Fix missing upgrader code 2023-11-09 01:58:17 +01:00
Andrea Cavalli 7ceede1cc6 Add tests 2023-11-09 01:56:13 +01:00
Andrea Cavalli 686cef66ac Add optional instance fields in upgraders 2023-11-09 01:56:09 +01:00
Andrea Cavalli 9118f2271b Optimize boolean, byte 2023-11-06 13:08:42 +01:00
Andrea Cavalli 6cc6894528 Update dependencies, use java 21, generate sealed types 2023-11-05 19:55:18 +01:00
Andrea Cavalli 5a10da543d Format buffers 2023-09-26 01:43:21 +02:00
Andrea Cavalli bb855a6e27 Fix sorting 2023-09-25 19:09:05 +02:00
Andrea Cavalli ee1e71da84 Fix sorting 2023-09-25 18:51:35 +02:00
Andrea Cavalli 70f83caf1d Fix tests 2023-05-22 23:31:11 +02:00
Andrea Cavalli 77894edce9 Fix written size 2023-05-22 23:26:36 +02:00
Andrea Cavalli 16b22d2e49 Bugfixes 2023-04-20 20:22:07 +02:00
Andrea Cavalli 938b404ec7 Rename package 2023-04-20 10:11:12 +02:00
Andrea Cavalli f9e5657a83 Fix strings 2023-04-20 02:10:53 +02:00
Andrea Cavalli c22d6719d9 More tests 2023-04-20 01:26:17 +02:00
Andrea Cavalli 1eb4b0334c Test buffers 2023-04-19 17:52:59 +02:00
Andrea Cavalli 95d8811bcb More tests 2023-04-19 01:29:45 +02:00
Andrea Cavalli 216899e0d9 Test buffers 2023-04-18 14:59:40 +02:00
Andrea Cavalli 23df869676 Test buffers 2023-04-18 14:48:31 +02:00
Andrea Cavalli 25779e6c0c Bugfix 2023-03-28 01:03:53 +02:00
Andrea Cavalli 4ff1eb0179 Optimization 2023-03-28 00:39:14 +02:00
Andrea Cavalli 40d7f35a8e Bugfix 2023-03-28 00:18:37 +02:00
Andrea Cavalli 7177f5944b Fast string read 2023-03-28 00:16:50 +02:00
Andrea Cavalli 9faebd75a0 Optimization 2023-03-27 23:30:52 +02:00
Andrea Cavalli 9da2c8f5d9 Optimization 2023-03-27 23:30:34 +02:00
Andrea Cavalli bc34559de0 Fix readutf implementation 2023-03-27 23:23:41 +02:00
Andrea Cavalli 58eb0d0b5c Remove error 2023-03-03 23:03:02 +01:00
Andrea Cavalli a97a5ee9b5 Remove exceptions 2023-03-03 22:43:49 +01:00
Andrea Cavalli d103367b43 Add a new exception 2023-03-03 00:36:43 +01:00
Andrea Cavalli 8cdeec91c9 Bugfix 2023-03-03 00:16:23 +01:00
Andrea Cavalli 9b36d831c6 Use safe buffers 2023-03-03 00:13:36 +01:00
Andrea Cavalli cb24914793 Add serial version 2023-03-02 22:58:40 +01:00
Andrea Cavalli 9d7264891c Use enhanced for 2023-03-02 22:46:54 +01:00
Andrea Cavalli 1a1a696c53 Fix exception 2023-02-27 16:01:53 +01:00
153 changed files with 6286 additions and 800 deletions

View File

@ -1,9 +0,0 @@
package it.cavallium.data.generator;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
public interface DataInitializer<T> {
@NotNull T initialize() throws IOException;
}

View File

@ -1,14 +0,0 @@
package it.cavallium.data.generator;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface DataSerializer<T> {
void serialize(DataOutput dataOutput, @NotNull T data) throws IOException;
@NotNull T deserialize(DataInput dataInput) throws IOException;
}

View File

@ -1,9 +0,0 @@
package it.cavallium.data.generator;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
public interface DataUpgrader<T, U> {
@NotNull U upgrade(@NotNull T data) throws IOException;
}

View File

@ -1,24 +0,0 @@
package it.cavallium.data.generator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface NativeNullable<T> {
boolean isEmpty();
default boolean isPresent() {
return !isEmpty();
}
@NotNull
T orElse(@NotNull T defaultValue);
@NotNull NativeNullable<? extends T> or(@NotNull NativeNullable<? extends T> fallback);
@Nullable
T getNullable();
@Nullable
T getNullable(@Nullable T defaultValue);
}

View File

@ -1,29 +0,0 @@
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 java.util.List;
import org.jetbrains.annotations.NotNull;
public class ArrayInt52Serializer implements DataSerializer< List<Int52>> {
@Override
public void serialize(DataOutput dataOutput, List<Int52> data) throws IOException {
dataOutput.writeInt(data.size());
for (Int52 datum : data) {
Int52Serializer.INSTANCE.serialize(dataOutput, datum);
}
}
@NotNull
@Override
public List<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 List.of(data);
}
}

View File

@ -1,29 +0,0 @@
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 java.util.List;
import org.jetbrains.annotations.NotNull;
public class ArrayStringSerializer implements DataSerializer<List<String>> {
@Override
public void serialize(DataOutput dataOutput, @NotNull List<String> data) throws IOException {
dataOutput.writeInt(data.size());
for (int i = 0; i < data.size(); i++) {
dataOutput.writeUTF(data.get(i));
}
}
@NotNull
@Override
public List<String> deserialize(DataInput dataInput) throws IOException {
var data = new String[dataInput.readInt()];
for (int i = 0; i < data.length; i++) {
data[i] = dataInput.readUTF();
}
return List.of(data);
}
}

View File

@ -1,63 +0,0 @@
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 java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.Channels;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.MalformedInputException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnmappableCharacterException;
import org.jetbrains.annotations.NotNull;
public class StringSerializer implements DataSerializer<String> {
public static final StringSerializer INSTANCE = new StringSerializer();
private static final ThreadLocal<CharsetEncoder> UTF8_ENCODER = ThreadLocal.withInitial(() -> StandardCharsets.UTF_8
.newEncoder()
.onUnmappableCharacter(CodingErrorAction.REPORT)
.onMalformedInput(CodingErrorAction.REPORT)
);
private static final ThreadLocal<CharsetDecoder> UTF8_DECODER = ThreadLocal.withInitial(() -> StandardCharsets.UTF_8
.newDecoder()
.onUnmappableCharacter(CodingErrorAction.REPORT)
.onMalformedInput(CodingErrorAction.REPORT)
);
@Override
public void serialize(DataOutput dataOutput, @NotNull String data) throws IOException {
try {
var bytes = UTF8_ENCODER.get().reset().encode(CharBuffer.wrap(data));
dataOutput.writeInt(bytes.limit());
if (bytes.hasArray()) {
dataOutput.write(bytes.array(), bytes.arrayOffset(), bytes.limit());
} else {
while (bytes.hasRemaining()) {
dataOutput.writeByte(bytes.get());
}
}
} catch (IllegalStateException | CharacterCodingException ex) {
throw new IOException("Can't encode this UTF-8 string", ex);
}
}
@NotNull
@Override
public String deserialize(DataInput dataInput) throws IOException {
byte[] bytes = new byte[dataInput.readInt()];
dataInput.readFully(bytes);
try {
CharBuffer decoded = UTF8_DECODER.get().reset().decode(ByteBuffer.wrap(bytes));
return decoded.toString();
} catch (IllegalStateException | CharacterCodingException ex) {
throw new IOException("Can't decode this UTF-8 string", ex);
}
}
}

View File

@ -1,6 +0,0 @@
module data.generator.runtime {
exports it.cavallium.data.generator.nativedata;
exports it.cavallium.data.generator;
requires org.jetbrains.annotations;
requires it.unimi.dsi.fastutil;
}

View File

@ -5,18 +5,18 @@
<modelVersion>4.0.0</modelVersion>
<name>Data generator</name>
<artifactId>data-generator-plugin</artifactId>
<artifactId>datagen-plugin</artifactId>
<version>${revision}</version>
<packaging>maven-plugin</packaging>
<parent>
<groupId>it.cavallium</groupId>
<version>${revision}</version>
<artifactId>data-generator</artifactId>
<artifactId>datagen-parent</artifactId>
</parent>
<properties>
<revision>1.0.0.0-SNAPSHOT</revision>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<fastutil.version>8.5.11</fastutil.version>
<fastutil.version>8.5.12</fastutil.version>
<maven.version>4.0.0-alpha-3</maven.version>
</properties>
<repositories>
@ -59,7 +59,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.7.1</version>
<version>3.10.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
@ -84,7 +84,7 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<release>17</release>
<release>21</release>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
@ -185,7 +185,7 @@
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
<version>2.0</version>
</dependency>
<dependency>
<groupId>net.fabricmc</groupId>
@ -195,7 +195,7 @@
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>23.1.0</version>
<version>24.0.1</version>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
@ -217,7 +217,7 @@
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.7.1</version>
<version>3.8.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -233,7 +233,7 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.19.0</version>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@ -243,7 +243,7 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.19.0</version>
<version>2.20.0</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
@ -269,7 +269,7 @@
</dependency>
<dependency>
<groupId>it.cavallium</groupId>
<artifactId>data-generator-runtime</artifactId>
<artifactId>datagen</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.LinkedHashMap;
import java.util.Objects;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;

View File

@ -1,8 +1,8 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeName;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import java.util.LinkedHashMap;
import java.util.stream.Stream;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;

View File

@ -1,10 +1,10 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import it.cavallium.data.generator.nativedata.UpgradeUtil;
import it.cavallium.datagen.nativedata.UpgradeUtil;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

View File

@ -1,19 +1,19 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import it.cavallium.data.generator.nativedata.ArrayInt52Serializer;
import it.cavallium.data.generator.nativedata.ArrayStringSerializer;
import it.cavallium.data.generator.nativedata.ArraybooleanSerializer;
import it.cavallium.data.generator.nativedata.ArraybyteSerializer;
import it.cavallium.data.generator.nativedata.ArraycharSerializer;
import it.cavallium.data.generator.nativedata.ArraydoubleSerializer;
import it.cavallium.data.generator.nativedata.ArrayfloatSerializer;
import it.cavallium.data.generator.nativedata.ArrayintSerializer;
import it.cavallium.data.generator.nativedata.ArraylongSerializer;
import it.cavallium.data.generator.nativedata.ArrayshortSerializer;
import it.cavallium.data.generator.nativedata.Serializers;
import it.cavallium.datagen.nativedata.ArrayInt52Serializer;
import it.cavallium.datagen.nativedata.ArrayStringSerializer;
import it.cavallium.datagen.nativedata.ArraybooleanSerializer;
import it.cavallium.datagen.nativedata.ArraybyteSerializer;
import it.cavallium.datagen.nativedata.ArraycharSerializer;
import it.cavallium.datagen.nativedata.ArraydoubleSerializer;
import it.cavallium.datagen.nativedata.ArrayfloatSerializer;
import it.cavallium.datagen.nativedata.ArrayintSerializer;
import it.cavallium.datagen.nativedata.ArraylongSerializer;
import it.cavallium.datagen.nativedata.ArrayshortSerializer;
import it.cavallium.datagen.nativedata.Serializers;
import it.unimi.dsi.fastutil.booleans.BooleanList;
import it.unimi.dsi.fastutil.bytes.ByteList;
import it.unimi.dsi.fastutil.chars.CharList;

View File

@ -1,11 +1,11 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import it.cavallium.data.generator.nativedata.UpgradeUtil;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.nativedata.UpgradeUtil;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;

View File

@ -1,8 +1,8 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.stream.Stream;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.ParameterizedTypeName;
@ -64,7 +64,7 @@ public final class ComputedTypeCustom implements ComputedType {
return false;
}
it.cavallium.data.generator.plugin.ComputedTypeCustom that = (it.cavallium.data.generator.plugin.ComputedTypeCustom) o;
ComputedTypeCustom that = (ComputedTypeCustom) o;
if (!Objects.equals(type, that.type)) {
return false;

View File

@ -1,10 +1,11 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import it.cavallium.data.generator.nativedata.Int52Serializer;
import it.cavallium.data.generator.nativedata.Serializers;
import it.cavallium.data.generator.nativedata.StringSerializer;
import it.cavallium.datagen.nativedata.Int52Serializer;
import it.cavallium.datagen.nativedata.Serializers;
import it.cavallium.datagen.nativedata.StringSerializer;
import it.cavallium.datagen.nativedata.Int52;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@ -40,7 +41,7 @@ public final class ComputedTypeNative implements ComputedType {
case "float" -> TypeName.FLOAT;
case "double" -> TypeName.DOUBLE;
case "byte" -> TypeName.BYTE;
case "Int52" -> ClassName.get(it.cavallium.data.generator.nativedata.Int52.class);
case "Int52" -> ClassName.get(Int52.class);
default -> throw new UnsupportedOperationException(type + " is not a known native type");
};
}
@ -81,7 +82,7 @@ public final class ComputedTypeNative implements ComputedType {
return false;
}
it.cavallium.data.generator.plugin.ComputedTypeNative that = (it.cavallium.data.generator.plugin.ComputedTypeNative) o;
ComputedTypeNative that = (ComputedTypeNative) o;
return Objects.equals(type, that.type);
}
@ -101,10 +102,10 @@ public final class ComputedTypeNative implements ComputedType {
return computedTypeSupplier.getDependents(getName());
}
public static List<it.cavallium.data.generator.plugin.ComputedTypeNative> get(ComputedTypeSupplier computedTypeSupplier) {
public static List<ComputedTypeNative> get(ComputedTypeSupplier computedTypeSupplier) {
return Stream
.of("String", "boolean", "short", "char", "int", "long", "float", "double", "byte", "Int52")
.map(name -> new it.cavallium.data.generator.plugin.ComputedTypeNative(name, computedTypeSupplier))
.map(name -> new ComputedTypeNative(name, computedTypeSupplier))
.toList();
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;

View File

@ -1,9 +1,9 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeName;
import it.cavallium.data.generator.nativedata.UpgradeUtil;
import it.cavallium.datagen.nativedata.UpgradeUtil;
import java.util.Objects;
import java.util.stream.Stream;

View File

@ -1,28 +1,28 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import it.cavallium.data.generator.nativedata.NullableInt52;
import it.cavallium.data.generator.nativedata.NullableInt52Serializer;
import it.cavallium.data.generator.nativedata.NullableString;
import it.cavallium.data.generator.nativedata.NullableStringSerializer;
import it.cavallium.data.generator.nativedata.Nullableboolean;
import it.cavallium.data.generator.nativedata.NullablebooleanSerializer;
import it.cavallium.data.generator.nativedata.Nullablebyte;
import it.cavallium.data.generator.nativedata.NullablebyteSerializer;
import it.cavallium.data.generator.nativedata.Nullablechar;
import it.cavallium.data.generator.nativedata.NullablecharSerializer;
import it.cavallium.data.generator.nativedata.Nullabledouble;
import it.cavallium.data.generator.nativedata.NullabledoubleSerializer;
import it.cavallium.data.generator.nativedata.Nullablefloat;
import it.cavallium.data.generator.nativedata.NullablefloatSerializer;
import it.cavallium.data.generator.nativedata.Nullableint;
import it.cavallium.data.generator.nativedata.NullableintSerializer;
import it.cavallium.data.generator.nativedata.Nullablelong;
import it.cavallium.data.generator.nativedata.NullablelongSerializer;
import it.cavallium.data.generator.nativedata.Nullableshort;
import it.cavallium.data.generator.nativedata.NullableshortSerializer;
import it.cavallium.data.generator.nativedata.Serializers;
import it.cavallium.datagen.nativedata.NullableInt52;
import it.cavallium.datagen.nativedata.NullableInt52Serializer;
import it.cavallium.datagen.nativedata.NullableString;
import it.cavallium.datagen.nativedata.NullableStringSerializer;
import it.cavallium.datagen.nativedata.Nullableboolean;
import it.cavallium.datagen.nativedata.NullablebooleanSerializer;
import it.cavallium.datagen.nativedata.Nullablebyte;
import it.cavallium.datagen.nativedata.NullablebyteSerializer;
import it.cavallium.datagen.nativedata.Nullablechar;
import it.cavallium.datagen.nativedata.NullablecharSerializer;
import it.cavallium.datagen.nativedata.Nullabledouble;
import it.cavallium.datagen.nativedata.NullabledoubleSerializer;
import it.cavallium.datagen.nativedata.Nullablefloat;
import it.cavallium.datagen.nativedata.NullablefloatSerializer;
import it.cavallium.datagen.nativedata.Nullableint;
import it.cavallium.datagen.nativedata.NullableintSerializer;
import it.cavallium.datagen.nativedata.Nullablelong;
import it.cavallium.datagen.nativedata.NullablelongSerializer;
import it.cavallium.datagen.nativedata.Nullableshort;
import it.cavallium.datagen.nativedata.NullableshortSerializer;
import it.cavallium.datagen.nativedata.Serializers;
import java.util.Objects;
import java.util.stream.Stream;

View File

@ -1,10 +1,10 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeName;
import it.cavallium.data.generator.nativedata.UpgradeUtil;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.nativedata.UpgradeUtil;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.stream.Stream;

View File

@ -1,8 +1,8 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@ -33,9 +33,9 @@ public final class ComputedTypeSuper implements VersionedComputedType {
}
@Override
public it.cavallium.data.generator.plugin.ComputedTypeSuper withChangeAtVersion(ComputedVersion version,
public ComputedTypeSuper withChangeAtVersion(ComputedVersion version,
VersionChangeChecker versionChangeChecker, LinkedHashMap<String, VersionedType> data) {
return new it.cavallium.data.generator.plugin.ComputedTypeSuper(type.withVersion(version),
return new ComputedTypeSuper(type.withVersion(version),
subTypes.stream().map(subType -> subType.withVersionIfChanged(version, versionChangeChecker)).toList(),
computedTypeSupplier
);
@ -62,7 +62,7 @@ public final class ComputedTypeSuper implements VersionedComputedType {
return false;
}
it.cavallium.data.generator.plugin.ComputedTypeSuper that = (it.cavallium.data.generator.plugin.ComputedTypeSuper) o;
ComputedTypeSuper that = (ComputedTypeSuper) o;
if (!Objects.equals(type, that.type)) {
return false;

View File

@ -1,8 +1,7 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

View File

@ -1,11 +1,9 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import static it.cavallium.data.generator.plugin.DataModel.joinPackage;
import static it.cavallium.datagen.plugin.DataModel.joinPackage;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
import org.jetbrains.annotations.NotNull;
public class ComputedVersion implements Comparable<ComputedVersion> {

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Collection;
import java.util.Map;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Objects;

View File

@ -1,9 +1,9 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import static java.util.Objects.requireNonNull;
import static java.util.function.Function.identity;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
@ -213,11 +213,20 @@ public class DataModel {
if (definition.isEmpty()) {
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
}
var prevDef = tryInsertAtIndex(transformClass.data,
t.to,
definition.get().getValue(),
definition.get().getKey()
);
String prevDef;
if (t.index != null) {
prevDef = tryInsertAtIndex(transformClass.data,
t.to,
definition.get().getValue(),
t.index
);
} else {
prevDef = tryInsertAtIndex(transformClass.data,
t.to,
definition.get().getValue(),
definition.get().getKey()
);
}
if (prevDef != null) {
throw new IllegalArgumentException(
transformCoordinate + " tries to overwrite the existing field \"" + t.to + "\" of value \""

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Objects;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.TypeName;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.HashMap;
import java.util.HashSet;

View File

@ -0,0 +1,42 @@
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import org.apache.commons.lang3.StringUtils;
public sealed interface JInterfaceLocation {
static JInterfaceLocation parse(String className, String instanceFieldLocation) {
if ((instanceFieldLocation != null) == (className != null)) {
if (instanceFieldLocation != null) {
throw new IllegalArgumentException("instance field location and class name are both set! You must set one");
} else {
throw new IllegalArgumentException("instance field location and class name are both empty! You must set one");
}
} else if (instanceFieldLocation != null) {
var fieldClass = StringUtils.substringBeforeLast(instanceFieldLocation, ".");
var fieldName = StringUtils.substringAfterLast(instanceFieldLocation, ".");
var fieldClassName = ClassName.bestGuess(fieldClass);
return new JInterfaceLocationInstanceField(new FieldLocation(fieldClassName, fieldName));
} else {
return new JInterfaceLocationClassName(ClassName.bestGuess(className));
}
}
String getIdentifier();
record JInterfaceLocationClassName(ClassName className) implements JInterfaceLocation {
@Override
public String getIdentifier() {
return "C:" + className.reflectionName();
}
}
record JInterfaceLocationInstanceField(FieldLocation fieldLocation) implements JInterfaceLocation {
@Override
public String getIdentifier() {
return "F:" + fieldLocation.className() + "." + fieldLocation.fieldName();
}
}
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.io.File;
import java.io.IOException;
@ -29,6 +29,9 @@ public class MavenPlugin extends AbstractMojo {
@Parameter( required = true, defaultValue = "false")
private String useRecordBuilder;
@Parameter(defaultValue = "false")
private String generateTestResources;
/**
* @parameter default-value="${project}"
* @required
@ -41,7 +44,8 @@ public class MavenPlugin extends AbstractMojo {
public void execute() throws MojoExecutionException, MojoFailureException {
try {
SourcesGenerator sourcesGenerator = SourcesGenerator.load(configPath.toPath());
Path genRecordsPath = project.getBasedir().getAbsoluteFile().toPath().resolve("target").resolve("generated-sources").resolve("database-classes");
project.hasLifecyclePhase("generate-test-sources");
Path genRecordsPath = project.getBasedir().getAbsoluteFile().toPath().resolve("target").resolve(Boolean.parseBoolean(generateTestResources) ? "generated-test-sources" : "generated-sources").resolve("database-classes");
Path outPath = genRecordsPath.resolve("java");
this.project.addCompileSourceRoot(outPath.toString());

View File

@ -1,12 +1,15 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Objects;
import org.jetbrains.annotations.Nullable;
public final class MoveDataConfiguration implements TransformationConfiguration {
public String transformClass;
public String from;
public String to;
@Nullable
public Integer index;
@Override
public String getTransformClass() {
@ -27,9 +30,8 @@ public final class MoveDataConfiguration implements TransformationConfiguration
return false;
}
MoveDataConfiguration that = (MoveDataConfiguration) o;
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from) && Objects.equals(to,
that.to
);
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from)
&& Objects.equals(to, that.to) && Objects.equals(index, that.index);
}
@Override
@ -38,6 +40,7 @@ public final class MoveDataConfiguration implements TransformationConfiguration
hash += ConfigUtils.hashCode(transformClass);
hash += ConfigUtils.hashCode(from);
hash += ConfigUtils.hashCode(to);
hash += ConfigUtils.hashCode(index);
return hash;
}
@ -46,6 +49,7 @@ public final class MoveDataConfiguration implements TransformationConfiguration
if (this.transformClass != null) c.transformClass = this.transformClass;
if (this.from != null) c.from = this.from;
if (this.to != null) c.to = this.to;
if (this.index != null) c.index = this.index;
return c;
}
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Objects;
import org.jetbrains.annotations.Nullable;
@ -9,6 +9,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
public String to;
public String type;
public String initializer;
public String initializerInstance;
@Nullable
public Integer index;
@ -22,6 +23,10 @@ public class NewDataConfiguration implements TransformationConfiguration {
return "new-data";
}
public JInterfaceLocation getInitializerLocation() {
return JInterfaceLocation.parse(initializer, initializerInstance);
}
@Override
public boolean equals(Object o) {
if (this == o) {
@ -33,6 +38,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
NewDataConfiguration that = (NewDataConfiguration) o;
return Objects.equals(transformClass, that.transformClass) && Objects.equals(to, that.to)
&& Objects.equals(type, that.type) && Objects.equals(initializer, that.initializer)
&& Objects.equals(initializerInstance, that.initializerInstance)
&& Objects.equals(index, that.index);
}
@ -43,6 +49,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
hash += ConfigUtils.hashCode(to);
hash += ConfigUtils.hashCode(type);
hash += ConfigUtils.hashCode(initializer);
hash += ConfigUtils.hashCode(initializerInstance);
hash += ConfigUtils.hashCode(index);
return hash;
}
@ -51,6 +58,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
var c = new NewDataConfiguration();
if (this.transformClass != null) c.transformClass = this.transformClass;
if (this.initializer != null) c.initializer = this.initializer;
if (this.initializerInstance != null) c.initializerInstance = this.initializerInstance;
if (this.to != null) c.to = this.to;
if (this.type != null) c.type = this.type;
if (this.index != null) c.index = this.index;

View File

@ -1,6 +1,6 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import static it.cavallium.data.generator.plugin.DataModel.fixType;
import static it.cavallium.datagen.plugin.DataModel.fixType;
import java.util.ArrayList;
import java.util.LinkedHashMap;

View File

@ -1,6 +1,6 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import static it.cavallium.data.generator.plugin.DataModel.fixType;
import static it.cavallium.datagen.plugin.DataModel.fixType;
import java.util.HashMap;
import java.util.HashSet;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.List;
import java.util.Objects;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Objects;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.CodeBlock;
import java.util.List;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
@ -12,27 +12,30 @@ import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec.Builder;
import it.cavallium.data.generator.plugin.ClassGenerator.ClassGeneratorParams;
import it.cavallium.data.generator.plugin.classgen.GenBaseType;
import it.cavallium.data.generator.plugin.classgen.GenCurrentVersion;
import it.cavallium.data.generator.plugin.classgen.GenDataBaseX;
import it.cavallium.data.generator.plugin.classgen.GenDataSuperX;
import it.cavallium.data.generator.plugin.classgen.GenIBaseType;
import it.cavallium.data.generator.plugin.classgen.GenINullableBaseType;
import it.cavallium.data.generator.plugin.classgen.GenINullableIType;
import it.cavallium.data.generator.plugin.classgen.GenINullableSuperType;
import it.cavallium.data.generator.plugin.classgen.GenIType;
import it.cavallium.data.generator.plugin.classgen.GenIVersion;
import it.cavallium.data.generator.plugin.classgen.GenNullableX;
import it.cavallium.data.generator.plugin.classgen.GenSerializerArrayX;
import it.cavallium.data.generator.plugin.classgen.GenSerializerBaseX;
import it.cavallium.data.generator.plugin.classgen.GenSerializerNullableX;
import it.cavallium.data.generator.plugin.classgen.GenSerializerSuperX;
import it.cavallium.data.generator.plugin.classgen.GenSuperType;
import it.cavallium.data.generator.plugin.classgen.GenUpgraderBaseX;
import it.cavallium.data.generator.plugin.classgen.GenUpgraderSuperX;
import it.cavallium.data.generator.plugin.classgen.GenVersion;
import it.cavallium.data.generator.plugin.classgen.GenVersions;
import it.cavallium.datagen.nativedata.Int52;
import it.cavallium.datagen.plugin.ClassGenerator.ClassGeneratorParams;
import it.cavallium.datagen.plugin.classgen.GenBaseType;
import it.cavallium.datagen.plugin.classgen.GenCurrentVersion;
import it.cavallium.datagen.plugin.classgen.GenDataBaseX;
import it.cavallium.datagen.plugin.classgen.GenDataSuperX;
import it.cavallium.datagen.plugin.classgen.GenIBaseType;
import it.cavallium.datagen.plugin.classgen.GenINullableBaseType;
import it.cavallium.datagen.plugin.classgen.GenINullableIType;
import it.cavallium.datagen.plugin.classgen.GenINullableSuperType;
import it.cavallium.datagen.plugin.classgen.GenIType;
import it.cavallium.datagen.plugin.classgen.GenIVersion;
import it.cavallium.datagen.plugin.classgen.GenNullableX;
import it.cavallium.datagen.plugin.classgen.GenSerializerArrayX;
import it.cavallium.datagen.plugin.classgen.GenSerializerBaseX;
import it.cavallium.datagen.plugin.classgen.GenSerializerNullableX;
import it.cavallium.datagen.plugin.classgen.GenSerializerSuperX;
import it.cavallium.datagen.plugin.classgen.GenSuperType;
import it.cavallium.datagen.plugin.classgen.GenUpgraderBaseX;
import it.cavallium.datagen.plugin.classgen.GenUpgraderSuperX;
import it.cavallium.datagen.plugin.classgen.GenVersion;
import it.cavallium.datagen.plugin.classgen.GenVersions;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import it.unimi.dsi.fastutil.booleans.BooleanList;
import it.unimi.dsi.fastutil.bytes.ByteList;
import it.unimi.dsi.fastutil.chars.CharList;
@ -41,8 +44,6 @@ import it.unimi.dsi.fastutil.floats.FloatList;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.longs.LongList;
import it.unimi.dsi.fastutil.shorts.ShortList;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@ -68,6 +69,7 @@ public class SourcesGenerator {
private static final Logger logger = LoggerFactory.getLogger(SourcesGenerator.class);
private static final boolean OVERRIDE_ALL_NULLABLE_METHODS = false;
private static final String SERIAL_VERSION = "2";
private final DataModel dataModel;
@ -113,18 +115,20 @@ public class SourcesGenerator {
var curHash = dataModel.computeHash();
if (Files.isRegularFile(hashPath) && Files.isReadable(hashPath)) {
var lines = Files.readAllLines(hashPath, StandardCharsets.UTF_8);
if (lines.size() >= 5) {
if (lines.size() >= 6) {
var prevBasePackageName = lines.get(0);
var prevRecordBuilders = lines.get(1);
var prevHash = lines.get(2);
var prevDeepCheckBeforeCreatingNewEqualInstances = lines.get(3);
var prevGenerateOldSerializers = lines.get(4);
var prevSerialVersion = lines.get(5);
if (!force
&& prevBasePackageName.equals(basePackageName)
&& (prevRecordBuilders.equalsIgnoreCase("true") == useRecordBuilders)
&& (prevDeepCheckBeforeCreatingNewEqualInstances.equalsIgnoreCase("true") == deepCheckBeforeCreatingNewEqualInstances)
&& (prevGenerateOldSerializers.equalsIgnoreCase("true") == generateOldSerializers)
&& (prevSerialVersion.equals(SERIAL_VERSION))
&& prevHash.equals(Integer.toString(curHash))) {
logger.info("Skipped sources generation because it didn't change");
return;
@ -198,14 +202,22 @@ public class SourcesGenerator {
new GenUpgraderSuperX(genParams).run();
// Update the hash at the end
Files.writeString(hashPath,
basePackageName + '\n' + useRecordBuilders + '\n' + deepCheckBeforeCreatingNewEqualInstances + '\n' + curHash
+ '\n',
StandardCharsets.UTF_8,
TRUNCATE_EXISTING,
WRITE,
CREATE
);
var newHashRaw = basePackageName + '\n' + useRecordBuilders + '\n' + deepCheckBeforeCreatingNewEqualInstances + '\n' + curHash + '\n';
String oldHashRaw;
if (Files.exists(hashPath)) {
oldHashRaw = Files.readString(hashPath, StandardCharsets.UTF_8);
} else {
oldHashRaw = null;
}
if (!Objects.equals(newHashRaw, oldHashRaw)) {
Files.writeString(hashPath,
newHashRaw,
StandardCharsets.UTF_8,
TRUNCATE_EXISTING,
WRITE,
CREATE
);
}
generatedFilesToDelete.remove(outPath.relativize(hashPath));
}
@ -249,8 +261,8 @@ public class SourcesGenerator {
private static String getSpecialNativePackage(String specialNativeType) {
//noinspection SwitchStatementWithTooFewBranches
return switch (specialNativeType) {
case "Int52" -> "it.cavallium.data.generator.nativedata";
default -> "java.lang";
case "Int52" -> Int52.class.getPackageName();
default -> Integer.class.getPackageName();
};
}
@ -279,10 +291,9 @@ public class SourcesGenerator {
serializeMethod.addModifiers(Modifier.PUBLIC);
serializeMethod.addModifiers(Modifier.FINAL);
serializeMethod.returns(TypeName.VOID);
serializeMethod.addParameter(ParameterSpec.builder(DataOutput.class, "dataOutput").build());
serializeMethod.addParameter(ParameterSpec.builder(SafeDataOutput.class, "dataOutput").build());
serializeMethod
.addParameter(ParameterSpec.builder(classType, "data").addAnnotation(NotNull.class).build());
serializeMethod.addException(IOException.class);
serializeMethod.addStatement("$T.requireNonNull(data)", Objects.class);
return serializeMethod;
}
@ -294,8 +305,7 @@ public class SourcesGenerator {
deserializeMethod.addModifiers(Modifier.PUBLIC);
deserializeMethod.addModifiers(Modifier.FINAL);
deserializeMethod.returns(classType);
deserializeMethod.addParameter(ParameterSpec.builder(DataInput.class, "dataInput").build());
deserializeMethod.addException(IOException.class);
deserializeMethod.addParameter(ParameterSpec.builder(SafeDataInput.class, "dataInput").build());
return deserializeMethod;
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Map;
import java.util.Objects;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import static java.lang.Boolean.parseBoolean;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
public interface TransformationConfiguration {

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Objects;
@ -8,6 +8,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
public String from;
public String type;
public String upgrader;
public String upgraderInstance;
@Override
public String getTransformClass() {
@ -19,6 +20,10 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
return "upgrade-data";
}
public JInterfaceLocation getUpgraderLocation() {
return JInterfaceLocation.parse(upgrader, upgraderInstance);
}
@Override
public boolean equals(Object o) {
if (this == o) {
@ -29,7 +34,8 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
}
UpgradeDataConfiguration that = (UpgradeDataConfiguration) o;
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from)
&& Objects.equals(type, that.type) && Objects.equals(upgrader, that.upgrader);
&& Objects.equals(type, that.type) && Objects.equals(upgrader, that.upgrader)
&& Objects.equals(upgraderInstance, that.upgraderInstance);
}
@Override
@ -39,6 +45,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
hash += ConfigUtils.hashCode(from);
hash += ConfigUtils.hashCode(type);
hash += ConfigUtils.hashCode(upgrader);
hash += ConfigUtils.hashCode(upgraderInstance);
return hash;
}
@ -48,6 +55,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
if (this.from != null) c.from = this.from;
if (this.type != null) c.type = this.type;
if (this.upgrader != null) c.upgrader = this.upgrader;
if (this.upgraderInstance != null) c.upgraderInstance = this.upgraderInstance;
return c;
}
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Set;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Objects;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin;
package it.cavallium.datagen.plugin;
import java.util.Objects;

View File

@ -1,7 +1,7 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ClassGenerator;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
@ -11,11 +11,10 @@ import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import com.squareup.javapoet.TypeVariableName;
import com.squareup.javapoet.WildcardTypeName;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedType;
import it.cavallium.data.generator.plugin.ComputedVersion;
import java.io.DataInput;
import java.io.IOException;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedType;
import it.cavallium.datagen.plugin.ComputedVersion;
import it.cavallium.stream.SafeDataInput;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
@ -119,8 +118,8 @@ public class GenCurrentVersion extends ClassGenerator {
.addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).returns(TypeVariableName.get("U"))
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build()).addParameter(
ParameterSpec.builder(ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType"), "type").build())
.addParameter(ParameterSpec.builder(DataInput.class, "oldDataInput").build())
.addException(IOException.class).beginControlFlow("return upgradeDataToLatestVersion(oldVersion, switch (oldVersion)");
.addParameter(ParameterSpec.builder(SafeDataInput.class, "oldDataInput").build())
.beginControlFlow("return upgradeDataToLatestVersion(oldVersion, switch (oldVersion)");
for (var versionConfiguration : dataModel.getVersionsSet()) {
// Add a case in which the data version deserializes the serialized data and upgrades it
var versions = ClassName.get(dataModel.getRootPackage(basePackageName), "Versions");
@ -131,7 +130,7 @@ public class GenCurrentVersion extends ClassGenerator {
);
}
var upgradeDataToLatestVersion1Method = upgradeDataToLatestVersion1MethodBuilder
.addStatement("default -> throw new $T(\"Unknown version: \" + oldVersion)", IOException.class)
.addStatement("default -> throw new $T(\"Unknown version: \" + oldVersion)", UnsupportedOperationException.class)
.addCode(CodeBlock.of("$<});"))
.build();
currentVersionClass.addMethod(upgradeDataToLatestVersion1Method);
@ -145,7 +144,6 @@ public class GenCurrentVersion extends ClassGenerator {
.returns(TypeVariableName.get("U"))
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build())
.addParameter(ParameterSpec.builder(TypeVariableName.get("T"), "oldData").build())
.addException(IOException.class)
.addStatement("$T data = oldData", Object.class);
upgradeDataToLatestVersion2MethodBuilder.beginControlFlow("switch (oldVersion)");
for (var versionConfiguration : dataModel.getVersionsSet()) {
@ -168,7 +166,7 @@ public class GenCurrentVersion extends ClassGenerator {
);
}
}
upgradeDataToLatestVersion2MethodBuilder.addStatement("default: throw new $T(\"Unknown version: \" + oldVersion)", IOException.class);
upgradeDataToLatestVersion2MethodBuilder.addStatement("default: throw new $T(\"Unknown version: \" + oldVersion)", UnsupportedOperationException.class);
upgradeDataToLatestVersion2MethodBuilder.endControlFlow();
currentVersionClass.addMethod(upgradeDataToLatestVersion2MethodBuilder.build());
}

View File

@ -1,13 +1,13 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeSpec;
import io.soabase.recordbuilder.core.RecordBuilder;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedTypeBase;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedTypeBase;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.Objects;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,12 +1,13 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedTypeSuper;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
import org.apache.commons.lang3.StringUtils;
@ -36,6 +37,17 @@ public class GenDataSuperX extends ClassGenerator {
classBuilder.addModifiers(Modifier.PUBLIC);
if (version.isCurrent()) {
classBuilder.addModifiers(Modifier.SEALED);
Stream<TypeName> superTypesThatExtendThisSuperType = dataModel.getSuperTypesComputed(version)
.filter(computedTypeSuper -> dataModel.getExtendsInterfaces(computedTypeSuper).anyMatch(typeSuper::equals))
.map(computedTypeSuper -> computedTypeSuper.getJTypeName(basePackageName));
Stream<TypeName> subTypes = typeSuper.subTypes().stream()
.map(subType -> subType.getJTypeName(basePackageName));
Stream<TypeName> permittedSubclasses = Stream.concat(superTypesThatExtendThisSuperType, subTypes).distinct();
classBuilder.addPermittedSubclasses(permittedSubclasses.toList());
}
dataModel.getTypeSameVersions(typeSuper).forEach(v -> {
var iTypeClass = ClassName.get(v.getPackage(basePackageName), "IBaseType");
classBuilder.addSuperinterface(iTypeClass);

View File

@ -1,10 +1,10 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,10 +1,10 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,10 +1,10 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.nativedata.INullable;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.datagen.nativedata.INullable;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,10 +1,10 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,9 +1,9 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.io.Serializable;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
@ -7,9 +7,8 @@ import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeVariableName;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.data.generator.plugin.ClassGenerator;
import java.io.IOException;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.datagen.plugin.ClassGenerator;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
@ -35,7 +34,6 @@ public class GenIVersion extends ClassGenerator {
TypeVariableName.get("B")
))
.returns(ParameterizedTypeName.get(ClassName.get(DataSerializer.class), TypeVariableName.get("T")))
.addException(IOException.class)
.addParameter(ParameterSpec
.builder(ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType"), "type")
.build());

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
@ -6,16 +6,16 @@ import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.TypedNullable;
import it.cavallium.data.generator.nativedata.INullable;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedTypeBase;
import it.cavallium.data.generator.plugin.ComputedTypeCustom;
import it.cavallium.data.generator.plugin.ComputedTypeNullable;
import it.cavallium.data.generator.plugin.ComputedTypeNullableFixed;
import it.cavallium.data.generator.plugin.ComputedTypeNullableVersioned;
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.datagen.TypedNullable;
import it.cavallium.datagen.nativedata.INullable;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedTypeBase;
import it.cavallium.datagen.plugin.ComputedTypeCustom;
import it.cavallium.datagen.plugin.ComputedTypeNullable;
import it.cavallium.datagen.plugin.ComputedTypeNullableFixed;
import it.cavallium.datagen.plugin.ComputedTypeNullableVersioned;
import it.cavallium.datagen.plugin.ComputedTypeSuper;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.List;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,23 +1,24 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ArrayTypeName;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.data.generator.nativedata.ImmutableWrappedArrayList;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedTypeArray;
import it.cavallium.data.generator.plugin.ComputedTypeArrayFixed;
import it.cavallium.data.generator.plugin.ComputedTypeArrayVersioned;
import it.cavallium.data.generator.plugin.ComputedVersion;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.NotSerializableException;
import com.squareup.javapoet.WildcardTypeName;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.datagen.NotSerializableException;
import it.cavallium.datagen.nativedata.ImmutableWrappedArrayList;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedTypeArray;
import it.cavallium.datagen.plugin.ComputedTypeArrayFixed;
import it.cavallium.datagen.plugin.ComputedTypeArrayVersioned;
import it.cavallium.datagen.plugin.ComputedVersion;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import java.util.Objects;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
@ -25,6 +26,11 @@ import org.jetbrains.annotations.NotNull;
public class GenSerializerArrayX extends ClassGenerator {
/**
* Enabling this option can slow down deserialization updates
*/
private static final boolean USE_NATIVE_TYPED_ARRAYS = false;
public GenSerializerArrayX(ClassGeneratorParams params) {
super(params);
}
@ -63,9 +69,8 @@ public class GenSerializerArrayX extends ClassGenerator {
var method = MethodSpec.methodBuilder("serialize");
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
method.addParameter(ParameterSpec.builder(DataOutput.class, "out").build());
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
method.addParameter(ParameterSpec
.builder(typeArray.getJTypeName(basePackageName), "data")
.addAnnotation(NotNull.class)
@ -77,9 +82,9 @@ public class GenSerializerArrayX extends ClassGenerator {
method.addStatement("final int sz = data.size()");
method.addStatement("out.writeInt(sz)");
method.addCode("\n");
method.beginControlFlow("for (int i = 0; i < sz; ++i)");
method.beginControlFlow("for (var item : data)");
var baseSerializerInstance = typeArray.getBase().getJSerializerInstance(basePackageName);
method.addStatement("$T.$N.serialize(out, ($T) data.get(i))",
method.addStatement("$T.$N.serialize(out, ($T) item)",
baseSerializerInstance.className(),
baseSerializerInstance.fieldName(),
typeArray.getBase().getJTypeName(basePackageName)
@ -96,26 +101,40 @@ public class GenSerializerArrayX extends ClassGenerator {
var method = MethodSpec.methodBuilder("deserialize");
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
var typeArrayClassName = typeArray.getJTypeName(basePackageName);
var arrayComponentTypeName = typeArray.getBase().getJTypeName(basePackageName);
var typedArrayTypeName = ArrayTypeName.of(arrayComponentTypeName);
method.returns(typeArrayClassName);
method.addAnnotation(NotNull.class);
method.addParameter(ParameterSpec.builder(DataInput.class, "in").build());
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
method.addStatement("int sz = in.readInt()");
var arrayTypeName = ArrayTypeName.of(typeArray.getBase().getJTypeName(basePackageName));
method.addStatement("$T a = new $T[sz]", arrayTypeName, arrayTypeName.componentType);
if (USE_NATIVE_TYPED_ARRAYS) {
method.addStatement("$T a = new $T[sz]", typedArrayTypeName, arrayComponentTypeName);
} else {
method.addStatement("$T a = new $T[sz]", Object[].class, Object.class);
}
method.addCode("\n");
method.beginControlFlow("for (int i = 0; i < sz; ++i)");
var baseSerializerInstance = typeArray.getBase().getJSerializerInstance(basePackageName);
method.addStatement("a[i] = $T.$N.deserialize(in)", baseSerializerInstance.className(), baseSerializerInstance.fieldName());
method.endControlFlow();
method.addCode("\n");
method.addStatement("return new $T(a)", ParameterizedTypeName.get(ClassName.get(ImmutableWrappedArrayList.class),
typeArray.getBase().getJTypeName(basePackageName)));
if (USE_NATIVE_TYPED_ARRAYS) {
method.addStatement("return $T.of(a)", ParameterizedTypeName.get(ClassName.get(ImmutableWrappedArrayList.class), arrayComponentTypeName));
} else {
method.addStatement("return ($T) ($T) $T.of(a)",
ParameterizedTypeName.get(ClassName.get(ImmutableWrappedArrayList.class), arrayComponentTypeName),
ParameterizedTypeName.get(ClassName.get(ImmutableWrappedArrayList.class), WildcardTypeName.subtypeOf(TypeName.OBJECT)),
ClassName.get(ImmutableWrappedArrayList.class)
);
}
classBuilder.addMethod(method.build());
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
@ -7,14 +7,13 @@ import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedTypeBase;
import it.cavallium.data.generator.plugin.ComputedVersion;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.NotSerializableException;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.datagen.NotSerializableException;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedTypeBase;
import it.cavallium.datagen.plugin.ComputedVersion;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import java.util.Objects;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
@ -60,9 +59,8 @@ public class GenSerializerBaseX extends ClassGenerator {
var method = MethodSpec.methodBuilder("serialize");
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
method.addParameter(ParameterSpec.builder(DataOutput.class, "out").build());
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
method.addParameter(ParameterSpec
.builder(typeBase.getJTypeName(basePackageName), "data")
.addAnnotation(NotNull.class)
@ -95,13 +93,12 @@ public class GenSerializerBaseX extends ClassGenerator {
var method = MethodSpec.methodBuilder("deserialize");
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
ClassName typeBaseClassName = typeBase.getJTypeName(basePackageName);
method.returns(typeBaseClassName);
method.addAnnotation(NotNull.class);
method.addParameter(ParameterSpec.builder(DataInput.class, "in").build());
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
method.addCode("return new $T(\n$>", typeBaseClassName);
typeBase.getData().entrySet().stream().flatMap(entry -> {

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
@ -6,16 +6,15 @@ import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedTypeNullable;
import it.cavallium.data.generator.plugin.ComputedTypeNullableFixed;
import it.cavallium.data.generator.plugin.ComputedTypeNullableVersioned;
import it.cavallium.data.generator.plugin.ComputedVersion;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.NotSerializableException;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.datagen.NotSerializableException;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedTypeNullable;
import it.cavallium.datagen.plugin.ComputedTypeNullableFixed;
import it.cavallium.datagen.plugin.ComputedTypeNullableVersioned;
import it.cavallium.datagen.plugin.ComputedVersion;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import java.util.Objects;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
@ -66,9 +65,8 @@ public class GenSerializerNullableX extends ClassGenerator {
var baseSerializerInstance = base.getJSerializerInstance(basePackageName);
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
method.addParameter(ParameterSpec.builder(DataOutput.class, "out").build());
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
method.addParameter(ParameterSpec
.builder(typeNullable.getJTypeName(basePackageName), "data")
.addAnnotation(NotNull.class)
@ -101,13 +99,12 @@ public class GenSerializerNullableX extends ClassGenerator {
var baseSerializerInstance = base.getJSerializerInstance(basePackageName);
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
var typeNullableClassName = typeNullable.getJTypeName(basePackageName);
method.returns(typeNullableClassName);
method.addAnnotation(NotNull.class);
method.addParameter(ParameterSpec.builder(DataInput.class, "in").build());
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
method.addStatement("return in.readBoolean() ? new $T(($T) $T.$N.deserialize(in)) : $T.empty()",
typeNullableClassName,

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
@ -6,15 +6,14 @@ import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedType;
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
import it.cavallium.data.generator.plugin.ComputedVersion;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.NotSerializableException;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.datagen.NotSerializableException;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedType;
import it.cavallium.datagen.plugin.ComputedTypeSuper;
import it.cavallium.datagen.plugin.ComputedVersion;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import java.util.Objects;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
@ -61,11 +60,10 @@ public class GenSerializerSuperX extends ClassGenerator {
int max = typeSuper.subTypes().size();
var method = MethodSpec.methodBuilder("checkIdValidity");
method.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
method.addException(IOException.class);
method.addParameter(ParameterSpec.builder(int.class, "id").build());
method.beginControlFlow("if (id < 0 || id >= $L)", max);
method.addStatement("throw new $T(new $T(id))", IOException.class, IndexOutOfBoundsException.class);
method.addStatement("throw new $T(id)", IndexOutOfBoundsException.class);
method.endControlFlow();
classBuilder.addMethod(method.build());
@ -75,9 +73,8 @@ public class GenSerializerSuperX extends ClassGenerator {
var method = MethodSpec.methodBuilder("serialize");
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
method.addParameter(ParameterSpec.builder(DataOutput.class, "out").build());
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
method.addParameter(ParameterSpec
.builder(typeSuper.getJTypeName(basePackageName), "data")
.addAnnotation(NotNull.class)
@ -118,13 +115,12 @@ public class GenSerializerSuperX extends ClassGenerator {
var method = MethodSpec.methodBuilder("deserialize");
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
ClassName typeSuperClassName = typeSuper.getJTypeName(basePackageName);
method.returns(typeSuperClassName);
method.addAnnotation(NotNull.class);
method.addParameter(ParameterSpec.builder(DataInput.class, "in").build());
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
method.addStatement("int id = in.readUnsignedByte()");
method.beginControlFlow("return switch (id)");

View File

@ -1,7 +1,7 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ClassGenerator;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -1,6 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
import static it.cavallium.data.generator.plugin.DataModel.fixType;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
@ -11,19 +9,22 @@ import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import it.cavallium.data.generator.DataInitializer;
import it.cavallium.data.generator.DataUpgrader;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedType;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.data.generator.plugin.ComputedTypeBase;
import it.cavallium.data.generator.plugin.ComputedVersion;
import it.cavallium.data.generator.plugin.MoveDataConfiguration;
import it.cavallium.data.generator.plugin.NewDataConfiguration;
import it.cavallium.data.generator.plugin.RemoveDataConfiguration;
import it.cavallium.data.generator.plugin.TransformationConfiguration;
import it.cavallium.data.generator.plugin.UpgradeDataConfiguration;
import java.io.IOException;
import it.cavallium.datagen.DataInitializer;
import it.cavallium.datagen.DataUpgrader;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedType;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.plugin.ComputedTypeBase;
import it.cavallium.datagen.plugin.ComputedVersion;
import it.cavallium.datagen.plugin.JInterfaceLocation;
import it.cavallium.datagen.plugin.JInterfaceLocation.JInterfaceLocationClassName;
import it.cavallium.datagen.plugin.JInterfaceLocation.JInterfaceLocationInstanceField;
import it.cavallium.datagen.plugin.MoveDataConfiguration;
import it.cavallium.datagen.plugin.NewDataConfiguration;
import it.cavallium.datagen.plugin.RemoveDataConfiguration;
import it.cavallium.datagen.plugin.TransformationConfiguration;
import it.cavallium.datagen.plugin.UpgradeDataConfiguration;
import it.cavallium.datagen.plugin.DataModel;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@ -79,7 +80,6 @@ public class GenUpgraderBaseX extends ClassGenerator {
var method = MethodSpec.methodBuilder("upgrade");
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
ClassName typeBaseClassName = typeBase.getJTypeName(basePackageName);
ClassName nextTypeBaseClassName = nextTypeBase.getJTypeName(basePackageName);
@ -118,8 +118,8 @@ public class GenUpgraderBaseX extends ClassGenerator {
var i = e.getKey();
var newDataConfiguration = e.getValue();
var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion());
var newFieldType = Objects.requireNonNull(computedTypes.get(fixType(newDataConfiguration.type)));
var initializerClass = ClassName.bestGuess(newDataConfiguration.initializer);
var newFieldType = Objects.requireNonNull(computedTypes.get(DataModel.fixType(newDataConfiguration.type)));
var initializerLocation = newDataConfiguration.getInitializerLocation();
var genericInitializerClass = ParameterizedTypeName.get(ClassName.get(DataInitializer.class),
newFieldType.getJTypeName(basePackageName).box()
);
@ -127,7 +127,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
var initializerName = createInitializerStaticField(nextInitializerStaticFieldId,
initializerStaticFieldNames,
classBuilder,
initializerClass,
initializerLocation,
genericInitializerClass
);
@ -148,7 +148,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
fieldName = moveDataConfiguration.to;
} else if (transformation instanceof NewDataConfiguration newDataConfiguration) {
if (newDataConfiguration.to.equals(fieldName)) {
var type = dataModel.getComputedTypes(version).get(fixType(newDataConfiguration.type));
var type = dataModel.getComputedTypes(version).get(DataModel.fixType(newDataConfiguration.type));
throw new IllegalStateException(
"New field " + typeBase.getName() + "." + fieldName + " of type \"" + type + "\" at version \"" + nextTypeBase.getVersion()
+ "\" conflicts with another field of type \"" + fieldType + "\" with the same name at version \""
@ -166,10 +166,10 @@ public class GenUpgraderBaseX extends ClassGenerator {
if (!upgradeDataConfiguration.from.equals(fieldName)) {
continue;
}
var upgraderClass = ClassName.bestGuess(upgradeDataConfiguration.upgrader);
var upgraderImplementationLocation = upgradeDataConfiguration.getUpgraderLocation();
var cb = CodeBlock.builder();
var newFieldType = Objects
.requireNonNull(dataModel.getComputedTypes(nextTypeBase.getVersion()).get(fixType(upgradeDataConfiguration.type)));
.requireNonNull(dataModel.getComputedTypes(nextTypeBase.getVersion()).get(DataModel.fixType(upgradeDataConfiguration.type)));
var genericUpgraderClass = ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
fieldType.getJTypeName(basePackageName).box(),
newFieldType.getJTypeName(basePackageName).box()
@ -178,7 +178,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
var upgraderName = createUpgraderStaticField(nextUpgraderStaticFieldId,
upgraderStaticFieldNames,
classBuilder,
upgraderClass,
upgraderImplementationLocation,
genericUpgraderClass
);
@ -225,18 +225,24 @@ public class GenUpgraderBaseX extends ClassGenerator {
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
HashMap<String, String> initializerStaticFieldNames,
Builder classBuilder,
ClassName initializerClass,
JInterfaceLocation initializerLocation,
TypeName genericInitializerClass) {
var ref = initializerClass.reflectionName();
var initializerName = initializerStaticFieldNames.get(ref);
var identifier = initializerLocation.getIdentifier();
var initializerName = initializerStaticFieldNames.get(identifier);
if (initializerName == null) {
initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement();
classBuilder.addField(FieldSpec
var fieldBuilder = FieldSpec
.builder(genericInitializerClass, initializerName)
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("new $T()", initializerClass)
.build());
initializerStaticFieldNames.put(ref, initializerName);
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL);
switch (initializerLocation) {
case JInterfaceLocationClassName className -> fieldBuilder.initializer("new $T()", className.className());
case JInterfaceLocationInstanceField instanceField -> fieldBuilder.initializer("$T.$N",
instanceField.fieldLocation().className(),
instanceField.fieldLocation().fieldName()
);
}
classBuilder.addField(fieldBuilder.build());
initializerStaticFieldNames.put(identifier, initializerName);
}
return initializerName;
}
@ -244,18 +250,24 @@ public class GenUpgraderBaseX extends ClassGenerator {
private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId,
HashMap<String, String> upgraderStaticFieldNames,
Builder classBuilder,
ClassName upgraderClass,
JInterfaceLocation upgraderLocation,
TypeName genericUpgraderClass) {
var ref = upgraderClass.reflectionName();
var upgraderName = upgraderStaticFieldNames.get(ref);
var identifier = upgraderLocation.getIdentifier();
var upgraderName = upgraderStaticFieldNames.get(identifier);
if (upgraderName == null) {
upgraderName = "U" + nextUpgraderStaticFieldId.getAndIncrement();
classBuilder.addField(FieldSpec
var fieldBuilder = FieldSpec
.builder(genericUpgraderClass, upgraderName)
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("new $T()", upgraderClass)
.build());
upgraderStaticFieldNames.put(ref, upgraderName);
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL);
switch (upgraderLocation) {
case JInterfaceLocationClassName className -> fieldBuilder.initializer("new $T()", className.className());
case JInterfaceLocationInstanceField instanceField -> fieldBuilder.initializer("$T.$N",
instanceField.fieldLocation().className(),
instanceField.fieldLocation().fieldName()
);
}
classBuilder.addField(fieldBuilder.build());
upgraderStaticFieldNames.put(identifier, upgraderName);
}
return upgraderName;
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
@ -7,13 +7,12 @@ import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import it.cavallium.data.generator.DataUpgrader;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedType;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
import it.cavallium.data.generator.plugin.ComputedVersion;
import java.io.IOException;
import it.cavallium.datagen.DataUpgrader;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedType;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.plugin.ComputedTypeSuper;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
import org.jetbrains.annotations.NotNull;
@ -61,7 +60,6 @@ public class GenUpgraderSuperX extends ClassGenerator {
var method = MethodSpec.methodBuilder("upgrade");
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
method.addException(IOException.class);
ClassName typeSuperClassName = typeSuper.getJTypeName(basePackageName);
ClassName nextTypeSuperClassName = nextTypeSuper.getJTypeName(basePackageName);

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
@ -9,17 +9,16 @@ import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import com.squareup.javapoet.TypeSpec.Builder;
import com.squareup.javapoet.TypeVariableName;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.data.generator.DataUpgrader;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
import it.cavallium.data.generator.plugin.ComputedTypeArrayFixed;
import it.cavallium.data.generator.plugin.ComputedTypeBase;
import it.cavallium.data.generator.plugin.ComputedTypeCustom;
import it.cavallium.data.generator.plugin.ComputedTypeNullableFixed;
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
import it.cavallium.data.generator.plugin.ComputedVersion;
import java.io.IOException;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.datagen.DataUpgrader;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.plugin.ComputedTypeArrayFixed;
import it.cavallium.datagen.plugin.ComputedTypeBase;
import it.cavallium.datagen.plugin.ComputedTypeCustom;
import it.cavallium.datagen.plugin.ComputedTypeNullableFixed;
import it.cavallium.datagen.plugin.ComputedTypeSuper;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.Objects;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
@ -105,7 +104,6 @@ public class GenVersion extends ClassGenerator {
var methodBuilder = MethodSpec.methodBuilder("upgradeToNextVersion");
methodBuilder.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
methodBuilder.addException(ClassName.get(IOException.class));
var nextIBaseType = ClassName.get(nextVersion.getPackage(basePackageName), "IBaseType");
methodBuilder.returns(nextIBaseType);
@ -211,7 +209,6 @@ public class GenVersion extends ClassGenerator {
methodBuilder.addModifiers(Modifier.PUBLIC);
methodBuilder.addAnnotation(Override.class);
methodBuilder.addException(ClassName.get(IOException.class));
var iBaseTypeClassName = ClassName.get(version.getPackage(basePackageName), "IBaseType");
methodBuilder.addTypeVariable(TypeVariableName.get("T", iBaseTypeClassName));

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator.plugin.classgen;
package it.cavallium.datagen.plugin.classgen;
import com.squareup.javapoet.ArrayTypeName;
import com.squareup.javapoet.ClassName;
@ -6,11 +6,9 @@ import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import it.cavallium.data.generator.plugin.ClassGenerator;
import it.cavallium.data.generator.plugin.ComputedVersion;
import java.nio.file.Path;
import it.cavallium.datagen.plugin.ClassGenerator;
import it.cavallium.datagen.plugin.ComputedVersion;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;

View File

@ -5,13 +5,13 @@
<modelVersion>4.0.0</modelVersion>
<name>Data generator runtime</name>
<artifactId>data-generator-runtime</artifactId>
<artifactId>datagen</artifactId>
<version>${revision}</version>
<packaging>jar</packaging>
<parent>
<groupId>it.cavallium</groupId>
<version>${revision}</version>
<artifactId>data-generator</artifactId>
<artifactId>datagen-parent</artifactId>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
@ -67,7 +67,7 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>17</release>
<release>21</release>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
@ -101,6 +101,37 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>attach-javadoc</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<doclint>all,-missing</doclint>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
@ -128,7 +159,7 @@
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
@ -143,7 +174,7 @@
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
@ -159,6 +190,17 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
@ -175,7 +217,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.0</version>
<version>5.9.2</version>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
@ -183,6 +225,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.9.2</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -0,0 +1,11 @@
package it.cavallium.buffer;
import java.util.Comparator;
public interface ArraysComparator extends Comparator<byte[]> {
@Override
int compare(byte[] a, byte[] b);
int compare(byte[] a, int aFrom, int aTo, byte[] b, int bFrom, int bTo);
}

View File

@ -0,0 +1,313 @@
package it.cavallium.buffer;
import it.cavallium.datagen.nativedata.Int52;
import it.cavallium.stream.SafeByteArrayInputStream;
import it.cavallium.stream.SafeByteArrayOutputStream;
import it.cavallium.stream.SafeDataOutput;
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
import it.unimi.dsi.fastutil.bytes.ByteList;
import java.nio.charset.Charset;
import java.util.RandomAccess;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
public interface Buf extends ByteList, RandomAccess {
static Buf wrap(ByteList bytes) {
if (bytes instanceof Buf buf) {
return buf;
} else if (bytes instanceof ByteArrayList byteArrayList) {
return ByteListBuf.wrap(byteArrayList.elements(), byteArrayList.size());
} else {
return ByteListBuf.wrap(bytes.toByteArray());
}
}
static Buf wrap(ByteList bytes, int from, int to) {
if (bytes instanceof Buf buf) {
return buf.subList(from, to);
} else if (bytes instanceof ByteArrayList byteArrayList) {
return ByteListBuf.wrap(byteArrayList.elements(), byteArrayList.size()).subList(from, to);
} else {
return ByteListBuf.wrap(bytes.toByteArray()).subList(from, to);
}
}
static Buf wrap(byte... bytes) {
return ByteListBuf.wrap(bytes);
}
static Buf wrap(byte[] bytes, int from, int to) {
return ByteListBuf.wrap(bytes, to).subList(from, to);
}
static Buf create(int initialCapacity) {
return new ByteListBuf(initialCapacity);
}
static Buf copyOf(byte[] original) {
return new ByteListBuf(original);
}
static Buf create() {
return new ByteListBuf();
}
static Buf wrap(byte[] array, int length) {
return ByteListBuf.wrap(array, length);
}
static Buf createZeroes(int length) {
return ByteListBuf.wrap(new byte[length], length);
}
/**
* Get this element as an array, converting it if needed
*/
byte @NotNull[] asArray();
/**
* Get this element as an array, only if it's already an array, otherwise return null
*/
byte @Nullable[] asArrayStrict();
/**
* Get this element as an array with equal or bigger size, converting it if needed
* The returned array may be bigger than expected!
*/
byte[] asUnboundedArray();
/**
* Get this element as an array with equal or bigger size, only if it's already an array, otherwise return null
* The returned array may be bigger than expected!
*/
byte @Nullable[] asUnboundedArrayStrict();
boolean isMutable();
Buf freeze();
@Override
Buf subList(int from, int to);
@VisibleForTesting
Buf subListForced(int from, int to);
Buf copyOfRange(int from, int to);
Buf copy();
SafeByteArrayInputStream binaryInputStream();
void writeTo(SafeDataOutput dataOutput);
/**
* @param i byte offset
*/
default float getFloat(int i) {
return Float.intBitsToFloat(getInt(i));
}
/**
* @param i byte offset
*/
default double getDouble(int i) {
return Double.longBitsToDouble(getLong(i));
}
/**
* @param i byte offset
*/
default char getChar(int i) {
byte b1 = getByte(i);
byte b2 = getByte(i + 1);
return (char) ((b1 & 0xFF) << 8 | (b2 & 0xFF));
}
/**
* @param i byte offset
*/
default short getShort(int i) {
byte b1 = getByte(i);
byte b2 = getByte(i + 1);
return (short) ((b1 & 0xFF) << 8 | (b2 & 0xFF));
}
/**
* @param i byte offset
*/
default int getInt(int i) {
byte b1 = getByte(i);
byte b2 = getByte(i + 1);
byte b3 = getByte(i + 2);
byte b4 = getByte(i + 3);
return b1 << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF);
}
/**
* @param i byte offset
*/
default long getLong(int i) {
byte b1 = getByte(i);
byte b2 = getByte(i + 1);
byte b3 = getByte(i + 2);
byte b4 = getByte(i + 3);
byte b5 = getByte(i + 4);
byte b6 = getByte(i + 5);
byte b7 = getByte(i + 6);
byte b8 = getByte(i + 7);
return (b1 & 0xFFL) << 56
| (b2 & 0xFFL) << 48
| (b3 & 0xFFL) << 40
| (b4 & 0xFFL) << 32
| (b5 & 0xFFL) << 24
| (b6 & 0xFFL) << 16
| (b7 & 0xFFL) << 8
| (b8 & 0xFFL);
}
/**
* @param i byte offset
*/
default long getInt52(int i) {
byte b1 = getByte(i);
byte b2 = getByte(i + 1);
byte b3 = getByte(i + 2);
byte b4 = getByte(i + 3);
byte b5 = getByte(i + 4);
byte b6 = getByte(i + 5);
byte b7 = getByte(i + 6);
return (b1 & 0xFFL) << 48
| (b2 & 0xFFL) << 40
| (b3 & 0xFFL) << 32
| (b4 & 0xFFL) << 24
| (b5 & 0xFFL) << 16
| (b6 & 0xFFL) << 8
| (b7 & 0xFFL);
}
/**
* @param i byte offset
*/
default boolean getBoolean(int i) {
return getByte(i) != 0;
}
/**
* @param i byte offset
*/
default String getShortText(int i, Charset charset) {
var len = getShort(i);
return getString(i + Short.BYTES, len, charset);
}
/**
* @param i byte offset
*/
default String getMediumText(int i, Charset charset) {
var len = getInt(i);
return getString(i + Integer.BYTES, len, charset);
}
/**
* @param i byte offset
*/
String getString(int i, int length, Charset charset);
/**
* @param i byte offset
*/
default void setBoolean(int i, boolean val) {
set(i, val ? (byte) 1 : 0);
}
/**
* @param i byte offset
*/
default void setByte(int i, byte val) {
set(i, val);
}
/**
* @param i byte offset
*/
default void setChar(int i, char val) {
set(i, (byte) (val >> 8));
set(i + 1, (byte) val);
}
/**
* @param i byte offset
*/
default void setShort(int i, short val) {
set(i, (byte) (val >> 8));
set(i + 1, (byte) val);
}
/**
* @param i byte offset
*/
default void setInt(int i, int val) {
set(i, (byte) (val >> 24));
set(i + 1, (byte) (val >> 16));
set(i + 2, (byte) (val >> 8));
set(i + 3, (byte) val);
}
/**
* @param i byte offset
*/
default void setLong(int i, long val) {
set(i, (byte) (val >> 56));
set(i + 1, (byte) (val >> 48));
set(i + 2, (byte) (val >> 40));
set(i + 3, (byte) (val >> 32));
set(i + 4, (byte) (val >> 24));
set(i + 5, (byte) (val >> 16));
set(i + 6, (byte) (val >> 8));
set(i + 7, (byte) val);
}
/**
* @param i byte offset
*/
default void setInt52(int i, long val) {
Int52.checkValidity(val);
set(i, (byte) (val >> 48));
set(i + 1, (byte) (val >> 40));
set(i + 2, (byte) (val >> 32));
set(i + 3, (byte) (val >> 24));
set(i + 4, (byte) (val >> 16));
set(i + 5, (byte) (val >> 8));
set(i + 6, (byte) val);
}
/**
* @param i byte offset
*/
default void setFloat(int i, float val) {
setInt(i, Float.floatToRawIntBits(val));
}
/**
* @param i byte offset
*/
default void setDouble(int i, double val) {
setLong(i, Double.doubleToRawLongBits(val));
}
default SafeByteArrayOutputStream binaryOutputStream() {
return binaryOutputStream(0, size());
}
default SafeByteArrayOutputStream binaryOutputStream(int from) {
return binaryOutputStream(from, size());
}
SafeByteArrayOutputStream binaryOutputStream(int from, int to);
boolean equals(int aStartIndex, Buf b, int bStartIndex, int length);
boolean equals(int aStartIndex, byte[] b, int bStartIndex, int length);
String toString(Charset charset);
}

View File

@ -0,0 +1,28 @@
package it.cavallium.buffer;
import it.cavallium.stream.SafeByteArrayInputStream;
import it.cavallium.stream.SafeDataInputStream;
import org.jetbrains.annotations.NotNull;
public class BufDataInput extends SafeDataInputStream {
/**
* Creates a DataInputStream that uses the specified underlying InputStream.
*
* @param in the specified input stream
*/
private BufDataInput(@NotNull SafeByteArrayInputStream in) {
super(in);
}
public static BufDataInput create(Buf byteList) {
return new BufDataInput(byteList.binaryInputStream());
}
@Deprecated
@Override
public void close() {
super.close();
}
}

View File

@ -0,0 +1,273 @@
package it.cavallium.buffer;
import static java.util.Objects.checkFromToIndex;
import it.cavallium.stream.SafeByteArrayOutputStream;
import it.cavallium.stream.SafeDataOutput;
import it.cavallium.stream.SafeDataOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
public class BufDataOutput implements SafeDataOutput {
private final SafeByteArrayOutputStream buf;
private final SafeDataOutputStream dOut;
private final int limit;
private BufDataOutput(SafeByteArrayOutputStream buf) {
this.buf = buf;
this.dOut = new SafeDataOutputStream(buf);
limit = Integer.MAX_VALUE;
}
private BufDataOutput(SafeByteArrayOutputStream buf, int maxSize) {
this.buf = buf;
this.dOut = new SafeDataOutputStream(buf);
this.limit = maxSize;
}
public static BufDataOutput createLimited(int maxSize, int hint) {
if (hint >= 0) {
if (maxSize < 0 || maxSize == Integer.MAX_VALUE) {
return create(hint);
} else {
return new BufDataOutput(new SafeByteArrayOutputStream(Math.min(maxSize, hint)), maxSize);
}
} else {
return createLimited(maxSize);
}
}
public static BufDataOutput createLimited(int maxSize) {
if (maxSize < 0 || maxSize == Integer.MAX_VALUE) {
return create();
} else {
return new BufDataOutput(new SafeByteArrayOutputStream(maxSize), maxSize);
}
}
public static BufDataOutput create() {
return new BufDataOutput(new SafeByteArrayOutputStream());
}
public static BufDataOutput create(int hint) {
if (hint >= 0) {
return new BufDataOutput(new SafeByteArrayOutputStream(hint));
} else {
return create();
}
}
@IgnoreCoverage
@Deprecated(forRemoval = true)
public static BufDataOutput wrap(Buf buf, int from, int to) {
checkFromToIndex(from, to, buf.size());
if (buf.isEmpty()) {
return createLimited(0);
} else {
return new BufDataOutput(buf.binaryOutputStream(from), to - from);
}
}
@IgnoreCoverage
@Deprecated(forRemoval = true)
public static BufDataOutput wrap(Buf buf) {
if (buf.isEmpty()) {
return createLimited(0);
} else {
return new BufDataOutput(buf.binaryOutputStream(), buf.size());
}
}
private IllegalStateException unreachable(IOException ex) {
return new IllegalStateException(ex);
}
@Override
public void write(int b) {
// Fast inlined checkOutOfBounds
if (dOut.size() >= limit) {
throw new IndexOutOfBoundsException(limit);
}
dOut.write(b);
}
private void checkOutOfBounds(int delta) {
if (dOut.size() + delta > limit) {
throw new IndexOutOfBoundsException(limit);
}
}
@Override
public void write(byte @NotNull [] b) {
checkOutOfBounds(b.length);
dOut.write(b);
}
@Override
public void write(byte @NotNull [] b, int off, int len) {
checkOutOfBounds(Math.max(0, Math.min(b.length - off, len)));
dOut.write(b, off, len);
}
@Override
public void writeBoolean(boolean v) {
// Fast inlined checkOutOfBounds
if (dOut.size() >= limit) {
throw new IndexOutOfBoundsException(limit);
}
dOut.writeBoolean(v);
}
@Override
public void writeByte(int v) {
this.write(v);
}
@Override
public void writeShort(int v) {
checkOutOfBounds(Short.BYTES);
dOut.writeShort(v);
}
@Override
public void writeChar(int v) {
checkOutOfBounds(Character.BYTES);
dOut.writeChar(v);
}
@Override
public void writeInt(int v) {
checkOutOfBounds(Integer.BYTES);
dOut.writeInt(v);
}
@Override
public void writeLong(long v) {
checkOutOfBounds(Long.BYTES);
dOut.writeLong(v);
}
public void writeInt52(long v) {
checkOutOfBounds(7);
dOut.writeInt52(v);
}
@Override
public void writeFloat(float v) {
checkOutOfBounds(Float.BYTES);
dOut.writeFloat(v);
}
@Override
public void writeDouble(double v) {
checkOutOfBounds(Double.BYTES);
dOut.writeDouble(v);
}
public void ensureWritable(int size) {
dOut.flush();
buf.ensureWritable(size);
}
@Override
public void writeBytes(@NotNull String s) {
checkOutOfBounds(s.length() * Byte.BYTES);
dOut.writeBytes(s);
}
// todo: check
public void writeBytes(Buf deserialized) {
checkOutOfBounds(deserialized.size());
deserialized.writeTo(dOut);
}
public void writeBytes(byte[] b, int off, int len) {
write(b, off, len);
}
@Override
public void writeChars(@NotNull String s) {
checkOutOfBounds(Character.BYTES * s.length());
dOut.writeChars(s);
}
private static String tooLongMsg(String s, int bits32) {
int slen = s.length();
String head = s.substring(0, 8);
String tail = s.substring(slen - 8, slen);
// handle int overflow with max 3x expansion
long actualLength = (long)slen + Integer.toUnsignedLong(bits32 - slen);
return "encoded string (" + head + "..." + tail + ") too long: "
+ actualLength + " bytes";
}
@Deprecated
@Override
public void writeUTF(@NotNull String str) {
writeShortText(str, StandardCharsets.UTF_8);
}
@Override
public void writeShortText(String s, Charset charset) {
var out = s.getBytes(charset);
if (out.length > Short.MAX_VALUE) {
throw new IndexOutOfBoundsException("String too long: " + out.length + " bytes");
}
checkOutOfBounds(Short.BYTES + out.length);
dOut.writeShort(out.length);
dOut.write(out);
}
@Override
public void writeMediumText(String s, Charset charset) {
var out = s.getBytes(charset);
checkOutOfBounds(Integer.BYTES + out.length);
dOut.writeInt(out.length);
dOut.write(out);
}
public Buf asList() {
dOut.flush();
return Buf.wrap(this.buf.array, this.buf.length);
}
public Buf toList() {
dOut.flush();
return Buf.wrap(Arrays.copyOf(this.buf.array, this.buf.length));
}
@Override
public String toString() {
return dOut.toString();
}
@Override
public int hashCode() {
return dOut.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BufDataOutput that = (BufDataOutput) o;
return Objects.equals(dOut, that.dOut);
}
public int size() {
return dOut.size();
}
}

View File

@ -0,0 +1,941 @@
package it.cavallium.buffer;
import static java.util.Objects.checkFromIndexSize;
import static java.util.Objects.checkFromToIndex;
import it.cavallium.stream.SafeByteArrayInputStream;
import it.cavallium.stream.SafeByteArrayOutputStream;
import it.cavallium.stream.SafeDataOutput;
import it.unimi.dsi.fastutil.bytes.AbstractByteList;
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
import it.unimi.dsi.fastutil.bytes.ByteArrays;
import it.unimi.dsi.fastutil.bytes.ByteCollection;
import it.unimi.dsi.fastutil.bytes.ByteConsumer;
import it.unimi.dsi.fastutil.bytes.ByteIterator;
import it.unimi.dsi.fastutil.bytes.ByteIterators;
import it.unimi.dsi.fastutil.bytes.ByteList;
import it.unimi.dsi.fastutil.bytes.ByteListIterator;
import it.unimi.dsi.fastutil.bytes.BytePredicate;
import it.unimi.dsi.fastutil.bytes.ByteSpliterator;
import it.unimi.dsi.fastutil.bytes.ByteSpliterators;
import it.unimi.dsi.fastutil.bytes.ByteUnaryOperator;
import java.io.Serial;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HexFormat;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.function.IntPredicate;
import java.util.function.IntUnaryOperator;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
class ByteListBuf extends ByteArrayList implements Buf {
private static final HexFormat HEX_FORMAT = HexFormat.of().withUpperCase();
private static final String IMMUTABLE_ERROR = "The buffer is immutable";
private static final VariableLengthLexiconographicComparator VAR_LENGTH_LEX_COMP = new VariableLengthLexiconographicComparator();
private boolean immutable;
protected ByteListBuf(byte[] a, boolean wrapped) {
super(a, wrapped);
}
public ByteListBuf(int capacity) {
super(capacity);
}
public ByteListBuf() {
}
public ByteListBuf(Collection<? extends Byte> c) {
super(c);
}
public ByteListBuf(ByteCollection c) {
super(c);
}
public ByteListBuf(ByteList l) {
super(l);
}
public ByteListBuf(byte[] a) {
super(a);
}
public ByteListBuf(byte[] a, int offset, int length) {
super(a, offset, length);
}
public ByteListBuf(Iterator<? extends Byte> i) {
super(i);
}
public ByteListBuf(ByteIterator i) {
super(i);
}
/**
* Wraps a given array into an array list of given size.
*
* <p>
* Note it is guaranteed that the type of the array returned by {@link #elements()} will be the same
* (see the comments in the class documentation).
*
* @param a an array to wrap.
* @param length the length of the resulting array list.
* @return a new array list of the given size, wrapping the given array.
*/
public static ByteListBuf wrap(final byte[] a, final int length) {
ByteArrays.ensureFromTo(a, 0, length);
final ByteListBuf l = new ByteListBuf(a, true);
l.size = length;
return l;
}
/**
* Wraps a given array into an array list.
*
* <p>
* Note it is guaranteed that the type of the array returned by {@link #elements()} will be the same
* (see the comments in the class documentation).
*
* @param a an array to wrap.
* @return a new array list wrapping the given array.
*/
public static ByteListBuf wrap(final byte[] a) {
return wrap(a, a.length);
}
/**
* Creates a new empty array list.
*
* @return a new empty array list.
*/
public static ByteListBuf of() {
return new ByteListBuf();
}
/**
* Creates an array list using an array of elements.
*
* @param init a the array the will become the new backing array of the array list.
* @return a new array list backed by the given array.
* @see #wrap
*/
public static ByteListBuf of(final byte... init) {
return wrap(init);
}
@Override
public byte @NotNull [] asArray() {
if (this.size() == a.length) {
return this.a;
} else {
return this.toByteArray();
}
}
@Override
public byte @Nullable [] asArrayStrict() {
if (this.size() == a.length) {
return a;
} else {
return null;
}
}
@Override
public byte[] asUnboundedArray() {
return a;
}
@Override
public byte @Nullable [] asUnboundedArrayStrict() {
return a;
}
@Override
public boolean isMutable() {
return !immutable;
}
@Override
public ByteListBuf freeze() {
immutable = true;
return this;
}
@Override
public Buf subList(int from, int to) {
if (from == 0 && to == size()) return this;
return subListForced(from, to);
}
@VisibleForTesting
public Buf subListForced(int from, int to) {
checkFromToIndex(from, to, this.size());
return new SubList(from, to);
}
@Override
public Buf copyOfRange(int from, int to) {
if (from == 0 && to == size()) {
return copy();
} else {
return ByteListBuf.wrap(Arrays.copyOfRange(this.a, from, to), to - from);
}
}
@Override
public Buf copy() {
return ByteListBuf.wrap(this.a.clone(), this.size);
}
@Override
public SafeByteArrayInputStream binaryInputStream() {
return new SafeByteArrayInputStream(this.a, 0, this.size);
}
@Override
public void writeTo(SafeDataOutput dataOutput) {
dataOutput.write(this.a, 0, this.size);
}
@Override
public SafeByteArrayOutputStream binaryOutputStream(int from, int to) {
checkFromToIndex(from, to, size);
return new SafeByteArrayOutputStream(a, from, to);
}
@Override
public boolean equals(int aStartIndex, Buf b, int bStartIndex, int length) {
if (aStartIndex + length > size()) {
return false;
}
return b.equals(bStartIndex, this.a, aStartIndex, length);
}
@Override
public boolean equals(int aStartIndex, byte[] b, int bStartIndex, int length) {
if (aStartIndex < 0) return false;
if (aStartIndex + length > this.size) {
return false;
}
if (bStartIndex + length > b.length) {
return false;
}
return Arrays.equals(a, aStartIndex, aStartIndex + length, b, bStartIndex, bStartIndex + length);
}
@Override
public String toString(Charset charset) {
return getString(0, size, charset);
}
@Override
public String toString() {
return HEX_FORMAT.formatHex(a, 0, size());
}
@Override
public String getString(int i, int length, Charset charset) {
return new String(a, i, length, charset);
}
class SubList extends AbstractByteList.ByteRandomAccessSubList implements Buf {
@Serial
private static final long serialVersionUID = -3185226345314976296L;
protected SubList(int from, int to) {
super(ByteListBuf.this, from, to);
}
// Most of the inherited methods should be fine, but we can override a few of them for performance.
// Needed because we can't access the parent class' instance variables directly in a different
// instance of SubList.
@IgnoreCoverage
private byte[] getParentArray() {
return a;
}
@Override
public @NotNull Buf subList(int from, int to) {
// Sadly we have to rewrap this, because if there is a sublist of a sublist, and the
// subsublist adds, both sublists need to update their "to" value.
return subListForced(from, to);
}
@Override
public Buf subListForced(int from, int to) {
checkFromToIndex(from, to, this.to);
var fromAbs = this.from + from;
var toAbs = this.from + to;
// Sadly we have to rewrap this, because if there is a sublist of a sublist, and the
// subsublist adds, both sublists need to update their "to" value.
return new SubList(fromAbs, toAbs);
}
@Override
public Buf copyOfRange(int from, int to) {
if (from == 0 && to == size()) {
return copy();
} else {
return Buf.wrap(Arrays.copyOfRange(a, this.from + from, this.from + to));
}
}
@Override
public Buf copy() {
return Buf.wrap(Arrays.copyOfRange(a, from, to));
}
@Override
public SafeByteArrayInputStream binaryInputStream() {
return new SafeByteArrayInputStream(a, from, size());
}
@Override
public void writeTo(SafeDataOutput dataOutput) {
dataOutput.write(a, from, size());
}
@Override
public SafeByteArrayOutputStream binaryOutputStream(int from, int to) {
checkFromToIndex(from, to, size());
return new SafeByteArrayOutputStream(a, from + this.from, to + this.from);
}
@Override
public boolean equals(int aStartIndex, Buf b, int bStartIndex, int length) {
if (aStartIndex + length > size()) {
return false;
}
return b.equals(bStartIndex, a, aStartIndex + from, length);
}
@Override
public boolean equals(int aStartIndex, byte[] b, int bStartIndex, int length) {
var aFrom = from + aStartIndex;
var aTo = from + aStartIndex + length;
var bTo = bStartIndex + length;
if (aFrom < from) return false;
if (aTo > to) return false;
if (bTo > b.length) return false;
return Arrays.equals(a, aFrom, aTo, b, bStartIndex, bTo);
}
@Override
public byte getByte(int i) {
ensureRestrictedIndex(i);
return a[i + from];
}
@Override
public byte @NotNull [] asArray() {
if (this.from == 0 && this.to == a.length) {
return a;
} else {
return SubList.this.toByteArray();
}
}
@Override
public byte @Nullable [] asArrayStrict() {
if (this.from == 0 && this.to == a.length) {
return a;
} else {
return null;
}
}
@Override
public byte[] asUnboundedArray() {
if (from == 0) {
return a;
} else {
return toByteArray();
}
}
@Override
public byte @Nullable [] asUnboundedArrayStrict() {
if (from == 0) {
return a;
} else {
return null;
}
}
@Override
public boolean isMutable() {
return ByteListBuf.this.isMutable();
}
@Override
public SubList freeze() {
immutable = true;
return this;
}
private final class SubListIterator extends ByteIterators.AbstractIndexBasedListIterator {
// We are using pos == 0 to be 0 relative to SubList.from (meaning you need to do a[from + i] when
// accessing array).
SubListIterator(int index) {
super(0, index);
}
@IgnoreCoverage
@Override
protected byte get(int i) {
return ByteListBuf.SubList.this.getByte(i);
}
@IgnoreCoverage
@Override
protected void add(int i, byte k) {
assert isMutable() : IMMUTABLE_ERROR;
ByteListBuf.SubList.this.add(i, k);
}
@IgnoreCoverage
@Override
protected void set(int i, byte k) {
assert isMutable() : IMMUTABLE_ERROR;
ByteListBuf.SubList.this.set(i, k);
}
@IgnoreCoverage
@Override
protected void remove(int i) {
assert isMutable() : IMMUTABLE_ERROR;
ByteListBuf.SubList.this.removeByte(i);
}
@Override
protected int getMaxPos() {
return to - from;
}
@Override
public byte nextByte() {
if (!hasNext()) throw new NoSuchElementException();
return a[from + (lastReturned = pos++)];
}
@Override
public byte previousByte() {
if (!hasPrevious()) throw new NoSuchElementException();
return a[from + (lastReturned = --pos)];
}
@Override
public void forEachRemaining(final ByteConsumer action) {
final int max = to - from;
while (pos < max) {
action.accept(a[from + (lastReturned = pos++)]);
}
}
}
@Override
public @NotNull ByteListIterator listIterator(int index) {
return new ByteListBuf.SubList.SubListIterator(index);
}
private final class SubListSpliterator extends ByteSpliterators.LateBindingSizeIndexBasedSpliterator {
// We are using pos == 0 to be 0 relative to real array 0
SubListSpliterator() {
super(from);
}
private SubListSpliterator(int pos, int maxPos) {
super(pos, maxPos);
}
@Override
protected int getMaxPosFromBackingStore() {
return to;
}
@IgnoreCoverage
@Override
protected byte get(int i) {
return a[i];
}
@Override
protected ByteListBuf.SubList.SubListSpliterator makeForSplit(int pos, int maxPos) {
return new ByteListBuf.SubList.SubListSpliterator(pos, maxPos);
}
@Override
public boolean tryAdvance(final ByteConsumer action) {
if (pos >= getMaxPos()) return false;
action.accept(a[pos++]);
return true;
}
@Override
public void forEachRemaining(final ByteConsumer action) {
final int max = getMaxPos();
while (pos < max) {
action.accept(a[pos++]);
}
}
}
@Override
public ByteSpliterator spliterator() {
return new ByteListBuf.SubList.SubListSpliterator();
}
boolean contentsEquals(byte[] otherA, int otherAFrom, int otherATo) {
if (a == otherA && from == otherAFrom && to == otherATo) return true;
return Arrays.equals(a, from, to, otherA, otherAFrom, otherATo);
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof java.util.List)) return false;
if (o instanceof ByteListBuf other) {
return contentsEquals(other.a, 0, other.size());
}
if (o instanceof SubList other) {
return contentsEquals(other.getParentArray(), other.from, other.to);
}
return super.equals(o);
}
int contentsCompareTo(byte[] otherA, int otherAFrom, int otherATo) {
if (a == otherA && from == otherAFrom && to == otherATo) return 0;
return VAR_LENGTH_LEX_COMP.compare(a, from, to, otherA, otherAFrom, otherATo);
}
@Override
public int compareTo(final java.util.@NotNull List<? extends Byte> l) {
if (l instanceof ByteListBuf other) {
return contentsCompareTo(other.a, 0, other.size());
}
if (l instanceof ByteListBuf.SubList other) {
return contentsCompareTo(other.getParentArray(), other.from, other.to);
}
return super.compareTo(l);
}
@Override
public String toString(Charset charset) {
return new String(a, from, size(), charset);
}
@Override
public String toString() {
return HEX_FORMAT.formatHex(a, from, from + size());
}
@Override
public String getString(int i, int length, Charset charset) {
checkFromIndexSize(i, length, to - from);
return new String(a, from + i, length, charset);
}
}
@IgnoreCoverage
@Override
public void add(int index, byte k) {
assert isMutable() : IMMUTABLE_ERROR;
super.add(index, k);
}
@IgnoreCoverage
@Override
public boolean add(byte k) {
assert isMutable() : IMMUTABLE_ERROR;
return super.add(k);
}
@IgnoreCoverage
@Override
public byte removeByte(int index) {
assert isMutable() : IMMUTABLE_ERROR;
return super.removeByte(index);
}
@IgnoreCoverage
@Override
public boolean rem(byte k) {
assert isMutable() : IMMUTABLE_ERROR;
return super.rem(k);
}
@IgnoreCoverage
@Override
public byte set(int index, byte k) {
assert isMutable() : IMMUTABLE_ERROR;
return super.set(index, k);
}
@IgnoreCoverage
@Override
public void clear() {
assert isMutable() : IMMUTABLE_ERROR;
super.clear();
}
@IgnoreCoverage
@Override
public void trim() {
assert isMutable() : IMMUTABLE_ERROR;
super.trim();
}
@IgnoreCoverage
@Override
public void trim(int n) {
assert isMutable() : IMMUTABLE_ERROR;
super.trim(n);
}
@IgnoreCoverage
@Override
public void removeElements(int from, int to) {
assert isMutable() : IMMUTABLE_ERROR;
super.removeElements(from, to);
}
@IgnoreCoverage
@Override
public void addElements(int index, byte[] a, int offset, int length) {
assert isMutable() : IMMUTABLE_ERROR;
super.addElements(index, a, offset, length);
}
@IgnoreCoverage
@Override
public void setElements(int index, byte[] a, int offset, int length) {
assert isMutable() : IMMUTABLE_ERROR;
super.setElements(index, a, offset, length);
}
@IgnoreCoverage
@Override
public boolean addAll(int index, ByteCollection c) {
assert isMutable() : IMMUTABLE_ERROR;
return super.addAll(index, c);
}
@IgnoreCoverage
@Override
public boolean addAll(int index, ByteList l) {
assert isMutable() : IMMUTABLE_ERROR;
return super.addAll(index, l);
}
@IgnoreCoverage
@Override
public boolean removeAll(ByteCollection c) {
assert isMutable() : IMMUTABLE_ERROR;
return super.removeAll(c);
}
@IgnoreCoverage
@Override
public boolean addAll(int index, @NotNull Collection<? extends Byte> c) {
assert isMutable() : IMMUTABLE_ERROR;
return super.addAll(index, c);
}
@IgnoreCoverage
@Override
public boolean addAll(@NotNull Collection<? extends Byte> c) {
assert isMutable() : IMMUTABLE_ERROR;
return super.addAll(c);
}
@IgnoreCoverage
@Override
public void addElements(int index, byte[] a) {
assert isMutable() : IMMUTABLE_ERROR;
super.addElements(index, a);
}
@IgnoreCoverage
@Override
public void push(byte o) {
assert isMutable() : IMMUTABLE_ERROR;
super.push(o);
}
@IgnoreCoverage
@Override
public byte popByte() {
assert isMutable() : IMMUTABLE_ERROR;
return super.popByte();
}
@IgnoreCoverage
@Override
public byte topByte() {
assert isMutable() : IMMUTABLE_ERROR;
return super.topByte();
}
@IgnoreCoverage
@Override
public boolean addAll(ByteCollection c) {
assert isMutable() : IMMUTABLE_ERROR;
return super.addAll(c);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public boolean add(Byte key) {
assert isMutable() : IMMUTABLE_ERROR;
return super.add(key);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public boolean remove(Object key) {
assert isMutable() : IMMUTABLE_ERROR;
return super.remove(key);
}
@IgnoreCoverage
@Override
public boolean removeAll(@NotNull Collection<?> c) {
assert isMutable() : IMMUTABLE_ERROR;
return super.removeAll(c);
}
@IgnoreCoverage
@Override
public boolean retainAll(ByteCollection c) {
assert isMutable() : IMMUTABLE_ERROR;
return super.retainAll(c);
}
@IgnoreCoverage
@Override
public boolean retainAll(@NotNull Collection<?> c) {
assert isMutable() : IMMUTABLE_ERROR;
return super.retainAll(c);
}
@IgnoreCoverage
@Override
public void setElements(byte[] a) {
assert isMutable() : IMMUTABLE_ERROR;
super.setElements(a);
}
@IgnoreCoverage
@Override
public void setElements(int index, byte[] a) {
assert isMutable() : IMMUTABLE_ERROR;
super.setElements(index, a);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public void add(int index, Byte key) {
assert isMutable() : IMMUTABLE_ERROR;
super.add(index, key);
}
@IgnoreCoverage
@Override
public void replaceAll(ByteUnaryOperator operator) {
assert isMutable() : IMMUTABLE_ERROR;
super.replaceAll(operator);
}
@IgnoreCoverage
@Override
public void replaceAll(IntUnaryOperator operator) {
assert isMutable() : IMMUTABLE_ERROR;
super.replaceAll(operator);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public void replaceAll(UnaryOperator<Byte> operator) {
assert isMutable() : IMMUTABLE_ERROR;
super.replaceAll(operator);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public Byte remove(int index) {
assert isMutable() : IMMUTABLE_ERROR;
return super.remove(index);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public Byte set(int index, Byte k) {
assert isMutable() : IMMUTABLE_ERROR;
return super.set(index, k);
}
@IgnoreCoverage
@Override
public boolean addAll(ByteList l) {
assert isMutable() : IMMUTABLE_ERROR;
return super.addAll(l);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public void sort(Comparator<? super Byte> comparator) {
assert isMutable() : IMMUTABLE_ERROR;
super.sort(comparator);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public void unstableSort(Comparator<? super Byte> comparator) {
assert isMutable() : IMMUTABLE_ERROR;
super.unstableSort(comparator);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public boolean removeIf(Predicate<? super Byte> filter) {
assert isMutable() : IMMUTABLE_ERROR;
return super.removeIf(filter);
}
@IgnoreCoverage
@Override
public boolean removeIf(BytePredicate filter) {
assert isMutable() : IMMUTABLE_ERROR;
return super.removeIf(filter);
}
@IgnoreCoverage
@Override
public boolean removeIf(IntPredicate filter) {
assert isMutable() : IMMUTABLE_ERROR;
return super.removeIf(filter);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public void push(Byte o) {
assert isMutable() : IMMUTABLE_ERROR;
super.push(o);
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public Byte pop() {
assert isMutable() : IMMUTABLE_ERROR;
return super.pop();
}
@IgnoreCoverage
@SuppressWarnings("deprecation")
@Deprecated
@Override
public Byte top() {
assert isMutable() : IMMUTABLE_ERROR;
return super.top();
}
@IgnoreCoverage
private void ensureMutable() {
if (!isMutable()) {
throw new UnsupportedOperationException(IMMUTABLE_ERROR);
}
}
@Override
public int compareTo(List<? extends Byte> l) {
if (l instanceof ByteArrayList) {
return compareTo((ByteArrayList)l);
}
if (l instanceof SubList) {
// Must negate because we are inverting the order of the comparison.
return -((SubList)l).compareTo(this);
}
return super.compareTo(l);
}
@Override
public int compareTo(ByteArrayList l) {
final int s1 = size(), s2 = l.size();
final byte[] a1 = a, a2 = l.elements();
if (a1 == a2 && s1 == s2) return 0;
return VAR_LENGTH_LEX_COMP.compare(a, 0, s1, a2, 0, s2);
}
/**
* Compares this type-specific array list to another one.
*
* @apiNote This method exists only for sake of efficiency. The implementation inherited from the
* abstract implementation would already work.
*
* @param l a type-specific array list.
* @return true if the argument contains the same elements of this type-specific array list.
*/
public boolean equals(final ByteArrayList l) {
if (l == this) return true;
int s = size();
if (s != l.size()) return false;
final byte[] a1 = a, a2 = l.elements();
final int s1 = this.size(), s2 = l.size();
return Arrays.equals(a1, 0, s1, a2, 0, s2);
}
@SuppressWarnings("unlikely-arg-type")
@Override
public boolean equals(final Object o) {
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof java.util.List)) return false;
if (o instanceof ByteArrayList) {
// Safe cast because we are only going to take elements from other list, never give them
return equals((ByteArrayList) o);
}
if (o instanceof SubList subList) {
// Safe cast because we are only going to take elements from other list, never give them
// Sublist has an optimized sub-array based comparison, reuse that.
return subList.equals(this);
}
return super.equals(o);
}
}

View File

@ -0,0 +1,8 @@
package it.cavallium.buffer;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.CLASS)
public @interface IgnoreCoverage {
}

View File

@ -0,0 +1,17 @@
package it.cavallium.buffer;
import java.util.Arrays;
public class VariableLengthLexiconographicComparator implements ArraysComparator {
@Override
public int compare(byte[] a, byte[] b) {
return a.length != b.length ? Integer.compare(a.length, b.length) : Arrays.compareUnsigned(a, b);
}
@Override
public int compare(byte[] a, int aFrom, int aTo, byte[] b, int bFrom, int bTo) {
return (aTo - aFrom) != (bTo - bFrom) ? Integer.compare(aTo - aFrom, bTo - bFrom)
: Arrays.compareUnsigned(a, aFrom, aTo, b, bFrom, bTo);
}
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator;
package it.cavallium.datagen;
public class CommonField {
public final String fieldName;

View File

@ -0,0 +1,8 @@
package it.cavallium.datagen;
import org.jetbrains.annotations.NotNull;
public interface DataInitializer<T> {
@NotNull T initialize();
}

View File

@ -0,0 +1,12 @@
package it.cavallium.datagen;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import org.jetbrains.annotations.NotNull;
public interface DataSerializer<T> {
void serialize(SafeDataOutput dataOutput, @NotNull T data);
@NotNull T deserialize(SafeDataInput dataInput);
}

View File

@ -0,0 +1,8 @@
package it.cavallium.datagen;
import org.jetbrains.annotations.NotNull;
public interface DataUpgrader<T, U> {
@NotNull U upgrade(@NotNull T data);
}

View File

@ -1,4 +1,4 @@
package it.cavallium.data.generator;
package it.cavallium.datagen;
import java.util.Objects;
import java.util.Optional;
@ -9,56 +9,26 @@ import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface TypedNullable<T> extends NativeNullable<T> {
public interface NativeNullable<T> {
boolean isEmpty();
default boolean isPresent() {
return !isEmpty();
}
@NotNull
default T get() throws NullPointerException {
var value = getNullable();
if (value == null) {
throw new NullPointerException();
} else {
return value;
}
}
T orElse(@NotNull T defaultValue);
@Override
default @Nullable T getNullable(@Nullable T defaultValue) {
var value = getNullable();
return value == null ? defaultValue : value;
}
@NotNull NativeNullable<? extends T> or(@NotNull NativeNullable<? extends T> fallback);
@Override
default @NotNull T orElse(@NotNull T defaultValue) {
var value = getNullable();
if (value == null) {
Objects.requireNonNull(defaultValue, "default value must not be null");
return defaultValue;
} else {
return value;
}
}
@Nullable
T getNullable();
@Override
default @NotNull NativeNullable<? extends T> or(@NotNull NativeNullable<? extends T> fallback) {
var value = getNullable();
if (value == null) {
return fallback;
} else {
return this;
}
}
@Nullable
T getNullable(@Nullable T defaultValue);
@Override
default boolean isPresent() {
return getNullable() != null;
}
@Override
default boolean isEmpty() {
return getNullable() == null;
}
default <U, TN extends TypedNullable<U>> @NotNull TN map(
default <U, TN> @NotNull TN map(
@NotNull Function<@NotNull T, @NotNull U> value,
@NotNull Function<@Nullable U, @NotNull TN> nullableConstructor) {
var nullable = getNullable();
@ -71,6 +41,19 @@ public interface TypedNullable<T> extends NativeNullable<T> {
}
}
default <U, TN extends TypedNullable<U>> @NotNull TN mapNullable(
@NotNull Function<@NotNull T, @NotNull TN> value,
@NotNull Supplier<@NotNull TN> emptyNullableConstructor) {
var nullable = getNullable();
if (nullable != null) {
var val = value.apply(nullable);
Objects.requireNonNull(val, "Mapped value must not be null");
return val;
} else {
return emptyNullableConstructor.get();
}
}
default <U> @NotNull Optional<U> map(@NotNull Function<@NotNull T, @NotNull U> value) {
var nullable = getNullable();
if (nullable != null) {

View File

@ -0,0 +1,3 @@
package it.cavallium.datagen;
public class NotSerializableException extends UnsupportedOperationException {}

View File

@ -0,0 +1,55 @@
package it.cavallium.datagen;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface TypedNullable<T> extends NativeNullable<T> {
@NotNull
default T get() throws NullPointerException {
var value = getNullable();
if (value == null) {
throw new NullPointerException();
} else {
return value;
}
}
@Override
default @Nullable T getNullable(@Nullable T defaultValue) {
var value = getNullable();
return value == null ? defaultValue : value;
}
@Override
default @NotNull T orElse(@NotNull T defaultValue) {
var value = getNullable();
if (value == null) {
Objects.requireNonNull(defaultValue, "default value must not be null");
return defaultValue;
} else {
return value;
}
}
@Override
default @NotNull NativeNullable<? extends T> or(@NotNull NativeNullable<? extends T> fallback) {
var value = getNullable();
if (value == null) {
return fallback;
} else {
return this;
}
}
@Override
default boolean isPresent() {
return getNullable() != null;
}
@Override
default boolean isEmpty() {
return getNullable() == null;
}
}

View File

@ -0,0 +1,28 @@
package it.cavallium.datagen.nativedata;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import java.util.List;
import org.jetbrains.annotations.NotNull;
public class ArrayInt52Serializer implements DataSerializer< List<Int52>> {
@Override
public void serialize(SafeDataOutput dataOutput, List<Int52> data) {
dataOutput.writeInt(data.size());
for (Int52 item : data) {
Int52Serializer.INSTANCE.serialize(dataOutput, item);
}
}
@NotNull
@Override
public List<Int52> deserialize(SafeDataInput dataInput) {
var data = new Int52[dataInput.readInt()];
for (int i = 0; i < data.length; i++) {
data[i] = Int52Serializer.INSTANCE.deserialize(dataInput);
}
return List.of(data);
}
}

View File

@ -0,0 +1,30 @@
package it.cavallium.datagen.nativedata;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import java.nio.charset.StandardCharsets;
import java.util.List;
import org.jetbrains.annotations.NotNull;
public class ArrayStringSerializer implements DataSerializer<List<String>> {
@Override
public void serialize(SafeDataOutput dataOutput, @NotNull List<String> data) {
dataOutput.writeInt(data.size());
for (String item : data) {
dataOutput.writeShortText(item, StandardCharsets.UTF_8);
}
}
@NotNull
@Override
public List<String> deserialize(SafeDataInput dataInput) {
var data = new String[dataInput.readInt()];
for (int i = 0; i < data.length; i++) {
data[i] = dataInput.readShortText(StandardCharsets.UTF_8);
}
return List.of(data);
}
}

View File

@ -1,16 +1,15 @@
package it.cavallium.data.generator.nativedata;
package it.cavallium.datagen.nativedata;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import it.unimi.dsi.fastutil.booleans.BooleanList;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
public class ArraybooleanSerializer implements DataSerializer<BooleanList> {
@Override
public void serialize(DataOutput dataOutput, @NotNull BooleanList data) throws IOException {
public void serialize(SafeDataOutput dataOutput, @NotNull BooleanList data) {
dataOutput.writeInt(data.size());
for (int i = 0; i < data.size(); i++) {
dataOutput.writeBoolean(data.getBoolean(i));
@ -19,7 +18,7 @@ public class ArraybooleanSerializer implements DataSerializer<BooleanList> {
@NotNull
@Override
public BooleanList deserialize(DataInput dataInput) throws IOException {
public BooleanList deserialize(SafeDataInput dataInput) {
var data = new boolean[dataInput.readInt()];
for (int i = 0; i < data.length; i++) {
data[i] = dataInput.readBoolean();

View File

@ -1,16 +1,15 @@
package it.cavallium.data.generator.nativedata;
package it.cavallium.datagen.nativedata;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import it.unimi.dsi.fastutil.bytes.ByteList;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
public class ArraybyteSerializer implements DataSerializer<ByteList> {
@Override
public void serialize(DataOutput dataOutput, @NotNull ByteList data) throws IOException {
public void serialize(SafeDataOutput dataOutput, @NotNull ByteList data) {
dataOutput.writeInt(data.size());
for (int i = 0; i < data.size(); i++) {
dataOutput.writeByte(data.getByte(i));
@ -19,7 +18,7 @@ public class ArraybyteSerializer implements DataSerializer<ByteList> {
@NotNull
@Override
public ByteList deserialize(DataInput dataInput) throws IOException {
public ByteList deserialize(SafeDataInput dataInput) {
var data = new byte[dataInput.readInt()];
for (int i = 0; i < data.length; i++) {
data[i] = dataInput.readByte();

View File

@ -1,16 +1,15 @@
package it.cavallium.data.generator.nativedata;
package it.cavallium.datagen.nativedata;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import it.unimi.dsi.fastutil.chars.CharList;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
public class ArraycharSerializer implements DataSerializer<CharList> {
@Override
public void serialize(DataOutput dataOutput, @NotNull CharList data) throws IOException {
public void serialize(SafeDataOutput dataOutput, @NotNull CharList data) {
dataOutput.writeInt(data.size());
for (int i = 0; i < data.size(); i++) {
dataOutput.writeChar(data.getChar(i));
@ -19,7 +18,7 @@ public class ArraycharSerializer implements DataSerializer<CharList> {
@NotNull
@Override
public CharList deserialize(DataInput dataInput) throws IOException {
public CharList deserialize(SafeDataInput dataInput) {
var data = new char[dataInput.readInt()];
for (int i = 0; i < data.length; i++) {
data[i] = dataInput.readChar();

View File

@ -1,16 +1,15 @@
package it.cavallium.data.generator.nativedata;
package it.cavallium.datagen.nativedata;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import it.unimi.dsi.fastutil.doubles.DoubleList;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
public class ArraydoubleSerializer implements DataSerializer<DoubleList> {
@Override
public void serialize(DataOutput dataOutput, @NotNull DoubleList data) throws IOException {
public void serialize(SafeDataOutput dataOutput, @NotNull DoubleList data) {
dataOutput.writeInt(data.size());
for (int i = 0; i < data.size(); i++) {
dataOutput.writeDouble(data.getDouble(i));
@ -19,7 +18,7 @@ public class ArraydoubleSerializer implements DataSerializer<DoubleList> {
@NotNull
@Override
public DoubleList deserialize(DataInput dataInput) throws IOException {
public DoubleList deserialize(SafeDataInput dataInput) {
var data = new double[dataInput.readInt()];
for (int i = 0; i < data.length; i++) {
data[i] = dataInput.readDouble();

View File

@ -1,16 +1,15 @@
package it.cavallium.data.generator.nativedata;
package it.cavallium.datagen.nativedata;
import it.cavallium.data.generator.DataSerializer;
import it.cavallium.datagen.DataSerializer;
import it.cavallium.stream.SafeDataInput;
import it.cavallium.stream.SafeDataOutput;
import it.unimi.dsi.fastutil.floats.FloatList;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
public class ArrayfloatSerializer implements DataSerializer<FloatList> {
@Override
public void serialize(DataOutput dataOutput, @NotNull FloatList data) throws IOException {
public void serialize(SafeDataOutput dataOutput, @NotNull FloatList data) {
dataOutput.writeInt(data.size());
for (int i = 0; i < data.size(); i++) {
dataOutput.writeFloat(data.getFloat(i));
@ -19,7 +18,7 @@ public class ArrayfloatSerializer implements DataSerializer<FloatList> {
@NotNull
@Override
public FloatList deserialize(DataInput dataInput) throws IOException {
public FloatList deserialize(SafeDataInput dataInput) {
var data = new float[dataInput.readInt()];
for (int i = 0; i < data.length; i++) {
data[i] = dataInput.readFloat();

Some files were not shown because too many files have changed in this diff Show More