in core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java [2637:2928]
public String readFieldName() {
final byte[] bytes = this.bytes;
byte strtype = this.strtype = bytes[offset++];
if (strtype == BC_NULL) {
return null;
}
boolean typeSymbol = strtype == BC_SYMBOL;
if (typeSymbol) {
strtype = this.strtype = bytes[offset];
if (isInt32(strtype)) {
int symbol = readInt32Value();
if (symbol < 0) {
return symbolTable.getName(-symbol);
}
if (symbol == 0) {
this.strtype = symbol0StrType;
strlen = symbol0Length;
strBegin = symbol0Begin;
return getFieldName();
}
int index = symbol * 2 + 1;
long strInfo = symbols[index];
this.strtype = (byte) strInfo;
strlen = ((int) strInfo) >> 8;
strBegin = (int) (strInfo >> 32);
return getString();
}
offset++;
}
strBegin = offset;
Charset charset = null;
String str = null;
if (strtype == BC_STR_ASCII_FIX_MIN + 1) {
str = TypeUtils.toString((char) (bytes[offset] & 0xff));
strlen = 1;
offset++;
} else if (strtype == BC_STR_ASCII_FIX_MIN + 2) {
str = TypeUtils.toString(
(char) (bytes[offset] & 0xff),
(char) (bytes[offset + 1] & 0xff)
);
strlen = 2;
offset += 2;
} else if (strtype >= BC_STR_ASCII_FIX_MIN && strtype <= BC_STR_ASCII) {
long nameValue0 = -1, nameValue1 = -1;
if (strtype == BC_STR_ASCII) {
strlen = readLength();
strBegin = offset;
} else {
final int offset = this.offset;
strlen = strtype - BC_STR_ASCII_FIX_MIN;
if (offset + strlen > bytes.length) {
throw new JSONException("illegal jsonb data");
}
switch (strlen) {
case 3:
nameValue0
= (bytes[offset + 2] << 16)
+ ((bytes[offset + 1] & 0xFFL) << 8)
+ (bytes[offset] & 0xFFL);
break;
case 4:
nameValue0 = UNSAFE.getInt(bytes, BASE + offset);
break;
case 5:
nameValue0
= (((long) bytes[offset + 4]) << 32)
+ (UNSAFE.getInt(bytes, BASE + offset) & 0xFFFFFFFFL);
break;
case 6:
nameValue0
= (((long) bytes[offset + 5]) << 40)
+ ((bytes[offset + 4] & 0xFFL) << 32)
+ (UNSAFE.getInt(bytes, BASE + offset) & 0xFFFFFFFFL);
break;
case 7:
nameValue0
= (((long) bytes[offset + 6]) << 48)
+ ((bytes[offset + 5] & 0xFFL) << 40)
+ ((bytes[offset + 4] & 0xFFL) << 32)
+ (UNSAFE.getInt(bytes, BASE + offset) & 0xFFFFFFFFL);
break;
case 8:
nameValue0 = UNSAFE.getLong(bytes, BASE + offset);
break;
case 9:
nameValue0 = bytes[offset];
nameValue1 = UNSAFE.getLong(bytes, BASE + offset + 1);
break;
case 10:
nameValue0 = UNSAFE.getShort(bytes, BASE + offset);
nameValue1 = UNSAFE.getLong(bytes, BASE + offset + 2);
break;
case 11:
nameValue0
= (bytes[offset] << 16)
+ ((bytes[offset + 1] & 0xFFL) << 8)
+ (bytes[offset + 2] & 0xFFL);
nameValue1 = UNSAFE.getLong(bytes, BASE + offset + 3);
break;
case 12:
nameValue0 = UNSAFE.getInt(bytes, BASE + offset);
nameValue1 = UNSAFE.getLong(bytes, BASE + offset + 4);
break;
case 13:
nameValue0
= (((long) bytes[offset + 4]) << 32)
+ (UNSAFE.getInt(bytes, BASE + offset) & 0xFFFFFFFFL);
nameValue1 = UNSAFE.getLong(bytes, BASE + offset + 5);
break;
case 14:
nameValue0
= (((long) bytes[offset + 5]) << 40)
+ ((bytes[offset + 4] & 0xFFL) << 32)
+ (UNSAFE.getInt(bytes, BASE + offset) & 0xFFFFFFFFL);
nameValue1 = UNSAFE.getLong(bytes, BASE + offset + 6);
break;
case 15:
nameValue0
= (((long) bytes[offset + 6]) << 48)
+ ((bytes[offset + 5] & 0xFFL) << 40)
+ ((bytes[offset + 4] & 0xFFL) << 32)
+ (UNSAFE.getInt(bytes, BASE + offset) & 0xFFFFFFFFL);
nameValue1 = UNSAFE.getLong(bytes, BASE + offset + 7);
break;
case 16:
nameValue0 = UNSAFE.getLong(bytes, BASE + offset);
nameValue1 = UNSAFE.getLong(bytes, BASE + offset + 8);
break;
default:
break;
}
}
final int strlen = this.strlen;
if (bytes[offset + strlen - 1] > 0 && nameValue0 != -1) {
if (nameValue1 != -1) {
long nameValue01 = nameValue0 ^ nameValue1;
int indexMask = ((int) (nameValue01 ^ (nameValue01 >>> 32))) & (NAME_CACHE2.length - 1);
JSONFactory.NameCacheEntry2 entry = NAME_CACHE2[indexMask];
if (entry == null) {
String name;
if (STRING_CREATOR_JDK8 != null) {
name = latin1StringJDK8(bytes, offset, strlen);
} else {
name = new String(bytes, offset, strlen, ISO_8859_1);
}
NAME_CACHE2[indexMask] = new JSONFactory.NameCacheEntry2(name, nameValue0, nameValue1);
offset += strlen;
str = name;
} else if (entry.value0 == nameValue0 && entry.value1 == nameValue1) {
offset += strlen;
str = entry.name;
}
} else {
int indexMask = ((int) (nameValue0 ^ (nameValue0 >>> 32))) & (NAME_CACHE.length - 1);
JSONFactory.NameCacheEntry entry = NAME_CACHE[indexMask];
if (entry == null) {
String name;
if (STRING_CREATOR_JDK8 != null) {
name = latin1StringJDK8(bytes, offset, strlen);
} else {
name = new String(bytes, offset, strlen, ISO_8859_1);
}
NAME_CACHE[indexMask] = new JSONFactory.NameCacheEntry(name, nameValue0);
offset += strlen;
str = name;
} else if (entry.value == nameValue0) {
offset += strlen;
str = entry.name;
}
}
}
if (str == null) {
if (strlen >= 0) {
if (STRING_CREATOR_JDK8 != null) {
str = latin1StringJDK8(bytes, offset, strlen);
offset += strlen;
} else if (STRING_CREATOR_JDK11 != null) {
byte[] chars = new byte[strlen];
System.arraycopy(bytes, offset, chars, 0, strlen);
str = STRING_CREATOR_JDK11.apply(chars, LATIN1);
offset += strlen;
}
}
charset = ISO_8859_1;
}
} else if (strtype == BC_STR_UTF8) {
strlen = readLength();
strBegin = offset;
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);
str = STRING_CREATOR_JDK11.apply(value, UTF16);
offset += strlen;
}
}
charset = StandardCharsets.UTF_8;
} else if (strtype == BC_STR_UTF16) {
strlen = readLength();
strBegin = offset;
charset = StandardCharsets.UTF_16;
} else if (strtype == BC_STR_UTF16LE) {
strlen = readLength();
strBegin = offset;
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, UTF16);
offset += strlen;
}
charset = StandardCharsets.UTF_16LE;
} else if (strtype == BC_STR_UTF16BE) {
strlen = readLength();
strBegin = offset;
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, UTF16);
offset += strlen;
}
charset = StandardCharsets.UTF_16BE;
} else if (strtype == BC_STR_GB18030) {
strlen = readLength();
if (GB18030 == null) {
GB18030 = Charset.forName("GB18030");
}
charset = GB18030;
}
if (strlen < 0) {
str = symbolTable.getName(-strlen);
}
if (str == null) {
str = new String(bytes, offset, strlen, charset);
offset += strlen;
}
if (typeSymbol) {
int symbol = readInt32Value();
if (symbol == 0) {
symbol0Begin = strBegin;
symbol0Length = strlen;
symbol0StrType = strtype;
} else {
int minCapacity = symbol * 2 + 2;
if (symbols == null) {
symbols = new long[Math.max(minCapacity, 32)];
} else if (symbols.length < minCapacity) {
symbols = Arrays.copyOf(symbols, symbols.length + 16);
}
long strInfo = ((long) strBegin << 32) + ((long) strlen << 8) + strtype;
symbols[symbol * 2 + 1] = strInfo;
}
}
return str;
}