1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package io.netty.buffer;
16
17 import io.netty.util.Recycler;
18 import io.netty.util.internal.PlatformDependent;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.nio.ByteBuffer;
24 import java.nio.channels.ClosedChannelException;
25 import java.nio.channels.GatheringByteChannel;
26 import java.nio.channels.ScatteringByteChannel;
27
28 class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
29
30 private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() {
31 @Override
32 protected PooledHeapByteBuf newObject(Handle handle) {
33 return new PooledHeapByteBuf(handle, 0);
34 }
35 };
36
37 static PooledHeapByteBuf newInstance(int maxCapacity) {
38 PooledHeapByteBuf buf = RECYCLER.get();
39 buf.reuse(maxCapacity);
40 return buf;
41 }
42
43 PooledHeapByteBuf(Recycler.Handle recyclerHandle, int maxCapacity) {
44 super(recyclerHandle, maxCapacity);
45 }
46
47 @Override
48 public final boolean isDirect() {
49 return false;
50 }
51
52 @Override
53 protected byte _getByte(int index) {
54 return HeapByteBufUtil.getByte(memory, idx(index));
55 }
56
57 @Override
58 protected short _getShort(int index) {
59 return HeapByteBufUtil.getShort(memory, idx(index));
60 }
61
62 @Override
63 protected int _getUnsignedMedium(int index) {
64 return HeapByteBufUtil.getUnsignedMedium(memory, idx(index));
65 }
66
67 @Override
68 protected int _getInt(int index) {
69 return HeapByteBufUtil.getInt(memory, idx(index));
70 }
71
72 @Override
73 protected long _getLong(int index) {
74 return HeapByteBufUtil.getLong(memory, idx(index));
75 }
76
77 @Override
78 public final ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
79 checkDstIndex(index, length, dstIndex, dst.capacity());
80 if (dst.hasMemoryAddress()) {
81 PlatformDependent.copyMemory(memory, idx(index), dst.memoryAddress() + dstIndex, length);
82 } else if (dst.hasArray()) {
83 getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
84 } else {
85 dst.setBytes(dstIndex, memory, idx(index), length);
86 }
87 return this;
88 }
89
90 @Override
91 public final ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
92 checkDstIndex(index, length, dstIndex, dst.length);
93 System.arraycopy(memory, idx(index), dst, dstIndex, length);
94 return this;
95 }
96
97 @Override
98 public final ByteBuf getBytes(int index, ByteBuffer dst) {
99 checkIndex(index, dst.remaining());
100 dst.put(memory, idx(index), dst.remaining());
101 return this;
102 }
103
104 @Override
105 public final ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
106 checkIndex(index, length);
107 out.write(memory, idx(index), length);
108 return this;
109 }
110
111 @Override
112 public final int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
113 return getBytes(index, out, length, false);
114 }
115
116 private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException {
117 checkIndex(index, length);
118 index = idx(index);
119 ByteBuffer tmpBuf;
120 if (internal) {
121 tmpBuf = internalNioBuffer();
122 } else {
123 tmpBuf = ByteBuffer.wrap(memory);
124 }
125 return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length));
126 }
127
128 @Override
129 public final int readBytes(GatheringByteChannel out, int length) throws IOException {
130 checkReadableBytes(length);
131 int readBytes = getBytes(readerIndex, out, length, true);
132 readerIndex += readBytes;
133 return readBytes;
134 }
135
136 @Override
137 protected void _setByte(int index, int value) {
138 HeapByteBufUtil.setByte(memory, idx(index), value);
139 }
140
141 @Override
142 protected void _setShort(int index, int value) {
143 HeapByteBufUtil.setShort(memory, idx(index), value);
144 }
145
146 @Override
147 protected void _setMedium(int index, int value) {
148 HeapByteBufUtil.setMedium(memory, idx(index), value);
149 }
150
151 @Override
152 protected void _setInt(int index, int value) {
153 HeapByteBufUtil.setInt(memory, idx(index), value);
154 }
155
156 @Override
157 protected void _setLong(int index, long value) {
158 HeapByteBufUtil.setLong(memory, idx(index), value);
159 }
160
161 @Override
162 public final ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
163 checkSrcIndex(index, length, srcIndex, src.capacity());
164 if (src.hasMemoryAddress()) {
165 PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, memory, idx(index), length);
166 } else if (src.hasArray()) {
167 setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
168 } else {
169 src.getBytes(srcIndex, memory, idx(index), length);
170 }
171 return this;
172 }
173
174 @Override
175 public final ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
176 checkSrcIndex(index, length, srcIndex, src.length);
177 System.arraycopy(src, srcIndex, memory, idx(index), length);
178 return this;
179 }
180
181 @Override
182 public final ByteBuf setBytes(int index, ByteBuffer src) {
183 int length = src.remaining();
184 checkIndex(index, length);
185 src.get(memory, idx(index), length);
186 return this;
187 }
188
189 @Override
190 public final int setBytes(int index, InputStream in, int length) throws IOException {
191 checkIndex(index, length);
192 return in.read(memory, idx(index), length);
193 }
194
195 @Override
196 public final int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
197 checkIndex(index, length);
198 index = idx(index);
199 try {
200 return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
201 } catch (ClosedChannelException ignored) {
202 return -1;
203 }
204 }
205
206 @Override
207 public final ByteBuf copy(int index, int length) {
208 checkIndex(index, length);
209 ByteBuf copy = alloc().heapBuffer(length, maxCapacity());
210 copy.writeBytes(memory, idx(index), length);
211 return copy;
212 }
213
214 @Override
215 public final int nioBufferCount() {
216 return 1;
217 }
218
219 @Override
220 public final ByteBuffer[] nioBuffers(int index, int length) {
221 return new ByteBuffer[] { nioBuffer(index, length) };
222 }
223
224 @Override
225 public final ByteBuffer nioBuffer(int index, int length) {
226 checkIndex(index, length);
227 index = idx(index);
228 ByteBuffer buf = ByteBuffer.wrap(memory, index, length);
229 return buf.slice();
230 }
231
232 @Override
233 public final ByteBuffer internalNioBuffer(int index, int length) {
234 checkIndex(index, length);
235 index = idx(index);
236 return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
237 }
238
239 @Override
240 public final boolean hasArray() {
241 return true;
242 }
243
244 @Override
245 public final byte[] array() {
246 ensureAccessible();
247 return memory;
248 }
249
250 @Override
251 public final int arrayOffset() {
252 return offset;
253 }
254
255 @Override
256 public final boolean hasMemoryAddress() {
257 return false;
258 }
259
260 @Override
261 public final long memoryAddress() {
262 throw new UnsupportedOperationException();
263 }
264
265 @Override
266 protected final ByteBuffer newInternalNioBuffer(byte[] memory) {
267 return ByteBuffer.wrap(memory);
268 }
269
270 @Override
271 protected Recycler<?> recycler() {
272 return RECYCLER;
273 }
274 }