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.Recycler;
20 import io.netty.util.internal.PlatformDependent;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.nio.ByteBuffer;
26 import java.nio.channels.ClosedChannelException;
27 import java.nio.channels.GatheringByteChannel;
28 import java.nio.channels.ScatteringByteChannel;
29
30 final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
31 private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() {
32 @Override
33 protected PooledUnsafeDirectByteBuf newObject(Handle handle) {
34 return new PooledUnsafeDirectByteBuf(handle, 0);
35 }
36 };
37
38 static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) {
39 PooledUnsafeDirectByteBuf buf = RECYCLER.get();
40 buf.reuse(maxCapacity);
41 return buf;
42 }
43
44 private long memoryAddress;
45
46 private PooledUnsafeDirectByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) {
47 super(recyclerHandle, maxCapacity);
48 }
49
50 @Override
51 void init(PoolChunk<ByteBuffer> chunk, long handle, int offset, int length, int maxLength,
52 PoolThreadCache cache) {
53 super.init(chunk, handle, offset, length, maxLength, cache);
54 initMemoryAddress();
55 }
56
57 @Override
58 void initUnpooled(PoolChunk<ByteBuffer> chunk, int length) {
59 super.initUnpooled(chunk, length);
60 initMemoryAddress();
61 }
62
63 private void initMemoryAddress() {
64 memoryAddress = PlatformDependent.directBufferAddress(memory) + offset;
65 }
66
67 @Override
68 protected ByteBuffer newInternalNioBuffer(ByteBuffer memory) {
69 return memory.duplicate();
70 }
71
72 @Override
73 public boolean isDirect() {
74 return true;
75 }
76
77 @Override
78 protected byte _getByte(int index) {
79 return UnsafeByteBufUtil.getByte(addr(index));
80 }
81
82 @Override
83 protected short _getShort(int index) {
84 return UnsafeByteBufUtil.getShort(addr(index));
85 }
86
87 @Override
88 protected int _getUnsignedMedium(int index) {
89 return UnsafeByteBufUtil.getUnsignedMedium(addr(index));
90 }
91
92 @Override
93 protected int _getInt(int index) {
94 return UnsafeByteBufUtil.getInt(addr(index));
95 }
96
97 @Override
98 protected long _getLong(int index) {
99 return UnsafeByteBufUtil.getLong(addr(index));
100 }
101
102 @Override
103 public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
104 UnsafeByteBufUtil.getBytes(this, addr(index), index, dst, dstIndex, length);
105 return this;
106 }
107
108 @Override
109 public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
110 UnsafeByteBufUtil.getBytes(this, addr(index), index, dst, dstIndex, length);
111 return this;
112 }
113
114 @Override
115 public ByteBuf getBytes(int index, ByteBuffer dst) {
116 UnsafeByteBufUtil.getBytes(this, addr(index), index, dst);
117 return this;
118 }
119
120 @Override
121 public ByteBuf readBytes(ByteBuffer dst) {
122 int length = dst.remaining();
123 checkReadableBytes(length);
124 getBytes(readerIndex, dst);
125 readerIndex += length;
126 return this;
127 }
128
129 @Override
130 public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
131 UnsafeByteBufUtil.getBytes(this, addr(index), index, out, length);
132 return this;
133 }
134
135 @Override
136 public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
137 return getBytes(index, out, length, false);
138 }
139
140 private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException {
141 checkIndex(index, length);
142 if (length == 0) {
143 return 0;
144 }
145
146 ByteBuffer tmpBuf;
147 if (internal) {
148 tmpBuf = internalNioBuffer();
149 } else {
150 tmpBuf = memory.duplicate();
151 }
152 index = idx(index);
153 tmpBuf.clear().position(index).limit(index + length);
154 return out.write(tmpBuf);
155 }
156
157 @Override
158 public int readBytes(GatheringByteChannel out, int length)
159 throws IOException {
160 checkReadableBytes(length);
161 int readBytes = getBytes(readerIndex, out, length, true);
162 readerIndex += readBytes;
163 return readBytes;
164 }
165
166 @Override
167 protected void _setByte(int index, int value) {
168 UnsafeByteBufUtil.setByte(addr(index), (byte) value);
169 }
170
171 @Override
172 protected void _setShort(int index, int value) {
173 UnsafeByteBufUtil.setShort(addr(index), value);
174 }
175
176 @Override
177 protected void _setMedium(int index, int value) {
178 UnsafeByteBufUtil.setMedium(addr(index), value);
179 }
180
181 @Override
182 protected void _setInt(int index, int value) {
183 UnsafeByteBufUtil.setInt(addr(index), value);
184 }
185
186 @Override
187 protected void _setLong(int index, long value) {
188 UnsafeByteBufUtil.setLong(addr(index), value);
189 }
190
191 @Override
192 public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
193 UnsafeByteBufUtil.setBytes(this, addr(index), index, src, srcIndex, length);
194 return this;
195 }
196
197 @Override
198 public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
199 UnsafeByteBufUtil.setBytes(this, addr(index), index, src, srcIndex, length);
200 return this;
201 }
202
203 @Override
204 public ByteBuf setBytes(int index, ByteBuffer src) {
205 UnsafeByteBufUtil.setBytes(this, addr(index), index, src);
206 return this;
207 }
208
209 @Override
210 public int setBytes(int index, InputStream in, int length) throws IOException {
211 return UnsafeByteBufUtil.setBytes(this, addr(index), index, in, length);
212 }
213
214 @Override
215 public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
216 checkIndex(index, length);
217 ByteBuffer tmpBuf = internalNioBuffer();
218 index = idx(index);
219 tmpBuf.clear().position(index).limit(index + length);
220 try {
221 return in.read(tmpBuf);
222 } catch (ClosedChannelException ignored) {
223 return -1;
224 }
225 }
226
227 @Override
228 public ByteBuf copy(int index, int length) {
229 return UnsafeByteBufUtil.copy(this, addr(index), index, length);
230 }
231
232 @Override
233 public int nioBufferCount() {
234 return 1;
235 }
236
237 @Override
238 public ByteBuffer[] nioBuffers(int index, int length) {
239 return new ByteBuffer[] { nioBuffer(index, length) };
240 }
241
242 @Override
243 public ByteBuffer nioBuffer(int index, int length) {
244 checkIndex(index, length);
245 index = idx(index);
246 return ((ByteBuffer) memory.duplicate().position(index).limit(index + length)).slice();
247 }
248
249 @Override
250 public ByteBuffer internalNioBuffer(int index, int length) {
251 checkIndex(index, length);
252 index = idx(index);
253 return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
254 }
255
256 @Override
257 public boolean hasArray() {
258 return false;
259 }
260
261 @Override
262 public byte[] array() {
263 throw new UnsupportedOperationException("direct buffer");
264 }
265
266 @Override
267 public int arrayOffset() {
268 throw new UnsupportedOperationException("direct buffer");
269 }
270
271 @Override
272 public boolean hasMemoryAddress() {
273 return true;
274 }
275
276 @Override
277 public long memoryAddress() {
278 ensureAccessible();
279 return memoryAddress;
280 }
281
282 private long addr(int index) {
283 return memoryAddress + index;
284 }
285
286 @Override
287 protected Recycler<?> recycler() {
288 return RECYCLER;
289 }
290
291 @Override
292 protected SwappedByteBuf newSwappedByteBuf() {
293 if (PlatformDependent.isUnaligned()) {
294
295 return new UnsafeDirectSwappedByteBuf(this);
296 }
297 return super.newSwappedByteBuf();
298 }
299
300 @Override
301 public ByteBuf setZero(int index, int length) {
302 checkIndex(index, length);
303 UnsafeByteBufUtil.setZero(addr(index), length);
304 return this;
305 }
306
307 @Override
308 public ByteBuf writeZero(int length) {
309 ensureWritable(length);
310 int wIndex = writerIndex;
311 UnsafeByteBufUtil.setZero(addr(wIndex), length);
312 writerIndex = wIndex + length;
313 return this;
314 }
315 }