in core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java [3078:3421]
public String readFieldName() {
final char quote = ch;
if (quote == '\'' && ((context.features & Feature.DisableSingleQuote.mask) != 0)) {
throw notSupportName();
}
if (quote != '"' && quote != '\'') {
if ((context.features & Feature.AllowUnQuotedFieldNames.mask) != 0 && isFirstIdentifier(quote)) {
return readFieldNameUnquote();
}
return null;
}
final byte[] bytes = this.bytes;
this.nameAscii = true;
this.nameEscape = false;
int offset = this.nameBegin = this.offset, end = this.end;
final int nameBegin = this.nameBegin;
for (int i = 0; offset < end; ++i) {
int ch = bytes[offset];
if (ch == '\\') {
nameEscape = true;
ch = bytes[offset + 1];
offset += (ch == 'u' ? 6 : (ch == 'x' ? 4 : 2));
continue;
}
if (ch == quote) {
this.nameLength = i;
this.nameEnd = offset;
offset++;
ch = bytes[offset] & 0xff;
while (ch <= ' ' && ((1L << ch) & SPACE) != 0) {
offset++;
ch = bytes[offset] & 0xff;
}
if (ch != ':') {
throw syntaxError(offset, ch);
}
ch = ++offset == end ? EOI : bytes[offset++];
while (ch <= ' ' && ((1L << ch) & SPACE) != 0) {
ch = offset == end ? EOI : bytes[offset++];
}
this.offset = offset;
this.ch = (char) ch;
break;
}
if (ch >= 0) {
offset++;
} else {
if (nameAscii) {
nameAscii = false;
}
switch ((ch & 0xFF) >> 4) {
case 12:
case 13:
/* 110x xxxx 10xx xxxx*/
offset += 2;
break;
case 14: {
offset += 3;
break;
}
default:
if ((ch >> 3) == -2) {
offset += 4;
break;
}
/* 10xx xxxx, 1111 xxxx */
throw syntaxError(offset, ch);
}
}
}
if (nameEnd < nameBegin) {
throw syntaxError(offset, ch);
}
int length = nameEnd - nameBegin;
if (!nameEscape) {
if (nameAscii) {
long nameValue0 = -1, nameValue1 = -1;
switch (length) {
case 1:
return TypeUtils.toString((char) (bytes[nameBegin] & 0xff));
case 2:
return TypeUtils.toString(
(char) (bytes[nameBegin] & 0xff),
(char) (bytes[nameBegin + 1] & 0xff)
);
case 3:
nameValue0
= (bytes[nameBegin + 2] << 16)
+ (bytes[nameBegin + 1] << 8)
+ (bytes[nameBegin]);
break;
case 4:
nameValue0
= (bytes[nameBegin + 3] << 24)
+ (bytes[nameBegin + 2] << 16)
+ (bytes[nameBegin + 1] << 8)
+ (bytes[nameBegin]);
break;
case 5:
nameValue0
= (((long) bytes[nameBegin + 4]) << 32)
+ (((long) bytes[nameBegin + 3]) << 24)
+ (((long) bytes[nameBegin + 2]) << 16)
+ (((long) bytes[nameBegin + 1]) << 8)
+ ((long) bytes[nameBegin]);
break;
case 6:
nameValue0
= (((long) bytes[nameBegin + 5]) << 40)
+ (((long) bytes[nameBegin + 4]) << 32)
+ (((long) bytes[nameBegin + 3]) << 24)
+ (((long) bytes[nameBegin + 2]) << 16)
+ (((long) bytes[nameBegin + 1]) << 8)
+ ((long) bytes[nameBegin]);
break;
case 7:
nameValue0
= (((long) bytes[nameBegin + 6]) << 48)
+ (((long) bytes[nameBegin + 5]) << 40)
+ (((long) bytes[nameBegin + 4]) << 32)
+ (((long) bytes[nameBegin + 3]) << 24)
+ (((long) bytes[nameBegin + 2]) << 16)
+ (((long) bytes[nameBegin + 1]) << 8)
+ ((long) bytes[nameBegin]);
break;
case 8:
nameValue0
= (((long) bytes[nameBegin + 7]) << 56)
+ (((long) bytes[nameBegin + 6]) << 48)
+ (((long) bytes[nameBegin + 5]) << 40)
+ (((long) bytes[nameBegin + 4]) << 32)
+ (((long) bytes[nameBegin + 3]) << 24)
+ (((long) bytes[nameBegin + 2]) << 16)
+ (((long) bytes[nameBegin + 1]) << 8)
+ ((long) bytes[nameBegin]);
break;
case 9:
nameValue0 = bytes[nameBegin];
nameValue1
= (((long) bytes[nameBegin + 8]) << 56)
+ (((long) bytes[nameBegin + 7]) << 48)
+ (((long) bytes[nameBegin + 6]) << 40)
+ (((long) bytes[nameBegin + 5]) << 32)
+ (((long) bytes[nameBegin + 4]) << 24)
+ (((long) bytes[nameBegin + 3]) << 16)
+ (((long) bytes[nameBegin + 2]) << 8)
+ ((long) bytes[nameBegin + 1]);
break;
case 10:
nameValue0
= (bytes[nameBegin + 1] << 8)
+ (bytes[nameBegin]);
nameValue1
= (((long) bytes[nameBegin + 9]) << 56)
+ (((long) bytes[nameBegin + 8]) << 48)
+ (((long) bytes[nameBegin + 7]) << 40)
+ (((long) bytes[nameBegin + 6]) << 32)
+ (((long) bytes[nameBegin + 5]) << 24)
+ (((long) bytes[nameBegin + 4]) << 16)
+ (((long) bytes[nameBegin + 3]) << 8)
+ ((long) bytes[nameBegin + 2]);
break;
case 11:
nameValue0
= (bytes[nameBegin + 2] << 16)
+ (bytes[nameBegin + 1] << 8)
+ (bytes[nameBegin]);
nameValue1
= (((long) bytes[nameBegin + 10]) << 56)
+ (((long) bytes[nameBegin + 9]) << 48)
+ (((long) bytes[nameBegin + 8]) << 40)
+ (((long) bytes[nameBegin + 7]) << 32)
+ (((long) bytes[nameBegin + 6]) << 24)
+ (((long) bytes[nameBegin + 5]) << 16)
+ (((long) bytes[nameBegin + 4]) << 8)
+ ((long) bytes[nameBegin + 3]);
break;
case 12:
nameValue0
= (bytes[nameBegin + 3] << 24)
+ (bytes[nameBegin + 2] << 16)
+ (bytes[nameBegin + 1] << 8)
+ (bytes[nameBegin]);
nameValue1
= (((long) bytes[nameBegin + 11]) << 56)
+ (((long) bytes[nameBegin + 10]) << 48)
+ (((long) bytes[nameBegin + 9]) << 40)
+ (((long) bytes[nameBegin + 8]) << 32)
+ (((long) bytes[nameBegin + 7]) << 24)
+ (((long) bytes[nameBegin + 6]) << 16)
+ (((long) bytes[nameBegin + 5]) << 8)
+ ((long) bytes[nameBegin + 4]);
break;
case 13:
nameValue0
= (((long) bytes[nameBegin + 4]) << 32)
+ (((long) bytes[nameBegin + 3]) << 24)
+ (((long) bytes[nameBegin + 2]) << 16)
+ (((long) bytes[nameBegin + 1]) << 8)
+ ((long) bytes[nameBegin]);
nameValue1
= (((long) bytes[nameBegin + 12]) << 56)
+ (((long) bytes[nameBegin + 11]) << 48)
+ (((long) bytes[nameBegin + 10]) << 40)
+ (((long) bytes[nameBegin + 9]) << 32)
+ (((long) bytes[nameBegin + 8]) << 24)
+ (((long) bytes[nameBegin + 7]) << 16)
+ (((long) bytes[nameBegin + 6]) << 8)
+ ((long) bytes[nameBegin + 5]);
break;
case 14:
nameValue0
= (((long) bytes[nameBegin + 5]) << 40)
+ (((long) bytes[nameBegin + 4]) << 32)
+ (((long) bytes[nameBegin + 3]) << 24)
+ (((long) bytes[nameBegin + 2]) << 16)
+ (((long) bytes[nameBegin + 1]) << 8)
+ ((long) bytes[nameBegin]);
nameValue1
= (((long) bytes[nameBegin + 13]) << 56)
+ (((long) bytes[nameBegin + 12]) << 48)
+ (((long) bytes[nameBegin + 11]) << 40)
+ (((long) bytes[nameBegin + 10]) << 32)
+ (((long) bytes[nameBegin + 9]) << 24)
+ (((long) bytes[nameBegin + 8]) << 16)
+ (((long) bytes[nameBegin + 7]) << 8)
+ ((long) bytes[nameBegin + 6]);
break;
case 15:
nameValue0
= (((long) bytes[nameBegin + 6]) << 48)
+ (((long) bytes[nameBegin + 5]) << 40)
+ (((long) bytes[nameBegin + 4]) << 32)
+ (((long) bytes[nameBegin + 3]) << 24)
+ (((long) bytes[nameBegin + 2]) << 16)
+ (((long) bytes[nameBegin + 1]) << 8)
+ ((long) bytes[nameBegin]);
nameValue1
= (((long) bytes[nameBegin + 14]) << 56)
+ (((long) bytes[nameBegin + 13]) << 48)
+ (((long) bytes[nameBegin + 12]) << 40)
+ (((long) bytes[nameBegin + 11]) << 32)
+ (((long) bytes[nameBegin + 10]) << 24)
+ (((long) bytes[nameBegin + 9]) << 16)
+ (((long) bytes[nameBegin + 8]) << 8)
+ ((long) bytes[nameBegin + 7]);
break;
case 16:
nameValue0
= (((long) bytes[nameBegin + 7]) << 56)
+ (((long) bytes[nameBegin + 6]) << 48)
+ (((long) bytes[nameBegin + 5]) << 40)
+ (((long) bytes[nameBegin + 4]) << 32)
+ (((long) bytes[nameBegin + 3]) << 24)
+ (((long) bytes[nameBegin + 2]) << 16)
+ (((long) bytes[nameBegin + 1]) << 8)
+ ((long) bytes[nameBegin]);
nameValue1
= (((long) bytes[nameBegin + 15]) << 56)
+ (((long) bytes[nameBegin + 14]) << 48)
+ (((long) bytes[nameBegin + 13]) << 40)
+ (((long) bytes[nameBegin + 12]) << 32)
+ (((long) bytes[nameBegin + 11]) << 24)
+ (((long) bytes[nameBegin + 10]) << 16)
+ (((long) bytes[nameBegin + 9]) << 8)
+ ((long) bytes[nameBegin + 8]);
break;
default:
break;
}
if (nameValue0 != -1) {
if (nameValue1 != -1) {
long nameValue01 = nameValue0 ^ nameValue1;
int indexMask = ((int) (nameValue01 ^ (nameValue01 >>> 32))) & (NAME_CACHE2.length - 1);
NameCacheEntry2 entry = NAME_CACHE2[indexMask];
if (entry == null) {
String name;
if (STRING_CREATOR_JDK8 != null) {
name = asciiStringJDK8(bytes, nameBegin, length);
} else if (ANDROID) {
name = getLatin1String(nameBegin, length);
} else {
name = new String(bytes, nameBegin, length, ISO_8859_1);
}
NAME_CACHE2[indexMask] = new NameCacheEntry2(name, nameValue0, nameValue1);
return name;
} else if (entry.value0 == nameValue0 && entry.value1 == nameValue1) {
return entry.name;
}
} else {
int indexMask = ((int) (nameValue0 ^ (nameValue0 >>> 32))) & (NAME_CACHE.length - 1);
NameCacheEntry entry = NAME_CACHE[indexMask];
if (entry == null) {
String name;
if (STRING_CREATOR_JDK8 != null) {
name = asciiStringJDK8(bytes, nameBegin, length);
} else if (ANDROID) {
name = getLatin1String(nameBegin, length);
} else {
name = new String(bytes, nameBegin, length, ISO_8859_1);
}
NAME_CACHE[indexMask] = new NameCacheEntry(name, nameValue0);
return name;
} else if (entry.value == nameValue0) {
return entry.name;
}
}
}
if (STRING_CREATOR_JDK8 != null) {
return asciiStringJDK8(bytes, nameBegin, length);
} else if (ANDROID) {
return getLatin1String(nameBegin, nameEnd - nameBegin);
} else if (STRING_CREATOR_JDK11 != null) {
return STRING_CREATOR_JDK11.apply(
Arrays.copyOfRange(bytes, nameBegin, nameEnd),
LATIN1);
}
}
if (nameAscii && ANDROID) {
return getLatin1String(nameBegin, length);
}
return new String(bytes, nameBegin, length,
nameAscii ? ISO_8859_1 : UTF_8
);
}
return getFieldName();
}