in core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java [1731:1976]
public long readTypeHashCode0() {
final byte[] bytes = this.bytes;
byte strtype = this.strtype = bytes[offset];
if (strtype == BC_SYMBOL) {
offset++;
strtype = this.strtype = bytes[offset];
if (isInt32(strtype)) {
int symbol;
if (strtype <= BC_INT32_NUM_MAX) {
offset++;
symbol = strtype;
} else {
symbol = readInt32Value();
}
if (symbol < 0) {
return symbolTable.getHashCode(-symbol);
}
if (symbol == 0) {
this.strtype = symbol0StrType;
strlen = symbol0Length;
strBegin = symbol0Begin;
if (symbol0Hash == 0) {
symbol0Hash = getNameHashCode();
}
return symbol0Hash;
}
int index = symbol * 2;
long strInfo = symbols[index + 1];
this.strtype = (byte) strInfo;
strlen = ((int) strInfo) >> 8;
strBegin = (int) (strInfo >> 32);
long nameHashCode = symbols[index];
if (nameHashCode == 0) {
nameHashCode = getNameHashCode();
symbols[index] = nameHashCode;
}
return nameHashCode;
}
}
if (isInt32(strtype)) {
int typeIndex;
if (strtype <= BC_INT32_NUM_MAX) {
offset++;
typeIndex = strtype;
} else if (strtype <= BC_INT32_BYTE_MAX) {
offset++;
typeIndex = ((strtype - BC_INT32_BYTE_ZERO) << 8)
+ (bytes[offset++] & 0xFF);
} else {
typeIndex = readInt32Value();
}
long refTypeHash;
if (typeIndex == 0) {
this.strtype = symbol0StrType;
strlen = symbol0Length;
strBegin = symbol0Begin;
if (symbol0Hash == 0) {
symbol0Hash = Fnv.hashCode64(getString());
}
refTypeHash = symbol0Hash;
} else if (typeIndex < 0) {
strlen = strtype;
refTypeHash = symbolTable.getHashCode(-typeIndex);
} else {
refTypeHash = symbols[typeIndex * 2];
if (refTypeHash == 0) {
long strInfo = symbols[typeIndex * 2 + 1];
this.strtype = (byte) strInfo;
strlen = ((int) strInfo) >> 8;
strBegin = (int) (strInfo >> 32);
refTypeHash = Fnv.hashCode64(getString());
}
}
if (refTypeHash == -1) {
throw typeRefNotFound(typeIndex);
}
return refTypeHash;
}
offset++;
strBegin = offset;
if (strtype >= BC_STR_ASCII_FIX_MIN && strtype <= BC_STR_ASCII_FIX_MAX) {
strlen = strtype - BC_STR_ASCII_FIX_MIN;
} else if (strtype == BC_STR_ASCII
|| strtype == BC_STR_UTF8
|| strtype == BC_STR_UTF16
|| strtype == BC_STR_UTF16LE
|| strtype == BC_STR_UTF16BE
) {
byte type = bytes[offset];
if (isInt32Num(type)) {
offset++;
strlen = type;
} else if (isInt32Byte(type)) { // type >= BC_INT32_BYTE_MIN && type <= BC_INT32_BYTE_MAX
offset++;
strlen = getIntByte(bytes, offset++, type);
} else {
strlen = readLength();
}
strBegin = offset;
} else {
throw readStringError();
}
long hashCode;
if (strlen < 0) {
hashCode = symbolTable.getHashCode(-strlen);
} else if (strtype == BC_STR_UTF8) {
hashCode = Fnv.MAGIC_HASH_CODE;
int end = offset + strlen;
while (offset < end) {
int c = bytes[offset];
if (c >= 0) {
offset++;
} else {
c &= 0xFF;
switch (c >> 4) {
case 12:
case 13: {
/* 110x xxxx 10xx xxxx*/
c = char2_utf8(c, bytes[offset + 1], offset);
offset += 2;
break;
}
case 14: {
c = char2_utf8(c, bytes[offset + 1], bytes[offset + 2], offset);
offset += 3;
break;
}
default:
/* 10xx xxxx, 1111 xxxx */
throw new JSONException("malformed input around byte " + offset);
}
}
hashCode ^= c;
hashCode *= Fnv.MAGIC_PRIME;
}
} else if (strtype == BC_STR_UTF16 || strtype == BC_STR_UTF16BE) {
hashCode = Fnv.MAGIC_HASH_CODE;
for (int i = 0; i < strlen; i += 2) {
byte c0 = bytes[offset + i];
byte c1 = bytes[offset + i + 1];
char ch = (char) ((c1 & 0xff) | ((c0 & 0xff) << 8));
hashCode ^= ch;
hashCode *= Fnv.MAGIC_PRIME;
}
} else if (strtype == BC_STR_UTF16LE) {
hashCode = Fnv.MAGIC_HASH_CODE;
for (int i = 0; i < strlen; i += 2) {
byte c0 = bytes[offset + i];
byte c1 = bytes[offset + i + 1];
char ch = (char) ((c0 & 0xff) | ((c1 & 0xff) << 8));
hashCode ^= ch;
hashCode *= Fnv.MAGIC_PRIME;
}
} else {
long nameValue = 0;
if (strlen <= 8) {
for (int i = 0, start = offset; i < strlen; offset++, i++) {
byte c = bytes[offset];
if (c < 0 || (c == 0 && bytes[start] == 0)) {
nameValue = 0;
offset = start;
break;
}
switch (i) {
case 0:
nameValue = c;
break;
case 1:
nameValue = ((c) << 8) + (nameValue & 0xFFL);
break;
case 2:
nameValue = ((c) << 16) + (nameValue & 0xFFFFL);
break;
case 3:
nameValue = ((c) << 24) + (nameValue & 0xFFFFFFL);
break;
case 4:
nameValue = (((long) c) << 32) + (nameValue & 0xFFFFFFFFL);
break;
case 5:
nameValue = (((long) c) << 40L) + (nameValue & 0xFFFFFFFFFFL);
break;
case 6:
nameValue = (((long) c) << 48L) + (nameValue & 0xFFFFFFFFFFFFL);
break;
case 7:
nameValue = (((long) c) << 56L) + (nameValue & 0xFFFFFFFFFFFFFFL);
break;
default:
break;
}
}
}
if (nameValue != 0) {
hashCode = nameValue;
} else {
hashCode = Fnv.MAGIC_HASH_CODE;
for (int i = 0; i < strlen; ++i) {
byte c = bytes[offset++];
hashCode ^= c;
hashCode *= Fnv.MAGIC_PRIME;
}
}
}
int symbol;
if (isInt32Num((type = bytes[offset]))) {
symbol = type;
offset++;
} else {
symbol = readInt32Value();
}
if (symbol == 0) {
symbol0Begin = strBegin;
symbol0Length = strlen;
symbol0StrType = strtype;
symbol0Hash = hashCode;
} 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, minCapacity + 16);
}
long strInfo = ((long) strBegin << 32) + ((long) strlen << 8) + strtype;
symbols[symbol * 2 + 1] = strInfo;
}
return hashCode;
}