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