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.core5.http2.hpack;
29
30 import org.apache.hc.core5.http.Header;
31 import org.apache.hc.core5.util.Args;
32 import org.apache.hc.core5.util.Asserts;
33
34 final class InboundDynamicTable {
35
36 private final StaticTable staticTable;
37 private final FifoBuffer headers;
38
39 private int maxSize;
40 private int currentSize;
41
42 InboundDynamicTable(final StaticTable staticTable) {
43 this.staticTable = staticTable;
44 this.headers = new FifoBuffer(256);
45 this.maxSize = Integer.MAX_VALUE;
46 this.currentSize = 0;
47 }
48
49 InboundDynamicTable() {
50 this(StaticTable.INSTANCE);
51 }
52
53 public int getMaxSize() {
54 return maxSize;
55 }
56
57 public void setMaxSize(final int maxSize) {
58 this.maxSize = maxSize;
59 evict();
60 }
61
62 public int getCurrentSize() {
63 return currentSize;
64 }
65
66 int staticLength() {
67 return staticTable.length();
68 }
69
70 int dynamicLength() {
71 return headers.size();
72 }
73
74 Header getDynamicEntry(final int index) {
75 return headers.get(index);
76 }
77
78 public int length() {
79 return staticTable.length() + headers.size();
80 }
81
82 public HPackHeader getHeader(final int index) {
83 final int length = length();
84 Args.check(index >= 1, "index %s cannot be less than 1", index);
85 Args.check(index <= length, "length %s cannot be greater than index %s", length, index);
86 return index <= staticTable.length()
87 ? staticTable.get(index)
88 : headers.get(index - staticTable.length() - 1);
89 }
90
91 public void add(final HPackHeader header) {
92 final int entrySize = header.getTotalSize();
93 if (entrySize > this.maxSize) {
94 clear();
95 return;
96 }
97 headers.addFirst(header);
98 currentSize += entrySize;
99 evict();
100 }
101
102 private void clear() {
103 currentSize = 0;
104 headers.clear();
105 }
106
107 private void evict() {
108 while (currentSize > maxSize) {
109 final HPackHeader header = headers.removeLast();
110 if (header != null) {
111 currentSize -= header.getTotalSize();
112 } else {
113 Asserts.check(currentSize == 0, "Current table size must be zero");
114 break;
115 }
116 }
117 }
118
119 }