diff --git a/build.gradle.kts b/build.gradle.kts index 98bd83ff6..614495f46 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -90,7 +90,7 @@ val githubRepositoryUrl = "https://github.com/amazon-ion/ion-java/" val isReleaseVersion: Boolean = !version.toString().endsWith("SNAPSHOT") // The name we're checking for corresponds to the name that is set in the `publish-release-artifacts.yml` file. val isReleaseWorkflow: Boolean = System.getenv("GITHUB_WORKFLOW") == "Publish Release Artifacts" -val generatedResourcesDir = "$buildDir/generated/main/resources" +val generatedResourcesDir = "${layout.buildDirectory}/generated/main/resources" sourceSets { main { @@ -103,7 +103,7 @@ licenseReport { // though ion-java does not depend on ion-java-cli. By default, the license report generator includes // the current project (ion-java) and all its subprojects. projects = arrayOf(project) - outputDir = "$buildDir/reports/licenses" + outputDir = "${layout.buildDirectory}/reports/licenses" renderers = arrayOf(InventoryMarkdownReportRenderer(), TextReportRenderer()) // Dependencies use inconsistent titles for Apache-2.0, so we need to specify mappings filters = arrayOf( diff --git a/src/main/java/com/amazon/ion/impl/IonReaderContinuableCoreBinary.java b/src/main/java/com/amazon/ion/impl/IonReaderContinuableCoreBinary.java index df501feb7..93331bfd3 100644 --- a/src/main/java/com/amazon/ion/impl/IonReaderContinuableCoreBinary.java +++ b/src/main/java/com/amazon/ion/impl/IonReaderContinuableCoreBinary.java @@ -1,6 +1,5 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 - package com.amazon.ion.impl; import com.amazon.ion.Decimal; @@ -594,6 +593,12 @@ public BigDecimal bigDecimalValue() { scalarConverter.cast(scalarConverter.get_conversion_fnid(_Private_ScalarConversions.AS_TYPE.decimal_value)); value = scalarConverter.getBigDecimal(); scalarConverter.clear(); + } else if (valueTid.type == IonType.FLOAT) { + scalarConverter.addValue(doubleValue()); + scalarConverter.setAuthoritativeType(_Private_ScalarConversions.AS_TYPE.double_value); + scalarConverter.cast(scalarConverter.get_conversion_fnid(_Private_ScalarConversions.AS_TYPE.decimal_value)); + value = scalarConverter.getDecimal(); + scalarConverter.clear(); } else { throwDueToInvalidType(IonType.DECIMAL); } @@ -622,6 +627,12 @@ public Decimal decimalValue() { scalarConverter.cast(scalarConverter.get_conversion_fnid(_Private_ScalarConversions.AS_TYPE.decimal_value)); value = scalarConverter.getDecimal(); scalarConverter.clear(); + } else if (valueTid.type == IonType.FLOAT) { + scalarConverter.addValue(doubleValue()); + scalarConverter.setAuthoritativeType(_Private_ScalarConversions.AS_TYPE.double_value); + scalarConverter.cast(scalarConverter.get_conversion_fnid(_Private_ScalarConversions.AS_TYPE.decimal_value)); + value = scalarConverter.getDecimal(); + scalarConverter.clear(); } else { throwDueToInvalidType(IonType.DECIMAL); } diff --git a/src/test/java/com/amazon/ion/IonReaderValueCoercionTest.java b/src/test/java/com/amazon/ion/IonReaderValueCoercionTest.java new file mode 100644 index 000000000..f7701a770 --- /dev/null +++ b/src/test/java/com/amazon/ion/IonReaderValueCoercionTest.java @@ -0,0 +1,78 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +package com.amazon.ion; + +import com.amazon.ion.system.IonReaderBuilder; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +class IonReaderValueCoercionTest { + + static Stream testData() { + byte[] textData = "$ion_1_0 42 42e0 42.0".getBytes(StandardCharsets.UTF_8); + byte[] binaryData = { + // Version marker 1.0 + (byte) 0xE0, 0x01, 0x00, (byte) 0xEA, + // 1-byte int + 0x21, + // `42` + 0x2A, + // 4-byte float + 0x44, + // `42e0` + 0x42, 0x28, 0x00, 0x00, + // 3-byte decimal + 0x53, + // `42d0` + (byte) 0xc1, 0x01, (byte) 0xa4, + }; + return Stream.of( + new ByteArrayInputStream(textData), + new ByteArrayInputStream(binaryData) + ); + } + + @ParameterizedTest + @MethodSource("testData") + void coerceNumberToDouble(InputStream inputStream) { + IonReader reader = IonReaderBuilder.standard().build(inputStream); + assertEquals(IonType.INT, reader.next()); + assertEquals(reader.doubleValue(), 42.0); + assertEquals(IonType.FLOAT, reader.next()); + assertEquals(reader.doubleValue(), 42.0); + assertEquals(IonType.DECIMAL, reader.next()); + assertEquals(reader.doubleValue(), 42.0); + } + + @ParameterizedTest + @MethodSource("testData") + void coerceNumberToBigDecimal(InputStream inputStream) { + IonReader reader = IonReaderBuilder.standard().build(inputStream); + assertEquals(IonType.INT, reader.next()); + assertEquals(reader.bigDecimalValue(), BigDecimal.valueOf(42)); + assertEquals(IonType.FLOAT, reader.next()); + assertEquals(reader.bigDecimalValue(), BigDecimal.valueOf(42.0)); + assertEquals(IonType.DECIMAL, reader.next()); + assertEquals(reader.bigDecimalValue(), BigDecimal.valueOf(42.0)); + } + + @ParameterizedTest + @MethodSource("testData") + void coerceNumberToDecimal(InputStream inputStream) { + IonReader reader = IonReaderBuilder.standard().build(inputStream); + assertEquals(IonType.INT, reader.next()); + assertEquals(reader.decimalValue(), Decimal.valueOf(42)); + assertEquals(IonType.FLOAT, reader.next()); + assertEquals(reader.decimalValue(), Decimal.valueOf(42.0)); + assertEquals(IonType.DECIMAL, reader.next()); + assertEquals(reader.decimalValue(), Decimal.valueOf(42.0)); + } +} \ No newline at end of file