Skip to content

Commit b754275

Browse files
authored
Sync with core#1434 change wrt JsonParser.getNumberType() (#596)
1 parent cea91f3 commit b754275

File tree

8 files changed

+105
-94
lines changed

8 files changed

+105
-94
lines changed

avro/src/main/java/tools/jackson/dataformat/avro/deser/AvroParserImpl.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,9 @@ public final boolean isNaN() {
210210
public final Number getNumberValue() throws JacksonException
211211
{
212212
if (_numTypesValid == NR_UNKNOWN) {
213-
_checkNumericValue(NR_UNKNOWN); // will also check event type
213+
_checkNumericValue(); // will also check event type
214214
}
215+
215216
// Separate types for int types
216217
if (_currToken == JsonToken.VALUE_NUMBER_INT) {
217218
if ((_numTypesValid & NR_INT) != 0) {
@@ -249,9 +250,6 @@ public final Number getNumberValueExact() throws JacksonException {
249250
@Override
250251
public final NumberType getNumberType() throws JacksonException
251252
{
252-
if (_numTypesValid == NR_UNKNOWN) {
253-
_checkNumericValue(NR_UNKNOWN); // will also check event type
254-
}
255253
if (_currToken == JsonToken.VALUE_NUMBER_INT) {
256254
if ((_numTypesValid & NR_INT) != 0) {
257255
return NumberType.INT;
@@ -265,13 +263,17 @@ public final NumberType getNumberType() throws JacksonException
265263
// And then floating point types. Here optimal type should be big decimal,
266264
// to avoid losing any data? However... using BD is slow, so let's allow returning
267265
// double as type if no explicit call has been made to access data as BD?
268-
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
269-
return NumberType.BIG_DECIMAL;
270-
}
271-
if ((_numTypesValid & NR_DOUBLE) != 0) {
272-
return NumberType.DOUBLE;
266+
if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) {
267+
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
268+
return NumberType.BIG_DECIMAL;
269+
}
270+
if ((_numTypesValid & NR_DOUBLE) != 0) {
271+
return NumberType.DOUBLE;
272+
}
273+
return NumberType.FLOAT;
273274
}
274-
return NumberType.FLOAT;
275+
276+
return null;
275277
}
276278

277279
@Override // since 2.17
@@ -295,7 +297,7 @@ public final float getFloatValue() throws JacksonException
295297
{
296298
if ((_numTypesValid & NR_FLOAT) == 0) {
297299
if (_numTypesValid == NR_UNKNOWN) {
298-
_checkNumericValue(NR_FLOAT);
300+
_checkNumericValue();
299301
}
300302
if ((_numTypesValid & NR_FLOAT) == 0) {
301303
convertNumberToFloat();
@@ -316,13 +318,12 @@ public final float getFloatValue() throws JacksonException
316318
/**********************************************************************
317319
*/
318320

319-
protected final void _checkNumericValue(int expType) throws JacksonException
321+
protected final void _checkNumericValue() throws JacksonException
320322
{
321323
// Int or float?
322-
if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) {
323-
return;
324+
if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) {
325+
throw _constructReadException("Current token (%s) not numeric, cannot use numeric value accessors", _currToken);
324326
}
325-
_reportError("Current token ("+currentToken()+") not numeric, can not use numeric value accessors");
326327
}
327328

328329
@Override
@@ -333,7 +334,7 @@ protected final void convertNumberToInt() throws JacksonException
333334
// Let's verify it's lossless conversion by simple roundtrip
334335
int result = (int) _numberLong;
335336
if (((long) result) != _numberLong) {
336-
_reportError("Numeric value ("+getString()+") out of range of int");
337+
_reportError("Numeric value ("+getString()+") out of range of `int`");
337338
}
338339
_numberInt = result;
339340
} else if ((_numTypesValid & NR_BIGINT) != 0) {

cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,7 +2011,7 @@ public boolean isNaN() {
20112011
public Number getNumberValue() throws JacksonException
20122012
{
20132013
if (_numTypesValid == NR_UNKNOWN) {
2014-
_checkNumericValue(NR_UNKNOWN); // will also check event type
2014+
_checkNumericValue(); // will also check event type
20152015
}
20162016
// Separate types for int types
20172017
if (_currToken == JsonToken.VALUE_NUMBER_INT) {
@@ -2050,9 +2050,6 @@ public final Number getNumberValueExact() throws JacksonException {
20502050
@Override
20512051
public NumberType getNumberType() throws JacksonException
20522052
{
2053-
if (_numTypesValid == NR_UNKNOWN) {
2054-
_checkNumericValue(NR_UNKNOWN); // will also check event type
2055-
}
20562053
if (_currToken == JsonToken.VALUE_NUMBER_INT) {
20572054
if ((_numTypesValid & NR_INT) != 0) {
20582055
return NumberType.INT;
@@ -2062,23 +2059,25 @@ public NumberType getNumberType() throws JacksonException
20622059
}
20632060
return NumberType.BIG_INTEGER;
20642061
}
2065-
20662062
/* And then floating point types. Here optimal type
20672063
* needs to be big decimal, to avoid losing any data?
20682064
* However... using BD is slow, so let's allow returning
20692065
* double as type if no explicit call has been made to access
20702066
* data as BD?
20712067
*/
2072-
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
2073-
return NumberType.BIG_DECIMAL;
2074-
}
2075-
if ((_numTypesValid & NR_DOUBLE) != 0) {
2076-
return NumberType.DOUBLE;
2068+
if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) {
2069+
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
2070+
return NumberType.BIG_DECIMAL;
2071+
}
2072+
if ((_numTypesValid & NR_DOUBLE) != 0) {
2073+
return NumberType.DOUBLE;
2074+
}
2075+
return NumberType.FLOAT;
20772076
}
2078-
return NumberType.FLOAT;
2077+
return null;
20792078
}
20802079

2081-
@Override // since 2.17
2080+
@Override
20822081
public NumberTypeFP getNumberTypeFP() throws JacksonException
20832082
{
20842083
if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) {
@@ -2106,11 +2105,9 @@ public float getFloatValue() throws JacksonException
21062105
{
21072106
if ((_numTypesValid & NR_FLOAT) == 0) {
21082107
if (_numTypesValid == NR_UNKNOWN) {
2109-
_checkNumericValue(NR_FLOAT);
2110-
}
2111-
if ((_numTypesValid & NR_FLOAT) == 0) {
2112-
convertNumberToFloat();
2108+
_checkNumericValue();
21132109
}
2110+
convertNumberToFloat();
21142111
}
21152112
// Bounds/range checks would be tricky here, so let's not bother even trying...
21162113
/*
@@ -2144,13 +2141,13 @@ protected int _parseIntValue() throws JacksonException {
21442141
/**********************************************************************
21452142
*/
21462143

2147-
protected void _checkNumericValue(int expType) throws JacksonException
2144+
protected void _checkNumericValue() throws JacksonException
21482145
{
21492146
// Int or float?
2150-
if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) {
2151-
return;
2147+
if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) {
2148+
throw _constructReadException("Current token (%s) not numeric, cannot use numeric value accessors",
2149+
_currToken);
21522150
}
2153-
_reportError("Current token ("+currentToken()+") not numeric, can not use numeric value accessors");
21542151
}
21552152

21562153
@Override // due to addition of Float as type

cbor/src/test/java/tools/jackson/dataformat/cbor/parse/CBORNumberParsingGetType1433Test.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
import org.junit.jupiter.api.Test;
44

55
import tools.jackson.core.*;
6-
import tools.jackson.core.exc.StreamReadException;
76
import tools.jackson.dataformat.cbor.CBORFactory;
87
import tools.jackson.dataformat.cbor.CBORTestBase;
98

109
import static org.junit.jupiter.api.Assertions.assertEquals;
1110
import static org.junit.jupiter.api.Assertions.assertNull;
12-
import static org.junit.jupiter.api.Assertions.fail;
1311

1412
public class CBORNumberParsingGetType1433Test
1513
extends CBORTestBase
@@ -59,12 +57,8 @@ void getNumberType() throws Exception
5957

6058
private void _verifyGetNumberTypeFail(JsonParser p, String token) throws Exception
6159
{
62-
try {
63-
p.getNumberType();
64-
fail("Should not pass");
65-
} catch (StreamReadException e) {
66-
verifyException(e, "Current token ("+token+") not numeric, can not use numeric");
67-
}
60+
// In 2.x got exception; in 3.x null
61+
assertNull(p.getNumberType());
6862
}
6963

7064
private CBORFactory jsonFactory() {

protobuf/src/main/java/tools/jackson/dataformat/protobuf/ProtobufParser.java

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,7 @@ public boolean isNaN() {
15971597
public Number getNumberValue() throws JacksonException
15981598
{
15991599
if (_numTypesValid == NR_UNKNOWN) {
1600-
_checkNumericValue(NR_UNKNOWN); // will also check event type
1600+
_checkNumericValue(); // will also check event type
16011601
}
16021602
// Separate types for int types
16031603
if (_currToken == JsonToken.VALUE_NUMBER_INT) {
@@ -1636,9 +1636,6 @@ public final Number getNumberValueExact() throws JacksonException {
16361636
@Override
16371637
public NumberType getNumberType() throws JacksonException
16381638
{
1639-
if (_numTypesValid == NR_UNKNOWN) {
1640-
_checkNumericValue(NR_UNKNOWN); // will also check event type
1641-
}
16421639
if (_currToken == JsonToken.VALUE_NUMBER_INT) {
16431640
if ((_numTypesValid & NR_LONG) != 0) {
16441641
return NumberType.LONG;
@@ -1655,13 +1652,17 @@ public NumberType getNumberType() throws JacksonException
16551652
* double as type if no explicit call has been made to access
16561653
* data as BD?
16571654
*/
1658-
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1659-
return NumberType.BIG_DECIMAL;
1660-
}
1661-
if ((_numTypesValid & NR_DOUBLE) != 0) {
1662-
return NumberType.DOUBLE;
1655+
if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) {
1656+
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1657+
return NumberType.BIG_DECIMAL;
1658+
}
1659+
if ((_numTypesValid & NR_DOUBLE) != 0) {
1660+
return NumberType.DOUBLE;
1661+
}
1662+
return NumberType.FLOAT;
16631663
}
1664-
return NumberType.FLOAT;
1664+
1665+
return null;
16651666
}
16661667

16671668
@Override // since 2.17
@@ -1686,11 +1687,9 @@ public int getIntValue() throws JacksonException
16861687
{
16871688
if ((_numTypesValid & NR_INT) == 0) {
16881689
if (_numTypesValid == NR_UNKNOWN) { // not parsed at all
1689-
_checkNumericValue(NR_INT); // will also check event type
1690-
}
1691-
if ((_numTypesValid & NR_INT) == 0) { // wasn't an int natively?
1692-
convertNumberToInt(); // let's make it so, if possible
1690+
_checkNumericValue(); // will also check event type
16931691
}
1692+
convertNumberToInt(); // let's make it so, if possible
16941693
}
16951694
return _numberInt;
16961695
}
@@ -1700,11 +1699,9 @@ public long getLongValue() throws JacksonException
17001699
{
17011700
if ((_numTypesValid & NR_LONG) == 0) {
17021701
if (_numTypesValid == NR_UNKNOWN) {
1703-
_checkNumericValue(NR_LONG);
1704-
}
1705-
if ((_numTypesValid & NR_LONG) == 0) {
1706-
convertNumberToLong();
1702+
_checkNumericValue();
17071703
}
1704+
convertNumberToLong();
17081705
}
17091706
return _numberLong;
17101707
}
@@ -1714,11 +1711,9 @@ public BigInteger getBigIntegerValue() throws JacksonException
17141711
{
17151712
if ((_numTypesValid & NR_BIGINT) == 0) {
17161713
if (_numTypesValid == NR_UNKNOWN) {
1717-
_checkNumericValue(NR_BIGINT);
1718-
}
1719-
if ((_numTypesValid & NR_BIGINT) == 0) {
1720-
convertNumberToBigInteger();
1714+
_checkNumericValue();
17211715
}
1716+
convertNumberToBigInteger();
17221717
}
17231718
return _numberBigInt;
17241719
}
@@ -1728,11 +1723,9 @@ public float getFloatValue() throws JacksonException
17281723
{
17291724
if ((_numTypesValid & NR_FLOAT) == 0) {
17301725
if (_numTypesValid == NR_UNKNOWN) {
1731-
_checkNumericValue(NR_FLOAT);
1732-
}
1733-
if ((_numTypesValid & NR_FLOAT) == 0) {
1734-
convertNumberToFloat();
1726+
_checkNumericValue();
17351727
}
1728+
convertNumberToFloat();
17361729
}
17371730
// Bounds/range checks would be tricky here, so let's not bother even trying...
17381731
/*
@@ -1748,11 +1741,9 @@ public double getDoubleValue() throws JacksonException
17481741
{
17491742
if ((_numTypesValid & NR_DOUBLE) == 0) {
17501743
if (_numTypesValid == NR_UNKNOWN) {
1751-
_checkNumericValue(NR_DOUBLE);
1752-
}
1753-
if ((_numTypesValid & NR_DOUBLE) == 0) {
1754-
convertNumberToDouble();
1744+
_checkNumericValue();
17551745
}
1746+
convertNumberToDouble();
17561747
}
17571748
return _numberDouble;
17581749
}
@@ -1762,11 +1753,9 @@ public BigDecimal getDecimalValue() throws JacksonException
17621753
{
17631754
if ((_numTypesValid & NR_BIGDECIMAL) == 0) {
17641755
if (_numTypesValid == NR_UNKNOWN) {
1765-
_checkNumericValue(NR_BIGDECIMAL);
1766-
}
1767-
if ((_numTypesValid & NR_BIGDECIMAL) == 0) {
1768-
convertNumberToBigDecimal();
1756+
_checkNumericValue();
17691757
}
1758+
convertNumberToBigDecimal();
17701759
}
17711760
return _numberBigDecimal;
17721761
}
@@ -1777,13 +1766,12 @@ public BigDecimal getDecimalValue() throws JacksonException
17771766
/**********************************************************************
17781767
*/
17791768

1780-
protected void _checkNumericValue(int expType) throws JacksonException
1769+
protected void _checkNumericValue() throws JacksonException
17811770
{
17821771
// Int or float?
1783-
if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) {
1784-
return;
1772+
if (_currToken != JsonToken.VALUE_NUMBER_INT && _currToken != JsonToken.VALUE_NUMBER_FLOAT) {
1773+
throw _constructReadException("Current token (%s) not numeric, cannot use numeric value accessors", _currToken);
17851774
}
1786-
_reportError("Current token ("+_currToken+") not numeric, can not use numeric value accessors");
17871775
}
17881776

17891777
protected void convertNumberToInt() throws JacksonException

smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,6 +2264,21 @@ protected void _parseNumericValue() throws JacksonException
22642264
throw _constructReadException("Current token (%s) not numeric, cannot use numeric value accessors", _currToken);
22652265
}
22662266

2267+
@Override
2268+
protected boolean _parseNumericValueIfNumber() throws JacksonException
2269+
{
2270+
if (_tokenIncomplete) {
2271+
_tokenIncomplete = false;
2272+
int tb = _typeAsInt;
2273+
// ensure we got a numeric type with value that is lazily parsed
2274+
if ((tb >> 5) == 1) {
2275+
_finishNumberToken(tb);
2276+
return true;
2277+
}
2278+
}
2279+
return false;
2280+
}
2281+
22672282
/*
22682283
@Override // since 2.6
22692284
protected int _parseIntValue() throws JacksonException

smile/src/main/java/tools/jackson/dataformat/smile/SmileParserBase.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,22 @@ public final boolean mayContainRawBinary() {
253253
@Override
254254
protected abstract void _closeInput() throws JacksonException;
255255

256+
/**
257+
* Method called to complete parsing of a numeric value: will throw
258+
* {@link StreamReadException} if current token is not numeric.
259+
*
260+
* @throws StreamReadException if current token is not numeric
261+
*/
256262
protected abstract void _parseNumericValue() throws JacksonException;
257263

264+
/**
265+
* Similar to {@link #_parseNumericValue()}, but will not throw exception
266+
* if the current token is not a numeric value.
267+
*
268+
* @return {@code true} if current token is numeric; {@code false} otherwise
269+
*/
270+
protected abstract boolean _parseNumericValueIfNumber() throws JacksonException;
271+
258272
// public abstract int releaseBuffered(OutputStream out) throws JacksonException;
259273
// public abstract Object getInputSource();
260274

@@ -391,7 +405,9 @@ public final Number getNumberValueExact() throws JacksonException {
391405
public final NumberType getNumberType() throws JacksonException
392406
{
393407
if (_numTypesValid == NR_UNKNOWN) {
394-
_parseNumericValue(); // will also check event type
408+
if (!_parseNumericValueIfNumber()) {
409+
return null;
410+
}
395411
}
396412
return _numberType;
397413
}

0 commit comments

Comments
 (0)