1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http2;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.ByteBufUtil;
20 import io.netty.buffer.Unpooled;
21 import io.netty.util.internal.StringUtil;
22 import io.netty.util.internal.UnstableApi;
23
24 import static io.netty.handler.codec.http2.Http2CodecUtil.verifyPadding;
25 import static io.netty.util.internal.ObjectUtil.checkNotNull;
26
27
28
29
30 @UnstableApi
31 public final class DefaultHttp2DataFrame extends AbstractHttp2StreamFrame implements Http2DataFrame {
32 private final ByteBuf content;
33 private final boolean endStream;
34 private final int padding;
35 private final int initialFlowControlledBytes;
36
37
38
39
40
41
42 public DefaultHttp2DataFrame(ByteBuf content) {
43 this(content, false);
44 }
45
46
47
48
49
50
51 public DefaultHttp2DataFrame(boolean endStream) {
52 this(Unpooled.EMPTY_BUFFER, endStream);
53 }
54
55
56
57
58
59
60
61 public DefaultHttp2DataFrame(ByteBuf content, boolean endStream) {
62 this(content, endStream, 0);
63 }
64
65
66
67
68
69
70
71
72
73 public DefaultHttp2DataFrame(ByteBuf content, boolean endStream, int padding) {
74 this.content = checkNotNull(content, "content");
75 this.endStream = endStream;
76 verifyPadding(padding);
77 this.padding = padding;
78 if (content().readableBytes() + (long) padding > Integer.MAX_VALUE) {
79 throw new IllegalArgumentException("content + padding must be <= Integer.MAX_VALUE");
80 }
81 initialFlowControlledBytes = content().readableBytes() + padding;
82 }
83
84 @Override
85 public DefaultHttp2DataFrame stream(Http2FrameStream stream) {
86 super.stream(stream);
87 return this;
88 }
89
90 @Override
91 public String name() {
92 return "DATA";
93 }
94
95 @Override
96 public boolean isEndStream() {
97 return endStream;
98 }
99
100 @Override
101 public int padding() {
102 return padding;
103 }
104
105 @Override
106 public ByteBuf content() {
107 return ByteBufUtil.ensureAccessible(content);
108 }
109
110 @Override
111 public int initialFlowControlledBytes() {
112 return initialFlowControlledBytes;
113 }
114
115 @Override
116 public DefaultHttp2DataFrame copy() {
117 return replace(content().copy());
118 }
119
120 @Override
121 public DefaultHttp2DataFrame duplicate() {
122 return replace(content().duplicate());
123 }
124
125 @Override
126 public DefaultHttp2DataFrame retainedDuplicate() {
127 return replace(content().retainedDuplicate());
128 }
129
130 @Override
131 public DefaultHttp2DataFrame replace(ByteBuf content) {
132 return new DefaultHttp2DataFrame(content, endStream, padding);
133 }
134
135 @Override
136 public int refCnt() {
137 return content.refCnt();
138 }
139
140 @Override
141 public boolean release() {
142 return content.release();
143 }
144
145 @Override
146 public boolean release(int decrement) {
147 return content.release(decrement);
148 }
149
150 @Override
151 public DefaultHttp2DataFrame retain() {
152 content.retain();
153 return this;
154 }
155
156 @Override
157 public DefaultHttp2DataFrame retain(int increment) {
158 content.retain(increment);
159 return this;
160 }
161
162 @Override
163 public String toString() {
164 return StringUtil.simpleClassName(this) + "(stream=" + stream() + ", content=" + content
165 + ", endStream=" + endStream + ", padding=" + padding + ')';
166 }
167
168 @Override
169 public DefaultHttp2DataFrame touch() {
170 content.touch();
171 return this;
172 }
173
174 @Override
175 public DefaultHttp2DataFrame touch(Object hint) {
176 content.touch(hint);
177 return this;
178 }
179
180 @Override
181 public boolean equals(Object o) {
182 if (!(o instanceof DefaultHttp2DataFrame)) {
183 return false;
184 }
185 DefaultHttp2DataFrame other = (DefaultHttp2DataFrame) o;
186 return super.equals(other) && content.equals(other.content())
187 && endStream == other.endStream && padding == other.padding;
188 }
189
190 @Override
191 public int hashCode() {
192 int hash = super.hashCode();
193 hash = hash * 31 + content.hashCode();
194 hash = hash * 31 + (endStream ? 0 : 1);
195 hash = hash * 31 + padding;
196 return hash;
197 }
198 }