1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.util;
18
19 import com.fasterxml.jackson.core.io.CharTypes;
20
21
22
23
24 public final class JsonUtils {
25
26 private final static char[] HC = CharTypes.copyHexChars();
27
28
29
30
31 private final static ThreadLocal<char[]> _qbufLocal = new ThreadLocal<>();
32
33 private static char[] getQBuf() {
34 char[] _qbuf = _qbufLocal.get();
35 if (_qbuf == null) {
36 _qbuf = new char[6];
37 _qbuf[0] = '\\';
38 _qbuf[2] = '0';
39 _qbuf[3] = '0';
40
41 _qbufLocal.set(_qbuf);
42 }
43 return _qbuf;
44 }
45
46
47
48
49 public static void quoteAsString(final CharSequence input, final StringBuilder output) {
50 final char[] qbuf = getQBuf();
51 final int[] escCodes = CharTypes.get7BitOutputEscapes();
52 final int escCodeCount = escCodes.length;
53 int inPtr = 0;
54 final int inputLen = input.length();
55
56 outer:
57 while (inPtr < inputLen) {
58 tight_loop:
59 while (true) {
60 final char c = input.charAt(inPtr);
61 if (c < escCodeCount && escCodes[c] != 0) {
62 break tight_loop;
63 }
64 output.append(c);
65 if (++inPtr >= inputLen) {
66 break outer;
67 }
68 }
69
70 final char d = input.charAt(inPtr++);
71 final int escCode = escCodes[d];
72 final int length = (escCode < 0)
73 ? _appendNumeric(d, qbuf)
74 : _appendNamed(escCode, qbuf);
75
76 output.append(qbuf, 0, length);
77 }
78 }
79
80 private static int _appendNumeric(final int value, final char[] qbuf) {
81 qbuf[1] = 'u';
82
83 qbuf[4] = HC[value >> 4];
84 qbuf[5] = HC[value & 0xF];
85 return 6;
86 }
87
88 private static int _appendNamed(final int esc, final char[] qbuf) {
89 qbuf[1] = (char) esc;
90 return 2;
91 }
92
93 }