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 java.util.ArrayList;
31 import java.util.List;
32
33 import org.apache.http.HeaderElement;
34 import org.apache.http.NameValuePair;
35 import org.apache.http.ParseException;
36 import org.apache.http.annotation.Immutable;
37 import org.apache.http.protocol.HTTP;
38 import org.apache.http.util.Args;
39 import org.apache.http.util.CharArrayBuffer;
40
41
42
43
44
45
46
47
48 @Immutable
49 public class BasicHeaderValueParser implements HeaderValueParser {
50
51
52
53
54
55
56
57
58
59 @Deprecated
60 public final static
61 BasicHeaderValueParser DEFAULT = new BasicHeaderValueParser();
62
63 public final static BasicHeaderValueParser INSTANCE = new BasicHeaderValueParser();
64
65 private final static char PARAM_DELIMITER = ';';
66 private final static char ELEM_DELIMITER = ',';
67 private final static char[] ALL_DELIMITERS = new char[] {
68 PARAM_DELIMITER,
69 ELEM_DELIMITER
70 };
71
72 public BasicHeaderValueParser() {
73 super();
74 }
75
76
77
78
79
80
81
82
83
84 public final static
85 HeaderElement[] parseElements(final String value,
86 HeaderValueParser parser) throws ParseException {
87 Args.notNull(value, "Value");
88 if (parser == null) {
89 parser = BasicHeaderValueParser.INSTANCE;
90 }
91
92 final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
93 buffer.append(value);
94 final ParserCursor cursor = new ParserCursor(0, value.length());
95 return parser.parseElements(buffer, cursor);
96 }
97
98
99
100 public HeaderElement[] parseElements(final CharArrayBuffer buffer,
101 final ParserCursor cursor) {
102 Args.notNull(buffer, "Char array buffer");
103 Args.notNull(cursor, "Parser cursor");
104 final List<HeaderElement> elements = new ArrayList<HeaderElement>();
105 while (!cursor.atEnd()) {
106 final HeaderElement element = parseHeaderElement(buffer, cursor);
107 if (!(element.getName().length() == 0 && element.getValue() == null)) {
108 elements.add(element);
109 }
110 }
111 return elements.toArray(new HeaderElement[elements.size()]);
112 }
113
114
115
116
117
118
119
120
121
122
123 public final static
124 HeaderElement parseHeaderElement(final String value,
125 HeaderValueParser parser) throws ParseException {
126 Args.notNull(value, "Value");
127 if (parser == null) {
128 parser = BasicHeaderValueParser.INSTANCE;
129 }
130
131 final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
132 buffer.append(value);
133 final ParserCursor cursor = new ParserCursor(0, value.length());
134 return parser.parseHeaderElement(buffer, cursor);
135 }
136
137
138
139 public HeaderElement parseHeaderElement(final CharArrayBuffer buffer,
140 final ParserCursor cursor) {
141 Args.notNull(buffer, "Char array buffer");
142 Args.notNull(cursor, "Parser cursor");
143 final NameValuePair nvp = parseNameValuePair(buffer, cursor);
144 NameValuePair[] params = null;
145 if (!cursor.atEnd()) {
146 final char ch = buffer.charAt(cursor.getPos() - 1);
147 if (ch != ELEM_DELIMITER) {
148 params = parseParameters(buffer, cursor);
149 }
150 }
151 return createHeaderElement(nvp.getName(), nvp.getValue(), params);
152 }
153
154
155
156
157
158
159
160
161 protected HeaderElement createHeaderElement(
162 final String name,
163 final String value,
164 final NameValuePair[] params) {
165 return new BasicHeaderElement(name, value, params);
166 }
167
168
169
170
171
172
173
174
175
176
177 public final static
178 NameValuePair[] parseParameters(final String value,
179 HeaderValueParser parser) throws ParseException {
180 Args.notNull(value, "Value");
181 if (parser == null) {
182 parser = BasicHeaderValueParser.INSTANCE;
183 }
184
185 final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
186 buffer.append(value);
187 final ParserCursor cursor = new ParserCursor(0, value.length());
188 return parser.parseParameters(buffer, cursor);
189 }
190
191
192
193
194 public NameValuePair[] parseParameters(final CharArrayBuffer buffer,
195 final ParserCursor cursor) {
196 Args.notNull(buffer, "Char array buffer");
197 Args.notNull(cursor, "Parser cursor");
198 int pos = cursor.getPos();
199 final int indexTo = cursor.getUpperBound();
200
201 while (pos < indexTo) {
202 final char ch = buffer.charAt(pos);
203 if (HTTP.isWhitespace(ch)) {
204 pos++;
205 } else {
206 break;
207 }
208 }
209 cursor.updatePos(pos);
210 if (cursor.atEnd()) {
211 return new NameValuePair[] {};
212 }
213
214 final List<NameValuePair> params = new ArrayList<NameValuePair>();
215 while (!cursor.atEnd()) {
216 final NameValuePair param = parseNameValuePair(buffer, cursor);
217 params.add(param);
218 final char ch = buffer.charAt(cursor.getPos() - 1);
219 if (ch == ELEM_DELIMITER) {
220 break;
221 }
222 }
223
224 return params.toArray(new NameValuePair[params.size()]);
225 }
226
227
228
229
230
231
232
233
234
235 public final static
236 NameValuePair parseNameValuePair(final String value,
237 HeaderValueParser parser) throws ParseException {
238 Args.notNull(value, "Value");
239 if (parser == null) {
240 parser = BasicHeaderValueParser.INSTANCE;
241 }
242
243 final CharArrayBuffer buffer = new CharArrayBuffer(value.length());
244 buffer.append(value);
245 final ParserCursor cursor = new ParserCursor(0, value.length());
246 return parser.parseNameValuePair(buffer, cursor);
247 }
248
249
250
251 public NameValuePair parseNameValuePair(final CharArrayBuffer buffer,
252 final ParserCursor cursor) {
253 return parseNameValuePair(buffer, cursor, ALL_DELIMITERS);
254 }
255
256 private static boolean isOneOf(final char ch, final char[] chs) {
257 if (chs != null) {
258 for (final char ch2 : chs) {
259 if (ch == ch2) {
260 return true;
261 }
262 }
263 }
264 return false;
265 }
266
267 public NameValuePair parseNameValuePair(final CharArrayBuffer buffer,
268 final ParserCursor cursor,
269 final char[] delimiters) {
270 Args.notNull(buffer, "Char array buffer");
271 Args.notNull(cursor, "Parser cursor");
272
273 boolean terminated = false;
274
275 int pos = cursor.getPos();
276 final int indexFrom = cursor.getPos();
277 final int indexTo = cursor.getUpperBound();
278
279
280 String name = null;
281 while (pos < indexTo) {
282 final char ch = buffer.charAt(pos);
283 if (ch == '=') {
284 break;
285 }
286 if (isOneOf(ch, delimiters)) {
287 terminated = true;
288 break;
289 }
290 pos++;
291 }
292
293 if (pos == indexTo) {
294 terminated = true;
295 name = buffer.substringTrimmed(indexFrom, indexTo);
296 } else {
297 name = buffer.substringTrimmed(indexFrom, pos);
298 pos++;
299 }
300
301 if (terminated) {
302 cursor.updatePos(pos);
303 return createNameValuePair(name, null);
304 }
305
306
307 String value = null;
308 int i1 = pos;
309
310 boolean qouted = false;
311 boolean escaped = false;
312 while (pos < indexTo) {
313 final char ch = buffer.charAt(pos);
314 if (ch == '"' && !escaped) {
315 qouted = !qouted;
316 }
317 if (!qouted && !escaped && isOneOf(ch, delimiters)) {
318 terminated = true;
319 break;
320 }
321 if (escaped) {
322 escaped = false;
323 } else {
324 escaped = qouted && ch == '\\';
325 }
326 pos++;
327 }
328
329 int i2 = pos;
330
331 while (i1 < i2 && (HTTP.isWhitespace(buffer.charAt(i1)))) {
332 i1++;
333 }
334
335 while ((i2 > i1) && (HTTP.isWhitespace(buffer.charAt(i2 - 1)))) {
336 i2--;
337 }
338
339 if (((i2 - i1) >= 2)
340 && (buffer.charAt(i1) == '"')
341 && (buffer.charAt(i2 - 1) == '"')) {
342 i1++;
343 i2--;
344 }
345 value = buffer.substring(i1, i2);
346 if (terminated) {
347 pos++;
348 }
349 cursor.updatePos(pos);
350 return createNameValuePair(name, value);
351 }
352
353
354
355
356
357
358
359
360
361
362 protected NameValuePair createNameValuePair(final String name, final String value) {
363 return new BasicNameValuePair(name, value);
364 }
365
366 }
367