| 670 | } |
| 671 | |
| 672 | public char[] toChars() { |
| 673 | char[] res = new char[charSize()]; |
| 674 | int p = 0; |
| 675 | tail.len = pos; |
| 676 | for (Block block = tail.next; ; block = block.next) { |
| 677 | byte[] buffer = block.buf; |
| 678 | for (int i = 0, n = block.len; i < n; ) { |
| 679 | int b = buffer[i]; |
| 680 | if (b >= 0) { // 0xxx xxxx |
| 681 | res[p++] = (char)b; |
| 682 | i++; |
| 683 | } else if (b >= -0x20) { |
| 684 | if (b >= -0x10) { // 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx |
| 685 | b = (b << 18) + (buffer[i + 1] << 12) + (buffer[i + 2] << 6) + buffer[i + 3] |
| 686 | + ((0x10 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 - 0x10000); |
| 687 | res[p++] = (char)(0xd800 + ((b >> 10) & 0x3ff)); |
| 688 | res[p++] = (char)(0xdc00 + (b & 0x3ff)); |
| 689 | i += 4; |
| 690 | } else { // 1110 xxxx 10xx xxxx 10xx xxxx |
| 691 | res[p++] = (char)((b << 12) + (buffer[i + 1] << 6) + buffer[i + 2] |
| 692 | + ((0x20 << 12) + (0x80 << 6) + 0x80)); |
| 693 | i += 3; |
| 694 | } |
| 695 | } else { // 110x xxxx 10xx xxxx |
| 696 | res[p++] = (char)((b << 6) + buffer[i + 1] + ((0x40 << 6) + 0x80)); |
| 697 | i += 2; |
| 698 | } |
| 699 | } |
| 700 | if (block == tail) |
| 701 | return res; |
| 702 | } |
| 703 | } |
| 704 | |
| 705 | @Override |
| 706 | public @NotNull String toString() { |