1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.message;
29
30 import org.apache.http.HeaderElement;
31 import org.apache.http.NameValuePair;
32 import org.apache.http.annotation.ThreadingBehavior;
33 import org.apache.http.annotation.Contract;
34 import org.apache.http.util.Args;
35 import org.apache.http.util.CharArrayBuffer;
36
37
38
39
40
41
42
43
44 @Contract(threading = ThreadingBehavior.IMMUTABLE)
45 public class BasicHeaderValueFormatter implements HeaderValueFormatter {
46
47
48
49
50
51
52
53
54
55 @Deprecated
56 public final static BasicHeaderValueFormatterr.html#BasicHeaderValueFormatter">BasicHeaderValueFormatter DEFAULT = new BasicHeaderValueFormatter();
57
58 public final static BasicHeaderValueFormatter.html#BasicHeaderValueFormatter">BasicHeaderValueFormatter INSTANCE = new BasicHeaderValueFormatter();
59
60
61
62
63
64
65 public final static String SEPARATORS = " ;,:@()<>\\\"/[]?={}\t";
66
67
68
69
70
71 public final static String UNSAFE_CHARS = "\"\\";
72
73 public BasicHeaderValueFormatter() {
74 super();
75 }
76
77
78
79
80
81
82
83
84
85
86
87
88 public static
89 String formatElements(final HeaderElement[] elems,
90 final boolean quote,
91 final HeaderValueFormatter formatter) {
92 return (formatter != null ? formatter : BasicHeaderValueFormatter.INSTANCE)
93 .formatElements(null, elems, quote).toString();
94 }
95
96
97
98 @Override
99 public CharArrayBufferrArrayBuffer">CharArrayBuffer formatElements(final CharArrayBuffer charBuffer,
100 final HeaderElement[] elems,
101 final boolean quote) {
102 Args.notNull(elems, "Header element array");
103 final int len = estimateElementsLen(elems);
104 CharArrayBuffer buffer = charBuffer;
105 if (buffer == null) {
106 buffer = new CharArrayBuffer(len);
107 } else {
108 buffer.ensureCapacity(len);
109 }
110
111 for (int i=0; i<elems.length; i++) {
112 if (i > 0) {
113 buffer.append(", ");
114 }
115 formatHeaderElement(buffer, elems[i], quote);
116 }
117
118 return buffer;
119 }
120
121
122
123
124
125
126
127
128
129 protected int estimateElementsLen(final HeaderElement[] elems) {
130 if ((elems == null) || (elems.length < 1)) {
131 return 0;
132 }
133
134 int result = (elems.length-1) * 2;
135 for (final HeaderElement elem : elems) {
136 result += estimateHeaderElementLen(elem);
137 }
138
139 return result;
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 public static
156 String formatHeaderElement(final HeaderElement elem,
157 final boolean quote,
158 final HeaderValueFormatter formatter) {
159 return (formatter != null ? formatter : BasicHeaderValueFormatter.INSTANCE)
160 .formatHeaderElement(null, elem, quote).toString();
161 }
162
163
164
165 @Override
166 public CharArrayBufferyBuffer">CharArrayBuffer formatHeaderElement(final CharArrayBuffer charBuffer,
167 final HeaderElement elem,
168 final boolean quote) {
169 Args.notNull(elem, "Header element");
170 final int len = estimateHeaderElementLen(elem);
171 CharArrayBuffer buffer = charBuffer;
172 if (buffer == null) {
173 buffer = new CharArrayBuffer(len);
174 } else {
175 buffer.ensureCapacity(len);
176 }
177
178 buffer.append(elem.getName());
179 final String value = elem.getValue();
180 if (value != null) {
181 buffer.append('=');
182 doFormatValue(buffer, value, quote);
183 }
184
185 final int parcnt = elem.getParameterCount();
186 if (parcnt > 0) {
187 for (int i=0; i<parcnt; i++) {
188 buffer.append("; ");
189 formatNameValuePair(buffer, elem.getParameter(i), quote);
190 }
191 }
192
193 return buffer;
194 }
195
196
197
198
199
200
201
202
203
204 protected int estimateHeaderElementLen(final HeaderElement elem) {
205 if (elem == null) {
206 return 0;
207 }
208
209 int result = elem.getName().length();
210 final String value = elem.getValue();
211 if (value != null) {
212
213 result += 3 + value.length();
214 }
215
216 final int parcnt = elem.getParameterCount();
217 if (parcnt > 0) {
218 for (int i=0; i<parcnt; i++) {
219 result += 2 +
220 estimateNameValuePairLen(elem.getParameter(i));
221 }
222 }
223
224 return result;
225 }
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 public static
242 String formatParameters(final NameValuePair[] nvps,
243 final boolean quote,
244 final HeaderValueFormatter formatter) {
245 return (formatter != null ? formatter : BasicHeaderValueFormatter.INSTANCE)
246 .formatParameters(null, nvps, quote).toString();
247 }
248
249
250
251 @Override
252 public CharArrayBufferrrayBuffer">CharArrayBuffer formatParameters(final CharArrayBuffer charBuffer,
253 final NameValuePair[] nvps,
254 final boolean quote) {
255 Args.notNull(nvps, "Header parameter array");
256 final int len = estimateParametersLen(nvps);
257 CharArrayBuffer buffer = charBuffer;
258 if (buffer == null) {
259 buffer = new CharArrayBuffer(len);
260 } else {
261 buffer.ensureCapacity(len);
262 }
263
264 for (int i = 0; i < nvps.length; i++) {
265 if (i > 0) {
266 buffer.append("; ");
267 }
268 formatNameValuePair(buffer, nvps[i], quote);
269 }
270
271 return buffer;
272 }
273
274
275
276
277
278
279
280
281
282 protected int estimateParametersLen(final NameValuePair[] nvps) {
283 if ((nvps == null) || (nvps.length < 1)) {
284 return 0;
285 }
286
287 int result = (nvps.length-1) * 2;
288 for (final NameValuePair nvp : nvps) {
289 result += estimateNameValuePairLen(nvp);
290 }
291
292 return result;
293 }
294
295
296
297
298
299
300
301
302
303
304
305
306
307 public static
308 String formatNameValuePair(final NameValuePair nvp,
309 final boolean quote,
310 final HeaderValueFormatter formatter) {
311 return (formatter != null ? formatter : BasicHeaderValueFormatter.INSTANCE)
312 .formatNameValuePair(null, nvp, quote).toString();
313 }
314
315
316
317 @Override
318 public CharArrayBufferyBuffer">CharArrayBuffer formatNameValuePair(final CharArrayBuffer charBuffer,
319 final NameValuePair nvp,
320 final boolean quote) {
321 Args.notNull(nvp, "Name / value pair");
322 final int len = estimateNameValuePairLen(nvp);
323 CharArrayBuffer buffer = charBuffer;
324 if (buffer == null) {
325 buffer = new CharArrayBuffer(len);
326 } else {
327 buffer.ensureCapacity(len);
328 }
329
330 buffer.append(nvp.getName());
331 final String value = nvp.getValue();
332 if (value != null) {
333 buffer.append('=');
334 doFormatValue(buffer, value, quote);
335 }
336
337 return buffer;
338 }
339
340
341
342
343
344
345
346
347
348 protected int estimateNameValuePairLen(final NameValuePair nvp) {
349 if (nvp == null) {
350 return 0;
351 }
352
353 int result = nvp.getName().length();
354 final String value = nvp.getValue();
355 if (value != null) {
356
357 result += 3 + value.length();
358 }
359 return result;
360 }
361
362
363
364
365
366
367
368
369
370
371
372
373 protected void doFormatValue(final CharArrayBuffer buffer,
374 final String value,
375 final boolean quote) {
376
377 boolean quoteFlag = quote;
378 if (!quoteFlag) {
379 for (int i = 0; (i < value.length()) && !quoteFlag; i++) {
380 quoteFlag = isSeparator(value.charAt(i));
381 }
382 }
383
384 if (quoteFlag) {
385 buffer.append('"');
386 }
387 for (int i = 0; i < value.length(); i++) {
388 final char ch = value.charAt(i);
389 if (isUnsafe(ch)) {
390 buffer.append('\\');
391 }
392 buffer.append(ch);
393 }
394 if (quoteFlag) {
395 buffer.append('"');
396 }
397 }
398
399
400
401
402
403
404
405
406
407
408 protected boolean isSeparator(final char ch) {
409 return SEPARATORS.indexOf(ch) >= 0;
410 }
411
412
413
414
415
416
417
418
419
420
421 protected boolean isUnsafe(final char ch) {
422 return UNSAFE_CHARS.indexOf(ch) >= 0;
423 }
424
425
426 }