1 /*
2 * Copyright 2013 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.FixedCompositeByteBuf;
17
18 import hunt.net.buffer.AbstractReferenceCountedByteBuf;
19 import hunt.net.buffer.ByteBuf;
20 import hunt.net.buffer.ByteBufUtil;
21 import hunt.net.buffer.Unpooled;
22 import hunt.net.buffer.WrappedByteBuf;
23
24 import hunt.io.ByteBuffer;
25 import hunt.Exceptions;
26 import hunt.net.Exceptions;
27 import hunt.stream.Common;
28 import hunt.util.StringBuilder;
29 import hunt.util.Common;
30
31 import std.conv;
32 import std.format;
33 import std.concurrency : initOnce;
34
35 // import io.netty.util.internal.EmptyArrays;
36 // import io.netty.util.internal.RecyclableArrayList;
37
38 // import java.io.IOException;
39 // import java.io.InputStream;
40 // import java.io.OutputStream;
41 // import java.nio.ByteBuffer;
42 // import java.nio.ByteOrder;
43 // import java.nio.ReadOnlyBufferException;
44 // import java.nio.channels.FileChannel;
45 // import java.nio.channels.GatheringByteChannel;
46 // import java.nio.channels.ScatteringByteChannel;
47 // import java.util.Collections;
48
49 /**
50 * {@link ByteBuf} implementation which allows to wrap an array of {@link ByteBuf} in a read-only mode.
51 * This is useful to write an array of {@link ByteBuf}s.
52 */
53 // final class FixedCompositeByteBuf : AbstractReferenceCountedByteBuf {
54 // private __gshared ByteBuf[] EMPTY() {
55 // return [Unpooled.EMPTY_BUFFER()];
56 // }
57
58 // private int nioBufferCount;
59 // private int capacity;
60 // private ByteBufAllocator allocator;
61 // private ByteOrder order;
62 // private ByteBuf[] buffers;
63 // private boolean direct;
64
65 // this(ByteBufAllocator allocator, ByteBuf[] buffers...) {
66 // super(AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY);
67 // if (buffers.length == 0) {
68 // this.buffers = EMPTY;
69 // order = ByteProcessor;
70 // nioBufferCount = 1;
71 // capacity = 0;
72 // direct = false;
73 // } else {
74 // ByteBuf b = buffers[0];
75 // this.buffers = buffers;
76 // boolean direct = true;
77 // int nioBufferCount = b.nioBufferCount();
78 // int capacity = b.readableBytes();
79 // order = b.order();
80 // for (int i = 1; i < buffers.length; i++) {
81 // b = buffers[i];
82 // if (buffers[i].order() != order) {
83 // throw new IllegalArgumentException("All ByteBufs need to have same ByteOrder");
84 // }
85 // nioBufferCount += b.nioBufferCount();
86 // capacity += b.readableBytes();
87 // if (!b.isDirect()) {
88 // direct = false;
89 // }
90 // }
91 // this.nioBufferCount = nioBufferCount;
92 // this.capacity = capacity;
93 // this.direct = direct;
94 // }
95 // setIndex(0, capacity());
96 // this.allocator = allocator;
97 // }
98
99 // override
100 // boolean isWritable() {
101 // return false;
102 // }
103
104 // override
105 // boolean isWritable(int size) {
106 // return false;
107 // }
108
109 // override
110 // ByteBuf discardReadBytes() {
111 // throw new ReadOnlyBufferException();
112 // }
113
114 // override
115 // ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
116 // throw new ReadOnlyBufferException();
117 // }
118
119 // override
120 // ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
121 // throw new ReadOnlyBufferException();
122 // }
123
124 // override
125 // ByteBuf setBytes(int index, ByteBuffer src) {
126 // throw new ReadOnlyBufferException();
127 // }
128
129 // override
130 // ByteBuf setByte(int index, int value) {
131 // throw new ReadOnlyBufferException();
132 // }
133
134 // override
135 // protected void _setByte(int index, int value) {
136 // throw new ReadOnlyBufferException();
137 // }
138
139 // override
140 // ByteBuf setShort(int index, int value) {
141 // throw new ReadOnlyBufferException();
142 // }
143
144 // override
145 // protected void _setShort(int index, int value) {
146 // throw new ReadOnlyBufferException();
147 // }
148
149 // override
150 // protected void _setShortLE(int index, int value) {
151 // throw new ReadOnlyBufferException();
152 // }
153
154 // override
155 // ByteBuf setMedium(int index, int value) {
156 // throw new ReadOnlyBufferException();
157 // }
158
159 // override
160 // protected void _setMedium(int index, int value) {
161 // throw new ReadOnlyBufferException();
162 // }
163
164 // override
165 // protected void _setMediumLE(int index, int value) {
166 // throw new ReadOnlyBufferException();
167 // }
168
169 // override
170 // ByteBuf setInt(int index, int value) {
171 // throw new ReadOnlyBufferException();
172 // }
173
174 // override
175 // protected void _setInt(int index, int value) {
176 // throw new ReadOnlyBufferException();
177 // }
178
179 // override
180 // protected void _setIntLE(int index, int value) {
181 // throw new ReadOnlyBufferException();
182 // }
183
184 // override
185 // ByteBuf setLong(int index, long value) {
186 // throw new ReadOnlyBufferException();
187 // }
188
189 // override
190 // protected void _setLong(int index, long value) {
191 // throw new ReadOnlyBufferException();
192 // }
193
194 // override
195 // protected void _setLongLE(int index, long value) {
196 // throw new ReadOnlyBufferException();
197 // }
198
199 // override
200 // int setBytes(int index, InputStream in, int length) {
201 // throw new ReadOnlyBufferException();
202 // }
203
204 // override
205 // int setBytes(int index, ScatteringByteChannel in, int length) {
206 // throw new ReadOnlyBufferException();
207 // }
208
209 // override
210 // int setBytes(int index, FileChannel in, long position, int length) {
211 // throw new ReadOnlyBufferException();
212 // }
213
214 // override
215 // int capacity() {
216 // return capacity;
217 // }
218
219 // override
220 // int maxCapacity() {
221 // return capacity;
222 // }
223
224 // override
225 // ByteBuf capacity(int newCapacity) {
226 // throw new ReadOnlyBufferException();
227 // }
228
229 // override
230 // ByteBufAllocator alloc() {
231 // return allocator;
232 // }
233
234 // override
235 // ByteOrder order() {
236 // return order;
237 // }
238
239 // override
240 // ByteBuf unwrap() {
241 // return null;
242 // }
243
244 // override
245 // boolean isDirect() {
246 // return direct;
247 // }
248
249 // private Component findComponent(int index) {
250 // int readable = 0;
251 // for (int i = 0 ; i < buffers.length; i++) {
252 // Component comp = null;
253 // ByteBuf b = buffers[i];
254 // if (b instanceof Component) {
255 // comp = (Component) b;
256 // b = comp.buf;
257 // }
258 // readable += b.readableBytes();
259 // if (index < readable) {
260 // if (comp is null) {
261 // // Create a new component and store it in the array so it not create a new object
262 // // on the next access.
263 // comp = new Component(i, readable - b.readableBytes(), b);
264 // buffers[i] = comp;
265 // }
266 // return comp;
267 // }
268 // }
269 // throw new IllegalStateException();
270 // }
271
272 // /**
273 // * Return the {@link ByteBuf} stored at the given index of the array.
274 // */
275 // private ByteBuf buffer(int i) {
276 // ByteBuf b = buffers[i];
277 // return b instanceof Component ? ((Component) b).buf : b;
278 // }
279
280 // override
281 // byte getByte(int index) {
282 // return _getByte(index);
283 // }
284
285 // override
286 // protected byte _getByte(int index) {
287 // Component c = findComponent(index);
288 // return c.buf.getByte(index - c.offset);
289 // }
290
291 // override
292 // protected short _getShort(int index) {
293 // Component c = findComponent(index);
294 // if (index + 2 <= c.endOffset) {
295 // return c.buf.getShort(index - c.offset);
296 // } else if (order() == ByteProcessor) {
297 // return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff);
298 // } else {
299 // return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8);
300 // }
301 // }
302
303 // override
304 // protected short _getShortLE(int index) {
305 // Component c = findComponent(index);
306 // if (index + 2 <= c.endOffset) {
307 // return c.buf.getShortLE(index - c.offset);
308 // } else if (order() == ByteProcessor) {
309 // return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8);
310 // } else {
311 // return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff);
312 // }
313 // }
314
315 // override
316 // protected int _getUnsignedMedium(int index) {
317 // Component c = findComponent(index);
318 // if (index + 3 <= c.endOffset) {
319 // return c.buf.getUnsignedMedium(index - c.offset);
320 // } else if (order() == ByteProcessor) {
321 // return (_getShort(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff;
322 // } else {
323 // return _getShort(index) & 0xFFFF | (_getByte(index + 2) & 0xFF) << 16;
324 // }
325 // }
326
327 // override
328 // protected int _getUnsignedMediumLE(int index) {
329 // Component c = findComponent(index);
330 // if (index + 3 <= c.endOffset) {
331 // return c.buf.getUnsignedMediumLE(index - c.offset);
332 // } else if (order() == ByteProcessor) {
333 // return _getShortLE(index) & 0xffff | (_getByte(index + 2) & 0xff) << 16;
334 // } else {
335 // return (_getShortLE(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff;
336 // }
337 // }
338
339 // override
340 // protected int _getInt(int index) {
341 // Component c = findComponent(index);
342 // if (index + 4 <= c.endOffset) {
343 // return c.buf.getInt(index - c.offset);
344 // } else if (order() == ByteProcessor) {
345 // return (_getShort(index) & 0xffff) << 16 | _getShort(index + 2) & 0xffff;
346 // } else {
347 // return _getShort(index) & 0xFFFF | (_getShort(index + 2) & 0xFFFF) << 16;
348 // }
349 // }
350
351 // override
352 // protected int _getIntLE(int index) {
353 // Component c = findComponent(index);
354 // if (index + 4 <= c.endOffset) {
355 // return c.buf.getIntLE(index - c.offset);
356 // } else if (order() == ByteProcessor) {
357 // return _getShortLE(index) & 0xFFFF | (_getShortLE(index + 2) & 0xFFFF) << 16;
358 // } else {
359 // return (_getShortLE(index) & 0xffff) << 16 | _getShortLE(index + 2) & 0xffff;
360 // }
361 // }
362
363 // override
364 // protected long _getLong(int index) {
365 // Component c = findComponent(index);
366 // if (index + 8 <= c.endOffset) {
367 // return c.buf.getLong(index - c.offset);
368 // } else if (order() == ByteProcessor) {
369 // return (_getInt(index) & 0xffffffffL) << 32 | _getInt(index + 4) & 0xffffffffL;
370 // } else {
371 // return _getInt(index) & 0xFFFFFFFFL | (_getInt(index + 4) & 0xFFFFFFFFL) << 32;
372 // }
373 // }
374
375 // override
376 // protected long _getLongLE(int index) {
377 // Component c = findComponent(index);
378 // if (index + 8 <= c.endOffset) {
379 // return c.buf.getLongLE(index - c.offset);
380 // } else if (order() == ByteProcessor) {
381 // return _getIntLE(index) & 0xffffffffL | (_getIntLE(index + 4) & 0xffffffffL) << 32;
382 // } else {
383 // return (_getIntLE(index) & 0xffffffffL) << 32 | _getIntLE(index + 4) & 0xffffffffL;
384 // }
385 // }
386
387 // override
388 // ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
389 // checkDstIndex(index, length, dstIndex, dst.length);
390 // if (length == 0) {
391 // return this;
392 // }
393
394 // Component c = findComponent(index);
395 // int i = c.index;
396 // int adjustment = c.offset;
397 // ByteBuf s = c.buf;
398 // for (;;) {
399 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
400 // s.getBytes(index - adjustment, dst, dstIndex, localLength);
401 // index += localLength;
402 // dstIndex += localLength;
403 // length -= localLength;
404 // adjustment += s.readableBytes();
405 // if (length <= 0) {
406 // break;
407 // }
408 // s = buffer(++i);
409 // }
410 // return this;
411 // }
412
413 // override
414 // ByteBuf getBytes(int index, ByteBuffer dst) {
415 // int limit = dst.limit();
416 // int length = dst.remaining();
417
418 // checkIndex(index, length);
419 // if (length == 0) {
420 // return this;
421 // }
422
423 // try {
424 // Component c = findComponent(index);
425 // int i = c.index;
426 // int adjustment = c.offset;
427 // ByteBuf s = c.buf;
428 // for (;;) {
429 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
430 // dst.limit(dst.position() + localLength);
431 // s.getBytes(index - adjustment, dst);
432 // index += localLength;
433 // length -= localLength;
434 // adjustment += s.readableBytes();
435 // if (length <= 0) {
436 // break;
437 // }
438 // s = buffer(++i);
439 // }
440 // } finally {
441 // dst.limit(limit);
442 // }
443 // return this;
444 // }
445
446 // override
447 // ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
448 // checkDstIndex(index, length, dstIndex, dst.capacity());
449 // if (length == 0) {
450 // return this;
451 // }
452
453 // Component c = findComponent(index);
454 // int i = c.index;
455 // int adjustment = c.offset;
456 // ByteBuf s = c.buf;
457 // for (;;) {
458 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
459 // s.getBytes(index - adjustment, dst, dstIndex, localLength);
460 // index += localLength;
461 // dstIndex += localLength;
462 // length -= localLength;
463 // adjustment += s.readableBytes();
464 // if (length <= 0) {
465 // break;
466 // }
467 // s = buffer(++i);
468 // }
469 // return this;
470 // }
471
472 // override
473 // int getBytes(int index, GatheringByteChannel out, int length) {
474 // int count = nioBufferCount();
475 // if (count == 1) {
476 // return out.write(internalNioBuffer(index, length));
477 // } else {
478 // long writtenBytes = out.write(nioBuffers(index, length));
479 // if (writtenBytes > Integer.MAX_VALUE) {
480 // return Integer.MAX_VALUE;
481 // } else {
482 // return (int) writtenBytes;
483 // }
484 // }
485 // }
486
487 // override
488 // int getBytes(int index, FileChannel out, long position, int length) {
489 // int count = nioBufferCount();
490 // if (count == 1) {
491 // return out.write(internalNioBuffer(index, length), position);
492 // } else {
493 // long writtenBytes = 0;
494 // foreach(ByteBuffer buf ; nioBuffers(index, length)) {
495 // writtenBytes += out.write(buf, position + writtenBytes);
496 // }
497 // if (writtenBytes > Integer.MAX_VALUE) {
498 // return Integer.MAX_VALUE;
499 // } else {
500 // return (int) writtenBytes;
501 // }
502 // }
503 // }
504
505 // override
506 // ByteBuf getBytes(int index, OutputStream out, int length) {
507 // checkIndex(index, length);
508 // if (length == 0) {
509 // return this;
510 // }
511
512 // Component c = findComponent(index);
513 // int i = c.index;
514 // int adjustment = c.offset;
515 // ByteBuf s = c.buf;
516 // for (;;) {
517 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
518 // s.getBytes(index - adjustment, out, localLength);
519 // index += localLength;
520 // length -= localLength;
521 // adjustment += s.readableBytes();
522 // if (length <= 0) {
523 // break;
524 // }
525 // s = buffer(++i);
526 // }
527 // return this;
528 // }
529
530 // override
531 // ByteBuf copy(int index, int length) {
532 // checkIndex(index, length);
533 // boolean release = true;
534 // ByteBuf buf = alloc().buffer(length);
535 // try {
536 // buf.writeBytes(this, index, length);
537 // release = false;
538 // return buf;
539 // } finally {
540 // if (release) {
541 // buf.release();
542 // }
543 // }
544 // }
545
546 // override
547 // int nioBufferCount() {
548 // return nioBufferCount;
549 // }
550
551 // override
552 // ByteBuffer nioBuffer(int index, int length) {
553 // checkIndex(index, length);
554 // if (buffers.length == 1) {
555 // ByteBuf buf = buffer(0);
556 // if (buf.nioBufferCount() == 1) {
557 // return buf.nioBuffer(index, length);
558 // }
559 // }
560 // ByteBuffer merged = ByteBuffer.allocate(length).order(order());
561 // ByteBuffer[] buffers = nioBuffers(index, length);
562
563 // //noinspection ForLoopReplaceableByForEach
564 // for (int i = 0; i < buffers.length; i++) {
565 // merged.put(buffers[i]);
566 // }
567
568 // merged.flip();
569 // return merged;
570 // }
571
572 // override
573 // ByteBuffer internalNioBuffer(int index, int length) {
574 // if (buffers.length == 1) {
575 // return buffer(0).internalNioBuffer(index, length);
576 // }
577 // throw new UnsupportedOperationException();
578 // }
579
580 // override
581 // ByteBuffer[] nioBuffers(int index, int length) {
582 // checkIndex(index, length);
583 // if (length == 0) {
584 // return EmptyArrays.EMPTY_BYTE_BUFFERS;
585 // }
586
587 // RecyclableArrayList array = RecyclableArrayList.newInstance(buffers.length);
588 // try {
589 // Component c = findComponent(index);
590 // int i = c.index;
591 // int adjustment = c.offset;
592 // ByteBuf s = c.buf;
593 // for (;;) {
594 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment));
595 // switch (s.nioBufferCount()) {
596 // case 0:
597 // throw new UnsupportedOperationException();
598 // case 1:
599 // array.add(s.nioBuffer(index - adjustment, localLength));
600 // break;
601 // default:
602 // Collections.addAll(array, s.nioBuffers(index - adjustment, localLength));
603 // }
604
605 // index += localLength;
606 // length -= localLength;
607 // adjustment += s.readableBytes();
608 // if (length <= 0) {
609 // break;
610 // }
611 // s = buffer(++i);
612 // }
613
614 // return array.toArray(new ByteBuffer[0]);
615 // } finally {
616 // array.recycle();
617 // }
618 // }
619
620 // override
621 // boolean hasArray() {
622 // switch (buffers.length) {
623 // case 0:
624 // return true;
625 // case 1:
626 // return buffer(0).hasArray();
627 // default:
628 // return false;
629 // }
630 // }
631
632 // override
633 // byte[] array() {
634 // switch (buffers.length) {
635 // case 0:
636 // return EmptyArrays.EMPTY_BYTES;
637 // case 1:
638 // return buffer(0).array();
639 // default:
640 // throw new UnsupportedOperationException();
641 // }
642 // }
643
644 // override
645 // int arrayOffset() {
646 // switch (buffers.length) {
647 // case 0:
648 // return 0;
649 // case 1:
650 // return buffer(0).arrayOffset();
651 // default:
652 // throw new UnsupportedOperationException();
653 // }
654 // }
655
656 // override
657 // boolean hasMemoryAddress() {
658 // switch (buffers.length) {
659 // case 0:
660 // return Unpooled.EMPTY_BUFFER.hasMemoryAddress();
661 // case 1:
662 // return buffer(0).hasMemoryAddress();
663 // default:
664 // return false;
665 // }
666 // }
667
668 // override
669 // long memoryAddress() {
670 // switch (buffers.length) {
671 // case 0:
672 // return Unpooled.EMPTY_BUFFER.memoryAddress();
673 // case 1:
674 // return buffer(0).memoryAddress();
675 // default:
676 // throw new UnsupportedOperationException();
677 // }
678 // }
679
680 // override
681 // protected void deallocate() {
682 // for (int i = 0; i < buffers.length; i++) {
683 // buffer(i).release();
684 // }
685 // }
686
687 // override
688 // string toString() {
689 // string result = super.toString();
690 // result = result.substring(0, result.length() - 1);
691 // return result ~ ", components=" ~ buffers.length + ')';
692 // }
693 // }
694
695
696
697 private static final class Component : WrappedByteBuf {
698 private int index;
699 private int offset;
700 private int endOffset;
701
702 this(int index, int offset, ByteBuf buf) {
703 super(buf);
704 this.index = index;
705 this.offset = offset;
706 endOffset = offset + buf.readableBytes();
707 }
708 }