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