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