Skip to content

Commit

Permalink
make BigInteger parsing lazy (#828)
Browse files Browse the repository at this point in the history
  • Loading branch information
pjfanning authored Oct 23, 2022
1 parent 93a5474 commit 351de07
Showing 1 changed file with 30 additions and 14 deletions.
44 changes: 30 additions & 14 deletions src/main/java/com/fasterxml/jackson/core/base/ParserBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ public abstract class ParserBase extends ParserMinimalBase

protected BigDecimal _numberBigDecimal;

protected String _numberString;

// And then other information about value itself

/**
Expand Down Expand Up @@ -607,7 +609,7 @@ public Number getNumberValue() throws IOException
return _numberLong;
}
if ((_numTypesValid & NR_BIGINT) != 0) {
return _numberBigInt;
return getBigInteger();
}
_throwInternal();
}
Expand Down Expand Up @@ -641,7 +643,7 @@ public Number getNumberValueExact() throws IOException
return _numberLong;
}
if ((_numTypesValid & NR_BIGINT) != 0) {
return _numberBigInt;
return getBigInteger();
}
_throwInternal();
}
Expand Down Expand Up @@ -731,7 +733,7 @@ public BigInteger getBigIntegerValue() throws IOException
convertNumberToBigInteger();
}
}
return _numberBigInt;
return getBigInteger();
}

@Override
Expand Down Expand Up @@ -930,8 +932,9 @@ private void _parseSlowInt(int expType) throws IOException
_numberDouble = NumberInput.parseDouble(numStr, isEnabled(Feature.USE_FAST_DOUBLE_PARSER));
_numTypesValid = NR_DOUBLE;
} else {
// nope, need the heavy guns... (rare case)
_numberBigInt = NumberInput.parseBigInteger(numStr);
// nope, need the heavy guns... (rare case) - since Jackson v2.14, BigInteger parsing is lazy
_numberBigInt = null;
_numberString = numStr;
_numTypesValid = NR_BIGINT;
}
}
Expand Down Expand Up @@ -968,11 +971,12 @@ protected void convertNumberToInt() throws IOException
}
_numberInt = result;
} else if ((_numTypesValid & NR_BIGINT) != 0) {
if (BI_MIN_INT.compareTo(_numberBigInt) > 0
|| BI_MAX_INT.compareTo(_numberBigInt) < 0) {
final BigInteger bigInteger = getBigInteger();
if (BI_MIN_INT.compareTo(bigInteger) > 0
|| BI_MAX_INT.compareTo(bigInteger) < 0) {
reportOverflowInt();
}
_numberInt = _numberBigInt.intValue();
_numberInt = bigInteger.intValue();
} else if ((_numTypesValid & NR_DOUBLE) != 0) {
// Need to check boundaries
if (_numberDouble < MIN_INT_D || _numberDouble > MAX_INT_D) {
Expand All @@ -996,11 +1000,12 @@ protected void convertNumberToLong() throws IOException
if ((_numTypesValid & NR_INT) != 0) {
_numberLong = (long) _numberInt;
} else if ((_numTypesValid & NR_BIGINT) != 0) {
if (BI_MIN_LONG.compareTo(_numberBigInt) > 0
|| BI_MAX_LONG.compareTo(_numberBigInt) < 0) {
final BigInteger bigInteger = getBigInteger();
if (BI_MIN_LONG.compareTo(bigInteger) > 0
|| BI_MAX_LONG.compareTo(bigInteger) < 0) {
reportOverflowLong();
}
_numberLong = _numberBigInt.longValue();
_numberLong = bigInteger.longValue();
} else if ((_numTypesValid & NR_DOUBLE) != 0) {
// Need to check boundaries
if (_numberDouble < MIN_LONG_D || _numberDouble > MAX_LONG_D) {
Expand Down Expand Up @@ -1047,7 +1052,7 @@ protected void convertNumberToDouble() throws IOException
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
_numberDouble = _numberBigDecimal.doubleValue();
} else if ((_numTypesValid & NR_BIGINT) != 0) {
_numberDouble = _numberBigInt.doubleValue();
_numberDouble = getBigInteger().doubleValue();
} else if ((_numTypesValid & NR_LONG) != 0) {
_numberDouble = (double) _numberLong;
} else if ((_numTypesValid & NR_INT) != 0) {
Expand All @@ -1071,7 +1076,7 @@ protected void convertNumberToFloat() throws IOException
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
_numberFloat = _numberBigDecimal.floatValue();
} else if ((_numTypesValid & NR_BIGINT) != 0) {
_numberFloat = _numberBigInt.floatValue();
_numberFloat = getBigInteger().floatValue();
} else if ((_numTypesValid & NR_LONG) != 0) {
_numberFloat = (float) _numberLong;
} else if ((_numTypesValid & NR_INT) != 0) {
Expand All @@ -1098,7 +1103,7 @@ protected void convertNumberToBigDecimal() throws IOException
*/
_numberBigDecimal = NumberInput.parseBigDecimal(getText());
} else if ((_numTypesValid & NR_BIGINT) != 0) {
_numberBigDecimal = new BigDecimal(_numberBigInt);
_numberBigDecimal = new BigDecimal(getBigInteger());
} else if ((_numTypesValid & NR_LONG) != 0) {
_numberBigDecimal = BigDecimal.valueOf(_numberLong);
} else if ((_numTypesValid & NR_INT) != 0) {
Expand Down Expand Up @@ -1345,4 +1350,15 @@ protected void loadMoreGuaranteed() throws IOException {

// Can't declare as deprecated, for now, but shouldn't be needed
protected void _finishString() throws IOException { }

private BigInteger getBigInteger() {
if (_numberBigInt != null) {
return _numberBigInt;
} else if (_numberString == null) {
throw new IllegalStateException("cannot get BigInteger from current parser state");
}
_numberBigInt = NumberInput.parseBigInteger(_numberString);
_numberString = null;
return _numberBigInt;
}
}

0 comments on commit 351de07

Please sign in to comment.