1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.fileupload;
18
19 import java.io.UnsupportedEncodingException;
20 import java.util.HashMap;
21 import java.util.Locale;
22 import java.util.Map;
23
24 import org.apache.commons.fileupload.util.mime.MimeUtility;
25
26
27
28
29
30
31
32
33
34
35
36
37 public class ParameterParser {
38
39
40
41
42 private char[] chars;
43
44
45
46
47 private int pos;
48
49
50
51
52 private int len;
53
54
55
56
57 private int i1;
58
59
60
61
62 private int i2;
63
64
65
66
67 private boolean lowerCaseNames;
68
69
70
71
72 public ParameterParser() {
73 }
74
75
76
77
78
79
80
81
82
83
84 private String getToken(final boolean quoted) {
85
86 while (i1 < i2 && Character.isWhitespace(chars[i1])) {
87 i1++;
88 }
89
90 while (i2 > i1 && Character.isWhitespace(chars[i2 - 1])) {
91 i2--;
92 }
93
94 if (quoted
95 && i2 - i1 >= 2
96 && chars[i1] == '"'
97 && chars[i2 - 1] == '"') {
98 i1++;
99 i2--;
100 }
101 String result = null;
102 if (i2 > i1) {
103 result = new String(chars, i1, i2 - i1);
104 }
105 return result;
106 }
107
108
109
110
111
112
113
114 private boolean hasChar() {
115 return pos < len;
116 }
117
118
119
120
121
122
123
124
125
126 public boolean isLowerCaseNames() {
127 return lowerCaseNames;
128 }
129
130
131
132
133
134
135
136
137
138 private boolean isOneOf(final char ch, final char[] charray) {
139 boolean result = false;
140 for (final char element : charray) {
141 if (ch == element) {
142 result = true;
143 break;
144 }
145 }
146 return result;
147 }
148
149
150
151
152
153
154
155
156
157
158 public Map<String, String> parse(final char[] charArray, final char separator) {
159 if (charArray == null) {
160 return new HashMap<>();
161 }
162 return parse(charArray, 0, charArray.length, separator);
163 }
164
165
166
167
168
169
170
171
172
173
174 public Map<String, String> parse(final char[] charArray, final int offset, final int length, final char separator) {
175 if (charArray == null) {
176 return new HashMap<>();
177 }
178 final HashMap<String, String> params = new HashMap<>();
179 chars = charArray.clone();
180 pos = offset;
181 len = length;
182 while (hasChar()) {
183 String paramName = parseToken(new char[] { '=', separator });
184 String paramValue = null;
185 if (hasChar() && charArray[pos] == '=') {
186 pos++;
187 paramValue = parseQuotedToken(new char[] { separator });
188 if (paramValue != null) {
189 try {
190 paramValue = RFC2231Utility.hasEncodedValue(paramName) ? RFC2231Utility.decodeText(paramValue) : MimeUtility.decodeText(paramValue);
191 } catch (final UnsupportedEncodingException e) {
192
193 }
194 }
195 }
196 if (hasChar() && charArray[pos] == separator) {
197 pos++;
198 }
199 if (paramName != null && !paramName.isEmpty()) {
200 paramName = RFC2231Utility.stripDelimiter(paramName);
201 if (lowerCaseNames) {
202 paramName = paramName.toLowerCase(Locale.ROOT);
203 }
204 params.put(paramName, paramValue);
205 }
206 }
207 return params;
208 }
209
210
211
212
213
214
215
216
217
218 public Map<String, String> parse(final String str, final char separator) {
219 if (str == null) {
220 return new HashMap<>();
221 }
222 return parse(str.toCharArray(), separator);
223 }
224
225
226
227
228
229
230
231
232
233
234 public Map<String, String> parse(final String str, final char[] separators) {
235 if (separators == null || separators.length == 0) {
236 return new HashMap<>();
237 }
238 char separator = separators[0];
239 if (str != null) {
240 int idx = str.length();
241 for (final char separator2 : separators) {
242 final int tmp = str.indexOf(separator2);
243 if (tmp != -1 && tmp < idx) {
244 idx = tmp;
245 separator = separator2;
246 }
247 }
248 }
249 return parse(str, separator);
250 }
251
252
253
254
255
256
257
258
259
260
261
262 private String parseQuotedToken(final char[] terminators) {
263 char ch;
264 i1 = pos;
265 i2 = pos;
266 boolean quoted = false;
267 boolean charEscaped = false;
268 while (hasChar()) {
269 ch = chars[pos];
270 if (!quoted && isOneOf(ch, terminators)) {
271 break;
272 }
273 if (!charEscaped && ch == '"') {
274 quoted = !quoted;
275 }
276 charEscaped = !charEscaped && ch == '\\';
277 i2++;
278 pos++;
279
280 }
281 return getToken(true);
282 }
283
284
285
286
287
288
289
290
291
292
293 private String parseToken(final char[] terminators) {
294 char ch;
295 i1 = pos;
296 i2 = pos;
297 while (hasChar()) {
298 ch = chars[pos];
299 if (isOneOf(ch, terminators)) {
300 break;
301 }
302 i2++;
303 pos++;
304 }
305 return getToken(false);
306 }
307
308
309
310
311
312
313
314
315
316 public void setLowerCaseNames(final boolean b) {
317 lowerCaseNames = b;
318 }
319
320 }