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.EmptyArrays;
19 import io.netty.util.internal.PlatformDependent;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.nio.ByteBuffer;
25 import java.nio.ByteOrder;
26 import java.nio.channels.ClosedChannelException;
27 import java.nio.channels.FileChannel;
28 import java.nio.channels.GatheringByteChannel;
29 import java.nio.channels.ScatteringByteChannel;
30
31 import static io.netty.util.internal.ObjectUtil.checkNotNull;
32
33
34
35
36
37
38 public class UnpooledHeapByteBuf extends AbstractReferenceCountedByteBuf {
39
40 private final ByteBufAllocator alloc;
41 byte[] array;
42 private ByteBuffer tmpNioBuf;
43
44
45
46
47
48
49
50 public UnpooledHeapByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
51 super(maxCapacity);
52
53 if (initialCapacity > maxCapacity) {
54 throw new IllegalArgumentException(String.format(
55 "initialCapacity(%d) > maxCapacity(%d)", initialCapacity, maxCapacity));
56 }
57
58 this.alloc = checkNotNull(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 if (initialArray.length > maxCapacity) {
75 throw new IllegalArgumentException(String.format(
76 "initialCapacity(%d) > maxCapacity(%d)", initialArray.length, maxCapacity));
77 }
78
79 this.alloc = alloc;
80 setArray(initialArray);
81 setIndex(0, initialArray.length);
82 }
83
84 protected byte[] allocateArray(int initialCapacity) {
85 return new byte[initialCapacity];
86 }
87
88 protected void freeArray(byte[] array) {
89
90 }
91
92 private void setArray(byte[] initialArray) {
93 array = initialArray;
94 tmpNioBuf = null;
95 }
96
97 @Override
98 public ByteBufAllocator alloc() {
99 return alloc;
100 }
101
102 @Override
103 public ByteOrder order() {
104 return ByteOrder.BIG_ENDIAN;
105 }
106
107 @Override
108 public boolean isDirect() {
109 return false;
110 }
111
112 @Override
113 public int capacity() {
114 return array.length;
115 }
116
117 @Override
118 public ByteBuf capacity(int newCapacity) {
119 checkNewCapacity(newCapacity);
120 byte[] oldArray = array;
121 int oldCapacity = oldArray.length;
122 if (newCapacity == oldCapacity) {
123 return this;
124 }
125
126 int bytesToCopy;
127 if (newCapacity > oldCapacity) {
128 bytesToCopy = oldCapacity;
129 } else {
130 trimIndicesToCapacity(newCapacity);
131 bytesToCopy = newCapacity;
132 }
133 byte[] newArray = allocateArray(newCapacity);
134 System.arraycopy(oldArray, 0, newArray, 0, bytesToCopy);
135 setArray(newArray);
136 freeArray(oldArray);
137 return this;
138 }
139
140 @Override
141 public boolean hasArray() {
142 return true;
143 }
144
145 @Override
146 public byte[] array() {
147 ensureAccessible();
148 return array;
149 }
150
151 @Override
152 public int arrayOffset() {
153 return 0;
154 }
155
156 @Override
157 public boolean hasMemoryAddress() {
158 return false;
159 }
160
161 @Override
162 public long memoryAddress() {
163 throw new UnsupportedOperationException();
164 }
165
166 @Override
167 public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
168 checkDstIndex(index, length, dstIndex, dst.capacity());
169 if (dst.hasMemoryAddress()) {
170 PlatformDependent.copyMemory(array, index, dst.memoryAddress() + dstIndex, length);
171 } else if (dst.hasArray()) {
172 getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
173 } else {
174 dst.setBytes(dstIndex, array, index, length);
175 }
176 return this;
177 }
178
179 @Override
180 public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
181 checkDstIndex(index, length, dstIndex, dst.length);
182 System.arraycopy(array, index, dst, dstIndex, length);
183 return this;
184 }
185
186 @Override
187 public ByteBuf getBytes(int index, ByteBuffer dst) {
188 ensureAccessible();
189 dst.put(array, index, dst.remaining());
190 return this;
191 }
192
193 @Override
194 public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
195 ensureAccessible();
196 out.write(array, index, length);
197 return this;
198 }
199
200 @Override
201 public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
202 ensureAccessible();
203 return getBytes(index, out, length, false);
204 }
205
206 @Override
207 public int getBytes(int index, FileChannel out, long position, int length) throws IOException {
208 ensureAccessible();
209 return getBytes(index, out, position, length, false);
210 }
211
212 private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException {
213 ensureAccessible();
214 ByteBuffer tmpBuf;
215 if (internal) {
216 tmpBuf = internalNioBuffer();
217 } else {
218 tmpBuf = ByteBuffer.wrap(array);
219 }
220 return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length));
221 }
222
223 private int getBytes(int index, FileChannel out, long position, int length, boolean internal) throws IOException {
224 ensureAccessible();
225 ByteBuffer tmpBuf = internal ? internalNioBuffer() : ByteBuffer.wrap(array);
226 return out.write((ByteBuffer) tmpBuf.clear().position(index).limit(index + length), position);
227 }
228
229 @Override
230 public int readBytes(GatheringByteChannel out, int length) throws IOException {
231 checkReadableBytes(length);
232 int readBytes = getBytes(readerIndex, out, length, true);
233 readerIndex += readBytes;
234 return readBytes;
235 }
236
237 @Override
238 public int readBytes(FileChannel out, long position, int length) throws IOException {
239 checkReadableBytes(length);
240 int readBytes = getBytes(readerIndex, out, position, length, true);
241 readerIndex += readBytes;
242 return readBytes;
243 }
244
245 @Override
246 public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
247 checkSrcIndex(index, length, srcIndex, src.capacity());
248 if (src.hasMemoryAddress()) {
249 PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, array, index, length);
250 } else if (src.hasArray()) {
251 setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
252 } else {
253 src.getBytes(srcIndex, array, index, length);
254 }
255 return this;
256 }
257
258 @Override
259 public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
260 checkSrcIndex(index, length, srcIndex, src.length);
261 System.arraycopy(src, srcIndex, array, index, length);
262 return this;
263 }
264
265 @Override
266 public ByteBuf setBytes(int index, ByteBuffer src) {
267 ensureAccessible();
268 src.get(array, index, src.remaining());
269 return this;
270 }
271
272 @Override
273 public int setBytes(int index, InputStream in, int length) throws IOException {
274 ensureAccessible();
275 return in.read(array, index, length);
276 }
277
278 @Override
279 public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
280 ensureAccessible();
281 try {
282 return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
283 } catch (ClosedChannelException ignored) {
284 return -1;
285 }
286 }
287
288 @Override
289 public int setBytes(int index, FileChannel in, long position, int length) throws IOException {
290 ensureAccessible();
291 try {
292 return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length), position);
293 } catch (ClosedChannelException ignored) {
294 return -1;
295 }
296 }
297
298 @Override
299 public int nioBufferCount() {
300 return 1;
301 }
302
303 @Override
304 public ByteBuffer nioBuffer(int index, int length) {
305 ensureAccessible();
306 return ByteBuffer.wrap(array, index, length).slice();
307 }
308
309 @Override
310 public ByteBuffer[] nioBuffers(int index, int length) {
311 return new ByteBuffer[] { nioBuffer(index, length) };
312 }
313
314 @Override
315 public ByteBuffer internalNioBuffer(int index, int length) {
316 checkIndex(index, length);
317 return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
318 }
319
320 @Override
321 public final boolean isContiguous() {
322 return true;
323 }
324
325 @Override
326 public byte getByte(int index) {
327 ensureAccessible();
328 return _getByte(index);
329 }
330
331 @Override
332 protected byte _getByte(int index) {
333 return HeapByteBufUtil.getByte(array, index);
334 }
335
336 @Override
337 public short getShort(int index) {
338 ensureAccessible();
339 return _getShort(index);
340 }
341
342 @Override
343 protected short _getShort(int index) {
344 return HeapByteBufUtil.getShort(array, index);
345 }
346
347 @Override
348 public short getShortLE(int index) {
349 ensureAccessible();
350 return _getShortLE(index);
351 }
352
353 @Override
354 protected short _getShortLE(int index) {
355 return HeapByteBufUtil.getShortLE(array, index);
356 }
357
358 @Override
359 public int getUnsignedMedium(int index) {
360 ensureAccessible();
361 return _getUnsignedMedium(index);
362 }
363
364 @Override
365 protected int _getUnsignedMedium(int index) {
366 return HeapByteBufUtil.getUnsignedMedium(array, index);
367 }
368
369 @Override
370 public int getUnsignedMediumLE(int index) {
371 ensureAccessible();
372 return _getUnsignedMediumLE(index);
373 }
374
375 @Override
376 protected int _getUnsignedMediumLE(int index) {
377 return HeapByteBufUtil.getUnsignedMediumLE(array, index);
378 }
379
380 @Override
381 public int getInt(int index) {
382 ensureAccessible();
383 return _getInt(index);
384 }
385
386 @Override
387 protected int _getInt(int index) {
388 return HeapByteBufUtil.getInt(array, index);
389 }
390
391 @Override
392 public int getIntLE(int index) {
393 ensureAccessible();
394 return _getIntLE(index);
395 }
396
397 @Override
398 protected int _getIntLE(int index) {
399 return HeapByteBufUtil.getIntLE(array, index);
400 }
401
402 @Override
403 public long getLong(int index) {
404 ensureAccessible();
405 return _getLong(index);
406 }
407
408 @Override
409 protected long _getLong(int index) {
410 return HeapByteBufUtil.getLong(array, index);
411 }
412
413 @Override
414 public long getLongLE(int index) {
415 ensureAccessible();
416 return _getLongLE(index);
417 }
418
419 @Override
420 protected long _getLongLE(int index) {
421 return HeapByteBufUtil.getLongLE(array, index);
422 }
423
424 @Override
425 public ByteBuf setByte(int index, int value) {
426 ensureAccessible();
427 _setByte(index, value);
428 return this;
429 }
430
431 @Override
432 protected void _setByte(int index, int value) {
433 HeapByteBufUtil.setByte(array, index, value);
434 }
435
436 @Override
437 public ByteBuf setShort(int index, int value) {
438 ensureAccessible();
439 _setShort(index, value);
440 return this;
441 }
442
443 @Override
444 protected void _setShort(int index, int value) {
445 HeapByteBufUtil.setShort(array, index, value);
446 }
447
448 @Override
449 public ByteBuf setShortLE(int index, int value) {
450 ensureAccessible();
451 _setShortLE(index, value);
452 return this;
453 }
454
455 @Override
456 protected void _setShortLE(int index, int value) {
457 HeapByteBufUtil.setShortLE(array, index, value);
458 }
459
460 @Override
461 public ByteBuf setMedium(int index, int value) {
462 ensureAccessible();
463 _setMedium(index, value);
464 return this;
465 }
466
467 @Override
468 protected void _setMedium(int index, int value) {
469 HeapByteBufUtil.setMedium(array, index, value);
470 }
471
472 @Override
473 public ByteBuf setMediumLE(int index, int value) {
474 ensureAccessible();
475 _setMediumLE(index, value);
476 return this;
477 }
478
479 @Override
480 protected void _setMediumLE(int index, int value) {
481 HeapByteBufUtil.setMediumLE(array, index, value);
482 }
483
484 @Override
485 public ByteBuf setInt(int index, int value) {
486 ensureAccessible();
487 _setInt(index, value);
488 return this;
489 }
490
491 @Override
492 protected void _setInt(int index, int value) {
493 HeapByteBufUtil.setInt(array, index, value);
494 }
495
496 @Override
497 public ByteBuf setIntLE(int index, int value) {
498 ensureAccessible();
499 _setIntLE(index, value);
500 return this;
501 }
502
503 @Override
504 protected void _setIntLE(int index, int value) {
505 HeapByteBufUtil.setIntLE(array, index, value);
506 }
507
508 @Override
509 public ByteBuf setLong(int index, long value) {
510 ensureAccessible();
511 _setLong(index, value);
512 return this;
513 }
514
515 @Override
516 protected void _setLong(int index, long value) {
517 HeapByteBufUtil.setLong(array, index, value);
518 }
519
520 @Override
521 public ByteBuf setLongLE(int index, long value) {
522 ensureAccessible();
523 _setLongLE(index, value);
524 return this;
525 }
526
527 @Override
528 protected void _setLongLE(int index, long value) {
529 HeapByteBufUtil.setLongLE(array, index, value);
530 }
531
532 @Override
533 public ByteBuf copy(int index, int length) {
534 checkIndex(index, length);
535 return alloc().heapBuffer(length, maxCapacity()).writeBytes(array, index, length);
536 }
537
538 private ByteBuffer internalNioBuffer() {
539 ByteBuffer tmpNioBuf = this.tmpNioBuf;
540 if (tmpNioBuf == null) {
541 this.tmpNioBuf = tmpNioBuf = ByteBuffer.wrap(array);
542 }
543 return tmpNioBuf;
544 }
545
546 @Override
547 protected void deallocate() {
548 freeArray(array);
549 array = EmptyArrays.EMPTY_BYTES;
550 }
551
552 @Override
553 public ByteBuf unwrap() {
554 return null;
555 }
556 }