1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.buffer;
18
19 import io.netty.util.IllegalReferenceCountException;
20 import io.netty.util.Recycler.EnhancedHandle;
21 import io.netty.util.internal.ObjectPool.Handle;
22
23 import java.nio.ByteBuffer;
24 import java.nio.ByteOrder;
25
26
27
28
29 abstract class AbstractPooledDerivedByteBuf extends AbstractReferenceCountedByteBuf {
30
31 private final EnhancedHandle<AbstractPooledDerivedByteBuf> recyclerHandle;
32 private AbstractByteBuf rootParent;
33
34
35
36
37
38
39 private ByteBuf parent;
40
41 @SuppressWarnings("unchecked")
42 AbstractPooledDerivedByteBuf(Handle<? extends AbstractPooledDerivedByteBuf> recyclerHandle) {
43 super(0);
44 this.recyclerHandle = (EnhancedHandle<AbstractPooledDerivedByteBuf>) recyclerHandle;
45 }
46
47
48 final void parent(ByteBuf newParent) {
49 assert newParent instanceof SimpleLeakAwareByteBuf;
50 parent = newParent;
51 }
52
53 @Override
54 public final AbstractByteBuf unwrap() {
55 AbstractByteBuf rootParent = this.rootParent;
56 if (rootParent == null) {
57 throw new IllegalReferenceCountException();
58 }
59 return rootParent;
60 }
61
62 final <U extends AbstractPooledDerivedByteBuf> U init(
63 AbstractByteBuf unwrapped, ByteBuf wrapped, int readerIndex, int writerIndex, int maxCapacity) {
64 wrapped.retain();
65 parent = wrapped;
66 rootParent = unwrapped;
67
68 try {
69 maxCapacity(maxCapacity);
70 setIndex0(readerIndex, writerIndex);
71 resetRefCnt();
72
73 @SuppressWarnings("unchecked")
74 final U castThis = (U) this;
75 wrapped = null;
76 return castThis;
77 } finally {
78 if (wrapped != null) {
79 parent = rootParent = null;
80 wrapped.release();
81 }
82 }
83 }
84
85 @Override
86 protected final void deallocate() {
87
88
89
90 ByteBuf parent = this.parent;
91
92 this.parent = this.rootParent = null;
93 recyclerHandle.unguardedRecycle(this);
94 parent.release();
95 }
96
97 @Override
98 public final ByteBufAllocator alloc() {
99 return unwrap().alloc();
100 }
101
102 @Override
103 @Deprecated
104 public final ByteOrder order() {
105 return unwrap().order();
106 }
107
108 @Override
109 public boolean isReadOnly() {
110 return unwrap().isReadOnly();
111 }
112
113 @Override
114 public final boolean isDirect() {
115 return unwrap().isDirect();
116 }
117
118 @Override
119 public boolean hasArray() {
120 return unwrap().hasArray();
121 }
122
123 @Override
124 public byte[] array() {
125 return unwrap().array();
126 }
127
128 @Override
129 public boolean hasMemoryAddress() {
130 return unwrap().hasMemoryAddress();
131 }
132
133 @Override
134 public boolean isContiguous() {
135 return unwrap().isContiguous();
136 }
137
138 @Override
139 public final int nioBufferCount() {
140 return unwrap().nioBufferCount();
141 }
142
143 @Override
144 public final ByteBuffer internalNioBuffer(int index, int length) {
145 return nioBuffer(index, length);
146 }
147
148 @Override
149 public final ByteBuf retainedSlice() {
150 final int index = readerIndex();
151 return retainedSlice(index, writerIndex() - index);
152 }
153
154 @Override
155 public ByteBuf slice(int index, int length) {
156 ensureAccessible();
157
158 return new PooledNonRetainedSlicedByteBuf(this, unwrap(), index, length);
159 }
160
161 final ByteBuf duplicate0() {
162 ensureAccessible();
163
164 return new PooledNonRetainedDuplicateByteBuf(this, unwrap());
165 }
166
167 private static final class PooledNonRetainedDuplicateByteBuf extends UnpooledDuplicatedByteBuf {
168 private final ByteBuf referenceCountDelegate;
169
170 PooledNonRetainedDuplicateByteBuf(ByteBuf referenceCountDelegate, AbstractByteBuf buffer) {
171 super(buffer);
172 this.referenceCountDelegate = referenceCountDelegate;
173 }
174
175 @Override
176 boolean isAccessible0() {
177 return referenceCountDelegate.isAccessible();
178 }
179
180 @Override
181 int refCnt0() {
182 return referenceCountDelegate.refCnt();
183 }
184
185 @Override
186 ByteBuf retain0() {
187 referenceCountDelegate.retain();
188 return this;
189 }
190
191 @Override
192 ByteBuf retain0(int increment) {
193 referenceCountDelegate.retain(increment);
194 return this;
195 }
196
197 @Override
198 ByteBuf touch0() {
199 referenceCountDelegate.touch();
200 return this;
201 }
202
203 @Override
204 ByteBuf touch0(Object hint) {
205 referenceCountDelegate.touch(hint);
206 return this;
207 }
208
209 @Override
210 boolean release0() {
211 return referenceCountDelegate.release();
212 }
213
214 @Override
215 boolean release0(int decrement) {
216 return referenceCountDelegate.release(decrement);
217 }
218
219 @Override
220 public ByteBuf duplicate() {
221 ensureAccessible();
222 return new PooledNonRetainedDuplicateByteBuf(referenceCountDelegate, this);
223 }
224
225 @Override
226 public ByteBuf retainedDuplicate() {
227 return PooledDuplicatedByteBuf.newInstance(unwrap(), this, readerIndex(), writerIndex());
228 }
229
230 @Override
231 public ByteBuf slice(int index, int length) {
232 checkIndex(index, length);
233 return new PooledNonRetainedSlicedByteBuf(referenceCountDelegate, unwrap(), index, length);
234 }
235
236 @Override
237 public ByteBuf retainedSlice() {
238
239 return retainedSlice(readerIndex(), capacity());
240 }
241
242 @Override
243 public ByteBuf retainedSlice(int index, int length) {
244 return PooledSlicedByteBuf.newInstance(unwrap(), this, index, length);
245 }
246 }
247
248 private static final class PooledNonRetainedSlicedByteBuf extends UnpooledSlicedByteBuf {
249 private final ByteBuf referenceCountDelegate;
250
251 PooledNonRetainedSlicedByteBuf(ByteBuf referenceCountDelegate,
252 AbstractByteBuf buffer, int index, int length) {
253 super(buffer, index, length);
254 this.referenceCountDelegate = referenceCountDelegate;
255 }
256
257 @Override
258 boolean isAccessible0() {
259 return referenceCountDelegate.isAccessible();
260 }
261
262 @Override
263 int refCnt0() {
264 return referenceCountDelegate.refCnt();
265 }
266
267 @Override
268 ByteBuf retain0() {
269 referenceCountDelegate.retain();
270 return this;
271 }
272
273 @Override
274 ByteBuf retain0(int increment) {
275 referenceCountDelegate.retain(increment);
276 return this;
277 }
278
279 @Override
280 ByteBuf touch0() {
281 referenceCountDelegate.touch();
282 return this;
283 }
284
285 @Override
286 ByteBuf touch0(Object hint) {
287 referenceCountDelegate.touch(hint);
288 return this;
289 }
290
291 @Override
292 boolean release0() {
293 return referenceCountDelegate.release();
294 }
295
296 @Override
297 boolean release0(int decrement) {
298 return referenceCountDelegate.release(decrement);
299 }
300
301 @Override
302 public ByteBuf duplicate() {
303 ensureAccessible();
304 return new PooledNonRetainedDuplicateByteBuf(referenceCountDelegate, unwrap())
305 .setIndex(idx(readerIndex()), idx(writerIndex()));
306 }
307
308 @Override
309 public ByteBuf retainedDuplicate() {
310 return PooledDuplicatedByteBuf.newInstance(unwrap(), this, idx(readerIndex()), idx(writerIndex()));
311 }
312
313 @Override
314 public ByteBuf slice(int index, int length) {
315 checkIndex(index, length);
316 return new PooledNonRetainedSlicedByteBuf(referenceCountDelegate, unwrap(), idx(index), length);
317 }
318
319 @Override
320 public ByteBuf retainedSlice() {
321
322 return retainedSlice(0, capacity());
323 }
324
325 @Override
326 public ByteBuf retainedSlice(int index, int length) {
327 return PooledSlicedByteBuf.newInstance(unwrap(), this, idx(index), length);
328 }
329 }
330 }