JSONScanner.java
package com.alibaba.fastjson.parser;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.util.DateUtils;
import java.io.Closeable;
import java.math.BigDecimal;
import java.util.Calendar;
public class JSONScanner
extends JSONLexerBase
implements Closeable {
private final JSONReader reader;
private boolean orderedField;
protected int token;
private String strVal;
protected Calendar calendar;
protected String str;
public JSONScanner(JSONReader reader) {
this.reader = reader;
}
public JSONScanner(String str) {
this.reader = JSONReader.of(str);
this.str = str;
}
public JSONScanner(String str, int features) {
this.reader = JSONReader.of(str, JSON.createReadContext(features));
}
public Calendar getCalendar() {
return calendar;
}
public boolean scanISO8601DateIfMatch() {
return scanISO8601DateIfMatch(true);
}
public boolean scanISO8601DateIfMatch(boolean strict) {
if (str != null) {
try {
long millis = DateUtils.parseMillis(str);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(millis);
this.calendar = calendar;
return true;
} catch (Exception ignored) {
return false;
}
}
throw new JSONException("UnsupportedOperation");
}
@Override
public JSONReader getReader() {
return reader;
}
public boolean isOrderedField() {
return orderedField;
}
@Override
public String stringVal() {
return strVal;
}
public BigDecimal decimalValue() {
return reader.getBigDecimal();
}
public int token() {
return token;
}
public void config(Feature feature, boolean state) {
JSONReader.Feature rawFeature = null;
boolean not = false;
switch (feature) {
case AllowUnQuotedFieldNames:
rawFeature = JSONReader.Feature.AllowUnQuotedFieldNames;
break;
case SupportArrayToBean:
rawFeature = JSONReader.Feature.SupportArrayToBean;
break;
case DisableFieldSmartMatch:
rawFeature = JSONReader.Feature.SupportSmartMatch;
not = true;
break;
case SupportAutoType:
rawFeature = JSONReader.Feature.SupportAutoType;
break;
case NonStringKeyAsString:
rawFeature = JSONReader.Feature.NonStringKeyAsString;
break;
case ErrorOnEnumNotMatch:
rawFeature = JSONReader.Feature.ErrorOnEnumNotMatch;
break;
case SupportClassForName:
rawFeature = JSONReader.Feature.SupportClassForName;
break;
case ErrorOnNotSupportAutoType:
rawFeature = JSONReader.Feature.ErrorOnNotSupportAutoType;
break;
case UseNativeJavaObject:
rawFeature = JSONReader.Feature.UseNativeObject;
break;
case UseBigDecimal:
rawFeature = JSONReader.Feature.UseDoubleForDecimals;
not = true;
break;
case OrderedField:
orderedField = state;
break;
default:
break;
}
if (rawFeature == null) {
return;
}
if (not) {
state = !state;
}
JSONReader.Context context = reader.getContext();
context.config(rawFeature, state);
}
public boolean isEnabled(Feature feature) {
JSONReader.Feature rawFeature = null;
switch (feature) {
case AllowUnQuotedFieldNames:
rawFeature = JSONReader.Feature.AllowUnQuotedFieldNames;
break;
case SupportArrayToBean:
rawFeature = JSONReader.Feature.SupportArrayToBean;
break;
case DisableFieldSmartMatch:
return !reader.isEnabled(JSONReader.Feature.SupportSmartMatch);
case SupportAutoType:
rawFeature = JSONReader.Feature.SupportAutoType;
break;
case NonStringKeyAsString:
rawFeature = JSONReader.Feature.NonStringKeyAsString;
break;
case ErrorOnEnumNotMatch:
rawFeature = JSONReader.Feature.ErrorOnEnumNotMatch;
break;
case SupportClassForName:
rawFeature = JSONReader.Feature.SupportClassForName;
break;
case ErrorOnNotSupportAutoType:
rawFeature = JSONReader.Feature.ErrorOnNotSupportAutoType;
break;
case UseNativeJavaObject:
rawFeature = JSONReader.Feature.UseNativeObject;
break;
case UseBigDecimal:
return !reader.isEnabled(JSONReader.Feature.UseDoubleForDecimals);
default:
break;
}
if (rawFeature == null) {
return true;
}
return reader.isEnabled(rawFeature);
}
@Override
public boolean isBlankInput() {
return reader.isEnd();
}
@Override
public int intValue() {
return reader.getInt32Value();
}
@Override
public long longValue() {
return reader.getInt64Value();
}
public final void nextToken() {
strVal = null;
char ch = reader.current();
switch (ch) {
case '[':
reader.next();
token = JSONToken.LBRACKET;
return;
case ']':
reader.next();
token = JSONToken.RBRACKET;
return;
case '{':
reader.next();
token = JSONToken.LBRACE;
return;
case '}':
reader.next();
token = JSONToken.RBRACE;
return;
case ':':
reader.next();
token = JSONToken.COLON;
return;
case '"':
case '\'':
strVal = reader.readString();
token = JSONToken.LITERAL_STRING;
return;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
case '+':
Number number = reader.readNumber();
if (number instanceof BigDecimal || number instanceof Float || number instanceof Double) {
token = JSONToken.LITERAL_FLOAT;
} else {
token = JSONToken.LITERAL_INT;
}
return;
case 't':
case 'f':
boolean boolValue = reader.readBoolValue();
token = boolValue ? JSONToken.TRUE : JSONToken.FALSE;
return;
case 'n':
reader.readNull();
token = JSONToken.NULL;
return;
case EOI:
token = JSONToken.EOF;
return;
default:
break;
}
if (reader.nextIfNull()) {
return;
}
throw new JSONException("not support operation");
}
@Override
public char getCurrent() {
return reader.current();
}
@Override
public final void nextToken(int expect) {
nextToken();
}
@Override
public boolean isEOF() {
return reader.isEnd();
}
@Override
public void close() {
}
}