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 }