Skip to content

Commit e655e46

Browse files
authored
Add StreamReadCapability.EXACT_FLOATS to signal potential precision loss for JSON non-doubles. (#733)
1 parent 6f810ea commit e655e46

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/main/java/com/fasterxml/jackson/core/StreamReadCapability.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,23 @@ public enum StreamReadCapability
4848
* This capability is true for many textual formats like CSV, Properties and XML.
4949
*/
5050
UNTYPED_SCALARS(false),
51+
52+
/**
53+
* Capability that indicates that data format may report floats
54+
* as a non-exact {@link com.fasterxml.jackson.core.JsonParser.NumberType},
55+
* due to prohibitively expensive parsing costs of determing the precision
56+
* upfront. For example, JSON numbers may be reported as
57+
* {@link com.fasterxml.jackson.core.JsonParser.NumberType#DOUBLE}
58+
* even if they would not fit into a 64-bit double without precision
59+
* loss. Methods like {@link JsonParser#getNumberValueExact()} or
60+
* {@link JsonParser#getValueAsString()} still report values without
61+
* precision loss.
62+
*
63+
* Capability is false for text formats JSON, but true for binary formats
64+
* like Smile, MessagePack, etc., where type is precisely and inexpensively
65+
* signaled by a tag.
66+
*/
67+
EXACT_FLOATS(false)
5168
;
5269

5370
/**
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.fasterxml.jackson.failing;
2+
3+
import com.fasterxml.jackson.core.BaseTest;
4+
import com.fasterxml.jackson.core.JsonFactory;
5+
import com.fasterxml.jackson.core.JsonGenerator;
6+
import com.fasterxml.jackson.core.JsonParser;
7+
8+
import java.io.ByteArrayOutputStream;
9+
import java.io.StringWriter;
10+
11+
public class ParserPrecisionLoss733Test extends BaseTest {
12+
final JsonFactory JSON_F = newStreamFactory();
13+
14+
/**
15+
* Attempt to pass a BigDecimal value through without losing precision,
16+
* e.g. for pretty printing a file.
17+
*/
18+
public void testCopyCurrentEventBigDecimal() throws Exception {
19+
String input = "1e999";
20+
JsonParser parser = JSON_F.createParser(input);
21+
parser.nextToken();
22+
StringWriter stringWriter = new StringWriter();
23+
JsonGenerator generator = JSON_F.createGenerator(stringWriter);
24+
generator.copyCurrentEvent(parser);
25+
parser.close();
26+
generator.close();
27+
String actual = stringWriter.toString();
28+
assertEquals(input, actual);
29+
}
30+
31+
/**
32+
* Same as {@link #testCopyCurrentEventBigDecimal()} using copyCurrentStructure instead.
33+
*/
34+
public void testCopyCurrentStructureBigDecimal() throws Exception {
35+
String input = "[1e999]";
36+
JsonParser parser = JSON_F.createParser(input);
37+
parser.nextToken();
38+
StringWriter stringWriter = new StringWriter();
39+
JsonGenerator generator = JSON_F.createGenerator(stringWriter);
40+
generator.copyCurrentStructure(parser);
41+
parser.close();
42+
generator.close();
43+
String actual = stringWriter.toString();
44+
assertEquals(input, actual);
45+
}
46+
47+
}

0 commit comments

Comments
 (0)