diff --git a/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java b/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java index b09b9a37e3..76b824265a 100644 --- a/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java +++ b/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java @@ -207,7 +207,7 @@ public abstract class ParserBase extends ParserMinimalBase * Textual number representation captured from input in cases lazy-parsing * is desired. *

- * As of 2.14 this only applies to {@link BigInteger}. + * As of 2.14, this only applies to {@link BigInteger} and {@link BigDecimal}. * * @since 2.14 */ @@ -625,7 +625,7 @@ public Number getNumberValue() throws IOException // And then floating point types. But here optimal type // needs to be big decimal, to avoid losing any data? if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - return _numberBigDecimal; + return _getBigDecimal(); } if ((_numTypesValid & NR_FLOAT) != 0) { return _numberFloat; @@ -660,7 +660,7 @@ public Number getNumberValueExact() throws IOException _parseNumericValue(NR_BIGDECIMAL); } if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - return _numberBigDecimal; + return _getBigDecimal(); } if ((_numTypesValid & NR_FLOAT) != 0) { return _numberFloat; @@ -791,7 +791,7 @@ public BigDecimal getDecimalValue() throws IOException convertNumberToBigDecimal(); } } - return _numberBigDecimal; + return _getBigDecimal(); } /* @@ -900,7 +900,8 @@ private void _parseSlowFloat(int expType) throws IOException */ try { if (expType == NR_BIGDECIMAL) { - _numberBigDecimal = _textBuffer.contentsAsDecimal(); + _numberBigDecimal = null; + _numberString = _textBuffer.contentsAsString(); _numTypesValid = NR_BIGDECIMAL; } else if (expType == NR_FLOAT) { _numberFloat = _textBuffer.contentsAsFloat(isEnabled(Feature.USE_FAST_DOUBLE_PARSER)); @@ -992,11 +993,12 @@ protected void convertNumberToInt() throws IOException } _numberInt = (int) _numberDouble; } else if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - if (BD_MIN_INT.compareTo(_numberBigDecimal) > 0 - || BD_MAX_INT.compareTo(_numberBigDecimal) < 0) { + final BigDecimal bigDecimal = _getBigDecimal(); + if (BD_MIN_INT.compareTo(bigDecimal) > 0 + || BD_MAX_INT.compareTo(bigDecimal) < 0) { reportOverflowInt(); } - _numberInt = _numberBigDecimal.intValue(); + _numberInt = bigDecimal.intValue(); } else { _throwInternal(); } @@ -1021,11 +1023,12 @@ protected void convertNumberToLong() throws IOException } _numberLong = (long) _numberDouble; } else if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - if (BD_MIN_LONG.compareTo(_numberBigDecimal) > 0 - || BD_MAX_LONG.compareTo(_numberBigDecimal) < 0) { + final BigDecimal bigDecimal = _getBigDecimal(); + if (BD_MIN_LONG.compareTo(bigDecimal) > 0 + || BD_MAX_LONG.compareTo(bigDecimal) < 0) { reportOverflowLong(); } - _numberLong = _numberBigDecimal.longValue(); + _numberLong = bigDecimal.longValue(); } else { _throwInternal(); } @@ -1036,7 +1039,7 @@ protected void convertNumberToBigInteger() throws IOException { if ((_numTypesValid & NR_BIGDECIMAL) != 0) { // here it'll just get truncated, no exceptions thrown - _numberBigInt = _numberBigDecimal.toBigInteger(); + _numberBigInt = _getBigDecimal().toBigInteger(); } else if ((_numTypesValid & NR_LONG) != 0) { _numberBigInt = BigInteger.valueOf(_numberLong); } else if ((_numTypesValid & NR_INT) != 0) { @@ -1058,7 +1061,7 @@ protected void convertNumberToDouble() throws IOException */ if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - _numberDouble = _numberBigDecimal.doubleValue(); + _numberDouble = _getBigDecimal().doubleValue(); } else if ((_numTypesValid & NR_BIGINT) != 0) { _numberDouble = _getBigInteger().doubleValue(); } else if ((_numTypesValid & NR_LONG) != 0) { @@ -1082,7 +1085,7 @@ protected void convertNumberToFloat() throws IOException */ if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - _numberFloat = _numberBigDecimal.floatValue(); + _numberFloat = _getBigDecimal().floatValue(); } else if ((_numTypesValid & NR_BIGINT) != 0) { _numberFloat = _getBigInteger().floatValue(); } else if ((_numTypesValid & NR_LONG) != 0) { @@ -1137,6 +1140,23 @@ protected BigInteger _getBigInteger() { _numberString = null; return _numberBigInt; } + + /** + * Internal accessor that needs to be used for accessing number value of type + * {@link BigDecimal} which -- as of 2.14 -- is typically lazily parsed. + * + * @since 2.14 + */ + protected BigDecimal _getBigDecimal() { + if (_numberBigDecimal != null) { + return _numberBigDecimal; + } else if (_numberString == null) { + throw new IllegalStateException("cannot get BigDecimal from current parser state"); + } + _numberBigDecimal = NumberInput.parseBigDecimal(_numberString); + _numberString = null; + return _numberBigDecimal; + } /* /********************************************************** @@ -1374,4 +1394,5 @@ protected void loadMoreGuaranteed() throws IOException { // Can't declare as deprecated, for now, but shouldn't be needed protected void _finishString() throws IOException { } + }