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 modulehunt.net.buffer.Unpooled;
17 18 importhunt.net.buffer.AbstractByteBuf;
19 importhunt.net.buffer.AbstractByteBufAllocator;
20 importhunt.net.buffer.ByteBuf;
21 importhunt.net.buffer.ByteBufAllocator;
22 importhunt.net.buffer.ByteBufUtil;
23 importhunt.net.buffer.CompositeByteBuf;
24 importhunt.net.buffer.ReadOnlyByteBufferBuf;
25 importhunt.net.buffer.UnpooledByteBufAllocator;
26 importhunt.net.buffer.UnpooledHeapByteBuf;
27 28 importhunt.Byte;
29 importhunt.io.ByteBuffer;
30 importhunt.Exceptions;
31 importhunt.logging;
32 importhunt.net.Exceptions;
33 importhunt.stream.Common;
34 importhunt.util.StringBuilder;
35 importhunt.text.Charset;
36 importhunt.util.ByteOrder;
37 38 importstd.conv;
39 importstd.format;
40 importstd.range;
41 importstd.concurrency : initOnce;
42 43 // import io.netty.buffer.CompositeByteBuf.ByteWrapper;44 // import io.netty.util.internal.PlatformDependent;45 46 // import java.nio.ByteBuffer;47 // import java.nio.ByteOrder;48 // import java.nio.CharBuffer;49 // import java.nio.charset.Charset;50 // import java.util.Arrays;51 52 53 /**
54 * Creates a new {@link ByteBuf} by allocating new space or by wrapping
55 * or copying existing byte arrays, byte buffers and a string.
56 *
57 * <h3>Use static import</h3>
58 * This classes is intended to be used with Java 5 static import statement:
59 *
60 * <pre>
61 * import static io.netty.buffer.{@link Unpooled}.*;
62 *
63 * {@link ByteBuf} heapBuffer = buffer(128);
64 * {@link ByteBuf} directBuffer = directBuffer(256);
65 * {@link ByteBuf} wrappedBuffer = wrappedBuffer(new byte[128], new byte[256]);
66 * {@link ByteBuf} copiedBuffer = copiedBuffer({@link ByteBuffer}.allocate(128));
67 * </pre>
68 *
69 * <h3>Allocating a new buffer</h3>
70 *
71 * Three buffer types are provided out of the box.
72 *
73 * <ul>
74 * <li>{@link #buffer(int)} allocates a new fixed-capacity heap buffer.</li>
75 * <li>{@link #directBuffer(int)} allocates a new fixed-capacity direct buffer.</li>
76 * </ul>
77 *
78 * <h3>Creating a wrapped buffer</h3>
79 *
80 * Wrapped buffer is a buffer which is a view of one or more existing
81 * byte arrays and byte buffers. Any changes in the content of the original
82 * array or buffer will be visible in the wrapped buffer. Various wrapper
83 * methods are provided and their name is all {@code wrappedBuffer()}.
84 * You might want to take a look at the methods that accept varargs closely if
85 * you want to create a buffer which is composed of more than one array to
86 * reduce the number of memory copy.
87 *
88 * <h3>Creating a copied buffer</h3>
89 *
90 * Copied buffer is a deep copy of one or more existing byte arrays, byte
91 * buffers or a string. Unlike a wrapped buffer, there's no shared data
92 * between the original data and the copied buffer. Various copy methods are
93 * provided and their name is all {@code copiedBuffer()}. It is also convenient
94 * to use this operation to merge multiple buffers into one buffer.
95 */96 finalclassUnpooled {
97 98 privatestaticByteBufAllocatorALLOC() {
99 __gsharedByteBufAllocatorinst;
100 returninitOnce!inst(UnpooledByteBufAllocator.DEFAULT());
101 }
102 103 /**
104 * Big endian byte order.
105 */106 enumByteOrderBIG_ENDIAN = ByteOrder.BigEndian;
107 108 /**
109 * Little endian byte order.
110 */111 enumByteOrderLITTLE_ENDIAN = ByteOrder.LittleEndian;
112 113 /**
114 * A buffer whose capacity is {@code 0}.
115 */116 staticByteBufEMPTY_BUFFER() {
117 __gsharedByteBufinst;
118 returninitOnce!inst(ALLOC.buffer(0, 0));
119 }
120 121 // static {122 // assert EMPTY_BUFFER instanceof EmptyByteBuf: "EMPTY_BUFFER must be an EmptyByteBuf.";123 // }124 125 /**
126 * Creates a new big-endian heap buffer with reasonably small initial capacity, which
127 * expands its capacity boundlessly on demand.
128 */129 staticByteBufbuffer() {
130 returnALLOC.heapBuffer();
131 }
132 133 /**
134 * Creates a new big-endian direct buffer with reasonably small initial capacity, which
135 * expands its capacity boundlessly on demand.
136 */137 staticByteBufdirectBuffer() {
138 returnALLOC.directBuffer();
139 }
140 141 /**
142 * Creates a new big-endian heap buffer with the specified {@code capacity}, which
143 * expands its capacity boundlessly on demand. The new buffer's {@code readerIndex} and
144 * {@code writerIndex} are {@code 0}.
145 */146 staticByteBufbuffer(size_tinitialCapacity) {
147 returnALLOC.heapBuffer(cast(int)initialCapacity);
148 }
149 150 /**
151 * Creates a new big-endian direct buffer with the specified {@code capacity}, which
152 * expands its capacity boundlessly on demand. The new buffer's {@code readerIndex} and
153 * {@code writerIndex} are {@code 0}.
154 */155 staticByteBufdirectBuffer(size_tinitialCapacity) {
156 returnALLOC.directBuffer(cast(int)initialCapacity);
157 }
158 159 /**
160 * Creates a new big-endian heap buffer with the specified
161 * {@code initialCapacity}, that may grow up to {@code maxCapacity}
162 * The new buffer's {@code readerIndex} and {@code writerIndex} are
163 * {@code 0}.
164 */165 staticByteBufbuffer(intinitialCapacity, intmaxCapacity) {
166 returnALLOC.heapBuffer(initialCapacity, maxCapacity);
167 }
168 169 /**
170 * Creates a new big-endian direct buffer with the specified
171 * {@code initialCapacity}, that may grow up to {@code maxCapacity}.
172 * The new buffer's {@code readerIndex} and {@code writerIndex} are
173 * {@code 0}.
174 */175 staticByteBufdirectBuffer(intinitialCapacity, intmaxCapacity) {
176 returnALLOC.directBuffer(initialCapacity, maxCapacity);
177 }
178 179 /**
180 * Creates a new big-endian buffer which wraps the specified {@code array}.
181 * A modification on the specified array's content will be visible to the
182 * returned buffer.
183 */184 staticByteBufwrappedBuffer(byte[] array) {
185 if (array.length == 0) {
186 returnEMPTY_BUFFER;
187 }
188 returnnewUnpooledHeapByteBuf(ALLOC, array, cast(int)array.length);
189 }
190 191 /**
192 * Creates a new big-endian buffer which wraps the sub-region of the
193 * specified {@code array}. A modification on the specified array's
194 * content will be visible to the returned buffer.
195 */196 staticByteBufwrappedBuffer(byte[] array, intoffset, intlength) {
197 if (length == 0) {
198 returnEMPTY_BUFFER;
199 }
200 201 if (offset == 0 && length == array.length) {
202 returnwrappedBuffer(array);
203 }
204 205 returnwrappedBuffer(array).slice(offset, length);
206 }
207 208 /**
209 * Creates a new buffer which wraps the specified NIO buffer's current
210 * slice. A modification on the specified buffer's content will be
211 * visible to the returned buffer.
212 */213 staticByteBufwrappedBuffer(ByteBufferbuffer) {
214 if (!buffer.hasRemaining()) {
215 returnEMPTY_BUFFER;
216 }
217 if (!buffer.isDirect() && buffer.hasArray()) {
218 ByteBufb = wrappedBuffer(
219 buffer.array(),
220 buffer.arrayOffset() + buffer.position(),
221 buffer.remaining());
222 // return .order(buffer.order());223 returnb;
224 } else {
225 if (buffer.isReadOnly()) {
226 returnnewReadOnlyByteBufferBuf(ALLOC, buffer);
227 } else {
228 implementationMissing(false);
229 returnnull;
230 // return new UnpooledDirectByteBuf(ALLOC, buffer, buffer.remaining());231 }
232 }
233 234 // if (!buffer.isDirect() && buffer.hasArray()) {235 // return wrappedBuffer(236 // buffer.array(),237 // buffer.arrayOffset() + buffer.position(),238 // buffer.remaining()).order(buffer.order());239 // } else if (PlatformDependent.hasUnsafe()) {240 // if (buffer.isReadOnly()) {241 // if (buffer.isDirect()) {242 // return new ReadOnlyUnsafeDirectByteBuf(ALLOC, buffer);243 // } else {244 // return new ReadOnlyByteBufferBuf(ALLOC, buffer);245 // }246 // } else {247 // return new UnpooledUnsafeDirectByteBuf(ALLOC, buffer, buffer.remaining());248 // }249 // } else {250 // if (buffer.isReadOnly()) {251 // return new ReadOnlyByteBufferBuf(ALLOC, buffer);252 // } else {253 // return new UnpooledDirectByteBuf(ALLOC, buffer, buffer.remaining());254 // }255 // }256 }
257 258 /**
259 * Creates a new buffer which wraps the specified memory address. If {@code doFree} is true the
260 * memoryAddress will automatically be freed once the reference count of the {@link ByteBuf} reaches {@code 0}.
261 */262 // static ByteBuf wrappedBuffer(long memoryAddress, int size, bool doFree) {263 // return new WrappedUnpooledUnsafeDirectByteBuf(ALLOC, memoryAddress, size, doFree);264 // }265 266 /**
267 * Creates a new buffer which wraps the specified buffer's readable bytes.
268 * A modification on the specified buffer's content will be visible to the
269 * returned buffer.
270 * @param buffer The buffer to wrap. Reference count ownership of this variable is transferred to this method.
271 * @return The readable portion of the {@code buffer}, or an empty buffer if there is no readable portion.
272 * The caller is responsible for releasing this buffer.
273 */274 staticByteBufwrappedBuffer(ByteBufbuffer) {
275 if (buffer.isReadable()) {
276 returnbuffer.slice();
277 } else {
278 buffer.release();
279 returnEMPTY_BUFFER;
280 }
281 }
282 283 /**
284 * Creates a new big-endian composite buffer which wraps the specified
285 * arrays without copying them. A modification on the specified arrays'
286 * content will be visible to the returned buffer.
287 */288 staticByteBufwrappedBuffer(byte[][] arrays... ) {
289 returnwrappedBuffer(cast(int)arrays.length, arrays);
290 }
291 292 /**
293 * Creates a new big-endian composite buffer which wraps the readable bytes of the
294 * specified buffers without copying them. A modification on the content
295 * of the specified buffers will be visible to the returned buffer.
296 * @param buffers The buffers to wrap. Reference count ownership of all variables is transferred to this method.
297 * @return The readable portion of the {@code buffers}. The caller is responsible for releasing this buffer.
298 */299 staticByteBufwrappedBuffer(ByteBuf[] buffers...) {
300 returnwrappedBuffer(cast(int)buffers.length, buffers);
301 }
302 303 /**
304 * Creates a new big-endian composite buffer which wraps the slices of the specified
305 * NIO buffers without copying them. A modification on the content of the
306 * specified buffers will be visible to the returned buffer.
307 */308 staticByteBufwrappedBuffer(ByteBuffer[] buffers...) {
309 returnwrappedBuffer(cast(int)buffers.length, buffers);
310 }
311 312 staticByteBufwrappedBuffer(T)(intmaxNumComponents, ByteWrapper!(T) wrapper, T[] array) {
313 switch (array.length) {
314 case0:
315 break;
316 case1:
317 if (!wrapper.isEmpty(array[0])) {
318 returnwrapper.wrap(array[0]);
319 }
320 break;
321 default:
322 for (inti = 0, len = cast(int)array.length; i < len; i++) {
323 Tbytes = array[i];
324 if (bytesisnull) {
325 returnEMPTY_BUFFER;
326 }
327 if (!wrapper.isEmpty(bytes)) {
328 returnnewCompositeByteBuf(ALLOC, false, maxNumComponents, wrapper, array, i);
329 }
330 }
331 }
332 333 returnEMPTY_BUFFER;
334 }
335 336 /**
337 * Creates a new big-endian composite buffer which wraps the specified
338 * arrays without copying them. A modification on the specified arrays'
339 * content will be visible to the returned buffer.
340 */341 staticByteBufwrappedBuffer(intmaxNumComponents, byte[][] arrays...) {
342 returnwrappedBuffer(maxNumComponents, CompositeByteBuf.BYTE_ARRAY_WRAPPER, arrays);
343 }
344 345 /**
346 * Creates a new big-endian composite buffer which wraps the readable bytes of the
347 * specified buffers without copying them. A modification on the content
348 * of the specified buffers will be visible to the returned buffer.
349 * @param maxNumComponents Advisement as to how many independent buffers are allowed to exist before
350 * consolidation occurs.
351 * @param buffers The buffers to wrap. Reference count ownership of all variables is transferred to this method.
352 * @return The readable portion of the {@code buffers}. The caller is responsible for releasing this buffer.
353 */354 staticByteBufwrappedBuffer(intmaxNumComponents, ByteBuf[] buffers...) {
355 switch (buffers.length) {
356 case0:
357 break;
358 case1:
359 ByteBufbuffer = buffers[0];
360 if (buffer.isReadable()) {
361 returnwrappedBuffer(buffer); // .order(BIG_ENDIAN)362 } else {
363 buffer.release();
364 }
365 break;
366 default:
367 for (inti = 0; i < buffers.length; i++) {
368 ByteBufbuf = buffers[i];
369 if (buf.isReadable()) {
370 returnnewCompositeByteBuf(ALLOC, false, maxNumComponents, buffers, i);
371 }
372 buf.release();
373 }
374 break;
375 }
376 returnEMPTY_BUFFER;
377 }
378 379 /**
380 * Creates a new big-endian composite buffer which wraps the slices of the specified
381 * NIO buffers without copying them. A modification on the content of the
382 * specified buffers will be visible to the returned buffer.
383 */384 staticByteBufwrappedBuffer(intmaxNumComponents, ByteBuffer[] buffers... ) {
385 returnwrappedBuffer(maxNumComponents, CompositeByteBuf.BYTE_BUFFER_WRAPPER, buffers);
386 }
387 388 /**
389 * Returns a new big-endian composite buffer with no components.
390 */391 staticCompositeByteBufcompositeBuffer() {
392 returncompositeBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS);
393 }
394 395 /**
396 * Returns a new big-endian composite buffer with no components.
397 */398 staticCompositeByteBufcompositeBuffer(intmaxNumComponents) {
399 returnnewCompositeByteBuf(ALLOC, false, maxNumComponents);
400 }
401 402 /**
403 * Creates a new big-endian buffer whose content is a copy of the
404 * specified {@code array}. The new buffer's {@code readerIndex} and
405 * {@code writerIndex} are {@code 0} and {@code array.length} respectively.
406 */407 staticByteBufcopiedBuffer(byte[] array) {
408 if (array.length == 0) {
409 returnEMPTY_BUFFER;
410 }
411 returnwrappedBuffer(array.dup);
412 }
413 414 /**
415 * Creates a new big-endian buffer whose content is a copy of the
416 * specified {@code array}'s sub-region. The new buffer's
417 * {@code readerIndex} and {@code writerIndex} are {@code 0} and
418 * the specified {@code length} respectively.
419 */420 staticByteBufcopiedBuffer(byte[] array, intoffset, intlength) {
421 if (length == 0) {
422 returnEMPTY_BUFFER;
423 }
424 // byte[] copy = PlatformDependent.allocateUninitializedArray(length);425 // System.arraycopy(array, offset, copy, 0, length);426 byte[] copy = array[offset .. offset+length].dup;
427 returnwrappedBuffer(copy);
428 }
429 430 /**
431 * Creates a new buffer whose content is a copy of the specified
432 * {@code buffer}'s current slice. The new buffer's {@code readerIndex}
433 * and {@code writerIndex} are {@code 0} and {@code buffer.remaining}
434 * respectively.
435 */436 staticByteBufcopiedBuffer(ByteBufferbuffer) {
437 intlength = buffer.remaining();
438 if (length == 0) {
439 returnEMPTY_BUFFER;
440 }
441 byte[] copy = newbyte[length]; // PlatformDependent.allocateUninitializedArray(length);442 // Duplicate the buffer so we not adjust the position during our get operation.443 // See https://github.com/netty/netty/issues/3896444 ByteBufferduplicate = buffer.duplicate();
445 duplicate.get(copy);
446 returnwrappedBuffer(copy); // .order(duplicate.order())447 }
448 449 /**
450 * Creates a new buffer whose content is a copy of the specified
451 * {@code buffer}'s readable bytes. The new buffer's {@code readerIndex}
452 * and {@code writerIndex} are {@code 0} and {@code buffer.readableBytes}
453 * respectively.
454 */455 staticByteBufcopiedBuffer(ByteBufb) {
456 intreadable = b.readableBytes();
457 if (readable > 0) {
458 ByteBufcopy = buffer(readable);
459 copy.writeBytes(b, b.readerIndex(), readable);
460 returncopy;
461 } else {
462 returnEMPTY_BUFFER;
463 }
464 }
465 466 /**
467 * Creates a new big-endian buffer whose content is a merged copy of
468 * the specified {@code arrays}. The new buffer's {@code readerIndex}
469 * and {@code writerIndex} are {@code 0} and the sum of all arrays'
470 * {@code length} respectively.
471 */472 staticByteBufcopiedBuffer(byte[][] arrays...) {
473 switch (arrays.length) {
474 case0:
475 returnEMPTY_BUFFER;
476 case1:
477 if (arrays[0].length == 0) {
478 returnEMPTY_BUFFER;
479 } else {
480 returncopiedBuffer(arrays[0]);
481 }
482 483 default:
484 break; // do nothing485 }
486 487 // Merge the specified arrays into one array.488 intlength = 0;
489 foreach(byte[] a; arrays) {
490 if (int.max - length < a.length) {
491 thrownewIllegalArgumentException(
492 "The total length of the specified arrays is too big.");
493 }
494 length += a.length;
495 }
496 497 if (length == 0) {
498 returnEMPTY_BUFFER;
499 }
500 501 byte[] mergedArray = newbyte[length];
502 for (size_ti = 0, j = 0; i < arrays.length; i ++) {
503 byte[] a = arrays[i];
504 // System.arraycopy(a, 0, mergedArray, j, a.length);505 mergedArray[j .. j+a.length] = a[0 .. $];
506 j += a.length;
507 }
508 509 returnwrappedBuffer(mergedArray);
510 }
511 512 /**
513 * Creates a new buffer whose content is a merged copy of the specified
514 * {@code buffers}' readable bytes. The new buffer's {@code readerIndex}
515 * and {@code writerIndex} are {@code 0} and the sum of all buffers'
516 * {@code readableBytes} respectively.
517 *
518 * @throws IllegalArgumentException
519 * if the specified buffers' endianness are different from each
520 * other
521 */522 staticByteBufcopiedBuffer(ByteBuf[] buffers...) {
523 switch (buffers.length) {
524 case0:
525 returnEMPTY_BUFFER;
526 case1:
527 returncopiedBuffer(buffers[0]);
528 default:
529 break;
530 }
531 532 // Merge the specified buffers into one buffer.533 ByteOrderorder;
534 booldetected = false;
535 intlength = 0;
536 foreach(ByteBufb; buffers) {
537 intbLen = b.readableBytes();
538 if (bLen <= 0) {
539 continue;
540 }
541 if (int.max - length < bLen) {
542 thrownewIllegalArgumentException(
543 "The total length of the specified buffers is too big.");
544 }
545 length += bLen;
546 if (detected) {
547 if (order != b.order()) {
548 thrownewIllegalArgumentException("inconsistent byte order");
549 }
550 } else {
551 order = b.order();
552 detected = true;
553 }
554 }
555 556 if (length == 0) {
557 returnEMPTY_BUFFER;
558 }
559 560 byte[] mergedArray = newbyte[length]; // PlatformDependent.allocateUninitializedArray(length);561 for (inti = 0, j = 0; i < cast(int)buffers.length; i ++) {
562 ByteBufb = buffers[i];
563 intbLen = b.readableBytes();
564 b.getBytes(b.readerIndex(), mergedArray, j, bLen);
565 j += bLen;
566 }
567 568 returnwrappedBuffer(mergedArray); //.order(order);569 }
570 571 /**
572 * Creates a new buffer whose content is a merged copy of the specified
573 * {@code buffers}' slices. The new buffer's {@code readerIndex} and
574 * {@code writerIndex} are {@code 0} and the sum of all buffers'
575 * {@code remaining} respectively.
576 *
577 * @throws IllegalArgumentException
578 * if the specified buffers' endianness are different from each
579 * other
580 */581 staticByteBufcopiedBuffer(ByteBuffer[] buffers...) {
582 switch (buffers.length) {
583 case0:
584 returnEMPTY_BUFFER;
585 case1:
586 returncopiedBuffer(buffers[0]);
587 default:
588 break;
589 }
590 591 // Merge the specified buffers into one buffer.592 ByteOrderorder;
593 boolisDetected = false;
594 intlength = 0;
595 foreach(ByteBufferb; buffers) {
596 intbLen = b.remaining();
597 if (bLen <= 0) {
598 continue;
599 }
600 if (int.max - length < bLen) {
601 thrownewIllegalArgumentException(
602 "The total length of the specified buffers is too big.");
603 }
604 length += bLen;
605 if (isDetected) {
606 if (order != b.order()) {
607 thrownewIllegalArgumentException("inconsistent byte order");
608 }
609 } else {
610 order = b.order();
611 isDetected = true;
612 }
613 }
614 615 if (length == 0) {
616 returnEMPTY_BUFFER;
617 }
618 619 byte[] mergedArray = newbyte[length]; // PlatformDependent.allocateUninitializedArray(length);620 for (inti = 0, j = 0; i < buffers.length; i ++) {
621 // Duplicate the buffer so we not adjust the position during our get operation.622 // See https://github.com/netty/netty/issues/3896623 ByteBufferb = buffers[i].duplicate();
624 intbLen = b.remaining();
625 b.get(mergedArray, j, bLen);
626 j += bLen;
627 }
628 629 returnwrappedBuffer(mergedArray); // .order(order);630 }
631 632 /**
633 * Creates a new big-endian buffer whose content is the specified
634 * {@code string} encoded in the specified {@code charset}.
635 * The new buffer's {@code readerIndex} and {@code writerIndex} are
636 * {@code 0} and the length of the encoded string respectively.
637 */638 staticByteBufcopiedBuffer(CharSequencedata, Charsetcharset) {
639 if (data.empty()) {
640 thrownewNullPointerException("data");
641 }
642 643 returncopiedBuffer(cast(char[])data, charset);
644 // FIXME: Needing refactor or cleanup -@zxp at 8/20/2019, 6:39:37 PM645 // 646 // if (string instanceof CharBuffer) {647 // return copiedBuffer((CharBuffer) string, charset);648 // }649 650 // return copiedBuffer(CharBuffer.wrap(data), charset);651 }
652 653 /**
654 * Creates a new big-endian buffer whose content is a subregion of
655 * the specified {@code string} encoded in the specified {@code charset}.
656 * The new buffer's {@code readerIndex} and {@code writerIndex} are
657 * {@code 0} and the length of the encoded string respectively.
658 */659 // static ByteBuf copiedBuffer(660 // CharSequence string, int offset, int length, Charset charset) {661 // if (string is null) {662 // throw new NullPointerException("string");663 // }664 // if (length == 0) {665 // return EMPTY_BUFFER;666 // }667 668 // if (string instanceof CharBuffer) {669 // CharBuffer buf = (CharBuffer) string;670 // if (buf.hasArray()) {671 // return copiedBuffer(672 // buf.array(),673 // buf.arrayOffset() + buf.position() + offset,674 // length, charset);675 // }676 677 // buf = buf.slice();678 // buf.limit(length);679 // buf.position(offset);680 // return copiedBuffer(buf, charset);681 // }682 683 // return copiedBuffer(CharBuffer.wrap(string, offset, offset + length), charset);684 // }685 686 /**
687 * Creates a new big-endian buffer whose content is the specified
688 * {@code array} encoded in the specified {@code charset}.
689 * The new buffer's {@code readerIndex} and {@code writerIndex} are
690 * {@code 0} and the length of the encoded string respectively.
691 */692 staticByteBufcopiedBuffer(char[] array, Charsetcharset) {
693 if (arrayisnull) {
694 thrownewNullPointerException("array");
695 }
696 returncopiedBuffer(array, 0, array.length, charset);
697 }
698 699 /**
700 * Creates a new big-endian buffer whose content is a subregion of
701 * the specified {@code array} encoded in the specified {@code charset}.
702 * The new buffer's {@code readerIndex} and {@code writerIndex} are
703 * {@code 0} and the length of the encoded string respectively.
704 */705 staticByteBufcopiedBuffer(char[] array, size_toffset, size_tlength, Charsetcharset) {
706 if (arrayisnull) {
707 thrownewNullPointerException("array");
708 }
709 if (length == 0) {
710 returnEMPTY_BUFFER;
711 }
712 // return copiedBuffer(CharBuffer.wrap(array, offset, length), charset);713 //ALLOC.wrap()714 715 returnwrappedBuffer(cast(byte[])array[offset .. offset + length].dup);
716 }
717 718 // private static ByteBuf copiedBuffer(CharBuffer buffer, Charset charset) {719 // return ByteBufUtil.encodeString0(ALLOC, true, buffer, charset, 0);720 // }721 722 /**
723 * Creates a read-only buffer which disallows any modification operations
724 * on the specified {@code buffer}. The new buffer has the same
725 * {@code readerIndex} and {@code writerIndex} with the specified
726 * {@code buffer}.
727 *
728 * deprecated("") Use {@link ByteBuf#asReadOnly()}.
729 */730 // deprecated("")731 // static ByteBuf unmodifiableBuffer(ByteBuf buffer) {732 // ByteOrder endianness = buffer.order();733 // if (endianness == ByteOrder.BigEndian) {734 // return new ReadOnlyByteBuf(buffer);735 // }736 737 // return new ReadOnlyByteBuf(buffer.order(BIG_ENDIAN)).order(LITTLE_ENDIAN);738 // }739 740 /**
741 * Creates a new 4-byte big-endian buffer that holds the specified 32-bit integer.
742 */743 staticByteBufcopyInt(intvalue) {
744 ByteBufbuf = buffer(4);
745 buf.writeInt(value);
746 returnbuf;
747 }
748 749 /**
750 * Create a big-endian buffer that holds a sequence of the specified 32-bit integers.
751 */752 staticByteBufcopyInt(int[] values...) {
753 if (valuesisnull || values.length == 0) {
754 returnEMPTY_BUFFER;
755 }
756 ByteBufbuffer = buffer(cast(int)values.length * 4);
757 foreach(intv; values) {
758 buffer.writeInt(v);
759 }
760 returnbuffer;
761 }
762 763 /**
764 * Creates a new 2-byte big-endian buffer that holds the specified 16-bit integer.
765 */766 // static ByteBuf copyShort(int value) {767 // ByteBuf buf = buffer(2);768 // buf.writeShort(value);769 // return buf;770 // }771 772 /**
773 * Create a new big-endian buffer that holds a sequence of the specified 16-bit integers.
774 */775 // static ByteBuf copyShort(short[] values...) {776 // if (values is null || values.length == 0) {777 // return EMPTY_BUFFER;778 // }779 // ByteBuf buffer = buffer(cast(int)values.length * 2);780 // foreach(int v; values) {781 // buffer.writeShort(v);782 // }783 // return buffer;784 // }785 786 /**
787 * Create a new big-endian buffer that holds a sequence of the specified 16-bit integers.
788 */789 staticByteBufcopyShort(int[] values...) {
790 if (valuesisnull || values.length == 0) {
791 returnEMPTY_BUFFER;
792 }
793 ByteBufbuffer = buffer(cast(int)values.length * 2);
794 foreach(intv; values) {
795 buffer.writeShort(v);
796 }
797 returnbuffer;
798 }
799 800 /**
801 * Creates a new 3-byte big-endian buffer that holds the specified 24-bit integer.
802 */803 staticByteBufcopyMedium(intvalue) {
804 ByteBufbuf = buffer(3);
805 buf.writeMedium(value);
806 returnbuf;
807 }
808 809 /**
810 * Create a new big-endian buffer that holds a sequence of the specified 24-bit integers.
811 */812 staticByteBufcopyMedium(int[] values...) {
813 if (valuesisnull || values.length == 0) {
814 returnEMPTY_BUFFER;
815 }
816 ByteBufbuffer = buffer(cast(int)values.length * 3);
817 foreach(intv; values) {
818 buffer.writeMedium(v);
819 }
820 returnbuffer;
821 }
822 823 /**
824 * Creates a new 8-byte big-endian buffer that holds the specified 64-bit integer.
825 */826 // static ByteBuf copyLong(long value) {827 // ByteBuf buf = buffer(8);828 // buf.writeLong(value);829 // return buf;830 // }831 832 /**
833 * Create a new big-endian buffer that holds a sequence of the specified 64-bit integers.
834 */835 staticByteBufcopyLong(long[] values...) {
836 if (valuesisnull || values.length == 0) {
837 returnEMPTY_BUFFER;
838 }
839 ByteBufbuffer = buffer(cast(int)values.length * 8);
840 foreach(longv; values) {
841 buffer.writeLong(v);
842 }
843 returnbuffer;
844 }
845 846 /**
847 * Creates a new single-byte big-endian buffer that holds the specified bool value.
848 */849 staticByteBufcopyBoolean(boolvalue) {
850 ByteBufbuf = buffer(1);
851 buf.writeBoolean(value);
852 returnbuf;
853 }
854 855 /**
856 * Create a new big-endian buffer that holds a sequence of the specified bool values.
857 */858 staticByteBufcopyBoolean(bool[] values...) {
859 if (valuesisnull || values.length == 0) {
860 returnEMPTY_BUFFER;
861 }
862 ByteBufbuffer = buffer(values.length);
863 foreach(boolv; values) {
864 buffer.writeBoolean(v);
865 }
866 returnbuffer;
867 }
868 869 /**
870 * Creates a new 4-byte big-endian buffer that holds the specified 32-bit floating point number.
871 */872 // static ByteBuf copyFloat(float value) {873 // ByteBuf buf = buffer(4);874 // buf.writeFloat(value);875 // return buf;876 // }877 878 /**
879 * Create a new big-endian buffer that holds a sequence of the specified 32-bit floating point numbers.
880 */881 staticByteBufcopyFloat(float[] values...) {
882 if (valuesisnull || values.length == 0) {
883 returnEMPTY_BUFFER;
884 }
885 ByteBufbuffer = buffer(values.length * 4);
886 foreach(floatv; values) {
887 buffer.writeFloat(v);
888 }
889 returnbuffer;
890 }
891 892 /**
893 * Creates a new 8-byte big-endian buffer that holds the specified 64-bit floating point number.
894 */895 // static ByteBuf copyDouble(double value) {896 // ByteBuf buf = buffer(8);897 // buf.writeDouble(value);898 // return buf;899 // }900 901 /**
902 * Create a new big-endian buffer that holds a sequence of the specified 64-bit floating point numbers.
903 */904 staticByteBufcopyDouble(double[] values...) {
905 if (valuesisnull || values.length == 0) {
906 returnEMPTY_BUFFER;
907 }
908 ByteBufbuffer = buffer(values.length * 8);
909 foreach(doublev; values) {
910 buffer.writeDouble(v);
911 }
912 returnbuffer;
913 }
914 915 /**
916 * Return a unreleasable view on the given {@link ByteBuf} which will just ignore release and retain calls.
917 */918 // static ByteBuf unreleasableBuffer(ByteBuf buf) {919 // return new UnreleasableByteBuf(buf);920 // }921 922 /**
923 * Wrap the given {@link ByteBuf}s in an unmodifiable {@link ByteBuf}. Be aware the returned {@link ByteBuf} will
924 * not try to slice the given {@link ByteBuf}s to reduce GC-Pressure.
925 *
926 * deprecated("") Use {@link #wrappedUnmodifiableBuffer(ByteBuf...)}.
927 */928 // deprecated("")929 // static ByteBuf unmodifiableBuffer(ByteBuf[] buffers...) {930 // return wrappedUnmodifiableBuffer(true, buffers);931 // }932 933 /**
934 * Wrap the given {@link ByteBuf}s in an unmodifiable {@link ByteBuf}. Be aware the returned {@link ByteBuf} will
935 * not try to slice the given {@link ByteBuf}s to reduce GC-Pressure.
936 *
937 * The returned {@link ByteBuf} may wrap the provided array directly, and so should not be subsequently modified.
938 */939 staticByteBufwrappedUnmodifiableBuffer(ByteBuf[] buffers...) {
940 returnwrappedUnmodifiableBuffer(false, buffers);
941 }
942 943 privatestaticByteBufwrappedUnmodifiableBuffer(boolcopy, ByteBuf[] buffers...) {
944 switch (buffers.length) {
945 case0:
946 returnEMPTY_BUFFER;
947 case1:
948 returnbuffers[0].asReadOnly();
949 default:
950 ByteBuf[] bs = buffers;
951 if (copy) {
952 bs = buffers.dup;
953 // buffers = Arrays.copyOf(buffers, buffers.length, ByteBuf[].class);954 }
955 implementationMissing(false);
956 returnnull;
957 // return new FixedCompositeByteBuf(ALLOC, bs);958 }
959 }
960 961 privatethis() {
962 // Unused963 }
964 }
965 966 967 968 aliascopiedBuffer = Unpooled.copiedBuffer;
969 aliascopyInt = Unpooled.copyInt;
970 aliascopyShort = Unpooled.copyShort;
971 aliascopyMedium = Unpooled.copyMedium;
972 aliascopyLong = Unpooled.copyLong;
973 aliascopyBoolean = Unpooled.copyBoolean;
974 aliascopyFloat = Unpooled.copyFloat;
975 aliascopyDouble = Unpooled.copyDouble;
976 aliasEMPTY_BUFFER = Unpooled.EMPTY_BUFFER;
977 aliaswrappedUnmodifiableBuffer = Unpooled.wrappedUnmodifiableBuffer;
978 aliaswrappedBuffer = Unpooled.wrappedBuffer;