in core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java [546:1023]
public Object readAny() {
int end = this.end;
byte[] bytes = this.bytes;
if (offset >= bytes.length) {
throw new JSONException("readAny overflow : " + offset + "/" + bytes.length);
}
type = bytes[offset++];
switch (type) {
case BC_NULL:
return null;
case BC_TRUE:
return true;
case BC_FALSE:
return false;
case BC_INT8:
return bytes[offset++];
case BC_INT16:
return (short) ((bytes[offset++] << 8)
+ (bytes[offset++] & 0xFF));
case BC_INT32: {
int int32Value = getIntBE(bytes, check3(offset, end));
offset += 4;
return int32Value;
}
case BC_INT64_INT: {
int int32Value = getIntBE(bytes, check3(offset, end));
offset += 4;
return (long) int32Value;
}
case BC_INT64: {
long int64Value = getLongBE(bytes, check7(offset, end));
offset += 8;
return int64Value;
}
case BC_BIGINT: {
int len = readInt32Value();
byte[] buf = new byte[len];
System.arraycopy(bytes, offset, buf, 0, len);
offset += len;
return new BigInteger(buf);
}
case BC_FLOAT: {
int int32Value = getIntBE(bytes, check3(offset, end));
offset += 4;
return Float.intBitsToFloat(int32Value);
}
case BC_FLOAT_INT: {
return (float) readInt32Value();
}
case BC_DOUBLE: {
long int64Value = getLongBE(bytes, check7(offset, end));
offset += 8;
return Double.longBitsToDouble(int64Value);
}
case BC_DOUBLE_LONG: {
return (double) readInt64Value();
}
case BC_STR_UTF8: {
int strlen = readLength();
if (STRING_CREATOR_JDK11 != null && !JDKUtils.BIG_ENDIAN) {
if (valueBytes == null) {
valueBytes = BYTES_UPDATER.getAndSet(cacheItem, null);
if (valueBytes == null) {
valueBytes = new byte[8192];
}
}
int minCapacity = strlen << 1;
if (minCapacity > valueBytes.length) {
valueBytes = new byte[minCapacity];
}
int utf16_len = IOUtils.decodeUTF8(bytes, offset, strlen, valueBytes);
if (utf16_len != -1) {
byte[] value = new byte[utf16_len];
System.arraycopy(valueBytes, 0, value, 0, utf16_len);
String str = STRING_CREATOR_JDK11.apply(value, UTF16);
offset += strlen;
return str;
}
}
String str = new String(bytes, offset, strlen, StandardCharsets.UTF_8);
offset += strlen;
return str;
}
case BC_STR_UTF16: {
int strlen = readLength();
String str = new String(bytes, offset, strlen, StandardCharsets.UTF_16);
offset += strlen;
return str;
}
case BC_STR_UTF16LE: {
int strlen = readLength();
String str;
if (STRING_CREATOR_JDK11 != null && !JDKUtils.BIG_ENDIAN) {
byte[] chars = new byte[strlen];
System.arraycopy(bytes, offset, chars, 0, strlen);
str = STRING_CREATOR_JDK11.apply(chars, strlen == 0 ? LATIN1 : UTF16);
} else {
str = new String(bytes, offset, strlen, StandardCharsets.UTF_16LE);
}
offset += strlen;
return str;
}
case BC_STR_UTF16BE: {
int strlen = readLength();
String str;
if (STRING_CREATOR_JDK11 != null && JDKUtils.BIG_ENDIAN) {
byte[] chars = new byte[strlen];
System.arraycopy(bytes, offset, chars, 0, strlen);
str = STRING_CREATOR_JDK11.apply(chars, strlen == 0 ? LATIN1 : UTF16);
} else {
str = new String(bytes, offset, strlen, StandardCharsets.UTF_16BE);
}
offset += strlen;
return str;
}
case BC_STR_GB18030: {
if (GB18030 == null) {
GB18030 = Charset.forName("GB18030");
}
int strlen = readLength();
String str = new String(bytes, offset, strlen, GB18030);
offset += strlen;
return str;
}
case BC_DECIMAL: {
int scale = readInt32Value();
BigInteger unscaledValue = readBigInteger();
BigDecimal decimal;
if (scale == 0) {
decimal = new BigDecimal(unscaledValue);
} else {
decimal = new BigDecimal(unscaledValue, scale);
}
return decimal;
}
case BC_DECIMAL_LONG: {
return BigDecimal.valueOf(
readInt64Value()
);
}
case BC_BINARY: {
int len = readLength();
byte[] binary = Arrays.copyOfRange(this.bytes, offset, offset + len);
offset += len;
return binary;
}
case BC_TIMESTAMP_MINUTES: {
long minutes = getIntBE(bytes, check3(offset, end));
offset += 4;
return new Date(minutes * 60L * 1000L);
}
case BC_TIMESTAMP_SECONDS: {
long seconds = getIntBE(bytes, check3(offset, end));
offset += 4;
return new Date(seconds * 1000);
}
case BC_LOCAL_DATE: {
int year = (bytes[offset++] << 8) + (bytes[offset++] & 0xFF);
byte month = bytes[offset++];
byte dayOfMonth = bytes[offset++];
return LocalDate.of(year, month, dayOfMonth);
}
case BC_LOCAL_TIME: {
byte hour = bytes[offset++];
byte minute = bytes[offset++];
byte second = bytes[offset++];
int nano = readInt32Value();
return LocalTime.of(hour, minute, second, nano);
}
case BC_LOCAL_DATETIME: {
int year = (bytes[offset++] << 8) + (bytes[offset++] & 0xFF);
byte month = bytes[offset++];
byte dayOfMonth = bytes[offset++];
byte hour = bytes[offset++];
byte minute = bytes[offset++];
byte second = bytes[offset++];
int nano = readInt32Value();
return LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nano);
}
case BC_TIMESTAMP_WITH_TIMEZONE: {
return readTimestampWithTimeZone();
}
case BC_TIMESTAMP: {
long epochSeconds = readInt64Value();
int nano = readInt32Value();
return Instant.ofEpochSecond(epochSeconds, nano);
}
case BC_TIMESTAMP_MILLIS: {
long millis = IOUtils.getLongBE(bytes, check7(offset, end));
offset += 8;
return new Date(millis);
}
case BC_BIGINT_LONG: {
return BigInteger.valueOf(
readInt64Value()
);
}
case BC_TYPED_ANY: {
long typeHash = readTypeHashCode();
if (context.autoTypeBeforeHandler != null) {
Class<?> filterClass = context.autoTypeBeforeHandler.apply(typeHash, null, context.features);
if (filterClass == null) {
String typeName = getString();
filterClass = context.autoTypeBeforeHandler.apply(typeName, null, context.features);
}
if (filterClass != null) {
ObjectReader autoTypeObjectReader = context.getObjectReader(filterClass);
return autoTypeObjectReader.readJSONBObject(this, null, null, 0);
}
}
boolean supportAutoType = (context.features & Feature.SupportAutoType.mask) != 0;
if (!supportAutoType) {
if (isObject()) {
return readObject();
}
if (isArray()) {
return readArray();
}
throw new JSONException("autoType not support , offset " + offset + "/" + bytes.length);
}
ObjectReader autoTypeObjectReader = context.getObjectReaderAutoType(typeHash);
if (autoTypeObjectReader == null) {
String typeName = getString();
autoTypeObjectReader = context.getObjectReaderAutoType(typeName, null);
if (autoTypeObjectReader == null) {
throw new JSONException("autoType not support : " + typeName + ", offset " + offset + "/" + bytes.length);
}
}
return autoTypeObjectReader.readJSONBObject(this, null, null, 0);
}
case BC_DOUBLE_NUM_0:
return 0D;
case BC_DOUBLE_NUM_1:
return 1D;
case BC_CHAR:
int intValue = readInt32Value();
return (char) intValue;
case BC_OBJECT: {
Map map = null;
boolean supportAutoType = (context.features & Feature.SupportAutoType.mask) != 0;
for (int i = 0; ; ++i) {
byte type = bytes[offset];
if (type == BC_OBJECT_END) {
offset++;
break;
}
Object name;
if (supportAutoType && i == 0 && type >= BC_STR_ASCII_FIX_MIN) {
long hash = readFieldNameHashCode();
if (hash == ObjectReader.HASH_TYPE) {
long typeHash = readValueHashCode();
ObjectReader autoTypeObjectReader = context.getObjectReaderAutoType(typeHash);
if (autoTypeObjectReader == null) {
String typeName = getString();
autoTypeObjectReader = context.getObjectReaderAutoType(typeName, null);
if (autoTypeObjectReader == null) {
throw new JSONException("autoType not support : " + typeName + ", offset " + offset + "/" + bytes.length);
}
}
typeRedirect = true;
return autoTypeObjectReader.readJSONBObject(this, null, null, 0);
}
name = getFieldName();
} else {
if (type >= BC_STR_ASCII_FIX_MIN) {
name = readFieldName();
} else {
name = readAny();
}
}
if (map == null) {
if ((context.features & Feature.UseNativeObject.mask) != 0) {
map = new HashMap();
} else {
map = new JSONObject();
}
}
if (isReference()) {
String reference = readReference();
if ("..".equals(reference)) {
map.put(name, map);
} else {
addResolveTask(map, name, JSONPath.of(reference));
map.put(name, null);
}
continue;
}
byte valueType = bytes[offset];
Object value;
if (valueType >= BC_STR_ASCII_FIX_MIN && valueType <= BC_STR_GB18030) {
value = readString();
} else if (isInt32Num(valueType)) {
offset++;
value = (int) valueType;
} else if (valueType == BC_TRUE) {
offset++;
value = Boolean.TRUE;
} else if (valueType == BC_FALSE) {
offset++;
value = Boolean.FALSE;
} else if (valueType == BC_OBJECT) {
value = readObject();
} else {
value = readAny();
}
if (value == null && (context.features & Feature.IgnoreNullPropertyValue.mask) != 0) {
continue;
}
map.put(name, value);
}
if (map == null) {
if ((context.features & Feature.UseNativeObject.mask) != 0) {
map = new HashMap();
} else {
map = new JSONObject();
}
}
return map;
}
default:
final byte type = this.type;
if (isInt32Num(type)) {
return (int) type;
}
if (isInt32Byte(type)) {
return getIntByte(bytes, offset++, type);
}
if (isInt32Short(type) && offset + 1 < end) {
int int3 = getInt3(bytes, offset, type);
offset += 2;
return int3;
}
if (isInt64Num(type)) {
return (long) INT64_NUM_LOW_VALUE + (type - BC_INT64_NUM_MIN);
}
if (isInt64Byte(type)) {
return (long) getLongByte(bytes, offset++, type);
}
if (isInt64Short(type) && offset + 1 < end) {
long value = getLong3(bytes, offset, type);
offset += 2;
return value;
}
if (type >= BC_ARRAY_FIX_MIN && type <= BC_ARRAY) {
int len = type == BC_ARRAY
? readLength()
: type - BC_ARRAY_FIX_MIN;
if (len == 0) {
if ((context.features & Feature.UseNativeObject.mask) != 0) {
return new ArrayList<>();
} else {
if (context.arraySupplier != null) {
return context.arraySupplier.get();
}
return new JSONArray();
}
}
List list;
if ((context.features & Feature.UseNativeObject.mask) != 0) {
list = new ArrayList(len);
} else {
list = new JSONArray(len);
}
for (int i = 0; i < len; ++i) {
if (isReference()) {
String reference = readReference();
if ("..".equals(reference)) {
list.add(list);
} else {
list.add(null);
addResolveTask(list, i, JSONPath.of(reference));
}
continue;
}
Object item = readAny();
list.add(item);
}
return list;
}
if (type >= BC_STR_ASCII_FIX_MIN && type <= BC_STR_ASCII) {
strlen = type == BC_STR_ASCII
? readLength()
: type - BC_STR_ASCII_FIX_MIN;
if (strlen < 0) {
return symbolTable.getName(-strlen);
}
if (STRING_CREATOR_JDK8 != null) {
String str = latin1StringJDK8(bytes, offset, strlen);
offset += strlen;
if ((context.features & Feature.TrimString.mask) != 0) {
str = str.trim();
}
// empty string to null
if (str.isEmpty() && (context.features & Feature.EmptyStringAsNull.mask) != 0) {
str = null;
}
return str;
} else if (STRING_CREATOR_JDK11 != null) {
byte[] chars = new byte[strlen];
System.arraycopy(bytes, offset, chars, 0, strlen);
offset += strlen;
String str = STRING_CREATOR_JDK11.apply(chars, LATIN1);
if ((context.features & Feature.TrimString.mask) != 0) {
str = str.trim();
}
// empty string to null
if (str.isEmpty() && (context.features & Feature.EmptyStringAsNull.mask) != 0) {
str = null;
}
return str;
}
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
if ((context.features & Feature.TrimString.mask) != 0) {
str = str.trim();
}
// empty string to null
if (str.isEmpty() && (context.features & Feature.EmptyStringAsNull.mask) != 0) {
str = null;
}
return str;
}
if (type == BC_SYMBOL) {
strlen = readLength();
if (strlen >= 0) {
throw new JSONException("not support symbol : " + strlen);
}
return symbolTable.getName(-strlen);
}
throw new JSONException("not support type : " + error(type));
}
}