Skip to content

Commit 68c985b

Browse files
committed
fix #167, if dot found, should always parse as double
1 parent e21a29f commit 68c985b

File tree

4 files changed

+43
-14
lines changed

4 files changed

+43
-14
lines changed

src/main/java/com/jsoniter/IterImplForStreaming.java

+24-7
Original file line numberDiff line numberDiff line change
@@ -539,15 +539,22 @@ static int readIntSlowPath(final JsonIterator iter, int value) throws IOExceptio
539539

540540
public static final double readDoubleSlowPath(final JsonIterator iter) throws IOException {
541541
try {
542-
String numberAsStr = readNumber(iter);
543-
return Double.valueOf(numberAsStr);
542+
numberChars numberChars = readNumber(iter);
543+
return Double.valueOf(new String(numberChars.chars, 0, numberChars.charsLength));
544544
} catch (NumberFormatException e) {
545545
throw iter.reportError("readDoubleSlowPath", e.toString());
546546
}
547547
}
548548

549-
public static final String readNumber(final JsonIterator iter) throws IOException {
549+
static class numberChars {
550+
char[] chars;
551+
int charsLength;
552+
boolean dotFound;
553+
}
554+
555+
public static final numberChars readNumber(final JsonIterator iter) throws IOException {
550556
int j = 0;
557+
boolean dotFound = false;
551558
for (; ; ) {
552559
for (int i = iter.head; i < iter.tail; i++) {
553560
if (j == iter.reusableChars.length) {
@@ -557,11 +564,13 @@ public static final String readNumber(final JsonIterator iter) throws IOExceptio
557564
}
558565
byte c = iter.buf[i];
559566
switch (c) {
560-
case '-':
561-
case '+':
562567
case '.':
563568
case 'e':
564569
case 'E':
570+
dotFound = true;
571+
// fallthrough
572+
case '-':
573+
case '+':
565574
case '0':
566575
case '1':
567576
case '2':
@@ -576,12 +585,20 @@ public static final String readNumber(final JsonIterator iter) throws IOExceptio
576585
break;
577586
default:
578587
iter.head = i;
579-
return new String(iter.reusableChars, 0, j);
588+
numberChars numberChars = new numberChars();
589+
numberChars.chars = iter.reusableChars;
590+
numberChars.charsLength = j;
591+
numberChars.dotFound = dotFound;
592+
return numberChars;
580593
}
581594
}
582595
if (!IterImpl.loadMore(iter)) {
583596
iter.head = iter.tail;
584-
return new String(iter.reusableChars, 0, j);
597+
numberChars numberChars = new numberChars();
598+
numberChars.chars = iter.reusableChars;
599+
numberChars.charsLength = j;
600+
numberChars.dotFound = dotFound;
601+
return numberChars;
585602
}
586603
}
587604
}

src/main/java/com/jsoniter/JsonIterator.java

+14-6
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ public final boolean readArray() throws IOException {
190190
}
191191

192192
public String readNumberAsString() throws IOException {
193-
return IterImplForStreaming.readNumber(this);
193+
IterImplForStreaming.numberChars numberChars = IterImplForStreaming.readNumber(this);
194+
return new String(numberChars.chars, 0, numberChars.charsLength);
194195
}
195196

196197
public static interface ReadArrayCallback {
@@ -239,7 +240,8 @@ public final BigDecimal readBigDecimal() throws IOException {
239240
if (valueType != ValueType.NUMBER) {
240241
throw reportError("readBigDecimal", "not number");
241242
}
242-
return new BigDecimal(IterImplForStreaming.readNumber(this));
243+
IterImplForStreaming.numberChars numberChars = IterImplForStreaming.readNumber(this);
244+
return new BigDecimal(numberChars.chars, 0, numberChars.charsLength);
243245
}
244246

245247
public final BigInteger readBigInteger() throws IOException {
@@ -252,7 +254,8 @@ public final BigInteger readBigInteger() throws IOException {
252254
if (valueType != ValueType.NUMBER) {
253255
throw reportError("readBigDecimal", "not number");
254256
}
255-
return new BigInteger(IterImplForStreaming.readNumber(this));
257+
IterImplForStreaming.numberChars numberChars = IterImplForStreaming.readNumber(this);
258+
return new BigInteger(new String(numberChars.chars, 0, numberChars.charsLength));
256259
}
257260

258261
public final Any readAny() throws IOException {
@@ -288,9 +291,14 @@ public final Object read() throws IOException {
288291
case STRING:
289292
return readString();
290293
case NUMBER:
291-
double number = readDouble();
292-
if (number == Math.floor(number) && !Double.isInfinite(number)) {
293-
long longNumber = (long) number;
294+
IterImplForStreaming.numberChars numberChars = IterImplForStreaming.readNumber(this);
295+
Double number = Double.valueOf(new String(numberChars.chars, 0, numberChars.charsLength));
296+
if (numberChars.dotFound) {
297+
return number;
298+
}
299+
double doubleNumber = number;
300+
if (doubleNumber == Math.floor(doubleNumber) && !Double.isInfinite(doubleNumber)) {
301+
long longNumber = (long) doubleNumber;
294302
if (longNumber <= Integer.MAX_VALUE && longNumber >= Integer.MIN_VALUE) {
295303
return (int) longNumber;
296304
}

src/test/java/com/jsoniter/IterImplForStreamingTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ public class IterImplForStreamingTest extends TestCase {
77
public void testReadMaxDouble() throws Exception {
88
String maxDouble = "1.7976931348623157e+308";
99
JsonIterator iter = JsonIterator.parse("1.7976931348623157e+308");
10-
String number = IterImplForStreaming.readNumber(iter);
10+
IterImplForStreaming.numberChars numberChars = IterImplForStreaming.readNumber(iter);
11+
String number = new String(numberChars.chars, 0, numberChars.charsLength);
1112
assertEquals(maxDouble, number);
1213
}
1314
}

src/test/java/com/jsoniter/TestFloat.java

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.jsoniter;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import junit.framework.TestCase;
45
import org.junit.experimental.categories.Category;
56

@@ -86,5 +87,7 @@ public void testBigDecimal() {
8687
public void testChooseDouble() {
8788
Object number = JsonIterator.deserialize("1.1", Object.class);
8889
assertEquals(1.1, number);
90+
number = JsonIterator.deserialize("1.0", Object.class);
91+
assertEquals(1.0, number);
8992
}
9093
}

0 commit comments

Comments
 (0)