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.hc.core5.http.message;
29
30 import java.util.ArrayList;
31 import java.util.BitSet;
32 import java.util.List;
33
34 import org.apache.hc.core5.annotation.Contract;
35 import org.apache.hc.core5.annotation.ThreadingBehavior;
36 import org.apache.hc.core5.http.HeaderElement;
37 import org.apache.hc.core5.http.NameValuePair;
38 import org.apache.hc.core5.util.Args;
39
40
41
42
43
44
45 @Contract(threading = ThreadingBehavior.IMMUTABLE)
46 public class BasicHeaderValueParser implements HeaderValueParser {
47
48 public final static BasicHeaderValueParseraderValueParser.html#BasicHeaderValueParser">BasicHeaderValueParser INSTANCE = new BasicHeaderValueParser();
49
50 private final static char PARAM_DELIMITER = ';';
51 private final static char ELEM_DELIMITER = ',';
52
53
54
55 private static final BitSet TOKEN_DELIMS = TokenParser.INIT_BITSET('=', PARAM_DELIMITER, ELEM_DELIMITER);
56 private static final BitSet VALUE_DELIMS = TokenParser.INIT_BITSET(PARAM_DELIMITER, ELEM_DELIMITER);
57
58 private final TokenParser tokenParser;
59
60 public BasicHeaderValueParser() {
61 this.tokenParser = TokenParser.INSTANCE;
62 }
63
64 @Override
65 public HeaderElement[] parseElements(final CharSequence buffer, final ParserCursor cursor) {
66 Args.notNull(buffer, "Char sequence");
67 Args.notNull(cursor, "Parser cursor");
68 final List<HeaderElement> elements = new ArrayList<>();
69 while (!cursor.atEnd()) {
70 final HeaderElement element = parseHeaderElement(buffer, cursor);
71 if (!(element.getName().isEmpty() && element.getValue() == null)) {
72 elements.add(element);
73 }
74 }
75 return elements.toArray(new HeaderElement[elements.size()]);
76 }
77
78 @Override
79 public HeaderElement parseHeaderElement(final CharSequence buffer, final ParserCursor cursor) {
80 Args.notNull(buffer, "Char sequence");
81 Args.notNull(cursor, "Parser cursor");
82 final NameValuePair nvp = parseNameValuePair(buffer, cursor);
83 NameValuePair[] params = null;
84 if (!cursor.atEnd()) {
85 final char ch = buffer.charAt(cursor.getPos() - 1);
86 if (ch != ELEM_DELIMITER) {
87 params = parseParameters(buffer, cursor);
88 }
89 }
90 return new BasicHeaderElement(nvp.getName(), nvp.getValue(), params);
91 }
92
93 @Override
94 public NameValuePair[] parseParameters(final CharSequence buffer, final ParserCursor cursor) {
95 Args.notNull(buffer, "Char sequence");
96 Args.notNull(cursor, "Parser cursor");
97 tokenParser.skipWhiteSpace(buffer, cursor);
98 final List<NameValuePair> params = new ArrayList<>();
99 while (!cursor.atEnd()) {
100 final NameValuePair param = parseNameValuePair(buffer, cursor);
101 params.add(param);
102 final char ch = buffer.charAt(cursor.getPos() - 1);
103 if (ch == ELEM_DELIMITER) {
104 break;
105 }
106 }
107 return params.toArray(new NameValuePair[params.size()]);
108 }
109
110 @Override
111 public NameValuePair parseNameValuePair(final CharSequence buffer, final ParserCursor cursor) {
112 Args.notNull(buffer, "Char sequence");
113 Args.notNull(cursor, "Parser cursor");
114
115 final String name = tokenParser.parseToken(buffer, cursor, TOKEN_DELIMS);
116 if (cursor.atEnd()) {
117 return new BasicNameValuePair(name, null);
118 }
119 final int delim = buffer.charAt(cursor.getPos());
120 cursor.updatePos(cursor.getPos() + 1);
121 if (delim != '=') {
122 return new BasicNameValuePair(name, null);
123 }
124 final String value = tokenParser.parseValue(buffer, cursor, VALUE_DELIMS);
125 if (!cursor.atEnd()) {
126 cursor.updatePos(cursor.getPos() + 1);
127 }
128 return new BasicNameValuePair(name, value);
129 }
130
131 }
132