Skip to content

Commit f3a0840

Browse files
authored
Update ParserBase to support floats directly (#757)
1 parent 5df30ee commit f3a0840

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

src/main/java/com/fasterxml/jackson/core/base/ParserBase.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ public abstract class ParserBase extends ParserMinimalBase
193193

194194
protected long _numberLong;
195195

196+
protected float _numberFloat;
197+
196198
protected double _numberDouble;
197199

198200
// And then object types
@@ -615,6 +617,9 @@ public Number getNumberValue() throws IOException
615617
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
616618
return _numberBigDecimal;
617619
}
620+
if ((_numTypesValid & NR_FLOAT) != 0) {
621+
return _numberFloat;
622+
}
618623
if ((_numTypesValid & NR_DOUBLE) == 0) { // sanity check
619624
_throwInternal();
620625
}
@@ -647,6 +652,9 @@ public Number getNumberValueExact() throws IOException
647652
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
648653
return _numberBigDecimal;
649654
}
655+
if ((_numTypesValid & NR_FLOAT) != 0) {
656+
return _numberFloat;
657+
}
650658
if ((_numTypesValid & NR_DOUBLE) == 0) { // sanity check
651659
_throwInternal();
652660
}
@@ -678,6 +686,9 @@ public NumberType getNumberType() throws IOException
678686
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
679687
return NumberType.BIG_DECIMAL;
680688
}
689+
if ((_numTypesValid & NR_FLOAT) != 0) {
690+
return NumberType.FLOAT;
691+
}
681692
return NumberType.DOUBLE;
682693
}
683694

@@ -726,7 +737,6 @@ public BigInteger getBigIntegerValue() throws IOException
726737
@Override
727738
public float getFloatValue() throws IOException
728739
{
729-
double value = getDoubleValue();
730740
/* 22-Jan-2009, tatu: Bounds/range checks would be tricky
731741
* here, so let's not bother even trying...
732742
*/
@@ -735,7 +745,15 @@ public float getFloatValue() throws IOException
735745
_reportError("Numeric value ("+getText()+") out of range of Java float");
736746
}
737747
*/
738-
return (float) value;
748+
if ((_numTypesValid & NR_FLOAT) == 0) {
749+
if (_numTypesValid == NR_UNKNOWN) {
750+
_parseNumericValue(NR_FLOAT);
751+
}
752+
if ((_numTypesValid & NR_FLOAT) == 0) {
753+
convertNumberToFloat();
754+
}
755+
}
756+
return _numberFloat;
739757
}
740758

741759
@Override
@@ -874,6 +892,9 @@ private void _parseSlowFloat(int expType) throws IOException
874892
if (expType == NR_BIGDECIMAL) {
875893
_numberBigDecimal = _textBuffer.contentsAsDecimal();
876894
_numTypesValid = NR_BIGDECIMAL;
895+
} else if (expType == NR_FLOAT) {
896+
_numberFloat = _textBuffer.contentsAsFloat();
897+
_numTypesValid = NR_FLOAT;
877898
} else {
878899
// Otherwise double has to do
879900
_numberDouble = _textBuffer.contentsAsDouble();
@@ -1031,11 +1052,37 @@ protected void convertNumberToDouble() throws IOException
10311052
_numberDouble = (double) _numberLong;
10321053
} else if ((_numTypesValid & NR_INT) != 0) {
10331054
_numberDouble = (double) _numberInt;
1055+
} else if ((_numTypesValid & NR_FLOAT) != 0) {
1056+
_numberDouble = (double) _numberFloat;
10341057
} else {
10351058
_throwInternal();
10361059
}
10371060
_numTypesValid |= NR_DOUBLE;
10381061
}
1062+
1063+
protected void convertNumberToFloat() throws IOException
1064+
{
1065+
/* 05-Aug-2008, tatus: Important note: this MUST start with
1066+
* more accurate representations, since we don't know which
1067+
* value is the original one (others get generated when
1068+
* requested)
1069+
*/
1070+
1071+
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1072+
_numberFloat = _numberBigDecimal.floatValue();
1073+
} else if ((_numTypesValid & NR_BIGINT) != 0) {
1074+
_numberFloat = _numberBigInt.floatValue();
1075+
} else if ((_numTypesValid & NR_LONG) != 0) {
1076+
_numberFloat = (float) _numberLong;
1077+
} else if ((_numTypesValid & NR_INT) != 0) {
1078+
_numberFloat = (float) _numberInt;
1079+
} else if ((_numTypesValid & NR_DOUBLE) != 0) {
1080+
_numberFloat = (float) _numberDouble;
1081+
} else {
1082+
_throwInternal();
1083+
}
1084+
_numTypesValid |= NR_FLOAT;
1085+
}
10391086

10401087
protected void convertNumberToBigDecimal() throws IOException
10411088
{

src/main/java/com/fasterxml/jackson/core/util/TextBuffer.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,19 @@ public double contentsAsDouble() throws NumberFormatException {
517517
return NumberInput.parseDouble(contentsAsString());
518518
}
519519

520+
/**
521+
* Convenience method for converting contents of the buffer
522+
* into a Float value.
523+
*
524+
* @return Buffered text value parsed as a {@link Float}, if possible
525+
*
526+
* @throws NumberFormatException if contents are not a valid Java number
527+
* @since 2.14
528+
*/
529+
public float contentsAsFloat() throws NumberFormatException {
530+
return NumberInput.parseFloat(contentsAsString());
531+
}
532+
520533
/**
521534
* Specialized convenience method that will decode a 32-bit int,
522535
* of at most 9 digits (and possible leading minus sign).

src/test/java/com/fasterxml/jackson/core/json/async/AsyncScalarArrayTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ private void _testFloats(JsonFactory f, float[] values,
199199
assertToken(JsonToken.VALUE_NUMBER_FLOAT, r.nextToken());
200200
assertEquals(values[i], r.getFloatValue());
201201
// json can't distinguish floats from doubles so
202-
assertEquals(NumberType.DOUBLE, r.getNumberType());
202+
assertEquals(NumberType.FLOAT, r.getNumberType());
203203
}
204204
assertToken(JsonToken.END_ARRAY, r.nextToken());
205205
// and end up with "no token" as well

0 commit comments

Comments
 (0)