diff --git a/java/fury-core/src/main/java/io/fury/resolver/ClassResolver.java b/java/fury-core/src/main/java/io/fury/resolver/ClassResolver.java index ded0536a48..e46ba87fe3 100644 --- a/java/fury-core/src/main/java/io/fury/resolver/ClassResolver.java +++ b/java/fury-core/src/main/java/io/fury/resolver/ClassResolver.java @@ -38,6 +38,8 @@ import io.fury.util.Platform; import io.fury.util.ReflectionUtils; import io.fury.util.StringUtils; +import java.math.BigDecimal; +import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -225,6 +227,8 @@ private void addDefaultSerializers() { addDefaultSerializer(Class.class, new Serializers.ClassSerializer(fury)); addDefaultSerializer(StringBuilder.class, new Serializers.StringBuilderSerializer(fury)); addDefaultSerializer(StringBuffer.class, new Serializers.StringBufferSerializer(fury)); + addDefaultSerializer(BigInteger.class, new Serializers.BigIntegerSerializer(fury)); + addDefaultSerializer(BigDecimal.class, new Serializers.BigDecimalSerializer(fury)); } private void addDefaultSerializer(Class type, Class serializerClass) { diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 286a051661..84b9108a7c 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -27,6 +27,8 @@ import io.fury.util.Utils; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.IdentityHashMap; /** @@ -439,6 +441,51 @@ public Enum read(MemoryBuffer buffer) { } } + public static final class BigDecimalSerializer extends Serializer { + public BigDecimalSerializer(Fury fury) { + super(fury, BigDecimal.class); + } + + @Override + public void write(MemoryBuffer buffer, BigDecimal value) { + final byte[] bytes = value.unscaledValue().toByteArray(); + Preconditions.checkArgument(bytes.length <= 16); + buffer.writeByte((byte) value.scale()); + buffer.writeByte((byte) bytes.length); + buffer.writeBytes(bytes); + } + + @Override + public BigDecimal read(MemoryBuffer buffer) { + int scale = buffer.readByte(); + int len = buffer.readByte(); + byte[] bytes = buffer.readBytes(len); + final BigInteger bigInteger = new BigInteger(bytes); + return new BigDecimal(bigInteger, scale); + } + } + + public static final class BigIntegerSerializer extends Serializer { + public BigIntegerSerializer(Fury fury) { + super(fury, BigInteger.class); + } + + @Override + public void write(MemoryBuffer buffer, BigInteger value) { + final byte[] bytes = value.toByteArray(); + Preconditions.checkArgument(bytes.length <= 16); + buffer.writeByte((byte) bytes.length); + buffer.writeBytes(bytes); + } + + @Override + public BigInteger read(MemoryBuffer buffer) { + int len = buffer.readByte(); + byte[] bytes = buffer.readBytes(len); + return new BigInteger(bytes); + } + } + public static final class StringArraySerializer extends Serializer { private final StringSerializer stringSerializer; diff --git a/java/fury-core/src/test/java/io/fury/serializer/SerializersTest.java b/java/fury-core/src/test/java/io/fury/serializer/SerializersTest.java index 1c09e61df4..a3f48fb144 100644 --- a/java/fury-core/src/test/java/io/fury/serializer/SerializersTest.java +++ b/java/fury-core/src/test/java/io/fury/serializer/SerializersTest.java @@ -24,6 +24,8 @@ import io.fury.FuryTestBase; import io.fury.Language; import io.fury.memory.MemoryBuffer; +import java.math.BigDecimal; +import java.math.BigInteger; import org.testng.annotations.Test; public class SerializersTest extends FuryTestBase { @@ -57,18 +59,13 @@ public void testUint16Serializer() { @Test(dataProvider = "crossLanguageReferenceTrackingConfig") public void testStringBuilder(boolean referenceTracking, Language language) { - Fury fury1 = + Fury.FuryBuilder builder = Fury.builder() .withLanguage(language) .withReferenceTracking(referenceTracking) - .disableSecureMode() - .build(); - Fury fury2 = - Fury.builder() - .withLanguage(language) - .withReferenceTracking(referenceTracking) - .disableSecureMode() - .build(); + .disableSecureMode(); + Fury fury1 = builder.build(); + Fury fury2 = builder.build(); assertEquals("str", serDe(fury1, fury2, "str")); assertEquals("str", serDe(fury1, fury2, new StringBuilder("str")).toString()); assertEquals("str", serDe(fury1, fury2, new StringBuffer("str")).toString()); @@ -94,18 +91,13 @@ void f() {} @Test(dataProvider = "crossLanguageReferenceTrackingConfig") public void testEnumSerialization(boolean referenceTracking, Language language) { - Fury fury1 = - Fury.builder() - .withLanguage(language) - .withReferenceTracking(referenceTracking) - .disableSecureMode() - .build(); - Fury fury2 = + Fury.FuryBuilder builder = Fury.builder() .withLanguage(language) .withReferenceTracking(referenceTracking) - .disableSecureMode() - .build(); + .disableSecureMode(); + Fury fury1 = builder.build(); + Fury fury2 = builder.build(); assertEquals(SerializersTest.EnumFoo.A, serDe(fury1, fury2, SerializersTest.EnumFoo.A)); assertEquals(SerializersTest.EnumFoo.B, serDe(fury1, fury2, SerializersTest.EnumFoo.B)); assertEquals( @@ -113,4 +105,17 @@ public void testEnumSerialization(boolean referenceTracking, Language language) assertEquals( SerializersTest.EnumSubClass.B, serDe(fury1, fury2, SerializersTest.EnumSubClass.B)); } + + @Test(dataProvider = "crossLanguageReferenceTrackingConfig") + public void testBigInt(boolean referenceTracking, Language language) { + Fury.FuryBuilder builder = + Fury.builder() + .withLanguage(language) + .withReferenceTracking(referenceTracking) + .disableSecureMode(); + Fury fury1 = builder.build(); + Fury fury2 = builder.build(); + assertEquals(BigInteger.valueOf(100), serDe(fury1, fury2, BigInteger.valueOf(100))); + assertEquals(BigDecimal.valueOf(100, 2), serDe(fury1, fury2, BigDecimal.valueOf(100, 2))); + } }