Private helper to wrap a CharEscaper as a UnicodeEscaper.
(final CharEscaper escaper)
| 241 | /** Private helper to wrap a CharEscaper as a UnicodeEscaper. */ |
| 242 | |
| 243 | private static UnicodeEscaper wrap(final CharEscaper escaper) { |
| 244 | return new UnicodeEscaper() { |
| 245 | @Override |
| 246 | protected char[] escape(int cp) { |
| 247 | // If a code point maps to a single character, just escape that. |
| 248 | if (cp < Character.MIN_SUPPLEMENTARY_CODE_POINT) { |
| 249 | return escaper.escape((char) cp); |
| 250 | } |
| 251 | // Convert the code point to a surrogate pair and escape them both. |
| 252 | // Note: This code path is horribly slow and typically allocates 4 new |
| 253 | // char[] each time it is invoked. However this avoids any |
| 254 | // synchronization issues and makes the escaper thread safe. |
| 255 | char[] surrogateChars = new char[2]; |
| 256 | Character.toChars(cp, surrogateChars, 0); |
| 257 | char[] hiChars = escaper.escape(surrogateChars[0]); |
| 258 | char[] loChars = escaper.escape(surrogateChars[1]); |
| 259 | |
| 260 | // If either hiChars or lowChars are non-null, the CharEscaper is trying |
| 261 | // to escape the characters of a surrogate pair separately. This is |
| 262 | // uncommon and applies only to escapers that assume UCS-2 rather than |
| 263 | // UTF-16. See: http://en.wikipedia.org/wiki/UTF-16/UCS-2 |
| 264 | if (hiChars == null && loChars == null) { |
| 265 | // We expect this to be the common code path for most escapers. |
| 266 | return null; |
| 267 | } |
| 268 | // Combine the characters and/or escaped sequences into a single array. |
| 269 | int hiCount = hiChars != null ? hiChars.length : 1; |
| 270 | int loCount = loChars != null ? loChars.length : 1; |
| 271 | char[] output = new char[hiCount + loCount]; |
| 272 | if (hiChars != null) { |
| 273 | // TODO: Is this faster than System.arraycopy() for small arrays? |
| 274 | for (int n = 0; n < hiChars.length; ++n) { |
| 275 | output[n] = hiChars[n]; |
| 276 | } |
| 277 | } else { |
| 278 | output[0] = surrogateChars[0]; |
| 279 | } |
| 280 | if (loChars != null) { |
| 281 | for (int n = 0; n < loChars.length; ++n) { |
| 282 | output[hiCount + n] = loChars[n]; |
| 283 | } |
| 284 | } else { |
| 285 | output[hiCount] = surrogateChars[1]; |
| 286 | } |
| 287 | return output; |
| 288 | } |
| 289 | }; |
| 290 | } |
| 291 | } |
no outgoing calls