1 /*
2 * Copyright 2012 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 module hunt.net.buffer.UnpooledHeapByteBuf;
17
18 import hunt.net.buffer.AbstractByteBuf;
19 import hunt.net.buffer.AbstractReferenceCountedByteBuf;
20 import hunt.net.buffer.ByteBuf;
21 import hunt.net.buffer.ByteBufAllocator;
22 import hunt.net.buffer.ByteBufUtil;
23 import hunt.net.buffer.HeapByteBufUtil;
24
25 import hunt.Byte;
26 import hunt.io.ByteBuffer;
27 import hunt.io.BufferUtils;
28 import hunt.Exceptions;
29 import hunt.net.Exceptions;
30 import hunt.stream.Common;
31 import hunt.util.StringBuilder;
32 import hunt.util.ByteOrder;
33
34 import std.conv;
35 import std.format;
36
37
38 /**
39 * Big endian Java heap buffer implementation. It is recommended to use
40 * {@link UnpooledByteBufAllocator#heapBuffer(int, int)}, {@link Unpooled#buffer(int)} and
41 * {@link Unpooled#wrappedBuffer(byte[])} instead of calling the constructor explicitly.
42 */
43 class UnpooledHeapByteBuf : AbstractReferenceCountedByteBuf {
44
45 private ByteBufAllocator _alloc;
46 byte[] _array;
47 private ByteBuffer tmpNioBuf;
48
49 /**
50 * Creates a new heap buffer with a newly allocated byte array.
51 *
52 * @param initialCapacity the initial capacity of the underlying byte array
53 * @param maxCapacity the max capacity of the underlying byte array
54 */
55 this(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
56 super(maxCapacity);
57
58 checkNotNull(alloc, "alloc");
59
60 if (initialCapacity > maxCapacity) {
61 throw new IllegalArgumentException(format(
62 "initialCapacity(%d) > maxCapacity(%d)", initialCapacity, maxCapacity));
63 }
64
65 this._alloc = alloc;
66 setArray(allocateArray(initialCapacity));
67 setIndex(0, 0);
68 }
69
70 /**
71 * Creates a new heap buffer with an existing byte array.
72 *
73 * @param initialArray the initial underlying byte array
74 * @param maxCapacity the max capacity of the underlying byte array
75 */
76 this(ByteBufAllocator alloc, byte[] initialArray, int maxCapacity) {
77 super(maxCapacity);
78
79 checkNotNull(alloc, "alloc");
80 checkNotNull(initialArray, "initialArray");
81
82 if (initialArray.length > maxCapacity) {
83 throw new IllegalArgumentException(format(
84 "initialCapacity(%d) > maxCapacity(%d)", initialArray.length, maxCapacity));
85 }
86
87 this._alloc = alloc;
88 setArray(initialArray);
89 setIndex(0, cast(int)initialArray.length);
90 }
91
92 protected byte[] allocateArray(int initialCapacity) {
93 return new byte[initialCapacity];
94 }
95
96 protected void freeArray(byte[]) {
97 // NOOP
98 }
99
100 private void setArray(byte[] initialArray) {
101 _array = initialArray;
102 tmpNioBuf = null;
103 }
104
105 override
106 ByteBufAllocator alloc() {
107 return _alloc;
108 }
109
110 override
111 ByteOrder order() {
112 return ByteOrder.BigEndian;
113 }
114
115 override
116 bool isDirect() {
117 return false;
118 }
119
120 override
121 int capacity() {
122 return cast(int)_array.length;
123 }
124
125 override
126 ByteBuf capacity(int newCapacity) {
127 checkNewCapacity(newCapacity);
128
129 int oldCapacity = cast(int)_array.length;
130 byte[] oldArray = _array;
131 if (newCapacity > oldCapacity) {
132 byte[] newArray = allocateArray(newCapacity);
133 // System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
134 newArray[0..oldArray.length] = oldArray[0 .. $];
135 setArray(newArray);
136 freeArray(oldArray);
137 } else if (newCapacity < oldCapacity) {
138 byte[] newArray = allocateArray(newCapacity);
139 int rIndex = readerIndex();
140 if (rIndex < newCapacity) {
141 int wIndex = writerIndex();
142 if (wIndex > newCapacity) {
143 wIndex = newCapacity;
144 writerIndex(wIndex);
145 }
146 // System.arraycopy(oldArray, rIndex, newArray, rIndex, wIndex - rIndex);
147 newArray[rIndex .. wIndex] = oldArray[rIndex .. wIndex];
148 } else {
149 setIndex(newCapacity, newCapacity);
150 }
151 setArray(newArray);
152 freeArray(oldArray);
153 }
154 return this;
155 }
156
157 override
158 bool hasArray() {
159 return true;
160 }
161
162 override
163 byte[] array() {
164 ensureAccessible();
165 return _array;
166 }
167
168 override
169 int arrayOffset() {
170 return 0;
171 }
172
173 override
174 bool hasMemoryAddress() {
175 return false;
176 }
177
178 override
179 long memoryAddress() {
180 throw new UnsupportedOperationException();
181 }
182
183 override
184 ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
185 checkDstIndex(index, length, dstIndex, dst.capacity());
186 // if (dst.hasMemoryAddress()) {
187 // PlatformDependent.copyMemory(_array, index, dst.memoryAddress() + dstIndex, length);
188 // } else if (dst.hasArray()) {
189 // getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
190 // } else {
191 // dst.setBytes(dstIndex, _array, index, length);
192 // }
193 if (dst.hasArray()) {
194 getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
195 } else {
196 dst.setBytes(dstIndex, _array, index, length);
197 }
198 return this;
199 }
200
201 override
202 ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
203 checkDstIndex(index, length, dstIndex, cast(int)dst.length);
204 // System.arraycopy(_array, index, dst, dstIndex, length);
205 dst[dstIndex .. dstIndex + length] = _array[index .. index+length];
206 return this;
207 }
208
209 override
210 ByteBuf getBytes(int index, ByteBuffer dst) {
211 ensureAccessible();
212 dst.put(_array, index, dst.remaining());
213 return this;
214 }
215
216 override
217 ByteBuf getBytes(int index, OutputStream output, int length) {
218 ensureAccessible();
219 output.write(_array, index, length);
220 return this;
221 }
222
223 // override
224 // int getBytes(int index, GatheringByteChannel output, int length) {
225 // ensureAccessible();
226 // return getBytes(index, output, length, false);
227 // }
228
229 // override
230 // int getBytes(int index, FileChannel output, long position, int length) {
231 // ensureAccessible();
232 // return getBytes(index, output, position, length, false);
233 // }
234
235 // private int getBytes(int index, GatheringByteChannel output, int length, bool internal) {
236 // ensureAccessible();
237 // ByteBuffer tmpBuf;
238 // if (internal) {
239 // tmpBuf = internalNioBuffer();
240 // } else {
241 // tmpBuf = ByteBuffer.wrap(_array);
242 // }
243 // return output.write(cast(ByteBuffer) tmpBuf.clear().position(index).limit(index + length));
244 // }
245
246 // private int getBytes(int index, FileChannel output, long position, int length, bool internal) {
247 // ensureAccessible();
248 // ByteBuffer tmpBuf = internal ? internalNioBuffer() : ByteBuffer.wrap(_array);
249 // return output.write(cast(ByteBuffer) tmpBuf.clear().position(index).limit(index + length), position);
250 // }
251
252 // override
253 // int readBytes(GatheringByteChannel output, int length) {
254 // checkReadableBytes(length);
255 // int readBytes = getBytes(readerIndex, output, length, true);
256 // readerIndex += readBytes;
257 // return readBytes;
258 // }
259
260 // override
261 // int readBytes(FileChannel output, long position, int length) {
262 // checkReadableBytes(length);
263 // int readBytes = getBytes(readerIndex, output, position, length, true);
264 // readerIndex += readBytes;
265 // return readBytes;
266 // }
267
268 override
269 ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
270 checkSrcIndex(index, length, srcIndex, src.capacity());
271 // if (src.hasMemoryAddress()) {
272 // PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, _array, index, length);
273 // } else if (src.hasArray()) {
274 // setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
275 // } else {
276 // src.getBytes(srcIndex, _array, index, length);
277 // }
278
279 if (src.hasArray()) {
280 setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
281 } else {
282 src.getBytes(srcIndex, _array, index, length);
283 }
284 return this;
285 }
286
287 override
288 ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
289 checkSrcIndex(index, length, srcIndex, cast(int)src.length);
290 // System.arraycopy(src, srcIndex, _array, index, length);
291 _array[index .. index+length] = src[srcIndex .. srcIndex+length];
292 return this;
293 }
294
295 override
296 ByteBuf setBytes(int index, ByteBuffer src) {
297 ensureAccessible();
298 src.get(_array, index, src.remaining());
299 return this;
300 }
301
302 override
303 int setBytes(int index, InputStream input, int length) {
304 ensureAccessible();
305 return input.read(_array, index, length);
306 }
307
308 // override
309 // int setBytes(int index, ScatteringByteChannel input, int length) {
310 // ensureAccessible();
311 // try {
312 // return input.read(cast(ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
313 // } catch (ClosedChannelException ignored) {
314 // return -1;
315 // }
316 // }
317
318 // override
319 // int setBytes(int index, FileChannel input, long position, int length) {
320 // ensureAccessible();
321 // try {
322 // return input.read(cast(ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length), position);
323 // } catch (ClosedChannelException ignored) {
324 // return -1;
325 // }
326 // }
327
328 override
329 int nioBufferCount() {
330 return 1;
331 }
332
333 override
334 ByteBuffer nioBuffer(int index, int length) {
335 ensureAccessible();
336 return BufferUtils.wrap(_array, index, length).slice();
337 }
338
339 override
340 ByteBuffer[] nioBuffers(int index, int length) {
341 return [nioBuffer(index, length)];
342 }
343
344 override
345 ByteBuffer internalNioBuffer(int index, int length) {
346 checkIndex(index, length);
347 return cast(ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
348 }
349
350 override
351 byte getByte(int index) {
352 ensureAccessible();
353 return _getByte(index);
354 }
355
356 override
357 protected byte _getByte(int index) {
358 return HeapByteBufUtil.getByte(_array, index);
359 }
360
361 override
362 short getShort(int index) {
363 ensureAccessible();
364 return _getShort(index);
365 }
366
367 override
368 protected short _getShort(int index) {
369 return HeapByteBufUtil.getShort(_array, index);
370 }
371
372 override
373 short getShortLE(int index) {
374 ensureAccessible();
375 return _getShortLE(index);
376 }
377
378 override
379 protected short _getShortLE(int index) {
380 return HeapByteBufUtil.getShortLE(_array, index);
381 }
382
383 override
384 int getUnsignedMedium(int index) {
385 ensureAccessible();
386 return _getUnsignedMedium(index);
387 }
388
389 override
390 protected int _getUnsignedMedium(int index) {
391 return HeapByteBufUtil.getUnsignedMedium(_array, index);
392 }
393
394 override
395 int getUnsignedMediumLE(int index) {
396 ensureAccessible();
397 return _getUnsignedMediumLE(index);
398 }
399
400 override
401 protected int _getUnsignedMediumLE(int index) {
402 return HeapByteBufUtil.getUnsignedMediumLE(_array, index);
403 }
404
405 override
406 int getInt(int index) {
407 ensureAccessible();
408 return _getInt(index);
409 }
410
411 override
412 protected int _getInt(int index) {
413 return HeapByteBufUtil.getInt(_array, index);
414 }
415
416 override
417 int getIntLE(int index) {
418 ensureAccessible();
419 return _getIntLE(index);
420 }
421
422 override
423 protected int _getIntLE(int index) {
424 return HeapByteBufUtil.getIntLE(_array, index);
425 }
426
427 override
428 long getLong(int index) {
429 ensureAccessible();
430 return _getLong(index);
431 }
432
433 override
434 protected long _getLong(int index) {
435 return HeapByteBufUtil.getLong(_array, index);
436 }
437
438 override
439 long getLongLE(int index) {
440 ensureAccessible();
441 return _getLongLE(index);
442 }
443
444 override
445 protected long _getLongLE(int index) {
446 return HeapByteBufUtil.getLongLE(_array, index);
447 }
448
449 override
450 ByteBuf setByte(int index, int value) {
451 ensureAccessible();
452 _setByte(index, value);
453 return this;
454 }
455
456 override
457 protected void _setByte(int index, int value) {
458 HeapByteBufUtil.setByte(_array, index, value);
459 }
460
461 override
462 ByteBuf setShort(int index, int value) {
463 ensureAccessible();
464 _setShort(index, value);
465 return this;
466 }
467
468 override
469 protected void _setShort(int index, int value) {
470 HeapByteBufUtil.setShort(_array, index, value);
471 }
472
473 override
474 ByteBuf setShortLE(int index, int value) {
475 ensureAccessible();
476 _setShortLE(index, value);
477 return this;
478 }
479
480 override
481 protected void _setShortLE(int index, int value) {
482 HeapByteBufUtil.setShortLE(_array, index, value);
483 }
484
485 override
486 ByteBuf setMedium(int index, int value) {
487 ensureAccessible();
488 _setMedium(index, value);
489 return this;
490 }
491
492 override
493 protected void _setMedium(int index, int value) {
494 HeapByteBufUtil.setMedium(_array, index, value);
495 }
496
497 override
498 ByteBuf setMediumLE(int index, int value) {
499 ensureAccessible();
500 _setMediumLE(index, value);
501 return this;
502 }
503
504 override
505 protected void _setMediumLE(int index, int value) {
506 HeapByteBufUtil.setMediumLE(_array, index, value);
507 }
508
509 override
510 ByteBuf setInt(int index, int value) {
511 ensureAccessible();
512 _setInt(index, value);
513 return this;
514 }
515
516 override
517 protected void _setInt(int index, int value) {
518 HeapByteBufUtil.setInt(_array, index, value);
519 }
520
521 override
522 ByteBuf setIntLE(int index, int value) {
523 ensureAccessible();
524 _setIntLE(index, value);
525 return this;
526 }
527
528 override
529 protected void _setIntLE(int index, int value) {
530 HeapByteBufUtil.setIntLE(_array, index, value);
531 }
532
533 override
534 ByteBuf setLong(int index, long value) {
535 ensureAccessible();
536 _setLong(index, value);
537 return this;
538 }
539
540 override
541 protected void _setLong(int index, long value) {
542 HeapByteBufUtil.setLong(_array, index, value);
543 }
544
545 override
546 ByteBuf setLongLE(int index, long value) {
547 ensureAccessible();
548 _setLongLE(index, value);
549 return this;
550 }
551
552 override
553 protected void _setLongLE(int index, long value) {
554 HeapByteBufUtil.setLongLE(_array, index, value);
555 }
556
557 override
558 ByteBuf copy(int index, int length) {
559 checkIndex(index, length);
560 return alloc().heapBuffer(length, maxCapacity()).writeBytes(_array, index, length);
561 }
562
563 private ByteBuffer internalNioBuffer() {
564 ByteBuffer tmpNioBuf = this.tmpNioBuf;
565 if (tmpNioBuf is null) {
566 this.tmpNioBuf = tmpNioBuf = BufferUtils.wrap(_array);
567 }
568 return tmpNioBuf;
569 }
570
571 override
572 protected void deallocate() {
573 freeArray(_array);
574 _array = [];
575 }
576
577 override
578 ByteBuf unwrap() {
579 return null;
580 }
581 }