Skip to content

Commit 351de07

Browse files
authored
make BigInteger parsing lazy (#828)
1 parent 93a5474 commit 351de07

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

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

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ public abstract class ParserBase extends ParserMinimalBase
203203

204204
protected BigDecimal _numberBigDecimal;
205205

206+
protected String _numberString;
207+
206208
// And then other information about value itself
207209

208210
/**
@@ -607,7 +609,7 @@ public Number getNumberValue() throws IOException
607609
return _numberLong;
608610
}
609611
if ((_numTypesValid & NR_BIGINT) != 0) {
610-
return _numberBigInt;
612+
return getBigInteger();
611613
}
612614
_throwInternal();
613615
}
@@ -641,7 +643,7 @@ public Number getNumberValueExact() throws IOException
641643
return _numberLong;
642644
}
643645
if ((_numTypesValid & NR_BIGINT) != 0) {
644-
return _numberBigInt;
646+
return getBigInteger();
645647
}
646648
_throwInternal();
647649
}
@@ -731,7 +733,7 @@ public BigInteger getBigIntegerValue() throws IOException
731733
convertNumberToBigInteger();
732734
}
733735
}
734-
return _numberBigInt;
736+
return getBigInteger();
735737
}
736738

737739
@Override
@@ -930,8 +932,9 @@ private void _parseSlowInt(int expType) throws IOException
930932
_numberDouble = NumberInput.parseDouble(numStr, isEnabled(Feature.USE_FAST_DOUBLE_PARSER));
931933
_numTypesValid = NR_DOUBLE;
932934
} else {
933-
// nope, need the heavy guns... (rare case)
934-
_numberBigInt = NumberInput.parseBigInteger(numStr);
935+
// nope, need the heavy guns... (rare case) - since Jackson v2.14, BigInteger parsing is lazy
936+
_numberBigInt = null;
937+
_numberString = numStr;
935938
_numTypesValid = NR_BIGINT;
936939
}
937940
}
@@ -968,11 +971,12 @@ protected void convertNumberToInt() throws IOException
968971
}
969972
_numberInt = result;
970973
} else if ((_numTypesValid & NR_BIGINT) != 0) {
971-
if (BI_MIN_INT.compareTo(_numberBigInt) > 0
972-
|| BI_MAX_INT.compareTo(_numberBigInt) < 0) {
974+
final BigInteger bigInteger = getBigInteger();
975+
if (BI_MIN_INT.compareTo(bigInteger) > 0
976+
|| BI_MAX_INT.compareTo(bigInteger) < 0) {
973977
reportOverflowInt();
974978
}
975-
_numberInt = _numberBigInt.intValue();
979+
_numberInt = bigInteger.intValue();
976980
} else if ((_numTypesValid & NR_DOUBLE) != 0) {
977981
// Need to check boundaries
978982
if (_numberDouble < MIN_INT_D || _numberDouble > MAX_INT_D) {
@@ -996,11 +1000,12 @@ protected void convertNumberToLong() throws IOException
9961000
if ((_numTypesValid & NR_INT) != 0) {
9971001
_numberLong = (long) _numberInt;
9981002
} else if ((_numTypesValid & NR_BIGINT) != 0) {
999-
if (BI_MIN_LONG.compareTo(_numberBigInt) > 0
1000-
|| BI_MAX_LONG.compareTo(_numberBigInt) < 0) {
1003+
final BigInteger bigInteger = getBigInteger();
1004+
if (BI_MIN_LONG.compareTo(bigInteger) > 0
1005+
|| BI_MAX_LONG.compareTo(bigInteger) < 0) {
10011006
reportOverflowLong();
10021007
}
1003-
_numberLong = _numberBigInt.longValue();
1008+
_numberLong = bigInteger.longValue();
10041009
} else if ((_numTypesValid & NR_DOUBLE) != 0) {
10051010
// Need to check boundaries
10061011
if (_numberDouble < MIN_LONG_D || _numberDouble > MAX_LONG_D) {
@@ -1047,7 +1052,7 @@ protected void convertNumberToDouble() throws IOException
10471052
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
10481053
_numberDouble = _numberBigDecimal.doubleValue();
10491054
} else if ((_numTypesValid & NR_BIGINT) != 0) {
1050-
_numberDouble = _numberBigInt.doubleValue();
1055+
_numberDouble = getBigInteger().doubleValue();
10511056
} else if ((_numTypesValid & NR_LONG) != 0) {
10521057
_numberDouble = (double) _numberLong;
10531058
} else if ((_numTypesValid & NR_INT) != 0) {
@@ -1071,7 +1076,7 @@ protected void convertNumberToFloat() throws IOException
10711076
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
10721077
_numberFloat = _numberBigDecimal.floatValue();
10731078
} else if ((_numTypesValid & NR_BIGINT) != 0) {
1074-
_numberFloat = _numberBigInt.floatValue();
1079+
_numberFloat = getBigInteger().floatValue();
10751080
} else if ((_numTypesValid & NR_LONG) != 0) {
10761081
_numberFloat = (float) _numberLong;
10771082
} else if ((_numTypesValid & NR_INT) != 0) {
@@ -1098,7 +1103,7 @@ protected void convertNumberToBigDecimal() throws IOException
10981103
*/
10991104
_numberBigDecimal = NumberInput.parseBigDecimal(getText());
11001105
} else if ((_numTypesValid & NR_BIGINT) != 0) {
1101-
_numberBigDecimal = new BigDecimal(_numberBigInt);
1106+
_numberBigDecimal = new BigDecimal(getBigInteger());
11021107
} else if ((_numTypesValid & NR_LONG) != 0) {
11031108
_numberBigDecimal = BigDecimal.valueOf(_numberLong);
11041109
} else if ((_numTypesValid & NR_INT) != 0) {
@@ -1345,4 +1350,15 @@ protected void loadMoreGuaranteed() throws IOException {
13451350

13461351
// Can't declare as deprecated, for now, but shouldn't be needed
13471352
protected void _finishString() throws IOException { }
1353+
1354+
private BigInteger getBigInteger() {
1355+
if (_numberBigInt != null) {
1356+
return _numberBigInt;
1357+
} else if (_numberString == null) {
1358+
throw new IllegalStateException("cannot get BigInteger from current parser state");
1359+
}
1360+
_numberBigInt = NumberInput.parseBigInteger(_numberString);
1361+
_numberString = null;
1362+
return _numberBigInt;
1363+
}
13481364
}

0 commit comments

Comments
 (0)