|
3 | 3 | import java.io.*; |
4 | 4 | import java.math.BigDecimal; |
5 | 5 | import java.math.BigInteger; |
| 6 | +import java.nio.charset.StandardCharsets; |
6 | 7 |
|
7 | 8 | import com.fasterxml.jackson.core.*; |
8 | 9 | import com.fasterxml.jackson.core.io.CharTypes; |
@@ -659,6 +660,10 @@ public void writeUTF8String(byte[] text, int offset, int len) throws IOException |
659 | 660 | _outputBuffer[_outputTail++] = _quoteChar; |
660 | 661 | } |
661 | 662 |
|
| 663 | + private boolean isSurrogatePair(char ch) { |
| 664 | + return (ch & 0xD800) == 0xD800; |
| 665 | + } |
| 666 | + |
662 | 667 | /* |
663 | 668 | /********************************************************** |
664 | 669 | /* Output method implementations, unprocessed ("raw") |
@@ -1510,7 +1515,14 @@ private final void _writeStringSegment2(final char[] cbuf, int offset, final int |
1510 | 1515 | outputBuffer[outputPtr++] = (byte) (0xc0 | (ch >> 6)); |
1511 | 1516 | outputBuffer[outputPtr++] = (byte) (0x80 | (ch & 0x3f)); |
1512 | 1517 | } else { |
1513 | | - outputPtr = _outputMultiByteChar(ch, outputPtr); |
| 1518 | + // multibyte character |
| 1519 | + if (isSurrogatePair((char) ch) && offset < end) { |
| 1520 | + char highSurrogate = (char) ch; |
| 1521 | + char lowSurrogate = cbuf[offset++]; |
| 1522 | + outputPtr = _outputSurrogatePair(highSurrogate, lowSurrogate, outputPtr); |
| 1523 | + } else { |
| 1524 | + outputPtr = _outputMultiByteChar(ch, outputPtr); |
| 1525 | + } |
1514 | 1526 | } |
1515 | 1527 | } |
1516 | 1528 | _outputTail = outputPtr; |
@@ -1548,7 +1560,14 @@ private final void _writeStringSegment2(final String text, int offset, final int |
1548 | 1560 | outputBuffer[outputPtr++] = (byte) (0xc0 | (ch >> 6)); |
1549 | 1561 | outputBuffer[outputPtr++] = (byte) (0x80 | (ch & 0x3f)); |
1550 | 1562 | } else { |
1551 | | - outputPtr = _outputMultiByteChar(ch, outputPtr); |
| 1563 | + // multibyte character |
| 1564 | + if (isSurrogatePair((char) ch) && offset < end) { |
| 1565 | + char highSurrogate = (char) ch; |
| 1566 | + char lowSurrogate = text.charAt(offset++); |
| 1567 | + outputPtr = _outputSurrogatePair(highSurrogate, lowSurrogate, outputPtr); |
| 1568 | + } else { |
| 1569 | + outputPtr = _outputMultiByteChar(ch, outputPtr); |
| 1570 | + } |
1552 | 1571 | } |
1553 | 1572 | } |
1554 | 1573 | _outputTail = outputPtr; |
@@ -2133,6 +2152,13 @@ protected final void _outputSurrogates(int surr1, int surr2) throws IOException |
2133 | 2152 | bbuf[_outputTail++] = (byte) (0x80 | (c & 0x3f)); |
2134 | 2153 | } |
2135 | 2154 |
|
| 2155 | + private int _outputSurrogatePair(char highSurrogate, char lowSurrogate, int outputPtr) { |
| 2156 | + String s = String.valueOf(highSurrogate) + lowSurrogate; |
| 2157 | + byte[] bytes = s.getBytes(StandardCharsets.UTF_8); |
| 2158 | + System.arraycopy(bytes, 0, _outputBuffer, outputPtr, bytes.length); |
| 2159 | + return outputPtr + bytes.length; |
| 2160 | + } |
| 2161 | + |
2136 | 2162 | /** |
2137 | 2163 | * |
2138 | 2164 | * @param ch |
|
0 commit comments