1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.buffer;
17
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.ByteOrder;
25 import java.nio.channels.ClosedChannelException;
26 import java.nio.channels.GatheringByteChannel;
27 import java.nio.channels.ScatteringByteChannel;
28
29 import static io.netty.util.internal.ObjectUtil.checkNotNull;
30
31
32
33
34
35
36 public class UnpooledHeapByteBuf extends AbstractReferenceCountedByteBuf {
37
38 private final ByteBufAllocator alloc;
39 byte[] array;
40 private ByteBuffer tmpNioBuf;
41
42
43
44
45
46
47
48 public UnpooledHeapByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
49 super(maxCapacity);
50
51 checkNotNull(alloc, "alloc");
52
53 if (initialCapacity > maxCapacity) {
54 throw new IllegalArgumentException(String.format(
55 "initialCapacity(%d) > maxCapacity(%d)", initialCapacity, maxCapacity));
56 }
57
58 this.alloc = alloc;
59 setArray(allocateArray(initialCapacity));
60 setIndex(0, 0);
61 }
62
63
64
65
66
67
68
69 protected UnpooledHeapByteBuf(ByteBufAllocator alloc, byte[] initialArray, int maxCapacity) {
70 super(maxCapacity);
71
72 checkNotNull(alloc, "alloc");
73 checkNotNull(initialArray, "initialArray");
74
75 if (initialArray.length > maxCapacity) {
76 throw new IllegalArgumentException(String.format(
77 "initialCapacity(%d) > maxCapacity(%d)", initialArray.length, maxCapacity));
78 }
79
80 this.alloc = alloc;
81 setArray(initialArray);
82 setIndex(0, initialArray.length);
83 }
84
85 byte[] allocateArray(int initialCapacity) {
86 return new byte[initialCapacity];
87 }
88
89 void freeArray(byte[] array) {
90
91 }
92
93 private void setArray(byte[] initialArray) {
94 array = initialArray;
95 tmpNioBuf = null;
96 }
97
98 @Override
99 public ByteBufAllocator alloc() {
100 return alloc;
101 }
102
103 @Override
104 public ByteOrder order() {
105 return ByteOrder.BIG_ENDIAN;
106 }
107
108 @Override
109 public boolean isDirect() {
110 return false;
111 }
112
113 @Override
114 public int capacity() {
115 ensureAccessible();
116 return array.length;
117 }
118
119 @Override
120 public ByteBuf capacity(int newCapacity) {
121 checkNewCapacity(newCapacity);
122
123 int oldCapacity = array.length;
124 byte[] oldArray = array;
125 if (newCapacity > oldCapacity) {
126 byte[] newArray = allocateArray(newCapacity);
127 System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
128 setArray(newArray);
129 freeArray(oldArray);
130 } else if (newCapacity < oldCapacity) {
131 byte[] newArray = allocateArray(newCapacity);
132 int readerIndex = readerIndex();
133 if (readerIndex < newCapacity) {
134 int writerIndex = writerIndex();
135 if (writerIndex > newCapacity) {
136 writerIndex(writerIndex = newCapacity);
137 }
138 System.arraycopy(oldArray, readerIndex, newArray, readerIndex, writerIndex - readerIndex);
139 } else {
140 setIndex(newCapacity, newCapacity);
141 }
142 setArray(newArray);
143 freeArray(oldArray);
144 }
145 return this;
146 }
147
148 @Override
149 public boolean hasArray() {
150 return true;
151 }
152
153 @Override
154 public byte[] array() {
155 ensureAccessible();
156 return array;
157 }
158
159 @Override
160 public int arrayOffset() {
161 return 0;
162 }
163
164 @Override
165 public boolean hasMemoryAddress() {
166 return false;
167 }
168
169 @Override
170 public long memoryAddress() {
171 throw new UnsupportedOperationException();
172 }
173
174 @Override
175 public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
176 checkDstIndex(index, length, dstIndex, dst.capacity());
177 if (dst.hasMemoryAddress()) {
178 PlatformDependent.copyMemory(array, index, dst.memoryAddress() + dstIndex, length);
179 } else if (dst.hasArray()) {
180 getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
181 } else {
182 dst.setBytes(dstIndex, array, index, length);
183 }
184 return this;
185 }
186
187 @Override
188 public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
189 checkDstIndex(index, length, dstIndex, dst.length);
190 System.arraycopy(array, index, dst, dstIndex, length);
191 return this;
192 }
193
194 @Override
195 public ByteBuf getBytes(int index, ByteBuffer dst) {
196 checkIndex(index, dst.remaining());
197 dst.put(array, index, dst.remaining());
198 return this;
199 }
200
201 @Override
202 public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
203 ensureAccessible();
204 out.write(array, index, length);
205 return this;
206 }
207
208 @Override
209 public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
210 ensureAccessible();
211 return getBytes(index, out, length, false);
212 }
213
214 private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException {
215 ensureAccessible();
216 ByteBuffer tmpBuf;
217 if (internal) {
218 tmpBuf = internalNioBuffer();
219 } else {
220 tmpBuf = ByteBuffer.wrap(array);
221 }
222 return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length));
223 }
224
225 @Override
226 public int readBytes(GatheringByteChannel out, int length) throws IOException {
227 checkReadableBytes(length);
228 int readBytes = getBytes(readerIndex, out, length, true);
229 readerIndex += readBytes;
230 return readBytes;
231 }
232
233 @Override
234 public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
235 checkSrcIndex(index, length, srcIndex, src.capacity());
236 if (src.hasMemoryAddress()) {
237 PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, array, index, length);
238 } else if (src.hasArray()) {
239 setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
240 } else {
241 src.getBytes(srcIndex, array, 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 System.arraycopy(src, srcIndex, array, index, length);
250 return this;
251 }
252
253 @Override
254 public ByteBuf setBytes(int index, ByteBuffer src) {
255 ensureAccessible();
256 src.get(array, index, src.remaining());
257 return this;
258 }
259
260 @Override
261 public int setBytes(int index, InputStream in, int length) throws IOException {
262 ensureAccessible();
263 return in.read(array, index, length);
264 }
265
266 @Override
267 public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
268 ensureAccessible();
269 try {
270 return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
271 } catch (ClosedChannelException ignored) {
272 return -1;
273 }
274 }
275
276 @Override
277 public int nioBufferCount() {
278 return 1;
279 }
280
281 @Override
282 public ByteBuffer nioBuffer(int index, int length) {
283 ensureAccessible();
284 return ByteBuffer.wrap(array, index, length).slice();
285 }
286
287 @Override
288 public ByteBuffer[] nioBuffers(int index, int length) {
289 return new ByteBuffer[] { nioBuffer(index, length) };
290 }
291
292 @Override
293 public ByteBuffer internalNioBuffer(int index, int length) {
294 checkIndex(index, length);
295 return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
296 }
297
298 @Override
299 public byte getByte(int index) {
300 ensureAccessible();
301 return _getByte(index);
302 }
303
304 @Override
305 protected byte _getByte(int index) {
306 return HeapByteBufUtil.getByte(array, index);
307 }
308
309 @Override
310 public short getShort(int index) {
311 ensureAccessible();
312 return _getShort(index);
313 }
314
315 @Override
316 protected short _getShort(int index) {
317 return HeapByteBufUtil.getShort(array, index);
318 }
319
320 @Override
321 public int getUnsignedMedium(int index) {
322 ensureAccessible();
323 return _getUnsignedMedium(index);
324 }
325
326 @Override
327 protected int _getUnsignedMedium(int index) {
328 return HeapByteBufUtil.getUnsignedMedium(array, index);
329 }
330
331 @Override
332 public int getInt(int index) {
333 ensureAccessible();
334 return _getInt(index);
335 }
336
337 @Override
338 protected int _getInt(int index) {
339 return HeapByteBufUtil.getInt(array, index);
340 }
341
342 @Override
343 public long getLong(int index) {
344 ensureAccessible();
345 return _getLong(index);
346 }
347
348 @Override
349 protected long _getLong(int index) {
350 return HeapByteBufUtil.getLong(array, index);
351 }
352
353 @Override
354 public ByteBuf setByte(int index, int value) {
355 ensureAccessible();
356 _setByte(index, value);
357 return this;
358 }
359
360 @Override
361 protected void _setByte(int index, int value) {
362 HeapByteBufUtil.setByte(array, index, value);
363 }
364
365 @Override
366 public ByteBuf setShort(int index, int value) {
367 ensureAccessible();
368 _setShort(index, value);
369 return this;
370 }
371
372 @Override
373 protected void _setShort(int index, int value) {
374 HeapByteBufUtil.setShort(array, index, value);
375 }
376
377 @Override
378 public ByteBuf setMedium(int index, int value) {
379 ensureAccessible();
380 _setMedium(index, value);
381 return this;
382 }
383
384 @Override
385 protected void _setMedium(int index, int value) {
386 HeapByteBufUtil.setMedium(array, index, value);
387 }
388
389 @Override
390 public ByteBuf setInt(int index, int value) {
391 ensureAccessible();
392 _setInt(index, value);
393 return this;
394 }
395
396 @Override
397 protected void _setInt(int index, int value) {
398 HeapByteBufUtil.setInt(array, index, value);
399 }
400
401 @Override
402 public ByteBuf setLong(int index, long value) {
403 ensureAccessible();
404 _setLong(index, value);
405 return this;
406 }
407
408 @Override
409 protected void _setLong(int index, long value) {
410 HeapByteBufUtil.setLong(array, index, value);
411 }
412
413 @Override
414 public ByteBuf copy(int index, int length) {
415 checkIndex(index, length);
416 byte[] copiedArray = new byte[length];
417 System.arraycopy(array, index, copiedArray, 0, length);
418 return new UnpooledHeapByteBuf(alloc(), copiedArray, maxCapacity());
419 }
420
421 private ByteBuffer internalNioBuffer() {
422 ByteBuffer tmpNioBuf = this.tmpNioBuf;
423 if (tmpNioBuf == null) {
424 this.tmpNioBuf = tmpNioBuf = ByteBuffer.wrap(array);
425 }
426 return tmpNioBuf;
427 }
428
429 @Override
430 protected void deallocate() {
431 freeArray(array);
432 array = null;
433 }
434
435 @Override
436 public ByteBuf unwrap() {
437 return null;
438 }
439 }