in core/src/main/java/com/alibaba/fastjson2/JSONWriter.java [2373:2675]
public String toString() {
if (fullPath != null) {
return fullPath;
}
byte[] buf = new byte[16];
int off = 0;
int level = 0;
Path[] items = new Path[4];
for (Path p = this; p != null; p = p.parent) {
if (items.length == level) {
items = Arrays.copyOf(items, items.length + 4);
}
items[level] = p;
level++;
}
boolean ascii = true;
for (int i = level - 1; i >= 0; i--) {
Path item = items[i];
String name = item.name;
if (name == null) {
int intValue = item.index;
int intValueSize = IOUtils.stringSize(intValue);
while (off + intValueSize + 2 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off++] = '[';
IOUtils.getChars(intValue, off + intValueSize, buf);
off += intValueSize;
buf[off++] = ']';
} else {
if (off + 1 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
if (i != level - 1) {
buf[off++] = '.';
}
if (JVM_VERSION == 8) {
char[] chars = getCharArray(name);
for (int j = 0; j < chars.length; j++) {
char ch = chars[j];
switch (ch) {
case '/':
case ':':
case ';':
case '`':
case '.':
case '~':
case '!':
case '@':
case '#':
case '%':
case '^':
case '&':
case '*':
case '[':
case ']':
case '<':
case '>':
case '?':
case '(':
case ')':
case '-':
case '+':
case '=':
case '\\':
case '"':
case '\'':
case ',':
if (off + 1 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off] = '\\';
buf[off + 1] = (byte) ch;
off += 2;
break;
default:
if ((ch >= 0x0001) && (ch <= 0x007F)) {
if (off == buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off++] = (byte) ch;
} else if (ch >= '\uD800' && ch < ('\uDFFF' + 1)) { // //Character.isSurrogate(c)
ascii = false;
final int uc;
if (ch < '\uDBFF' + 1) { // Character.isHighSurrogate(c)
if (name.length() - i < 2) {
uc = -1;
} else {
char d = name.charAt(i + 1);
// d >= '\uDC00' && d < ('\uDFFF' + 1)
if (d >= '\uDC00' && d < ('\uDFFF' + 1)) { // Character.isLowSurrogate(d)
uc = ((ch << 10) + d) + (0x010000 - ('\uD800' << 10) - '\uDC00'); // Character.toCodePoint(c, d)
} else {
// throw new JSONException("encodeUTF8 error", new MalformedInputException(1));
buf[off++] = (byte) '?';
continue;
}
}
} else {
//
// Character.isLowSurrogate(c)
buf[off++] = (byte) '?';
continue;
// throw new JSONException("encodeUTF8 error", new MalformedInputException(1));
}
if (uc < 0) {
if (off == buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off++] = (byte) '?';
} else {
if (off + 3 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off] = (byte) (0xf0 | ((uc >> 18)));
buf[off + 1] = (byte) (0x80 | ((uc >> 12) & 0x3f));
buf[off + 2] = (byte) (0x80 | ((uc >> 6) & 0x3f));
buf[off + 3] = (byte) (0x80 | (uc & 0x3f));
off += 4;
j++; // 2 chars
}
} else if (ch > 0x07FF) {
if (off + 2 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
ascii = false;
buf[off] = (byte) (0xE0 | ((ch >> 12) & 0x0F));
buf[off + 1] = (byte) (0x80 | ((ch >> 6) & 0x3F));
buf[off + 2] = (byte) (0x80 | ((ch) & 0x3F));
off += 3;
} else {
if (off + 1 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
ascii = false;
buf[off] = (byte) (0xC0 | ((ch >> 6) & 0x1F));
buf[off + 1] = (byte) (0x80 | ((ch) & 0x3F));
off += 2;
}
break;
}
}
} else {
for (int j = 0; j < name.length(); j++) {
char ch = name.charAt(j);
switch (ch) {
case '/':
case ':':
case ';':
case '`':
case '.':
case '~':
case '!':
case '@':
case '#':
case '%':
case '^':
case '&':
case '*':
case '[':
case ']':
case '<':
case '>':
case '?':
case '(':
case ')':
case '-':
case '+':
case '=':
case '\\':
case '"':
case '\'':
case ',':
if (off + 1 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off] = '\\';
buf[off + 1] = (byte) ch;
off += 2;
break;
default:
if ((ch >= 0x0001) && (ch <= 0x007F)) {
if (off == buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off++] = (byte) ch;
} else if (ch >= '\uD800' && ch < ('\uDFFF' + 1)) { // //Character.isSurrogate(c)
ascii = false;
final int uc;
if (ch < '\uDBFF' + 1) { // Character.isHighSurrogate(c)
if (name.length() - i < 2) {
uc = -1;
} else {
char d = name.charAt(i + 1);
// d >= '\uDC00' && d < ('\uDFFF' + 1)
if (d >= '\uDC00' && d < ('\uDFFF' + 1)) { // Character.isLowSurrogate(d)
uc = ((ch << 10) + d) + (0x010000 - ('\uD800' << 10) - '\uDC00'); // Character.toCodePoint(c, d)
} else {
// throw new JSONException("encodeUTF8 error", new MalformedInputException(1));
buf[off++] = (byte) '?';
continue;
}
}
} else {
//
// Character.isLowSurrogate(c)
buf[off++] = (byte) '?';
continue;
// throw new JSONException("encodeUTF8 error", new MalformedInputException(1));
}
if (uc < 0) {
if (off == buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off++] = (byte) '?';
} else {
if (off + 4 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
buf[off] = (byte) (0xf0 | ((uc >> 18)));
buf[off + 1] = (byte) (0x80 | ((uc >> 12) & 0x3f));
buf[off + 2] = (byte) (0x80 | ((uc >> 6) & 0x3f));
buf[off + 3] = (byte) (0x80 | (uc & 0x3f));
off += 4;
j++; // 2 chars
}
} else if (ch > 0x07FF) {
if (off + 2 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
ascii = false;
buf[off] = (byte) (0xE0 | ((ch >> 12) & 0x0F));
buf[off + 1] = (byte) (0x80 | ((ch >> 6) & 0x3F));
buf[off + 2] = (byte) (0x80 | ((ch) & 0x3F));
off += 3;
} else {
if (off + 1 >= buf.length) {
int newCapacity = buf.length + (buf.length >> 1);
buf = Arrays.copyOf(buf, newCapacity);
}
ascii = false;
buf[off] = (byte) (0xC0 | ((ch >> 6) & 0x1F));
buf[off + 1] = (byte) (0x80 | ((ch) & 0x3F));
off += 2;
}
break;
}
}
}
}
}
if (ascii) {
if (STRING_CREATOR_JDK11 != null) {
byte[] bytes;
if (off == buf.length) {
bytes = buf;
} else {
bytes = new byte[off];
System.arraycopy(buf, 0, bytes, 0, off);
}
return fullPath = STRING_CREATOR_JDK11.apply(bytes, LATIN1);
}
if (STRING_CREATOR_JDK8 != null) {
char[] chars = new char[off];
for (int i = 0; i < off; i++) {
chars[i] = (char) buf[i];
}
return fullPath = STRING_CREATOR_JDK8.apply(chars, Boolean.TRUE);
}
}
return fullPath = new String(buf, 0, off, ascii ? StandardCharsets.ISO_8859_1 : StandardCharsets.UTF_8);
}