Skip to content

Commit 3ab625d

Browse files
authored
Update CsvDecoder.java (#351)
1 parent d03bb82 commit 3ab625d

File tree

1 file changed

+65
-17
lines changed

1 file changed

+65
-17
lines changed

csv/src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvDecoder.java

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,16 @@ public class CsvDecoder
254254

255255
protected BigDecimal _numberBigDecimal;
256256

257+
/**
258+
* Textual number representation captured from input in cases lazy-parsing
259+
* is desired.
260+
*<p>
261+
* As of 2.14, this only applies to {@link BigInteger} and {@link BigDecimal}.
262+
*
263+
* @since 2.14
264+
*/
265+
protected String _numberString;
266+
257267
/*
258268
/**********************************************************************
259269
/* Life-cycle
@@ -1019,12 +1029,12 @@ public Number getNumberValue(boolean exact) throws IOException
10191029
return Long.valueOf(_numberLong);
10201030
}
10211031
if ((_numTypesValid & NR_BIGINT) != 0) {
1022-
return _numberBigInt;
1032+
return _getBigInteger();
10231033
}
10241034
// And then floating point types. But here optimal type
10251035
// needs to be big decimal, to avoid losing any data?
10261036
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1027-
return _numberBigDecimal;
1037+
return _getBigDecimal();
10281038
}
10291039
if ((_numTypesValid & NR_DOUBLE) == 0) { // sanity check
10301040
_throwInternal();
@@ -1093,7 +1103,7 @@ public BigInteger getBigIntegerValue() throws IOException
10931103
convertNumberToBigInteger();
10941104
}
10951105
}
1096-
return _numberBigInt;
1106+
return _getBigInteger();
10971107
}
10981108

10991109
public float getFloatValue() throws IOException
@@ -1126,6 +1136,40 @@ public BigDecimal getDecimalValue() throws IOException
11261136
convertNumberToBigDecimal();
11271137
}
11281138
}
1139+
return _getBigDecimal();
1140+
}
1141+
1142+
/**
1143+
* Internal accessor that needs to be used for accessing number value of type
1144+
* {@link BigInteger} which -- as of 2.14 -- is typically lazily parsed.
1145+
*
1146+
* @since 2.14
1147+
*/
1148+
protected BigInteger _getBigInteger() {
1149+
if (_numberBigInt != null) {
1150+
return _numberBigInt;
1151+
} else if (_numberString == null) {
1152+
throw new IllegalStateException("cannot get BigInteger from current parser state");
1153+
}
1154+
_numberBigInt = NumberInput.parseBigInteger(_numberString);
1155+
_numberString = null;
1156+
return _numberBigInt;
1157+
}
1158+
1159+
/**
1160+
* Internal accessor that needs to be used for accessing number value of type
1161+
* {@link BigDecimal} which -- as of 2.14 -- is typically lazily parsed.
1162+
*
1163+
* @since 2.14
1164+
*/
1165+
protected BigDecimal _getBigDecimal() {
1166+
if (_numberBigDecimal != null) {
1167+
return _numberBigDecimal;
1168+
} else if (_numberString == null) {
1169+
throw new IllegalStateException("cannot get BigDecimal from current parser state");
1170+
}
1171+
_numberBigDecimal = NumberInput.parseBigDecimal(_numberString);
1172+
_numberString = null;
11291173
return _numberBigDecimal;
11301174
}
11311175

@@ -1226,7 +1270,8 @@ private final void _parseSlowFloatValue(boolean exactNumber)
12261270
*/
12271271
try {
12281272
if (exactNumber) {
1229-
_numberBigDecimal = _textBuffer.contentsAsDecimal();
1273+
_numberBigDecimal = null;
1274+
_numberString = _textBuffer.contentsAsString();
12301275
_numTypesValid = NR_BIGDECIMAL;
12311276
} else {
12321277
// Otherwise double has to do
@@ -1251,7 +1296,8 @@ private final void _parseSlowIntValue(char[] buf, int offset, int len,
12511296
_numTypesValid = NR_LONG;
12521297
} else {
12531298
// nope, need the heavy guns... (rare case)
1254-
_numberBigInt = NumberInput.parseBigInteger(numStr);
1299+
_numberBigInt = null;
1300+
_numberString = numStr;
12551301
_numTypesValid = NR_BIGINT;
12561302
}
12571303
} catch (NumberFormatException nex) {
@@ -1278,19 +1324,20 @@ protected void convertNumberToInt() throws IOException
12781324
_numberInt = result;
12791325
} else if ((_numTypesValid & NR_BIGINT) != 0) {
12801326
// !!! Should check for range...
1281-
_numberInt = _numberBigInt.intValue();
1327+
_numberInt = _getBigInteger().intValue();
12821328
} else if ((_numTypesValid & NR_DOUBLE) != 0) {
12831329
// Need to check boundaries
12841330
if (_numberDouble < MIN_INT_D || _numberDouble > MAX_INT_D) {
12851331
reportOverflowInt();
12861332
}
12871333
_numberInt = (int) _numberDouble;
12881334
} else if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1289-
if (BD_MIN_INT.compareTo(_numberBigDecimal) > 0
1290-
|| BD_MAX_INT.compareTo(_numberBigDecimal) < 0) {
1335+
final BigDecimal bigDecimal = _getBigDecimal();
1336+
if (BD_MIN_INT.compareTo(bigDecimal) > 0
1337+
|| BD_MAX_INT.compareTo(bigDecimal) < 0) {
12911338
reportOverflowInt();
12921339
}
1293-
_numberInt = _numberBigDecimal.intValue();
1340+
_numberInt = bigDecimal.intValue();
12941341
} else {
12951342
_throwInternal(); // should never get here
12961343
}
@@ -1304,19 +1351,20 @@ protected void convertNumberToLong() throws IOException
13041351
_numberLong = _numberInt;
13051352
} else if ((_numTypesValid & NR_BIGINT) != 0) {
13061353
// !!! Should check for range...
1307-
_numberLong = _numberBigInt.longValue();
1354+
_numberLong = _getBigInteger().longValue();
13081355
} else if ((_numTypesValid & NR_DOUBLE) != 0) {
13091356
// Need to check boundaries
13101357
if (_numberDouble < MIN_LONG_D || _numberDouble > MAX_LONG_D) {
13111358
reportOverflowLong();
13121359
}
13131360
_numberLong = (long) _numberDouble;
13141361
} else if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1315-
if (BD_MIN_LONG.compareTo(_numberBigDecimal) > 0
1316-
|| BD_MAX_LONG.compareTo(_numberBigDecimal) < 0) {
1362+
final BigDecimal bigDecimal = _getBigDecimal();
1363+
if (BD_MIN_LONG.compareTo(bigDecimal) > 0
1364+
|| BD_MAX_LONG.compareTo(bigDecimal) < 0) {
13171365
reportOverflowLong();
13181366
}
1319-
_numberLong = _numberBigDecimal.longValue();
1367+
_numberLong = bigDecimal.longValue();
13201368
} else {
13211369
_throwInternal(); // should never get here
13221370
}
@@ -1329,7 +1377,7 @@ protected void convertNumberToBigInteger()
13291377
{
13301378
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
13311379
// here it'll just get truncated, no exceptions thrown
1332-
_numberBigInt = _numberBigDecimal.toBigInteger();
1380+
_numberBigInt = _getBigDecimal().toBigInteger();
13331381
} else if ((_numTypesValid & NR_LONG) != 0) {
13341382
_numberBigInt = BigInteger.valueOf(_numberLong);
13351383
} else if ((_numTypesValid & NR_INT) != 0) {
@@ -1352,9 +1400,9 @@ protected void convertNumberToDouble()
13521400
*/
13531401

13541402
if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1355-
_numberDouble = _numberBigDecimal.doubleValue();
1403+
_numberDouble = _getBigDecimal().doubleValue();
13561404
} else if ((_numTypesValid & NR_BIGINT) != 0) {
1357-
_numberDouble = _numberBigInt.doubleValue();
1405+
_numberDouble = _getBigInteger().doubleValue();
13581406
} else if ((_numTypesValid & NR_LONG) != 0) {
13591407
_numberDouble = _numberLong;
13601408
} else if ((_numTypesValid & NR_INT) != 0) {
@@ -1374,7 +1422,7 @@ protected void convertNumberToBigDecimal() throws IOException
13741422
*/
13751423
_numberBigDecimal = NumberInput.parseBigDecimal(getText());
13761424
} else if ((_numTypesValid & NR_BIGINT) != 0) {
1377-
_numberBigDecimal = new BigDecimal(_numberBigInt);
1425+
_numberBigDecimal = new BigDecimal(_getBigInteger());
13781426
} else if ((_numTypesValid & NR_LONG) != 0) {
13791427
_numberBigDecimal = BigDecimal.valueOf(_numberLong);
13801428
} else if ((_numTypesValid & NR_INT) != 0) {

0 commit comments

Comments
 (0)