1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package io.netty.handler.codec;
16
17 import io.netty.util.HashingStrategy;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
27 import java.util.NoSuchElementException;
28 import java.util.Set;
29 import java.util.function.BiPredicate;
30
31 import static io.netty.util.HashingStrategy.JAVA_HASHER;
32 import static io.netty.util.internal.MathUtil.findNextPositivePowerOfTwo;
33 import static io.netty.util.internal.ObjectUtil.checkNotNull;
34 import static java.lang.Math.max;
35 import static java.lang.Math.min;
36
37
38
39
40
41
42
43
44 public class DefaultHeaders<K, V, T extends Headers<K, V, T>> implements Headers<K, V, T> {
45
46
47
48 static final int HASH_CODE_SEED = 0xc2b2ae35;
49
50 private final HeaderEntry<K, V>[] entries;
51 protected final HeaderEntry<K, V> head;
52
53 private final byte hashMask;
54 private final ValueConverter<V> valueConverter;
55 private final NameValidator<K> nameValidator;
56 private final ValueValidator<V> valueValidator;
57 private final HashingStrategy<K> hashingStrategy;
58 int size;
59
60 public interface NameValidator<K> {
61
62
63
64
65
66 void validateName(K name);
67
68 @SuppressWarnings("rawtypes")
69 NameValidator NOT_NULL = new NameValidator() {
70 @Override
71 public void validateName(Object name) {
72 checkNotNull(name, "name");
73 }
74 };
75 }
76
77 public interface ValueValidator<V> {
78
79
80
81
82
83
84 void validate(V value);
85
86 ValueValidator<?> NO_VALIDATION = new ValueValidator<Object>() {
87 @Override
88 public void validate(Object value) {
89 }
90 };
91 }
92
93 @SuppressWarnings("unchecked")
94 public DefaultHeaders(ValueConverter<V> valueConverter) {
95 this(JAVA_HASHER, valueConverter);
96 }
97
98 @SuppressWarnings("unchecked")
99 public DefaultHeaders(ValueConverter<V> valueConverter, NameValidator<K> nameValidator) {
100 this(JAVA_HASHER, valueConverter, nameValidator);
101 }
102
103 @SuppressWarnings("unchecked")
104 public DefaultHeaders(HashingStrategy<K> nameHashingStrategy, ValueConverter<V> valueConverter) {
105 this(nameHashingStrategy, valueConverter, NameValidator.NOT_NULL);
106 }
107
108 public DefaultHeaders(HashingStrategy<K> nameHashingStrategy,
109 ValueConverter<V> valueConverter, NameValidator<K> nameValidator) {
110 this(nameHashingStrategy, valueConverter, nameValidator, 16);
111 }
112
113
114
115
116
117
118
119
120
121 @SuppressWarnings("unchecked")
122 public DefaultHeaders(HashingStrategy<K> nameHashingStrategy,
123 ValueConverter<V> valueConverter, NameValidator<K> nameValidator, int arraySizeHint) {
124 this(nameHashingStrategy, valueConverter, nameValidator, arraySizeHint,
125 (ValueValidator<V>) ValueValidator.NO_VALIDATION);
126 }
127
128
129
130
131
132
133
134
135
136
137 @SuppressWarnings("unchecked")
138 public DefaultHeaders(HashingStrategy<K> nameHashingStrategy, ValueConverter<V> valueConverter,
139 NameValidator<K> nameValidator, int arraySizeHint, ValueValidator<V> valueValidator) {
140 this.valueConverter = checkNotNull(valueConverter, "valueConverter");
141 this.nameValidator = checkNotNull(nameValidator, "nameValidator");
142 hashingStrategy = checkNotNull(nameHashingStrategy, "nameHashingStrategy");
143 this.valueValidator = checkNotNull(valueValidator, "valueValidator");
144
145
146 entries = new HeaderEntry[findNextPositivePowerOfTwo(max(2, min(arraySizeHint, 128)))];
147 hashMask = (byte) (entries.length - 1);
148 head = new HeaderEntry<K, V>();
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162
163 public boolean containsAny(K name, V predicateArg, BiPredicate<? super V, ? super V> valuePredicate) {
164 checkNotNull(name, "name");
165 checkNotNull(valuePredicate, "valuePredicate");
166 int h = hashingStrategy.hashCode(name);
167 int i = index(h);
168 HeaderEntry<K, V> e = entries[i];
169 while (e != null) {
170 if (e.hash == h && hashingStrategy.equals(name, e.key) && valuePredicate.test(e.value, predicateArg)) {
171 return true;
172 }
173 e = e.next;
174 }
175 return false;
176 }
177
178 @Override
179 public V get(K name) {
180 checkNotNull(name, "name");
181
182 int h = hashingStrategy.hashCode(name);
183 int i = index(h);
184 HeaderEntry<K, V> e = entries[i];
185 V value = null;
186
187 while (e != null) {
188 if (e.hash == h && hashingStrategy.equals(name, e.key)) {
189 value = e.value;
190 }
191
192 e = e.next;
193 }
194 return value;
195 }
196
197 @Override
198 public V get(K name, V defaultValue) {
199 V value = get(name);
200 if (value == null) {
201 return defaultValue;
202 }
203 return value;
204 }
205
206 @Override
207 public V getAndRemove(K name) {
208 int h = hashingStrategy.hashCode(name);
209 return remove0(h, index(h), checkNotNull(name, "name"));
210 }
211
212 @Override
213 public V getAndRemove(K name, V defaultValue) {
214 V value = getAndRemove(name);
215 if (value == null) {
216 return defaultValue;
217 }
218 return value;
219 }
220
221 @Override
222 public List<V> getAll(K name) {
223 checkNotNull(name, "name");
224
225 int h = hashingStrategy.hashCode(name);
226 int i = index(h);
227
228 ArrayList<V> values = null;
229 V value = null;
230 HeaderEntry<K, V> e = entries[i];
231 while (e != null) {
232 if (e.hash == h && hashingStrategy.equals(name, e.key)) {
233 if (value == null) {
234 value = e.getValue();
235 } else {
236 if (values == null) {
237 values = new ArrayList<>(2);
238 values.add(value);
239 }
240 values.add(e.getValue());
241 }
242 }
243 e = e.next;
244 }
245
246 if (values == null) {
247 if (value == null) {
248 return Collections.emptyList();
249 }
250 return Collections.singletonList(value);
251 }
252
253 assert values.size() > 1;
254 Collections.reverse(values);
255
256 return values;
257 }
258
259
260
261
262
263
264 public Iterator<V> valueIterator(K name) {
265 return new ValueIterator(name);
266 }
267
268 @Override
269 public List<V> getAllAndRemove(K name) {
270 List<V> all = getAll(name);
271 remove(name);
272 return all;
273 }
274
275 @Override
276 public boolean contains(K name) {
277 return get(name) != null;
278 }
279
280 @Override
281 public boolean containsObject(K name, Object value) {
282 return contains(name, fromObject(name, value));
283 }
284
285 @Override
286 public boolean containsBoolean(K name, boolean value) {
287 return contains(name, fromBoolean(name, value));
288 }
289
290 @Override
291 public boolean containsByte(K name, byte value) {
292 return contains(name, fromByte(name, value));
293 }
294
295 @Override
296 public boolean containsChar(K name, char value) {
297 return contains(name, fromChar(name, value));
298 }
299
300 @Override
301 public boolean containsShort(K name, short value) {
302 return contains(name, fromShort(name, value));
303 }
304
305 @Override
306 public boolean containsInt(K name, int value) {
307 return contains(name, fromInt(name, value));
308 }
309
310 @Override
311 public boolean containsLong(K name, long value) {
312 return contains(name, fromLong(name, value));
313 }
314
315 @Override
316 public boolean containsFloat(K name, float value) {
317 return contains(name, fromFloat(name, value));
318 }
319
320 @Override
321 public boolean containsDouble(K name, double value) {
322 return contains(name, fromDouble(name, value));
323 }
324
325 @Override
326 public boolean containsTimeMillis(K name, long value) {
327 return contains(name, fromTimeMillis(name, value));
328 }
329
330 @SuppressWarnings("unchecked")
331 @Override
332 public boolean contains(K name, V value) {
333 return contains(name, value, JAVA_HASHER);
334 }
335
336 public final boolean contains(K name, V value, HashingStrategy<? super V> valueHashingStrategy) {
337 checkNotNull(name, "name");
338
339 int h = hashingStrategy.hashCode(name);
340 int i = index(h);
341 HeaderEntry<K, V> e = entries[i];
342 while (e != null) {
343 if (e.hash == h && hashingStrategy.equals(name, e.key) && valueHashingStrategy.equals(value, e.value)) {
344 return true;
345 }
346 e = e.next;
347 }
348 return false;
349 }
350
351 @Override
352 public int size() {
353 return size;
354 }
355
356 @Override
357 public boolean isEmpty() {
358 return head == head.after;
359 }
360
361 @Override
362 public Set<K> names() {
363 if (isEmpty()) {
364 return Collections.emptySet();
365 }
366 Set<K> names = new LinkedHashSet<K>(size());
367 HeaderEntry<K, V> e = head.after;
368 while (e != head) {
369 names.add(e.getKey());
370 e = e.after;
371 }
372 return names;
373 }
374
375 @Override
376 public T add(K name, V value) {
377 validateName(nameValidator, true, name);
378 validateValue(valueValidator, name, value);
379 checkNotNull(value, "value");
380 int h = hashingStrategy.hashCode(name);
381 int i = index(h);
382 add0(h, i, name, value);
383 return thisT();
384 }
385
386 @Override
387 public T add(K name, Iterable<? extends V> values) {
388 validateName(nameValidator, true, name);
389 int h = hashingStrategy.hashCode(name);
390 int i = index(h);
391 for (V v: values) {
392 validateValue(valueValidator, name, v);
393 add0(h, i, name, v);
394 }
395 return thisT();
396 }
397
398 @Override
399 public T add(K name, V... values) {
400 validateName(nameValidator, true, name);
401 int h = hashingStrategy.hashCode(name);
402 int i = index(h);
403 for (V v: values) {
404 validateValue(valueValidator, name, v);
405 add0(h, i, name, v);
406 }
407 return thisT();
408 }
409
410 @Override
411 public T addObject(K name, Object value) {
412 return add(name, fromObject(name, value));
413 }
414
415 @Override
416 public T addObject(K name, Iterable<?> values) {
417 for (Object value : values) {
418 addObject(name, value);
419 }
420 return thisT();
421 }
422
423 @Override
424 public T addObject(K name, Object... values) {
425 for (Object value: values) {
426 addObject(name, value);
427 }
428 return thisT();
429 }
430
431 @Override
432 public T addInt(K name, int value) {
433 return add(name, fromInt(name, value));
434 }
435
436 @Override
437 public T addLong(K name, long value) {
438 return add(name, fromLong(name, value));
439 }
440
441 @Override
442 public T addDouble(K name, double value) {
443 return add(name, fromDouble(name, value));
444 }
445
446 @Override
447 public T addTimeMillis(K name, long value) {
448 return add(name, fromTimeMillis(name, value));
449 }
450
451 @Override
452 public T addChar(K name, char value) {
453 return add(name, fromChar(name, value));
454 }
455
456 @Override
457 public T addBoolean(K name, boolean value) {
458 return add(name, fromBoolean(name, value));
459 }
460
461 @Override
462 public T addFloat(K name, float value) {
463 return add(name, fromFloat(name, value));
464 }
465
466 @Override
467 public T addByte(K name, byte value) {
468 return add(name, fromByte(name, value));
469 }
470
471 @Override
472 public T addShort(K name, short value) {
473 return add(name, fromShort(name, value));
474 }
475
476 @Override
477 public T add(Headers<? extends K, ? extends V, ?> headers) {
478 if (headers == this) {
479 throw new IllegalArgumentException("can't add to itself.");
480 }
481 addImpl(headers);
482 return thisT();
483 }
484
485 protected void addImpl(Headers<? extends K, ? extends V, ?> headers) {
486 if (headers instanceof DefaultHeaders) {
487 @SuppressWarnings("unchecked")
488 final DefaultHeaders<? extends K, ? extends V, T> defaultHeaders =
489 (DefaultHeaders<? extends K, ? extends V, T>) headers;
490 HeaderEntry<? extends K, ? extends V> e = defaultHeaders.head.after;
491 if (defaultHeaders.hashingStrategy == hashingStrategy &&
492 defaultHeaders.nameValidator == nameValidator &&
493 defaultHeaders.valueValidator == valueValidator) {
494
495
496 while (e != defaultHeaders.head) {
497 add0(e.hash, index(e.hash), e.key, e.value);
498 e = e.after;
499 }
500 } else {
501
502 while (e != defaultHeaders.head) {
503 add(e.key, e.value);
504 e = e.after;
505 }
506 }
507 } else {
508
509 for (Entry<? extends K, ? extends V> header : headers) {
510 add(header.getKey(), header.getValue());
511 }
512 }
513 }
514
515 @Override
516 public T set(K name, V value) {
517 validateName(nameValidator, false, name);
518 validateValue(valueValidator, name, value);
519 checkNotNull(value, "value");
520 int h = hashingStrategy.hashCode(name);
521 int i = index(h);
522 remove0(h, i, name);
523 add0(h, i, name, value);
524 return thisT();
525 }
526
527 @Override
528 public T set(K name, Iterable<? extends V> values) {
529 validateName(nameValidator, false, name);
530 checkNotNull(values, "values");
531
532 int h = hashingStrategy.hashCode(name);
533 int i = index(h);
534
535 remove0(h, i, name);
536 for (V v: values) {
537 if (v == null) {
538 break;
539 }
540 validateValue(valueValidator, name, v);
541 add0(h, i, name, v);
542 }
543
544 return thisT();
545 }
546
547 @Override
548 public T set(K name, V... values) {
549 validateName(nameValidator, false, name);
550 checkNotNull(values, "values");
551
552 int h = hashingStrategy.hashCode(name);
553 int i = index(h);
554
555 remove0(h, i, name);
556 for (V v: values) {
557 if (v == null) {
558 break;
559 }
560 validateValue(valueValidator, name, v);
561 add0(h, i, name, v);
562 }
563
564 return thisT();
565 }
566
567 @Override
568 public T setObject(K name, Object value) {
569 V convertedValue = checkNotNull(fromObject(name, value), "convertedValue");
570 return set(name, convertedValue);
571 }
572
573 @Override
574 public T setObject(K name, Iterable<?> values) {
575 validateName(nameValidator, false, name);
576
577 int h = hashingStrategy.hashCode(name);
578 int i = index(h);
579
580 remove0(h, i, name);
581 for (Object v: values) {
582 if (v == null) {
583 break;
584 }
585 V converted = fromObject(name, v);
586 validateValue(valueValidator, name, converted);
587 add0(h, i, name, converted);
588 }
589
590 return thisT();
591 }
592
593 @Override
594 public T setObject(K name, Object... values) {
595 validateName(nameValidator, false, name);
596
597 int h = hashingStrategy.hashCode(name);
598 int i = index(h);
599
600 remove0(h, i, name);
601 for (Object v: values) {
602 if (v == null) {
603 break;
604 }
605 V converted = fromObject(name, v);
606 validateValue(valueValidator, name, converted);
607 add0(h, i, name, converted);
608 }
609
610 return thisT();
611 }
612
613 @Override
614 public T setInt(K name, int value) {
615 return set(name, fromInt(name, value));
616 }
617
618 @Override
619 public T setLong(K name, long value) {
620 return set(name, fromLong(name, value));
621 }
622
623 @Override
624 public T setDouble(K name, double value) {
625 return set(name, fromDouble(name, value));
626 }
627
628 @Override
629 public T setTimeMillis(K name, long value) {
630 return set(name, fromTimeMillis(name, value));
631 }
632
633 @Override
634 public T setFloat(K name, float value) {
635 return set(name, fromFloat(name, value));
636 }
637
638 @Override
639 public T setChar(K name, char value) {
640 return set(name, fromChar(name, value));
641 }
642
643 @Override
644 public T setBoolean(K name, boolean value) {
645 return set(name, fromBoolean(name, value));
646 }
647
648 @Override
649 public T setByte(K name, byte value) {
650 return set(name, fromByte(name, value));
651 }
652
653 @Override
654 public T setShort(K name, short value) {
655 return set(name, fromShort(name, value));
656 }
657
658 @Override
659 public T set(Headers<? extends K, ? extends V, ?> headers) {
660 if (headers != this) {
661 clear();
662 addImpl(headers);
663 }
664 return thisT();
665 }
666
667 @Override
668 public T setAll(Headers<? extends K, ? extends V, ?> headers) {
669 if (headers != this) {
670 for (K key : headers.names()) {
671 remove(key);
672 }
673 addImpl(headers);
674 }
675 return thisT();
676 }
677
678 @Override
679 public boolean remove(K name) {
680 return getAndRemove(name) != null;
681 }
682
683 @Override
684 public T clear() {
685 Arrays.fill(entries, null);
686 head.before = head.after = head;
687 size = 0;
688 return thisT();
689 }
690
691 @Override
692 public Iterator<Entry<K, V>> iterator() {
693 return new HeaderIterator();
694 }
695
696 @Override
697 public Boolean getBoolean(K name) {
698 V v = get(name);
699 try {
700 return v != null ? toBoolean(name, v) : null;
701 } catch (RuntimeException ignore) {
702 return null;
703 }
704 }
705
706 @Override
707 public boolean getBoolean(K name, boolean defaultValue) {
708 Boolean v = getBoolean(name);
709 return v != null ? v : defaultValue;
710 }
711
712 @Override
713 public Byte getByte(K name) {
714 V v = get(name);
715 try {
716 return v != null ? toByte(name, v) : null;
717 } catch (RuntimeException ignore) {
718 return null;
719 }
720 }
721
722 @Override
723 public byte getByte(K name, byte defaultValue) {
724 Byte v = getByte(name);
725 return v != null ? v : defaultValue;
726 }
727
728 @Override
729 public Character getChar(K name) {
730 V v = get(name);
731 try {
732 return v != null ? toChar(name, v) : null;
733 } catch (RuntimeException ignore) {
734 return null;
735 }
736 }
737
738 @Override
739 public char getChar(K name, char defaultValue) {
740 Character v = getChar(name);
741 return v != null ? v : defaultValue;
742 }
743
744 @Override
745 public Short getShort(K name) {
746 V v = get(name);
747 try {
748 return v != null ? toShort(name, v) : null;
749 } catch (RuntimeException ignore) {
750 return null;
751 }
752 }
753
754 @Override
755 public short getShort(K name, short defaultValue) {
756 Short v = getShort(name);
757 return v != null ? v : defaultValue;
758 }
759
760 @Override
761 public Integer getInt(K name) {
762 V v = get(name);
763 try {
764 return v != null ? toInt(name, v) : null;
765 } catch (RuntimeException ignore) {
766 return null;
767 }
768 }
769
770 @Override
771 public int getInt(K name, int defaultValue) {
772 Integer v = getInt(name);
773 return v != null ? v : defaultValue;
774 }
775
776 @Override
777 public Long getLong(K name) {
778 V v = get(name);
779 try {
780 return v != null ? toLong(name, v) : null;
781 } catch (RuntimeException ignore) {
782 return null;
783 }
784 }
785
786 @Override
787 public long getLong(K name, long defaultValue) {
788 Long v = getLong(name);
789 return v != null ? v : defaultValue;
790 }
791
792 @Override
793 public Float getFloat(K name) {
794 V v = get(name);
795 try {
796 return v != null ? toFloat(name, v) : null;
797 } catch (RuntimeException ignore) {
798 return null;
799 }
800 }
801
802 @Override
803 public float getFloat(K name, float defaultValue) {
804 Float v = getFloat(name);
805 return v != null ? v : defaultValue;
806 }
807
808 @Override
809 public Double getDouble(K name) {
810 V v = get(name);
811 try {
812 return v != null ? toDouble(name, v) : null;
813 } catch (RuntimeException ignore) {
814 return null;
815 }
816 }
817
818 @Override
819 public double getDouble(K name, double defaultValue) {
820 Double v = getDouble(name);
821 return v != null ? v : defaultValue;
822 }
823
824 @Override
825 public Long getTimeMillis(K name) {
826 V v = get(name);
827 try {
828 return v != null ? toTimeMillis(name, v) : null;
829 } catch (RuntimeException ignore) {
830 return null;
831 }
832 }
833
834 @Override
835 public long getTimeMillis(K name, long defaultValue) {
836 Long v = getTimeMillis(name);
837 return v != null ? v : defaultValue;
838 }
839
840 @Override
841 public Boolean getBooleanAndRemove(K name) {
842 V v = getAndRemove(name);
843 try {
844 return v != null ? toBoolean(name, v) : null;
845 } catch (RuntimeException ignore) {
846 return null;
847 }
848 }
849
850 @Override
851 public boolean getBooleanAndRemove(K name, boolean defaultValue) {
852 Boolean v = getBooleanAndRemove(name);
853 return v != null ? v : defaultValue;
854 }
855
856 @Override
857 public Byte getByteAndRemove(K name) {
858 V v = getAndRemove(name);
859 try {
860 return v != null ? toByte(name, v) : null;
861 } catch (RuntimeException ignore) {
862 return null;
863 }
864 }
865
866 @Override
867 public byte getByteAndRemove(K name, byte defaultValue) {
868 Byte v = getByteAndRemove(name);
869 return v != null ? v : defaultValue;
870 }
871
872 @Override
873 public Character getCharAndRemove(K name) {
874 V v = getAndRemove(name);
875 try {
876 return v != null ? toChar(name, v) : null;
877 } catch (RuntimeException ignore) {
878 return null;
879 }
880 }
881
882 @Override
883 public char getCharAndRemove(K name, char defaultValue) {
884 Character v = getCharAndRemove(name);
885 return v != null ? v : defaultValue;
886 }
887
888 @Override
889 public Short getShortAndRemove(K name) {
890 V v = getAndRemove(name);
891 try {
892 return v != null ? toShort(name, v) : null;
893 } catch (RuntimeException ignore) {
894 return null;
895 }
896 }
897
898 @Override
899 public short getShortAndRemove(K name, short defaultValue) {
900 Short v = getShortAndRemove(name);
901 return v != null ? v : defaultValue;
902 }
903
904 @Override
905 public Integer getIntAndRemove(K name) {
906 V v = getAndRemove(name);
907 try {
908 return v != null ? toInt(name, v) : null;
909 } catch (RuntimeException ignore) {
910 return null;
911 }
912 }
913
914 @Override
915 public int getIntAndRemove(K name, int defaultValue) {
916 Integer v = getIntAndRemove(name);
917 return v != null ? v : defaultValue;
918 }
919
920 @Override
921 public Long getLongAndRemove(K name) {
922 V v = getAndRemove(name);
923 try {
924 return v != null ? toLong(name, v) : null;
925 } catch (RuntimeException ignore) {
926 return null;
927 }
928 }
929
930 @Override
931 public long getLongAndRemove(K name, long defaultValue) {
932 Long v = getLongAndRemove(name);
933 return v != null ? v : defaultValue;
934 }
935
936 @Override
937 public Float getFloatAndRemove(K name) {
938 V v = getAndRemove(name);
939 try {
940 return v != null ? toFloat(name, v) : null;
941 } catch (RuntimeException ignore) {
942 return null;
943 }
944 }
945
946 @Override
947 public float getFloatAndRemove(K name, float defaultValue) {
948 Float v = getFloatAndRemove(name);
949 return v != null ? v : defaultValue;
950 }
951
952 @Override
953 public Double getDoubleAndRemove(K name) {
954 V v = getAndRemove(name);
955 try {
956 return v != null ? toDouble(name, v) : null;
957 } catch (RuntimeException ignore) {
958 return null;
959 }
960 }
961
962 @Override
963 public double getDoubleAndRemove(K name, double defaultValue) {
964 Double v = getDoubleAndRemove(name);
965 return v != null ? v : defaultValue;
966 }
967
968 @Override
969 public Long getTimeMillisAndRemove(K name) {
970 V v = getAndRemove(name);
971 try {
972 return v != null ? toTimeMillis(name, v) : null;
973 } catch (RuntimeException ignore) {
974 return null;
975 }
976 }
977
978 @Override
979 public long getTimeMillisAndRemove(K name, long defaultValue) {
980 Long v = getTimeMillisAndRemove(name);
981 return v != null ? v : defaultValue;
982 }
983
984 @SuppressWarnings("unchecked")
985 @Override
986 public boolean equals(Object o) {
987 if (!(o instanceof Headers)) {
988 return false;
989 }
990
991 return equals((Headers<K, V, ?>) o, JAVA_HASHER);
992 }
993
994 @SuppressWarnings("unchecked")
995 @Override
996 public int hashCode() {
997 return hashCode(JAVA_HASHER);
998 }
999
1000
1001
1002
1003
1004
1005
1006
1007 public final boolean equals(Headers<K, V, ?> h2, HashingStrategy<V> valueHashingStrategy) {
1008 if (h2.size() != size()) {
1009 return false;
1010 }
1011
1012 if (this == h2) {
1013 return true;
1014 }
1015
1016 for (K name : names()) {
1017 List<V> otherValues = h2.getAll(name);
1018 List<V> values = getAll(name);
1019 if (otherValues.size() != values.size()) {
1020 return false;
1021 }
1022 for (int i = 0; i < otherValues.size(); i++) {
1023 if (!valueHashingStrategy.equals(otherValues.get(i), values.get(i))) {
1024 return false;
1025 }
1026 }
1027 }
1028 return true;
1029 }
1030
1031
1032
1033
1034
1035
1036 public final int hashCode(HashingStrategy<V> valueHashingStrategy) {
1037 int result = HASH_CODE_SEED;
1038 for (K name : names()) {
1039 result = 31 * result + hashingStrategy.hashCode(name);
1040 List<V> values = getAll(name);
1041 for (int i = 0; i < values.size(); ++i) {
1042 result = 31 * result + valueHashingStrategy.hashCode(values.get(i));
1043 }
1044 }
1045 return result;
1046 }
1047
1048 @Override
1049 public String toString() {
1050 return HeadersUtils.toString(getClass(), iterator(), size());
1051 }
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061 protected void validateName(NameValidator<K> validator, boolean forAdd, K name) {
1062 validator.validateName(name);
1063 }
1064
1065 protected void validateValue(ValueValidator<V> validator, K name, V value) {
1066 try {
1067 validator.validate(value);
1068 } catch (IllegalArgumentException e) {
1069 throw new IllegalArgumentException("Validation failed for header '" + name + "'", e);
1070 }
1071 }
1072
1073 protected HeaderEntry<K, V> newHeaderEntry(int h, K name, V value, HeaderEntry<K, V> next) {
1074 return new HeaderEntry<K, V>(h, name, value, next, head);
1075 }
1076
1077 protected ValueConverter<V> valueConverter() {
1078 return valueConverter;
1079 }
1080
1081 protected NameValidator<K> nameValidator() {
1082 return nameValidator;
1083 }
1084
1085 protected ValueValidator<V> valueValidator() {
1086 return valueValidator;
1087 }
1088
1089 private int index(int hash) {
1090 return hash & hashMask;
1091 }
1092
1093 private void add0(int h, int i, K name, V value) {
1094
1095 HeaderEntry<K, V> entry = newHeaderEntry(h, name, value, entries[i]);
1096 if (valueValidator != ValueValidator.NO_VALIDATION) {
1097
1098 entry.origin = this;
1099 }
1100 entries[i] = entry;
1101 ++size;
1102 }
1103
1104
1105
1106
1107 private V remove0(int h, int i, K name) {
1108 HeaderEntry<K, V> e = entries[i];
1109 if (e == null) {
1110 return null;
1111 }
1112
1113 V value = null;
1114 HeaderEntry<K, V> next = e.next;
1115 while (next != null) {
1116 if (next.hash == h && hashingStrategy.equals(name, next.key)) {
1117 value = next.value;
1118 e.next = next.next;
1119 next.remove();
1120 --size;
1121 } else {
1122 e = next;
1123 }
1124
1125 next = e.next;
1126 }
1127
1128 e = entries[i];
1129 if (e.hash == h && hashingStrategy.equals(name, e.key)) {
1130 if (value == null) {
1131 value = e.value;
1132 }
1133 entries[i] = e.next;
1134 e.remove();
1135 --size;
1136 }
1137
1138 return value;
1139 }
1140
1141 HeaderEntry<K, V> remove0(HeaderEntry<K, V> entry, HeaderEntry<K, V> previous) {
1142 int i = index(entry.hash);
1143 HeaderEntry<K, V> firstEntry = entries[i];
1144 if (firstEntry == entry) {
1145 entries[i] = entry.next;
1146 previous = entries[i];
1147 } else if (previous == null) {
1148
1149 previous = firstEntry;
1150 HeaderEntry<K, V> next = firstEntry.next;
1151 while (next != null && next != entry) {
1152 previous = next;
1153 next = next.next;
1154 }
1155 assert next != null: "Entry not found in its hash bucket: " + entry;
1156 previous.next = entry.next;
1157 } else {
1158 previous.next = entry.next;
1159 }
1160 entry.remove();
1161 --size;
1162 return previous;
1163 }
1164
1165 @SuppressWarnings("unchecked")
1166 private T thisT() {
1167 return (T) this;
1168 }
1169
1170 private V fromObject(K name, Object value) {
1171 try {
1172 return valueConverter.convertObject(checkNotNull(value, "value"));
1173 } catch (IllegalArgumentException e) {
1174 throw new IllegalArgumentException("Failed to convert object value for header '" + name + '\'', e);
1175 }
1176 }
1177
1178 private V fromBoolean(K name, boolean value) {
1179 try {
1180 return valueConverter.convertBoolean(value);
1181 } catch (IllegalArgumentException e) {
1182 throw new IllegalArgumentException("Failed to convert boolean value for header '" + name + '\'', e);
1183 }
1184 }
1185
1186 private V fromByte(K name, byte value) {
1187 try {
1188 return valueConverter.convertByte(value);
1189 } catch (IllegalArgumentException e) {
1190 throw new IllegalArgumentException("Failed to convert byte value for header '" + name + '\'', e);
1191 }
1192 }
1193
1194 private V fromChar(K name, char value) {
1195 try {
1196 return valueConverter.convertChar(value);
1197 } catch (IllegalArgumentException e) {
1198 throw new IllegalArgumentException("Failed to convert char value for header '" + name + '\'', e);
1199 }
1200 }
1201
1202 private V fromShort(K name, short value) {
1203 try {
1204 return valueConverter.convertShort(value);
1205 } catch (IllegalArgumentException e) {
1206 throw new IllegalArgumentException("Failed to convert short value for header '" + name + '\'', e);
1207 }
1208 }
1209
1210 private V fromInt(K name, int value) {
1211 try {
1212 return valueConverter.convertInt(value);
1213 } catch (IllegalArgumentException e) {
1214 throw new IllegalArgumentException("Failed to convert int value for header '" + name + '\'', e);
1215 }
1216 }
1217
1218 private V fromLong(K name, long value) {
1219 try {
1220 return valueConverter.convertLong(value);
1221 } catch (IllegalArgumentException e) {
1222 throw new IllegalArgumentException("Failed to convert long value for header '" + name + '\'', e);
1223 }
1224 }
1225
1226 private V fromFloat(K name, float value) {
1227 try {
1228 return valueConverter.convertFloat(value);
1229 } catch (IllegalArgumentException e) {
1230 throw new IllegalArgumentException("Failed to convert float value for header '" + name + '\'', e);
1231 }
1232 }
1233
1234 private V fromDouble(K name, double value) {
1235 try {
1236 return valueConverter.convertDouble(value);
1237 } catch (IllegalArgumentException e) {
1238 throw new IllegalArgumentException("Failed to convert double value for header '" + name + '\'', e);
1239 }
1240 }
1241
1242 private V fromTimeMillis(K name, long value) {
1243 try {
1244 return valueConverter.convertTimeMillis(value);
1245 } catch (IllegalArgumentException e) {
1246 throw new IllegalArgumentException("Failed to convert millsecond value for header '" + name + '\'', e);
1247 }
1248 }
1249
1250 private boolean toBoolean(K name, V value) {
1251 try {
1252 return valueConverter.convertToBoolean(value);
1253 } catch (IllegalArgumentException e) {
1254 throw new IllegalArgumentException("Failed to convert header value to boolean for header '" + name + '\'');
1255 }
1256 }
1257
1258 private byte toByte(K name, V value) {
1259 try {
1260 return valueConverter.convertToByte(value);
1261 } catch (IllegalArgumentException e) {
1262 throw new IllegalArgumentException("Failed to convert header value to byte for header '" + name + '\'');
1263 }
1264 }
1265
1266 private char toChar(K name, V value) {
1267 try {
1268 return valueConverter.convertToChar(value);
1269 } catch (IllegalArgumentException e) {
1270 throw new IllegalArgumentException("Failed to convert header value to char for header '" + name + '\'');
1271 }
1272 }
1273
1274 private short toShort(K name, V value) {
1275 try {
1276 return valueConverter.convertToShort(value);
1277 } catch (IllegalArgumentException e) {
1278 throw new IllegalArgumentException("Failed to convert header value to short for header '" + name + '\'');
1279 }
1280 }
1281
1282 private int toInt(K name, V value) {
1283 try {
1284 return valueConverter.convertToInt(value);
1285 } catch (IllegalArgumentException e) {
1286 throw new IllegalArgumentException("Failed to convert header value to int for header '" + name + '\'');
1287 }
1288 }
1289
1290 private long toLong(K name, V value) {
1291 try {
1292 return valueConverter.convertToLong(value);
1293 } catch (IllegalArgumentException e) {
1294 throw new IllegalArgumentException("Failed to convert header value to long for header '" + name + '\'');
1295 }
1296 }
1297
1298 private float toFloat(K name, V value) {
1299 try {
1300 return valueConverter.convertToFloat(value);
1301 } catch (IllegalArgumentException e) {
1302 throw new IllegalArgumentException("Failed to convert header value to float for header '" + name + '\'');
1303 }
1304 }
1305
1306 private double toDouble(K name, V value) {
1307 try {
1308 return valueConverter.convertToDouble(value);
1309 } catch (IllegalArgumentException e) {
1310 throw new IllegalArgumentException("Failed to convert header value to double for header '" + name + '\'');
1311 }
1312 }
1313
1314 private long toTimeMillis(K name, V value) {
1315 try {
1316 return valueConverter.convertToTimeMillis(value);
1317 } catch (IllegalArgumentException e) {
1318 throw new IllegalArgumentException(
1319 "Failed to convert header value to millsecond for header '" + name + '\'');
1320 }
1321 }
1322
1323
1324
1325
1326 public DefaultHeaders<K, V, T> copy() {
1327 DefaultHeaders<K, V, T> copy = new DefaultHeaders<K, V, T>(
1328 hashingStrategy, valueConverter, nameValidator, entries.length, valueValidator);
1329 copy.addImpl(this);
1330 return copy;
1331 }
1332
1333 private final class HeaderIterator implements Iterator<Entry<K, V>> {
1334 private HeaderEntry<K, V> current = head;
1335
1336 @Override
1337 public boolean hasNext() {
1338 return current.after != head;
1339 }
1340
1341 @Override
1342 public Entry<K, V> next() {
1343 current = current.after;
1344
1345 if (current == head) {
1346 throw new NoSuchElementException();
1347 }
1348
1349 return current;
1350 }
1351
1352 @Override
1353 public void remove() {
1354 throw new UnsupportedOperationException("read only");
1355 }
1356 }
1357
1358 private final class ValueIterator implements Iterator<V> {
1359 private final K name;
1360 private final int hash;
1361 private HeaderEntry<K, V> removalPrevious;
1362 private HeaderEntry<K, V> previous;
1363 private HeaderEntry<K, V> next;
1364
1365 ValueIterator(K name) {
1366 this.name = checkNotNull(name, "name");
1367 hash = hashingStrategy.hashCode(name);
1368 calculateNext(entries[index(hash)]);
1369 }
1370
1371 @Override
1372 public boolean hasNext() {
1373 return next != null;
1374 }
1375
1376 @Override
1377 public V next() {
1378 if (!hasNext()) {
1379 throw new NoSuchElementException();
1380 }
1381 if (previous != null) {
1382 removalPrevious = previous;
1383 }
1384 previous = next;
1385 calculateNext(next.next);
1386 return previous.value;
1387 }
1388
1389 @Override
1390 public void remove() {
1391 if (previous == null) {
1392 throw new IllegalStateException();
1393 }
1394 removalPrevious = remove0(previous, removalPrevious);
1395 previous = null;
1396 }
1397
1398 private void calculateNext(HeaderEntry<K, V> entry) {
1399 while (entry != null) {
1400 if (entry.hash == hash && hashingStrategy.equals(name, entry.key)) {
1401 next = entry;
1402 return;
1403 }
1404 entry = entry.next;
1405 }
1406 next = null;
1407 }
1408 }
1409
1410 protected static class HeaderEntry<K, V> implements Entry<K, V> {
1411 protected final int hash;
1412 protected final K key;
1413 protected V value;
1414
1415
1416
1417 protected HeaderEntry<K, V> next;
1418
1419
1420
1421 protected HeaderEntry<K, V> before, after;
1422
1423
1424
1425 private DefaultHeaders<K, V, ?> origin;
1426
1427 protected HeaderEntry(int hash, K key) {
1428 this.hash = hash;
1429 this.key = key;
1430 }
1431
1432 HeaderEntry(int hash, K key, V value, HeaderEntry<K, V> next, HeaderEntry<K, V> head) {
1433 this.hash = hash;
1434 this.key = key;
1435 this.value = value;
1436 this.next = next;
1437
1438 after = head;
1439 before = head.before;
1440 pointNeighborsToThis();
1441 }
1442
1443 HeaderEntry() {
1444 hash = -1;
1445 key = null;
1446 before = after = this;
1447 }
1448
1449 protected final void pointNeighborsToThis() {
1450 before.after = this;
1451 after.before = this;
1452 }
1453
1454 public final HeaderEntry<K, V> before() {
1455 return before;
1456 }
1457
1458 public final HeaderEntry<K, V> after() {
1459 return after;
1460 }
1461
1462 protected void remove() {
1463 before.after = after;
1464 after.before = before;
1465 }
1466
1467 @Override
1468 public final K getKey() {
1469 return key;
1470 }
1471
1472 @Override
1473 public final V getValue() {
1474 return value;
1475 }
1476
1477 @Override
1478 public final V setValue(V value) {
1479 checkNotNull(value, "value");
1480 if (origin != null) {
1481 try {
1482 origin.validateValue(origin.valueValidator, key, value);
1483 } catch (IllegalArgumentException e) {
1484 throw new IllegalArgumentException("Validation failed for header '" + key + "'", e);
1485 }
1486 }
1487 V oldValue = this.value;
1488 this.value = value;
1489 return oldValue;
1490 }
1491
1492 @Override
1493 public final String toString() {
1494 return key.toString() + '=' + value.toString();
1495 }
1496
1497 @Override
1498 public boolean equals(Object o) {
1499 if (!(o instanceof Map.Entry)) {
1500 return false;
1501 }
1502 Entry<?, ?> other = (Entry<?, ?>) o;
1503 return (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) &&
1504 (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
1505 }
1506
1507 @Override
1508 public int hashCode() {
1509 return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
1510 }
1511 }
1512 }