@@ -647,11 +647,16 @@ public void writeUTF8String(byte[] text, int offset, int len) throws IOException
647
647
_flushBuffer ();
648
648
}
649
649
_outputBuffer [_outputTail ++] = _quoteChar ;
650
+
651
+ // When writing raw UTF-8 encoded bytes, it is beneficial if the escaping table can directly be indexed into
652
+ // using the byte value.
653
+ final int [] extendedOutputEscapes = _extendOutputEscapesTo8Bits ();
654
+
650
655
// One or multiple segments?
651
656
if (len <= _outputMaxContiguous ) {
652
- _writeUTF8Segment (text , offset , len );
657
+ _writeUTF8Segment (text , offset , len , extendedOutputEscapes );
653
658
} else {
654
- _writeUTF8Segments (text , offset , len );
659
+ _writeUTF8Segments (text , offset , len , extendedOutputEscapes );
655
660
}
656
661
if (_outputTail >= _outputEnd ) {
657
662
_flushBuffer ();
@@ -1846,28 +1851,26 @@ private final int _handleLongCustomEscape(byte[] outputBuffer, int outputPtr, in
1846
1851
* to fit in the output buffer after escaping; as such, we just need to
1847
1852
* chunk writes.
1848
1853
*/
1849
- private final void _writeUTF8Segments (byte [] utf8 , int offset , int totalLen )
1854
+ private final void _writeUTF8Segments (byte [] utf8 , int offset , int totalLen , final int [] extendedOutputEscapes )
1850
1855
throws IOException , JsonGenerationException
1851
1856
{
1852
1857
do {
1853
1858
int len = Math .min (_outputMaxContiguous , totalLen );
1854
- _writeUTF8Segment (utf8 , offset , len );
1859
+ _writeUTF8Segment (utf8 , offset , len , extendedOutputEscapes );
1855
1860
offset += len ;
1856
1861
totalLen -= len ;
1857
1862
} while (totalLen > 0 );
1858
1863
}
1859
1864
1860
- private final void _writeUTF8Segment (byte [] utf8 , final int offset , final int len )
1865
+ private final void _writeUTF8Segment (byte [] utf8 , final int offset , final int len , final int [] extendedOutputEscapes )
1861
1866
throws IOException , JsonGenerationException
1862
1867
{
1863
1868
// fast loop to see if escaping is needed; don't copy, just look
1864
- final int [] escCodes = _outputEscapes ;
1865
-
1866
1869
for (int ptr = offset , end = offset + len ; ptr < end ; ) {
1867
1870
// 28-Feb-2011, tatu: escape codes just cover 7-bit range, so:
1868
- int ch = utf8 [ptr ++];
1869
- if (( ch >= 0 ) && escCodes [ch ] != 0 ) {
1870
- _writeUTF8Segment2 (utf8 , offset , len );
1871
+ int ch = utf8 [ptr ++] & 0xFF ;
1872
+ if (extendedOutputEscapes [ch ] != 0 ) {
1873
+ _writeUTF8Segment2 (utf8 , offset , len , extendedOutputEscapes );
1871
1874
return ;
1872
1875
}
1873
1876
}
@@ -1880,7 +1883,7 @@ private final void _writeUTF8Segment(byte[] utf8, final int offset, final int le
1880
1883
_outputTail += len ;
1881
1884
}
1882
1885
1883
- private final void _writeUTF8Segment2 (final byte [] utf8 , int offset , int len )
1886
+ private final void _writeUTF8Segment2 (final byte [] utf8 , int offset , int len , final int [] extendedOutputEscapes )
1884
1887
throws IOException , JsonGenerationException
1885
1888
{
1886
1889
int outputPtr = _outputTail ;
@@ -1892,17 +1895,16 @@ private final void _writeUTF8Segment2(final byte[] utf8, int offset, int len)
1892
1895
}
1893
1896
1894
1897
final byte [] outputBuffer = _outputBuffer ;
1895
- final int [] escCodes = _outputEscapes ;
1896
1898
len += offset ; // so 'len' becomes 'end'
1897
1899
1898
1900
while (offset < len ) {
1899
1901
byte b = utf8 [offset ++];
1900
- int ch = b ;
1901
- if (ch < 0 || escCodes [ch ] == 0 ) {
1902
+ int ch = b & 0xFF ;
1903
+ int escape = extendedOutputEscapes [ch ];
1904
+ if (escape == 0 ) {
1902
1905
outputBuffer [outputPtr ++] = b ;
1903
1906
continue ;
1904
1907
}
1905
- int escape = escCodes [ch ];
1906
1908
if (escape > 0 ) { // 2-char escape, fine
1907
1909
outputBuffer [outputPtr ++] = BYTE_BACKSLASH ;
1908
1910
outputBuffer [outputPtr ++] = (byte ) escape ;
@@ -1914,6 +1916,18 @@ private final void _writeUTF8Segment2(final byte[] utf8, int offset, int len)
1914
1916
_outputTail = outputPtr ;
1915
1917
}
1916
1918
1919
+ private int [] _extendOutputEscapesTo8Bits () {
1920
+ final int [] escapes = _outputEscapes ;
1921
+ if (escapes .length >= 0xFF ) {
1922
+ return escapes ;
1923
+ }
1924
+
1925
+ final int [] extended = new int [0xFF ];
1926
+ System .arraycopy (escapes , 0 , extended , 0 , escapes .length );
1927
+ _outputEscapes = extended ;
1928
+ return extended ;
1929
+ }
1930
+
1917
1931
/*
1918
1932
/**********************************************************
1919
1933
/* Internal methods, low-level writing, base64 encoded
0 commit comments