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.client5.http.ssl;
29
30 import java.util.ArrayList;
31 import java.util.BitSet;
32 import java.util.List;
33
34 import org.apache.hc.core5.http.NameValuePair;
35 import org.apache.hc.core5.http.message.BasicNameValuePair;
36 import org.apache.hc.core5.http.message.ParserCursor;
37 import org.apache.hc.core5.http.message.TokenParser;
38 import org.apache.hc.core5.util.CharArrayBuffer;
39
40 final class DistinguishedNameParser {
41
42 public final static DistinguishedNameParserhedNameParser.html#DistinguishedNameParser">DistinguishedNameParser INSTANCE = new DistinguishedNameParser();
43
44 private static final BitSet EQUAL_OR_COMMA_OR_PLUS = TokenParser.INIT_BITSET('=', ',', '+');
45 private static final BitSet COMMA_OR_PLUS = TokenParser.INIT_BITSET(',', '+');
46
47 private final TokenParser tokenParser;
48
49 DistinguishedNameParser() {
50 this.tokenParser = new InternalTokenParser();
51 }
52
53 private String parseToken(final CharArrayBuffer buf, final ParserCursor cursor, final BitSet delimiters) {
54 return tokenParser.parseToken(buf, cursor, delimiters);
55 }
56
57 private String parseValue(final CharArrayBuffer buf, final ParserCursor cursor, final BitSet delimiters) {
58 return tokenParser.parseValue(buf, cursor, delimiters);
59 }
60
61 private NameValuePair parseParameter(final CharArrayBuffer buf, final ParserCursor cursor) {
62 final String name = parseToken(buf, cursor, EQUAL_OR_COMMA_OR_PLUS);
63 if (cursor.atEnd()) {
64 return new BasicNameValuePair(name, null);
65 }
66 final int delim = buf.charAt(cursor.getPos());
67 cursor.updatePos(cursor.getPos() + 1);
68 if (delim == ',') {
69 return new BasicNameValuePair(name, null);
70 }
71 final String value = parseValue(buf, cursor, COMMA_OR_PLUS);
72 if (!cursor.atEnd()) {
73 cursor.updatePos(cursor.getPos() + 1);
74 }
75 return new BasicNameValuePair(name, value);
76 }
77
78 List<NameValuePair> parse(final CharArrayBuffer buf, final ParserCursor cursor) {
79 final List<NameValuePair> params = new ArrayList<>();
80 tokenParser.skipWhiteSpace(buf, cursor);
81 while (!cursor.atEnd()) {
82 final NameValuePair param = parseParameter(buf, cursor);
83 params.add(param);
84 }
85 return params;
86 }
87
88 List<NameValuePair> parse(final String s) {
89 if (s == null) {
90 return null;
91 }
92 final CharArrayBuffer buffer = new CharArrayBuffer(s.length());
93 buffer.append(s);
94 final ParserCursor cursor = new ParserCursor(0, s.length());
95 return parse(buffer, cursor);
96 }
97
98 static class InternalTokenParser extends TokenParser {
99
100 @Override
101 public void copyUnquotedContent(
102 final CharSequence buf,
103 final ParserCursor cursor,
104 final BitSet delimiters,
105 final StringBuilder dst) {
106 int pos = cursor.getPos();
107 final int indexFrom = cursor.getPos();
108 final int indexTo = cursor.getUpperBound();
109 boolean escaped = false;
110 for (int i = indexFrom; i < indexTo; i++, pos++) {
111 final char current = buf.charAt(i);
112 if (escaped) {
113 dst.append(current);
114 escaped = false;
115 } else {
116 if ((delimiters != null && delimiters.get(current))
117 || TokenParser.isWhitespace(current) || current == '\"') {
118 break;
119 } else if (current == '\\') {
120 escaped = true;
121 } else {
122 dst.append(current);
123 }
124 }
125 }
126 cursor.updatePos(pos);
127 }
128 }
129
130 }
131