in core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java [5411:5611]
public final void readNumber(ValueConsumer consumer, boolean quoted) {
boolean valid = false;
this.wasNull = false;
this.boolValue = false;
this.mag0 = 0;
this.mag1 = 0;
this.mag2 = 0;
this.mag3 = 0;
this.negative = false;
this.exponent = 0;
this.scale = 0;
final int end = this.end;
final byte[] bytes = this.bytes;
char quote = '\0';
if (ch == '"' || ch == '\'') {
quote = ch;
ch = (char) bytes[offset++];
}
final int start = offset;
if (ch == '-') {
negative = true;
ch = (char) bytes[offset++];
}
boolean intOverflow = false;
valueType = JSON_TYPE_INT;
while (ch >= '0' && ch <= '9') {
valid = true;
if (!intOverflow) {
int mag3_10 = mag3 * 10 + (ch - '0');
if (mag3_10 < mag3) {
intOverflow = true;
} else {
mag3 = mag3_10;
}
}
ch = (char) bytes[offset++];
}
if (ch == '.') {
valueType = JSON_TYPE_DEC;
ch = (char) bytes[offset++];
while (ch >= '0' && ch <= '9') {
valid = true;
if (!intOverflow) {
int mag3_10 = mag3 * 10 + (ch - '0');
if (mag3_10 < mag3) {
intOverflow = true;
} else {
mag3 = mag3_10;
}
}
this.scale++;
ch = (char) bytes[offset++];
}
}
if (intOverflow) {
int numStart = negative ? start : start - 1;
bigInt(bytes, numStart, offset - 1);
}
if (ch == 'e' || ch == 'E') {
boolean negativeExp = false;
int expValue = 0;
ch = (char) bytes[offset++];
if (ch == '-') {
negativeExp = true;
ch = (char) bytes[offset++];
} else if (ch == '+') {
ch = (char) bytes[offset++];
}
while (ch >= '0' && ch <= '9') {
valid = true;
int byteVal = (ch - '0');
expValue = expValue * 10 + byteVal;
if (expValue > MAX_EXP) {
throw new JSONException("too large exp value : " + expValue);
}
ch = (char) bytes[offset++];
}
if (negativeExp) {
expValue = -expValue;
}
this.exponent = (short) expValue;
valueType = JSON_TYPE_DEC;
}
int len = offset - start;
if (offset == start) {
if (ch == 'n') {
if (bytes[offset++] == 'u'
&& bytes[offset++] == 'l'
&& bytes[offset++] == 'l'
) {
valid = true;
wasNull = true;
valueType = JSON_TYPE_NULL;
ch = (char) bytes[offset++];
}
} else if (ch == 't') {
if (bytes[offset++] == 'r'
&& bytes[offset++] == 'u'
&& bytes[offset++] == 'e'
) {
valid = true;
boolValue = true;
valueType = JSON_TYPE_BOOL;
ch = (char) bytes[offset++];
}
} else if (ch == 'f' && offset + 3 < end && IOUtils.isALSE(bytes, offset)) {
valid = true;
offset += 4;
boolValue = false;
valueType = JSON_TYPE_BOOL;
ch = (char) bytes[offset++];
} else if (ch == '{' && quote == 0) {
this.complex = readObject();
valueType = JSON_TYPE_OBJECT;
return;
} else if (ch == '[' && quote == 0) {
this.complex = readArray();
valueType = JSON_TYPE_ARRAY;
return;
}
}
if (quote != 0) {
if (ch != quote) {
this.offset -= 1;
this.ch = quote;
readString0();
valueType = JSON_TYPE_STRING;
return;
}
ch = (char) bytes[offset++];
}
while (ch <= ' ' && ((1L << ch) & SPACE) != 0) {
if (offset >= end) {
ch = EOI;
} else {
ch = (char) bytes[offset++];
}
}
if (comma = (ch == ',')) {
this.ch = (char) bytes[this.offset++];
// next inline
if (this.offset >= end) {
this.ch = EOI;
} else {
while (ch <= ' ' && ((1L << ch) & SPACE) != 0) {
if (offset >= end) {
ch = EOI;
} else {
ch = (char) bytes[offset++];
}
}
}
}
if (!quoted && (valueType == JSON_TYPE_INT || valueType == JSON_TYPE_DEC)) {
consumer.accept(bytes, start - 1, len);
return;
}
if (valueType == JSON_TYPE_INT) {
if (mag0 == 0 && mag1 == 0 && mag2 == 0 && mag3 != Integer.MIN_VALUE) {
int intValue = negative ? -mag3 : mag3;
consumer.accept(intValue);
return;
}
if (mag0 == 0 && mag1 == 0) {
long v3 = mag3 & 0XFFFFFFFFL;
long v2 = mag2 & 0XFFFFFFFFL;
if (v2 <= Integer.MAX_VALUE) {
long v23 = (v2 << 32) + (v3);
long longValue = negative ? -v23 : v23;
consumer.accept(longValue);
return;
}
}
}
Number number = getNumber();
consumer.accept(number);
if (!valid) {
throw new JSONException(info("illegal input error"));
}
}