in core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java [1979:2286]
public long readValueHashCode() {
final byte[] bytes = this.bytes;
final byte strtype = this.strtype = bytes[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
) {
strlen = readLength();
strBegin = offset;
} else if (strtype == BC_SYMBOL) {
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) {
final int offset = this.offset;
hashCode = Fnv.MAGIC_HASH_CODE;
if (bytes[offset] == (byte) 0xFE
&& bytes[offset + 1] == (byte) 0xFF
) {
if (strlen <= 16) {
long nameValue = 0;
for (int i = 2; i < strlen; i += 2) {
byte c0 = bytes[offset + i];
byte c1 = bytes[offset + i + 1];
char ch = (char) ((c1 & 0xff) | ((c0 & 0xff) << 8));
if (ch > 0x7F || (i == 0 && ch == 0)) {
nameValue = 0;
break;
}
byte c = (byte) ch;
switch ((i - 2) >> 1) {
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) {
return nameValue;
}
}
for (int i = 2; 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 (bytes[offset] == (byte) 0xFF
&& bytes[offset + 1] == (byte) 0xFE
) {
for (int i = 2; i < strlen; i += 2) {
byte c1 = bytes[offset + i];
byte c0 = bytes[offset + i + 1];
char ch = (char) ((c1 & 0xff) | ((c0 & 0xff) << 8));
hashCode ^= ch;
hashCode *= Fnv.MAGIC_PRIME;
}
} else {
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 if (strtype == BC_STR_UTF16BE) {
final int offset = this.offset;
if (strlen <= 16) {
long nameValue = 0;
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));
if (ch > 0x7F || (i == 0 && ch == 0)) {
nameValue = 0;
break;
}
byte c = (byte) ch;
switch (i >> 1) {
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) {
return nameValue;
}
}
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) {
final int offset = this.offset;
if (strlen <= 16) {
long nameValue = 0;
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));
if (ch > 0x7F || (i == 0 && ch == 0)) {
nameValue = 0;
break;
}
byte c = (byte) ch;
switch (i >> 1) {
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) {
return nameValue;
}
}
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 {
if (strlen <= 8) {
long nameValue = 0;
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) {
return nameValue;
}
}
hashCode = Fnv.MAGIC_HASH_CODE;
for (int i = 0; i < strlen; ++i) {
byte c = bytes[offset++];
hashCode ^= c;
hashCode *= Fnv.MAGIC_PRIME;
}
}
return hashCode;
}