Skip to content

Commit

Permalink
Fix #490: regression in Double/Float conversion for "untyped" deseria…
Browse files Browse the repository at this point in the history
…lization (#492)
  • Loading branch information
cowtowncoder committed May 4, 2024
1 parent 1efa12b commit 4d4d141
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ private double _getDoubleValue() throws IOException {
@Override
public float getFloatValue() throws IOException {
_verifyIsNumberToken();
// 04-May-2024, tatu: May seem odd but Ion really does not
// expose 32-bit floats even if it MAY use them internally
// for encoding. So:
return (float) _getDoubleValue();
}

Expand Down Expand Up @@ -472,6 +475,7 @@ public NumberType getNumberType() throws IOException
return NumberType.BIG_INTEGER;
}
case FLOAT:
// 04-May-2024, tatu: Ion really does not expose 32-bit floats, so:
return NumberType.DOUBLE;
default:
}
Expand All @@ -489,7 +493,9 @@ public NumberTypeFP getNumberTypeFP() throws IOException
// 06-Jan-2024, tatu: Existing code maps Ion `FLOAT` into Java
// `float`. But code in `IonReader` suggests `Double` might
// be more accurate mapping... odd.
return NumberTypeFP.FLOAT32;
// 04-May-2024, tatu: Ion really does not expose 32-bit floats;
// must expose as 64-bit here too
return NumberTypeFP.DOUBLE64;
}
if (type == IonType.DECIMAL) {
// 06-Jan-2024, tatu: Seems like `DECIMAL` is expected to map
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.fasterxml.jackson.dataformat.ion;

import java.util.*;
import org.junit.Test;

import com.fasterxml.jackson.databind.ObjectMapper;

import static org.junit.Assert.*;

// for [dataformats-binary#490]
public class DatabindNumberRoundtrip490Test
{
private final IonObjectMapper BINARY_MAPPER = IonObjectMapper.builderForBinaryWriters()
.build();
private final IonObjectMapper TEXT_MAPPER = IonObjectMapper.builderForTextualWriters()
.build();

@Test
public void testBinaryFloats() throws Exception {
_floatRoundtrip(BINARY_MAPPER);
}

@Test
public void testBinaryIntegers() throws Exception {
_integerRoundtrip490(BINARY_MAPPER);
}

@Test
public void testTextualFloats() throws Exception {
_floatRoundtrip(TEXT_MAPPER);
}

@Test
public void testTextualIntegers() throws Exception {
_integerRoundtrip490(TEXT_MAPPER);
}

private void _floatRoundtrip(ObjectMapper mapper) throws Exception
{
final double d = 42.25d;
final float f = 42.75f;

_roundtrip490(mapper, d, d);

// Ion oddity: "float"s get upgraded to "double"s, so...
_roundtrip490(mapper, f, (double) f);
}

private void _integerRoundtrip490(ObjectMapper mapper) throws Exception
{
_roundtrip490(mapper, Integer.MAX_VALUE, Integer.MAX_VALUE);
_roundtrip490(mapper, Long.MAX_VALUE, Long.MAX_VALUE);
}

private void _roundtrip490(ObjectMapper mapper,
Object input, Object result)
throws Exception
{
byte[] serialized = mapper.writeValueAsBytes(Collections.singletonMap("k", input));

Map<?,?> deserialized = mapper.readValue(serialized, Map.class);
assertEquals(result, deserialized.get("k"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ public void testGetNumberTypeAndValue() throws Exception {
IonParser floatParser = new IonFactory().createParser(ionFloat);
Assert.assertEquals(JsonToken.VALUE_NUMBER_FLOAT, floatParser.nextToken());
Assert.assertEquals(JsonParser.NumberType.DOUBLE, floatParser.getNumberType());
Assert.assertEquals(JsonParser.NumberTypeFP.FLOAT32, floatParser.getNumberTypeFP());
// [dataformats-binary#490]: float coerces to double
Assert.assertEquals(JsonParser.NumberTypeFP.DOUBLE64, floatParser.getNumberTypeFP());
Assert.assertEquals(floatValue, floatParser.getNumberValue());

BigDecimal bigDecimalValue = new BigDecimal(Double.MAX_VALUE + "1");
Expand Down
3 changes: 2 additions & 1 deletion release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ Active maintainers:
#487 (ion): Don't close IonParser on EOF to be compatible with `MappingIterator`
when source is an empty `InputStream`
(contributed by Yoann V)
#488 (ion): Upgrade `ion-java` to 1.11.7 (from 1.11.2)
#490 (ion) ION deserialization type change from Double to Float in 2.17.0
(reported by Florian H)
2.17.0 (12-Mar-2024)
Expand Down

0 comments on commit 4d4d141

Please sign in to comment.