1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.codec;
17
18 import java.util.AbstractCollection;
19 import java.util.AbstractList;
20 import java.util.Collection;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map.Entry;
24 import java.util.Set;
25
26 import static java.util.Objects.requireNonNull;
27
28
29
30
31 public final class HeadersUtils {
32
33 private HeadersUtils() {
34 }
35
36
37
38
39
40
41 public static <K, V> List<String> getAllAsString(Headers<K, V, ?> headers, K name) {
42 final List<V> allNames = headers.getAll(name);
43 return new AbstractList<>() {
44 @Override
45 public String get(int index) {
46 V value = allNames.get(index);
47 return value != null ? value.toString() : null;
48 }
49
50 @Override
51 public int size() {
52 return allNames.size();
53 }
54 };
55 }
56
57
58
59
60
61
62
63 public static <K, V> String getAsString(Headers<K, V, ?> headers, K name) {
64 V orig = headers.get(name);
65 return orig != null ? orig.toString() : null;
66 }
67
68
69
70
71 public static Iterator<Entry<String, String>> iteratorAsString(
72 Iterable<Entry<CharSequence, CharSequence>> headers) {
73 return new StringEntryIterator(headers.iterator());
74 }
75
76
77
78
79
80
81
82
83 public static <K, V> String toString(Class<?> headersClass, Iterator<Entry<K, V>> headersIt, int size) {
84 String simpleName = headersClass.getSimpleName();
85 if (size == 0) {
86 return simpleName + "[]";
87 } else {
88
89 StringBuilder sb = new StringBuilder(simpleName.length() + 2 + size * 20)
90 .append(simpleName)
91 .append('[');
92 while (headersIt.hasNext()) {
93 Entry<?, ?> header = headersIt.next();
94 sb.append(header.getKey()).append(": ").append(header.getValue()).append(", ");
95 }
96 sb.setLength(sb.length() - 2);
97 return sb.append(']').toString();
98 }
99 }
100
101
102
103
104
105
106 public static Set<String> namesAsString(Headers<CharSequence, CharSequence, ?> headers) {
107 return new CharSequenceDelegatingStringSet(headers.names());
108 }
109
110 private static final class StringEntryIterator implements Iterator<Entry<String, String>> {
111 private final Iterator<Entry<CharSequence, CharSequence>> iter;
112
113 StringEntryIterator(Iterator<Entry<CharSequence, CharSequence>> iter) {
114 this.iter = iter;
115 }
116
117 @Override
118 public boolean hasNext() {
119 return iter.hasNext();
120 }
121
122 @Override
123 public Entry<String, String> next() {
124 return new StringEntry(iter.next());
125 }
126
127 @Override
128 public void remove() {
129 iter.remove();
130 }
131 }
132
133 private static final class StringEntry implements Entry<String, String> {
134 private final Entry<CharSequence, CharSequence> entry;
135 private String name;
136 private String value;
137
138 StringEntry(Entry<CharSequence, CharSequence> entry) {
139 this.entry = entry;
140 }
141
142 @Override
143 public String getKey() {
144 if (name == null) {
145 name = entry.getKey().toString();
146 }
147 return name;
148 }
149
150 @Override
151 public String getValue() {
152 if (value == null && entry.getValue() != null) {
153 value = entry.getValue().toString();
154 }
155 return value;
156 }
157
158 @Override
159 public String setValue(String value) {
160 String old = getValue();
161 entry.setValue(value);
162 return old;
163 }
164
165 @Override
166 public String toString() {
167 return entry.toString();
168 }
169 }
170
171 private static final class StringIterator<T> implements Iterator<String> {
172 private final Iterator<T> iter;
173
174 StringIterator(Iterator<T> iter) {
175 this.iter = iter;
176 }
177
178 @Override
179 public boolean hasNext() {
180 return iter.hasNext();
181 }
182
183 @Override
184 public String next() {
185 T next = iter.next();
186 return next != null ? next.toString() : null;
187 }
188
189 @Override
190 public void remove() {
191 iter.remove();
192 }
193 }
194
195 private static final class CharSequenceDelegatingStringSet extends DelegatingStringSet<CharSequence> {
196 CharSequenceDelegatingStringSet(Set<CharSequence> allNames) {
197 super(allNames);
198 }
199
200 @Override
201 public boolean add(String e) {
202 return allNames.add(e);
203 }
204
205 @Override
206 public boolean addAll(Collection<? extends String> c) {
207 return allNames.addAll(c);
208 }
209 }
210
211 private abstract static class DelegatingStringSet<T> extends AbstractCollection<String> implements Set<String> {
212 protected final Set<T> allNames;
213
214 DelegatingStringSet(Set<T> allNames) {
215 this.allNames = requireNonNull(allNames, "allNames");
216 }
217
218 @Override
219 public int size() {
220 return allNames.size();
221 }
222
223 @Override
224 public boolean isEmpty() {
225 return allNames.isEmpty();
226 }
227
228 @Override
229 public boolean contains(Object o) {
230 return allNames.contains(o.toString());
231 }
232
233 @Override
234 public Iterator<String> iterator() {
235 return new StringIterator<>(allNames.iterator());
236 }
237
238 @Override
239 public boolean remove(Object o) {
240 return allNames.remove(o);
241 }
242
243 @Override
244 public void clear() {
245 allNames.clear();
246 }
247 }
248 }