for (int i = 0, n = length; i < n;) {
byte b = data.get();
i++;
if (STRICTLY_CHECK_FORMAT && !ALLOW_NORMAL_UTF8)
if (b == 0)
throw new UTFDataFormatException(
"0 byte encountered at location " + (i - 1));
if (b >= 0) { // < 0x80 unsigned
// in the range '\001' to '\177'
result[result_index++] = (char) b;
continue;
}
try {
byte nb = data.get();
i++;
if (b < -32) { // < 0xe0 unsigned
// '\000' or in the range '\200' to '\u07FF'
char c = result[result_index++] = (char) (((b & 0x1f) << 6) | (nb & 0x3f));
if (STRICTLY_CHECK_FORMAT) {
if (((b & 0xe0) != 0xc0) || ((nb & 0xc0) != 0x80))
throw new UTFDataFormatException(
"invalid marker bits for double byte char at location "
+ (i - 2));
if (c < '\200') {
if (!ALLOW_PSEUDO_UTF8 || (c != '\000'))
throw new UTFDataFormatException(
"encountered double byte char that should have been single byte at location "
+ (i - 2));
} else if (c > '\u07FF')
throw new UTFDataFormatException(
"encountered double byte char that should have been triple byte at location "
+ (i - 2));
}
} else {
byte nnb = data.get();
i++;
// in the range '\u0800' to '\uFFFF'
char c = result[result_index++] = (char) (((b & 0x0f) << 12) | ((nb & 0x3f) << 6) | (nnb & 0x3f));
if (STRICTLY_CHECK_FORMAT) {
if (((b & 0xf0) != 0xe0) || ((nb & 0xc0) != 0x80)
|| ((nnb & 0xc0) != 0x80))
throw new UTFDataFormatException(
"invalid marker bits for triple byte char at location "
+ (i - 3));
if (c < '\u0800')
throw new UTFDataFormatException(
"encountered triple byte char that should have been fewer bytes at location "
+ (i - 3));
}
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new UTFDataFormatException("unexpected end at location "
+ i);
}
}
return InternString.internString(new String(result, 0, result_index));
}