@@ -271,8 +271,9 @@ public class ProtobufParser extends ParserMinimalBase
271
271
272
272
// And then floating point types
273
273
274
- final protected static int NR_DOUBLE = 0x008 ;
275
- final protected static int NR_BIGDECIMAL = 0x0010 ;
274
+ final protected static int NR_FLOAT = 0x008 ;
275
+ final protected static int NR_DOUBLE = 0x010 ;
276
+ final protected static int NR_BIGDECIMAL = 0x0020 ;
276
277
277
278
// Also, we need some numeric constants
278
279
@@ -298,7 +299,7 @@ public class ProtobufParser extends ParserMinimalBase
298
299
299
300
final static double MIN_INT_D = (double ) Integer .MIN_VALUE ;
300
301
final static double MAX_INT_D = (double ) Integer .MAX_VALUE ;
301
-
302
+
302
303
/**
303
304
* Bitfield that indicates which numeric representations
304
305
* have been calculated for the current type
@@ -308,6 +309,8 @@ public class ProtobufParser extends ParserMinimalBase
308
309
// First primitives
309
310
310
311
protected int _numberInt ;
312
+ protected float _numberFloat ;
313
+
311
314
protected long _numberLong ;
312
315
protected double _numberDouble ;
313
316
@@ -802,8 +805,8 @@ private JsonToken _readNextValue(FieldType t, int nextState) throws IOException
802
805
type = JsonToken .VALUE_NUMBER_FLOAT ;
803
806
break ;
804
807
case FLOAT :
805
- _numberDouble = ( double ) Float .intBitsToFloat (_decode32Bits ());
806
- _numTypesValid = NR_DOUBLE ;
808
+ _numberFloat = Float .intBitsToFloat (_decode32Bits ());
809
+ _numTypesValid = NR_FLOAT ;
807
810
type = JsonToken .VALUE_NUMBER_FLOAT ;
808
811
break ;
809
812
case VINT32_Z :
@@ -1478,7 +1481,23 @@ public int readBinaryValue(Base64Variant b64variant, OutputStream out) throws IO
1478
1481
/* Numeric accessors of public API
1479
1482
/**********************************************************
1480
1483
*/
1481
-
1484
+
1485
+ @ Override // since 2.9
1486
+ public boolean isNaN () {
1487
+ if (_currToken == JsonToken .VALUE_NUMBER_FLOAT ) {
1488
+ if ((_numTypesValid & NR_DOUBLE ) != 0 ) {
1489
+ // 10-Mar-2017, tatu: Alas, `Double.isFinite(d)` only added in JDK 8
1490
+ double d = _numberDouble ;
1491
+ return Double .isNaN (d ) || Double .isInfinite (d );
1492
+ }
1493
+ if ((_numTypesValid & NR_FLOAT ) != 0 ) {
1494
+ float f = _numberFloat ;
1495
+ return Float .isNaN (f ) || Float .isInfinite (f );
1496
+ }
1497
+ }
1498
+ return false ;
1499
+ }
1500
+
1482
1501
@ Override
1483
1502
public Number getNumberValue () throws IOException
1484
1503
{
@@ -1499,17 +1518,19 @@ public Number getNumberValue() throws IOException
1499
1518
// Shouldn't get this far but if we do
1500
1519
return _numberBigDecimal ;
1501
1520
}
1502
-
1503
- /* And then floating point types. But here optimal type
1504
- * needs to be big decimal, to avoid losing any data?
1505
- */
1521
+
1522
+ // And then floating point types. But here optimal type
1523
+ // needs to be big decimal, to avoid losing any data?
1506
1524
if ((_numTypesValid & NR_BIGDECIMAL ) != 0 ) {
1507
1525
return _numberBigDecimal ;
1508
1526
}
1509
- if ((_numTypesValid & NR_DOUBLE ) == 0 ) { // sanity check
1527
+ if ((_numTypesValid & NR_DOUBLE ) != 0 ) {
1528
+ return _numberDouble ;
1529
+ }
1530
+ if ((_numTypesValid & NR_FLOAT ) == 0 ) { // sanity check
1510
1531
_throwInternal ();
1511
1532
}
1512
- return _numberDouble ;
1533
+ return _numberFloat ;
1513
1534
}
1514
1535
1515
1536
@ Override
@@ -1537,9 +1558,12 @@ public NumberType getNumberType() throws IOException
1537
1558
if ((_numTypesValid & NR_BIGDECIMAL ) != 0 ) {
1538
1559
return NumberType .BIG_DECIMAL ;
1539
1560
}
1540
- return NumberType .DOUBLE ;
1561
+ if ((_numTypesValid & NR_DOUBLE ) != 0 ) {
1562
+ return NumberType .DOUBLE ;
1563
+ }
1564
+ return NumberType .FLOAT ;
1541
1565
}
1542
-
1566
+
1543
1567
@ Override
1544
1568
public int getIntValue () throws IOException
1545
1569
{
@@ -1585,16 +1609,21 @@ public BigInteger getBigIntegerValue() throws IOException
1585
1609
@ Override
1586
1610
public float getFloatValue () throws IOException
1587
1611
{
1588
- double value = getDoubleValue ();
1589
- /* 22-Jan-2009, tatu: Bounds/range checks would be tricky
1590
- * here, so let's not bother even trying...
1591
- */
1612
+ if ((_numTypesValid & NR_FLOAT ) == 0 ) {
1613
+ if (_numTypesValid == NR_UNKNOWN ) {
1614
+ _checkNumericValue (NR_FLOAT );
1615
+ }
1616
+ if ((_numTypesValid & NR_FLOAT ) == 0 ) {
1617
+ convertNumberToFloat ();
1618
+ }
1619
+ }
1620
+ // Bounds/range checks would be tricky here, so let's not bother even trying...
1592
1621
/*
1593
1622
if (value < -Float.MAX_VALUE || value > MAX_FLOAT_D) {
1594
1623
_reportError("Numeric value ("+getText()+") out of range of Java float");
1595
1624
}
1596
1625
*/
1597
- return ( float ) value ;
1626
+ return _numberFloat ;
1598
1627
}
1599
1628
1600
1629
@ Override
@@ -1640,18 +1669,6 @@ protected void _checkNumericValue(int expType) throws IOException
1640
1669
_reportError ("Current token (" +_currToken +") not numeric, can not use numeric value accessors" );
1641
1670
}
1642
1671
1643
- @ Override // since 2.9
1644
- public boolean isNaN () {
1645
- if (_currToken == JsonToken .VALUE_NUMBER_FLOAT ) {
1646
- if ((_numTypesValid & NR_DOUBLE ) != 0 ) {
1647
- // 10-Mar-2017, tatu: Alas, `Double.isFinite(d)` only added in JDK 8
1648
- double d = _numberDouble ;
1649
- return Double .isNaN (d ) || Double .isInfinite (d );
1650
- }
1651
- }
1652
- return false ;
1653
- }
1654
-
1655
1672
protected void convertNumberToInt () throws IOException
1656
1673
{
1657
1674
// First, converting from long ought to be easy
@@ -1674,6 +1691,11 @@ protected void convertNumberToInt() throws IOException
1674
1691
reportOverflowInt ();
1675
1692
}
1676
1693
_numberInt = (int ) _numberDouble ;
1694
+ } else if ((_numTypesValid & NR_FLOAT ) != 0 ) {
1695
+ if (_numberFloat < MIN_INT_D || _numberFloat > MAX_INT_D ) {
1696
+ reportOverflowInt ();
1697
+ }
1698
+ _numberInt = (int ) _numberFloat ;
1677
1699
} else if ((_numTypesValid & NR_BIGDECIMAL ) != 0 ) {
1678
1700
if (BD_MIN_INT .compareTo (_numberBigDecimal ) > 0
1679
1701
|| BD_MAX_INT .compareTo (_numberBigDecimal ) < 0 ) {
@@ -1697,11 +1719,15 @@ protected void convertNumberToLong() throws IOException
1697
1719
}
1698
1720
_numberLong = _numberBigInt .longValue ();
1699
1721
} else if ((_numTypesValid & NR_DOUBLE ) != 0 ) {
1700
- // Need to check boundaries
1701
1722
if (_numberDouble < MIN_LONG_D || _numberDouble > MAX_LONG_D ) {
1702
1723
reportOverflowLong ();
1703
1724
}
1704
1725
_numberLong = (long ) _numberDouble ;
1726
+ } else if ((_numTypesValid & NR_FLOAT ) != 0 ) {
1727
+ if (_numberFloat < MIN_LONG_D || _numberFloat > MAX_LONG_D ) {
1728
+ reportOverflowInt ();
1729
+ }
1730
+ _numberLong = (long ) _numberFloat ;
1705
1731
} else if ((_numTypesValid & NR_BIGDECIMAL ) != 0 ) {
1706
1732
if (BD_MIN_LONG .compareTo (_numberBigDecimal ) > 0
1707
1733
|| BD_MAX_LONG .compareTo (_numberBigDecimal ) < 0 ) {
@@ -1725,18 +1751,42 @@ protected void convertNumberToBigInteger() throws IOException
1725
1751
_numberBigInt = BigInteger .valueOf (_numberInt );
1726
1752
} else if ((_numTypesValid & NR_DOUBLE ) != 0 ) {
1727
1753
_numberBigInt = BigDecimal .valueOf (_numberDouble ).toBigInteger ();
1754
+ } else if ((_numTypesValid & NR_FLOAT ) != 0 ) {
1755
+ _numberBigInt = BigDecimal .valueOf (_numberFloat ).toBigInteger ();
1728
1756
} else {
1729
1757
_throwInternal ();
1730
1758
}
1731
1759
_numTypesValid |= NR_BIGINT ;
1732
1760
}
1733
-
1761
+
1762
+ protected void convertNumberToFloat () throws IOException
1763
+ {
1764
+ // Note: this MUST start with more accurate representations, since we don't know which
1765
+ // value is the original one (others get generated when requested)
1766
+ if ((_numTypesValid & NR_BIGDECIMAL ) != 0 ) {
1767
+ _numberFloat = _numberBigDecimal .floatValue ();
1768
+ } else if ((_numTypesValid & NR_BIGINT ) != 0 ) {
1769
+ _numberFloat = _numberBigInt .floatValue ();
1770
+ } else if ((_numTypesValid & NR_DOUBLE ) != 0 ) {
1771
+ _numberFloat = (float ) _numberDouble ;
1772
+ } else if ((_numTypesValid & NR_LONG ) != 0 ) {
1773
+ _numberFloat = (float ) _numberLong ;
1774
+ } else if ((_numTypesValid & NR_INT ) != 0 ) {
1775
+ _numberFloat = (float ) _numberInt ;
1776
+ } else {
1777
+ _throwInternal ();
1778
+ }
1779
+ _numTypesValid |= NR_FLOAT ;
1780
+ }
1781
+
1734
1782
protected void convertNumberToDouble () throws IOException
1735
1783
{
1736
1784
// Note: this MUST start with more accurate representations, since we don't know which
1737
1785
// value is the original one (others get generated when requested)
1738
1786
if ((_numTypesValid & NR_BIGDECIMAL ) != 0 ) {
1739
1787
_numberDouble = _numberBigDecimal .doubleValue ();
1788
+ } else if ((_numTypesValid & NR_FLOAT ) != 0 ) {
1789
+ _numberDouble = (double ) _numberFloat ;
1740
1790
} else if ((_numTypesValid & NR_BIGINT ) != 0 ) {
1741
1791
_numberDouble = _numberBigInt .doubleValue ();
1742
1792
} else if ((_numTypesValid & NR_LONG ) != 0 ) {
@@ -1753,7 +1803,7 @@ protected void convertNumberToBigDecimal() throws IOException
1753
1803
{
1754
1804
// Note: this MUST start with more accurate representations, since we don't know which
1755
1805
// value is the original one (others get generated when requested)
1756
- if ((_numTypesValid & NR_DOUBLE ) != 0 ) {
1806
+ if ((_numTypesValid & ( NR_DOUBLE | NR_FLOAT ) ) != 0 ) {
1757
1807
// Let's parse from String representation, to avoid rounding errors that
1758
1808
//non-decimal floating operations would incur
1759
1809
_numberBigDecimal = NumberInput .parseBigDecimal (getText ());
@@ -2453,16 +2503,6 @@ protected final static long _long(int i1, int i2)
2453
2503
/**********************************************************
2454
2504
*/
2455
2505
2456
- protected void reportOverflowInt () throws IOException {
2457
- _reportErrorF ("Numeric value (%s) out of range of int (%d - %d)" ,
2458
- getText (), Integer .MIN_VALUE , Integer .MAX_VALUE );
2459
- }
2460
-
2461
- protected void reportOverflowLong () throws IOException {
2462
- _reportErrorF ("Numeric value (%s) out of range of long (%d - %d)" ,
2463
- getText (), Long .MIN_VALUE , Long .MAX_VALUE );
2464
- }
2465
-
2466
2506
private void _reportErrorF (String format , Object ... args ) throws JsonParseException {
2467
2507
_reportError (String .format (format , args ));
2468
2508
}
0 commit comments