From 182869cca1af1a99474d7687a044ef4b2aa5b6ad Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 29 May 2025 20:54:35 -0700 Subject: [PATCH 1/5] Sync with core#1434 change wrt JsonParser.getNumberType() --- .../jackson/dataformat/cbor/CBORParser.java | 36 +++++++++---------- .../CBORNumberParsingGetType1433Test.java | 10 ++---- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java b/cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java index 5bdb0ebfc..7c38395b1 100644 --- a/cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java +++ b/cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java @@ -2011,7 +2011,7 @@ public boolean isNaN() { public Number getNumberValue() throws JacksonException { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_UNKNOWN); // will also check event type + _checkNumericValue(); // will also check event type } // Separate types for int types if (_currToken == JsonToken.VALUE_NUMBER_INT) { @@ -2050,9 +2050,6 @@ public final Number getNumberValueExact() throws JacksonException { @Override public NumberType getNumberType() throws JacksonException { - if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_UNKNOWN); // will also check event type - } if (_currToken == JsonToken.VALUE_NUMBER_INT) { if ((_numTypesValid & NR_INT) != 0) { return NumberType.INT; @@ -2062,23 +2059,25 @@ public NumberType getNumberType() throws JacksonException } return NumberType.BIG_INTEGER; } - /* And then floating point types. Here optimal type * needs to be big decimal, to avoid losing any data? * However... using BD is slow, so let's allow returning * double as type if no explicit call has been made to access * data as BD? */ - if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - return NumberType.BIG_DECIMAL; - } - if ((_numTypesValid & NR_DOUBLE) != 0) { - return NumberType.DOUBLE; + if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) { + if ((_numTypesValid & NR_BIGDECIMAL) != 0) { + return NumberType.BIG_DECIMAL; + } + if ((_numTypesValid & NR_DOUBLE) != 0) { + return NumberType.DOUBLE; + } + return NumberType.FLOAT; } - return NumberType.FLOAT; + return null; } - @Override // since 2.17 + @Override public NumberTypeFP getNumberTypeFP() throws JacksonException { if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) { @@ -2106,11 +2105,9 @@ public float getFloatValue() throws JacksonException { if ((_numTypesValid & NR_FLOAT) == 0) { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_FLOAT); - } - if ((_numTypesValid & NR_FLOAT) == 0) { - convertNumberToFloat(); + _checkNumericValue(); } + convertNumberToFloat(); } // Bounds/range checks would be tricky here, so let's not bother even trying... /* @@ -2144,13 +2141,12 @@ protected int _parseIntValue() throws JacksonException { /********************************************************************** */ - protected void _checkNumericValue(int expType) throws JacksonException + protected void _checkNumericValue() throws JacksonException { // Int or float? - if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) { - return; + if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) { + _reportError("Current token ("+_currToken+") not numeric, can not use numeric value accessors"); } - _reportError("Current token ("+currentToken()+") not numeric, can not use numeric value accessors"); } @Override // due to addition of Float as type diff --git a/cbor/src/test/java/tools/jackson/dataformat/cbor/parse/CBORNumberParsingGetType1433Test.java b/cbor/src/test/java/tools/jackson/dataformat/cbor/parse/CBORNumberParsingGetType1433Test.java index 9c2e9522b..a1b01328c 100644 --- a/cbor/src/test/java/tools/jackson/dataformat/cbor/parse/CBORNumberParsingGetType1433Test.java +++ b/cbor/src/test/java/tools/jackson/dataformat/cbor/parse/CBORNumberParsingGetType1433Test.java @@ -3,13 +3,11 @@ import org.junit.jupiter.api.Test; import tools.jackson.core.*; -import tools.jackson.core.exc.StreamReadException; import tools.jackson.dataformat.cbor.CBORFactory; import tools.jackson.dataformat.cbor.CBORTestBase; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.fail; public class CBORNumberParsingGetType1433Test extends CBORTestBase @@ -59,12 +57,8 @@ void getNumberType() throws Exception private void _verifyGetNumberTypeFail(JsonParser p, String token) throws Exception { - try { - p.getNumberType(); - fail("Should not pass"); - } catch (StreamReadException e) { - verifyException(e, "Current token ("+token+") not numeric, can not use numeric"); - } + // In 2.x got exception; in 3.x null + assertNull(p.getNumberType()); } private CBORFactory jsonFactory() { From 329cef3450780d5ff9bc378ef90859bbe142f4f7 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 29 May 2025 21:03:59 -0700 Subject: [PATCH 2/5] Convert Smile backend --- .../jackson/dataformat/smile/SmileParser.java | 15 +++++++++++++++ .../dataformat/smile/SmileParserBase.java | 18 +++++++++++++++++- .../smile/async/NonBlockingParserBase.java | 12 +++++++++--- .../SmileNumberParsingGetType1433Test.java | 10 ++-------- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java index 7aea285d1..a5f5929e3 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java @@ -2264,6 +2264,21 @@ protected void _parseNumericValue() throws JacksonException throw _constructReadException("Current token (%s) not numeric, cannot use numeric value accessors", _currToken); } + @Override + protected boolean _parseNumericValueIfNumber() throws JacksonException + { + if (_tokenIncomplete) { + _tokenIncomplete = false; + int tb = _typeAsInt; + // ensure we got a numeric type with value that is lazily parsed + if ((tb >> 5) == 1) { + _finishNumberToken(tb); + return true; + } + } + return false; + } + /* @Override // since 2.6 protected int _parseIntValue() throws JacksonException diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java index 51006bef5..5daef7805 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java @@ -253,8 +253,22 @@ public final boolean mayContainRawBinary() { @Override protected abstract void _closeInput() throws JacksonException; + /** + * Method called to complete parsing of a numeric value: will throw + * {@link StreamReadException} if current token is not numeric. + * + * @throws StreamReadException if current token is not numeric + */ protected abstract void _parseNumericValue() throws JacksonException; + /** + * Similar to {@link #_parseNumericValue()}, but will not throw exception + * if the current token is not a numeric value. + * + * @return {@code true} if current token is numeric; {@code false} otherwise + */ + protected abstract boolean _parseNumericValueIfNumber() throws JacksonException; + // public abstract int releaseBuffered(OutputStream out) throws JacksonException; // public abstract Object getInputSource(); @@ -391,7 +405,9 @@ public final Number getNumberValueExact() throws JacksonException { public final NumberType getNumberType() throws JacksonException { if (_numTypesValid == NR_UNKNOWN) { - _parseNumericValue(); // will also check event type + if (!_parseNumericValueIfNumber()) { + return null; + } } return _numberType; } diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingParserBase.java b/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingParserBase.java index 941c47726..5a56367d8 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingParserBase.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingParserBase.java @@ -210,10 +210,16 @@ protected void _closeInput() { // in future @Override protected void _parseNumericValue() throws JacksonException { - if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) { - return; + if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) { + _reportError("Current token (%s) not numeric, can not use numeric value accessors", _currToken); } - _reportError("Current token (%s) not numeric, can not use numeric value accessors", _currToken); + } + + @Override + protected boolean _parseNumericValueIfNumber() throws JacksonException + { + // No incomplete values so just return + return false; } /* diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/parse/SmileNumberParsingGetType1433Test.java b/smile/src/test/java/tools/jackson/dataformat/smile/parse/SmileNumberParsingGetType1433Test.java index caa7c5ab6..07a07cc51 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/parse/SmileNumberParsingGetType1433Test.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/parse/SmileNumberParsingGetType1433Test.java @@ -3,13 +3,11 @@ import org.junit.jupiter.api.Test; import tools.jackson.core.*; -import tools.jackson.core.exc.StreamReadException; import tools.jackson.dataformat.smile.SmileFactory; import tools.jackson.dataformat.smile.BaseTestForSmile; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.fail; public class SmileNumberParsingGetType1433Test extends BaseTestForSmile @@ -59,12 +57,8 @@ void getNumberType() throws Exception private void _verifyGetNumberTypeFail(JsonParser p, String token) throws Exception { - try { - p.getNumberType(); - fail("Should not pass"); - } catch (StreamReadException e) { - verifyException(e, "Current token ("+token+") not numeric, cannot use numeric"); - } + // In 2.x got exception; in 3.x null + assertNull(p.getNumberType()); } private SmileFactory jsonFactory() { From 2ca8372602f0f05d36f12ae18325e454179d7ed9 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 29 May 2025 21:07:54 -0700 Subject: [PATCH 3/5] Convert Avro --- .../dataformat/avro/deser/AvroParserImpl.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java b/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java index e93c31580..5aafb6999 100644 --- a/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java +++ b/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java @@ -209,9 +209,6 @@ public final boolean isNaN() { @Override public final Number getNumberValue() throws JacksonException { - if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_UNKNOWN); // will also check event type - } // Separate types for int types if (_currToken == JsonToken.VALUE_NUMBER_INT) { if ((_numTypesValid & NR_INT) != 0) { @@ -229,16 +226,20 @@ public final Number getNumberValue() throws JacksonException // 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; - } - if ((_numTypesValid & NR_DOUBLE) != 0) { - return _numberDouble; - } - if ((_numTypesValid & NR_FLOAT) == 0) { // sanity check - _throwInternal(); + if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) { + if ((_numTypesValid & NR_BIGDECIMAL) != 0) { + return _numberBigDecimal; + } + if ((_numTypesValid & NR_DOUBLE) != 0) { + return _numberDouble; + } + if ((_numTypesValid & NR_FLOAT) == 0) { // sanity check + _throwInternal(); + } + return _numberFloat; } - return _numberFloat; + + return null; } @Override // @since 2.12 -- for (most?) binary formats exactness guaranteed anyway @@ -250,7 +251,7 @@ public final Number getNumberValueExact() throws JacksonException { public final NumberType getNumberType() throws JacksonException { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_UNKNOWN); // will also check event type + _checkNumericValue(); // will also check event type } if (_currToken == JsonToken.VALUE_NUMBER_INT) { if ((_numTypesValid & NR_INT) != 0) { @@ -295,7 +296,7 @@ public final float getFloatValue() throws JacksonException { if ((_numTypesValid & NR_FLOAT) == 0) { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_FLOAT); + _checkNumericValue(); } if ((_numTypesValid & NR_FLOAT) == 0) { convertNumberToFloat(); @@ -316,13 +317,12 @@ public final float getFloatValue() throws JacksonException /********************************************************************** */ - protected final void _checkNumericValue(int expType) throws JacksonException + protected final void _checkNumericValue() throws JacksonException { // Int or float? - if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) { - return; + if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) { + _reportError("Current token ("+currentToken()+") not numeric, cannot use numeric value accessors"); } - _reportError("Current token ("+currentToken()+") not numeric, can not use numeric value accessors"); } @Override From 951f88410d47314128146309ca264acd7842e9ed Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 29 May 2025 21:12:43 -0700 Subject: [PATCH 4/5] Protobuf convered --- .../dataformat/avro/deser/AvroParserImpl.java | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java b/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java index 5aafb6999..1fac6426e 100644 --- a/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java +++ b/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java @@ -209,6 +209,10 @@ public final boolean isNaN() { @Override public final Number getNumberValue() throws JacksonException { + if (_numTypesValid == NR_UNKNOWN) { + _checkNumericValue(); // will also check event type + } + // Separate types for int types if (_currToken == JsonToken.VALUE_NUMBER_INT) { if ((_numTypesValid & NR_INT) != 0) { @@ -226,20 +230,16 @@ public final Number getNumberValue() throws JacksonException // And then floating point types. But here optimal type // needs to be big decimal, to avoid losing any data? - if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) { - if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - return _numberBigDecimal; - } - if ((_numTypesValid & NR_DOUBLE) != 0) { - return _numberDouble; - } - if ((_numTypesValid & NR_FLOAT) == 0) { // sanity check - _throwInternal(); - } - return _numberFloat; + if ((_numTypesValid & NR_BIGDECIMAL) != 0) { + return _numberBigDecimal; } - - return null; + if ((_numTypesValid & NR_DOUBLE) != 0) { + return _numberDouble; + } + if ((_numTypesValid & NR_FLOAT) == 0) { // sanity check + _throwInternal(); + } + return _numberFloat; } @Override // @since 2.12 -- for (most?) binary formats exactness guaranteed anyway @@ -250,9 +250,6 @@ public final Number getNumberValueExact() throws JacksonException { @Override public final NumberType getNumberType() throws JacksonException { - if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(); // will also check event type - } if (_currToken == JsonToken.VALUE_NUMBER_INT) { if ((_numTypesValid & NR_INT) != 0) { return NumberType.INT; @@ -266,13 +263,17 @@ public final NumberType getNumberType() throws JacksonException // And then floating point types. Here optimal type should be big decimal, // to avoid losing any data? However... using BD is slow, so let's allow returning // double as type if no explicit call has been made to access data as BD? - if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - return NumberType.BIG_DECIMAL; - } - if ((_numTypesValid & NR_DOUBLE) != 0) { - return NumberType.DOUBLE; + if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) { + if ((_numTypesValid & NR_BIGDECIMAL) != 0) { + return NumberType.BIG_DECIMAL; + } + if ((_numTypesValid & NR_DOUBLE) != 0) { + return NumberType.DOUBLE; + } + return NumberType.FLOAT; } - return NumberType.FLOAT; + + return null; } @Override // since 2.17 From eaa5f62b5e44178eef547175ebdd81cba3fe3821 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 29 May 2025 21:20:20 -0700 Subject: [PATCH 5/5] Complete conversions x --- .../dataformat/avro/deser/AvroParserImpl.java | 4 +- .../jackson/dataformat/cbor/CBORParser.java | 3 +- .../dataformat/protobuf/ProtobufParser.java | 64 ++++++++----------- 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java b/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java index 1fac6426e..62441d1ed 100644 --- a/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java +++ b/avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java @@ -322,7 +322,7 @@ protected final void _checkNumericValue() throws JacksonException { // Int or float? if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) { - _reportError("Current token ("+currentToken()+") not numeric, cannot use numeric value accessors"); + throw _constructReadException("Current token (%s) not numeric, cannot use numeric value accessors", _currToken); } } @@ -334,7 +334,7 @@ protected final void convertNumberToInt() throws JacksonException // Let's verify it's lossless conversion by simple roundtrip int result = (int) _numberLong; if (((long) result) != _numberLong) { - _reportError("Numeric value ("+getString()+") out of range of int"); + _reportError("Numeric value ("+getString()+") out of range of `int`"); } _numberInt = result; } else if ((_numTypesValid & NR_BIGINT) != 0) { diff --git a/cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java b/cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java index 7c38395b1..e7c357218 100644 --- a/cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java +++ b/cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java @@ -2145,7 +2145,8 @@ protected void _checkNumericValue() throws JacksonException { // Int or float? if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) { - _reportError("Current token ("+_currToken+") not numeric, can not use numeric value accessors"); + throw _constructReadException("Current token (%s) not numeric, cannot use numeric value accessors", + _currToken); } } diff --git a/protobuf/src/main/java/tools/jackson/dataformat/protobuf/ProtobufParser.java b/protobuf/src/main/java/tools/jackson/dataformat/protobuf/ProtobufParser.java index 44fd79123..750382b33 100644 --- a/protobuf/src/main/java/tools/jackson/dataformat/protobuf/ProtobufParser.java +++ b/protobuf/src/main/java/tools/jackson/dataformat/protobuf/ProtobufParser.java @@ -1597,7 +1597,7 @@ public boolean isNaN() { public Number getNumberValue() throws JacksonException { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_UNKNOWN); // will also check event type + _checkNumericValue(); // will also check event type } // Separate types for int types if (_currToken == JsonToken.VALUE_NUMBER_INT) { @@ -1636,9 +1636,6 @@ public final Number getNumberValueExact() throws JacksonException { @Override public NumberType getNumberType() throws JacksonException { - if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_UNKNOWN); // will also check event type - } if (_currToken == JsonToken.VALUE_NUMBER_INT) { if ((_numTypesValid & NR_LONG) != 0) { return NumberType.LONG; @@ -1655,13 +1652,17 @@ public NumberType getNumberType() throws JacksonException * double as type if no explicit call has been made to access * data as BD? */ - if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - return NumberType.BIG_DECIMAL; - } - if ((_numTypesValid & NR_DOUBLE) != 0) { - return NumberType.DOUBLE; + if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) { + if ((_numTypesValid & NR_BIGDECIMAL) != 0) { + return NumberType.BIG_DECIMAL; + } + if ((_numTypesValid & NR_DOUBLE) != 0) { + return NumberType.DOUBLE; + } + return NumberType.FLOAT; } - return NumberType.FLOAT; + + return null; } @Override // since 2.17 @@ -1686,11 +1687,9 @@ public int getIntValue() throws JacksonException { if ((_numTypesValid & NR_INT) == 0) { if (_numTypesValid == NR_UNKNOWN) { // not parsed at all - _checkNumericValue(NR_INT); // will also check event type - } - if ((_numTypesValid & NR_INT) == 0) { // wasn't an int natively? - convertNumberToInt(); // let's make it so, if possible + _checkNumericValue(); // will also check event type } + convertNumberToInt(); // let's make it so, if possible } return _numberInt; } @@ -1700,11 +1699,9 @@ public long getLongValue() throws JacksonException { if ((_numTypesValid & NR_LONG) == 0) { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_LONG); - } - if ((_numTypesValid & NR_LONG) == 0) { - convertNumberToLong(); + _checkNumericValue(); } + convertNumberToLong(); } return _numberLong; } @@ -1714,11 +1711,9 @@ public BigInteger getBigIntegerValue() throws JacksonException { if ((_numTypesValid & NR_BIGINT) == 0) { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_BIGINT); - } - if ((_numTypesValid & NR_BIGINT) == 0) { - convertNumberToBigInteger(); + _checkNumericValue(); } + convertNumberToBigInteger(); } return _numberBigInt; } @@ -1728,11 +1723,9 @@ public float getFloatValue() throws JacksonException { if ((_numTypesValid & NR_FLOAT) == 0) { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_FLOAT); - } - if ((_numTypesValid & NR_FLOAT) == 0) { - convertNumberToFloat(); + _checkNumericValue(); } + convertNumberToFloat(); } // Bounds/range checks would be tricky here, so let's not bother even trying... /* @@ -1748,11 +1741,9 @@ public double getDoubleValue() throws JacksonException { if ((_numTypesValid & NR_DOUBLE) == 0) { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_DOUBLE); - } - if ((_numTypesValid & NR_DOUBLE) == 0) { - convertNumberToDouble(); + _checkNumericValue(); } + convertNumberToDouble(); } return _numberDouble; } @@ -1762,11 +1753,9 @@ public BigDecimal getDecimalValue() throws JacksonException { if ((_numTypesValid & NR_BIGDECIMAL) == 0) { if (_numTypesValid == NR_UNKNOWN) { - _checkNumericValue(NR_BIGDECIMAL); - } - if ((_numTypesValid & NR_BIGDECIMAL) == 0) { - convertNumberToBigDecimal(); + _checkNumericValue(); } + convertNumberToBigDecimal(); } return _numberBigDecimal; } @@ -1777,13 +1766,12 @@ public BigDecimal getDecimalValue() throws JacksonException /********************************************************************** */ - protected void _checkNumericValue(int expType) throws JacksonException + protected void _checkNumericValue() throws JacksonException { // Int or float? - if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) { - return; + if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) { + throw _constructReadException("Current token (%s) not numeric, cannot use numeric value accessors", _currToken); } - _reportError("Current token ("+_currToken+") not numeric, can not use numeric value accessors"); } protected void convertNumberToInt() throws JacksonException