1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.util;
18
19 import java.util.Map.Entry;
20
21 import static java.lang.Character.toLowerCase;
22
23
24
25
26 public final class StringBuilders {
27 private StringBuilders() {
28 }
29
30
31
32
33
34
35
36
37 public static StringBuilder appendDqValue(final StringBuilder sb, final Object value) {
38 return sb.append(Chars.DQUOTE).append(value).append(Chars.DQUOTE);
39 }
40
41
42
43
44
45
46
47
48 public static StringBuilder appendKeyDqValue(final StringBuilder sb, final Entry<String, String> entry) {
49 return appendKeyDqValue(sb, entry.getKey(), entry.getValue());
50 }
51
52
53
54
55
56
57
58
59
60 public static StringBuilder appendKeyDqValue(final StringBuilder sb, final String key, final Object value) {
61 return sb.append(key).append(Chars.EQ).append(Chars.DQUOTE).append(value).append(Chars.DQUOTE);
62 }
63
64
65
66
67
68
69
70
71 public static void appendValue(final StringBuilder stringBuilder, final Object obj) {
72 if (!appendSpecificTypes(stringBuilder, obj)) {
73 stringBuilder.append(obj);
74 }
75 }
76
77 public static boolean appendSpecificTypes(final StringBuilder stringBuilder, final Object obj) {
78 if (obj == null || obj instanceof String) {
79 stringBuilder.append((String) obj);
80 } else if (obj instanceof StringBuilderFormattable) {
81 ((StringBuilderFormattable) obj).formatTo(stringBuilder);
82 } else if (obj instanceof CharSequence) {
83 stringBuilder.append((CharSequence) obj);
84 } else if (obj instanceof Integer) {
85 stringBuilder.append(((Integer) obj).intValue());
86 } else if (obj instanceof Long) {
87 stringBuilder.append(((Long) obj).longValue());
88 } else if (obj instanceof Double) {
89 stringBuilder.append(((Double) obj).doubleValue());
90 } else if (obj instanceof Boolean) {
91 stringBuilder.append(((Boolean) obj).booleanValue());
92 } else if (obj instanceof Character) {
93 stringBuilder.append(((Character) obj).charValue());
94 } else if (obj instanceof Short) {
95 stringBuilder.append(((Short) obj).shortValue());
96 } else if (obj instanceof Float) {
97 stringBuilder.append(((Float) obj).floatValue());
98 } else if (obj instanceof Byte) {
99 stringBuilder.append(((Byte) obj).byteValue());
100 } else {
101 return false;
102 }
103 return true;
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118 public static boolean equals(final CharSequence left, final int leftOffset, final int leftLength,
119 final CharSequence right, final int rightOffset, final int rightLength) {
120 if (leftLength == rightLength) {
121 for (int i = 0; i < rightLength; i++) {
122 if (left.charAt(i + leftOffset) != right.charAt(i + rightOffset)) {
123 return false;
124 }
125 }
126 return true;
127 }
128 return false;
129 }
130
131
132
133
134
135
136
137
138
139
140
141
142
143 public static boolean equalsIgnoreCase(final CharSequence left, final int leftOffset, final int leftLength,
144 final CharSequence right, final int rightOffset, final int rightLength) {
145 if (leftLength == rightLength) {
146 for (int i = 0; i < rightLength; i++) {
147 if (toLowerCase(left.charAt(i + leftOffset)) != toLowerCase(right.charAt(i + rightOffset))) {
148 return false;
149 }
150 }
151 return true;
152 }
153 return false;
154 }
155
156
157
158
159
160
161
162
163
164 public static void trimToMaxSize(final StringBuilder stringBuilder, final int maxSize) {
165 if (stringBuilder != null && stringBuilder.capacity() > maxSize) {
166 stringBuilder.setLength(maxSize);
167 stringBuilder.trimToSize();
168 }
169 }
170
171 public static void escapeJson(final StringBuilder toAppendTo, final int start) {
172 int escapeCount = 0;
173 for (int i = start; i < toAppendTo.length(); i++) {
174 final char c = toAppendTo.charAt(i);
175 switch (c) {
176 case '\b':
177 case '\t':
178 case '\f':
179 case '\n':
180 case '\r':
181 case '"':
182 case '\\':
183 escapeCount++;
184 break;
185 default:
186 if (Character.isISOControl(c)) {
187 escapeCount += 5;
188 }
189 }
190 }
191
192 final int lastChar = toAppendTo.length() - 1;
193 toAppendTo.setLength(toAppendTo.length() + escapeCount);
194 int lastPos = toAppendTo.length() - 1;
195
196 for (int i = lastChar; lastPos > i; i--) {
197 final char c = toAppendTo.charAt(i);
198 switch (c) {
199 case '\b':
200 lastPos = escapeAndDecrement(toAppendTo, lastPos, 'b');
201 break;
202
203 case '\t':
204 lastPos = escapeAndDecrement(toAppendTo, lastPos, 't');
205 break;
206
207 case '\f':
208 lastPos = escapeAndDecrement(toAppendTo, lastPos, 'f');
209 break;
210
211 case '\n':
212 lastPos = escapeAndDecrement(toAppendTo, lastPos, 'n');
213 break;
214
215 case '\r':
216 lastPos = escapeAndDecrement(toAppendTo, lastPos, 'r');
217 break;
218
219 case '"':
220 case '\\':
221 lastPos = escapeAndDecrement(toAppendTo, lastPos, c);
222 break;
223
224 default:
225 if (Character.isISOControl(c)) {
226
227 toAppendTo.setCharAt(lastPos--, Chars.getUpperCaseHex(c & 0xF));
228 toAppendTo.setCharAt(lastPos--, Chars.getUpperCaseHex((c & 0xF0) >> 4));
229 toAppendTo.setCharAt(lastPos--, '0');
230 toAppendTo.setCharAt(lastPos--, '0');
231 toAppendTo.setCharAt(lastPos--, 'u');
232 toAppendTo.setCharAt(lastPos--, '\\');
233 } else {
234 toAppendTo.setCharAt(lastPos, c);
235 lastPos--;
236 }
237 }
238 }
239 }
240
241 private static int escapeAndDecrement(final StringBuilder toAppendTo, int lastPos, final char c) {
242 toAppendTo.setCharAt(lastPos--, c);
243 toAppendTo.setCharAt(lastPos--, '\\');
244 return lastPos;
245 }
246
247 public static void escapeXml(final StringBuilder toAppendTo, final int start) {
248 int escapeCount = 0;
249 for (int i = start; i < toAppendTo.length(); i++) {
250 final char c = toAppendTo.charAt(i);
251 switch (c) {
252 case '&':
253 escapeCount += 4;
254 break;
255 case '<':
256 case '>':
257 escapeCount += 3;
258 break;
259 case '"':
260 case '\'':
261 escapeCount += 5;
262 }
263 }
264
265 final int lastChar = toAppendTo.length() - 1;
266 toAppendTo.setLength(toAppendTo.length() + escapeCount);
267 int lastPos = toAppendTo.length() - 1;
268
269 for (int i = lastChar; lastPos > i; i--) {
270 final char c = toAppendTo.charAt(i);
271 switch (c) {
272 case '&':
273 toAppendTo.setCharAt(lastPos--, ';');
274 toAppendTo.setCharAt(lastPos--, 'p');
275 toAppendTo.setCharAt(lastPos--, 'm');
276 toAppendTo.setCharAt(lastPos--, 'a');
277 toAppendTo.setCharAt(lastPos--, '&');
278 break;
279 case '<':
280 toAppendTo.setCharAt(lastPos--, ';');
281 toAppendTo.setCharAt(lastPos--, 't');
282 toAppendTo.setCharAt(lastPos--, 'l');
283 toAppendTo.setCharAt(lastPos--, '&');
284 break;
285 case '>':
286 toAppendTo.setCharAt(lastPos--, ';');
287 toAppendTo.setCharAt(lastPos--, 't');
288 toAppendTo.setCharAt(lastPos--, 'g');
289 toAppendTo.setCharAt(lastPos--, '&');
290 break;
291 case '"':
292 toAppendTo.setCharAt(lastPos--, ';');
293 toAppendTo.setCharAt(lastPos--, 't');
294 toAppendTo.setCharAt(lastPos--, 'o');
295 toAppendTo.setCharAt(lastPos--, 'u');
296 toAppendTo.setCharAt(lastPos--, 'q');
297 toAppendTo.setCharAt(lastPos--, '&');
298 break;
299 case '\'':
300 toAppendTo.setCharAt(lastPos--, ';');
301 toAppendTo.setCharAt(lastPos--, 's');
302 toAppendTo.setCharAt(lastPos--, 'o');
303 toAppendTo.setCharAt(lastPos--, 'p');
304 toAppendTo.setCharAt(lastPos--, 'a');
305 toAppendTo.setCharAt(lastPos--, '&');
306 break;
307 default:
308 toAppendTo.setCharAt(lastPos--, c);
309 }
310 }
311 }
312 }