package it.cavallium.dbengine.database.serialization;
import io.net5.buffer.api.Buffer;
import io.net5.buffer.api.BufferAllocator;
import io.net5.buffer.api.Send;
import it.cavallium.dbengine.database.LLUtils;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("unused")
public interface SerializerFixedBinaryLength extends Serializer {
int getSerializedBinaryLength();
@Override
default int getSerializedSizeHint() {
return getSerializedBinaryLength();
}
static SerializerFixedBinaryLength noop(int length) {
return new SerializerFixedBinaryLength<>() {
@Override
public @NotNull Buffer deserialize(@NotNull Buffer serialized) {
Objects.requireNonNull(serialized);
if (serialized.readableBytes() < getSerializedBinaryLength()) {
throw new IllegalArgumentException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to deserialize an element with "
+ serialized.readableBytes() + " bytes instead");
}
return serialized.readSplit(getSerializedBinaryLength());
}
@Override
public void serialize(@NotNull Buffer deserialized, Buffer output) {
try (deserialized) {
if (deserialized.readableBytes() != getSerializedBinaryLength()) {
throw new IllegalArgumentException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to serialize an element with "
+ deserialized.readableBytes() + " bytes instead");
}
output.writeBytes(deserialized);
}
}
@Override
public int getSerializedBinaryLength() {
return length;
}
};
}
static SerializerFixedBinaryLength utf8(int length) {
return new SerializerFixedBinaryLength<>() {
@Override
public @NotNull String deserialize(@NotNull Buffer serialized) throws SerializationException {
if (serialized.readableBytes() < getSerializedBinaryLength()) {
throw new SerializationException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to deserialize an element with "
+ serialized.readableBytes() + " bytes instead");
}
var readerOffset = serialized.readerOffset();
return LLUtils.deserializeString(serialized.send(), readerOffset, length, StandardCharsets.UTF_8);
}
@Override
public void serialize(@NotNull String deserialized, Buffer output) throws SerializationException {
assert output.isAccessible();
var bytes = deserialized.getBytes(StandardCharsets.UTF_8);
output.ensureWritable(bytes.length);
output.writeBytes(bytes);
if (output.readableBytes() < getSerializedBinaryLength()) {
throw new SerializationException("Fixed serializer with " + getSerializedBinaryLength()
+ " bytes has tried to serialize an element with "
+ output.readableBytes() + " bytes instead");
}
assert output.isAccessible();
}
@Override
public int getSerializedBinaryLength() {
return length;
}
};
}
static SerializerFixedBinaryLength intSerializer(BufferAllocator allocator) {
return new SerializerFixedBinaryLength<>() {
@Override
public @NotNull Integer deserialize(@NotNull Buffer serialized) {
Objects.requireNonNull(serialized);
if (serialized.readableBytes() < getSerializedBinaryLength()) {
throw new IllegalArgumentException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to deserialize an element with "
+ serialized.readableBytes() + " bytes instead");
}
return serialized.readInt();
}
@Override
public void serialize(@NotNull Integer deserialized, Buffer output) {
output.writeInt(deserialized);
}
@Override
public int getSerializedBinaryLength() {
return Integer.BYTES;
}
};
}
static SerializerFixedBinaryLength longSerializer(BufferAllocator allocator) {
return new SerializerFixedBinaryLength<>() {
@Override
public @NotNull Long deserialize(@NotNull Buffer serialized) {
Objects.requireNonNull(serialized);
if (serialized.readableBytes() < getSerializedBinaryLength()) {
throw new IllegalArgumentException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to deserialize an element with "
+ serialized.readableBytes() + " bytes instead");
}
return serialized.readLong();
}
@Override
public void serialize(@NotNull Long deserialized, Buffer output) {
output.writeLong(deserialized);
}
@Override
public int getSerializedBinaryLength() {
return Long.BYTES;
}
};
}
}