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.ByteProcessor;
19 import io.netty.util.IllegalReferenceCountException;
20 import io.netty.util.ReferenceCountUtil;
21 import io.netty.util.internal.EmptyArrays;
22 import io.netty.util.internal.ObjectUtil;
23 import io.netty.util.internal.RecyclableArrayList;
24
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.nio.ByteBuffer;
29 import java.nio.ByteOrder;
30 import java.nio.channels.FileChannel;
31 import java.nio.channels.GatheringByteChannel;
32 import java.nio.channels.ScatteringByteChannel;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.ConcurrentModificationException;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.NoSuchElementException;
41
42 import static io.netty.util.internal.ObjectUtil.checkNotNull;
43
44
45
46
47
48
49 public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements Iterable<ByteBuf> {
50
51 private static final ByteBuffer EMPTY_NIO_BUFFER = Unpooled.EMPTY_BUFFER.nioBuffer();
52 private static final Iterator<ByteBuf> EMPTY_ITERATOR = Collections.<ByteBuf>emptyList().iterator();
53
54 private final ByteBufAllocator alloc;
55 private final boolean direct;
56 private final int maxNumComponents;
57
58 private int componentCount;
59 private Component[] components;
60
61 private boolean freed;
62
63 private CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents, int initSize) {
64 super(AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY);
65
66 this.alloc = ObjectUtil.checkNotNull(alloc, "alloc");
67 if (maxNumComponents < 1) {
68 throw new IllegalArgumentException(
69 "maxNumComponents: " + maxNumComponents + " (expected: >= 1)");
70 }
71
72 this.direct = direct;
73 this.maxNumComponents = maxNumComponents;
74 components = newCompArray(initSize, maxNumComponents);
75 }
76
77 public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents) {
78 this(alloc, direct, maxNumComponents, 0);
79 }
80
81 public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents, ByteBuf... buffers) {
82 this(alloc, direct, maxNumComponents, buffers, 0);
83 }
84
85 CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents,
86 ByteBuf[] buffers, int offset) {
87 this(alloc, direct, maxNumComponents, buffers.length - offset);
88
89 addComponents0(false, 0, buffers, offset);
90 consolidateIfNeeded();
91 setIndex0(0, capacity());
92 }
93
94 public CompositeByteBuf(
95 ByteBufAllocator alloc, boolean direct, int maxNumComponents, Iterable<ByteBuf> buffers) {
96 this(alloc, direct, maxNumComponents,
97 buffers instanceof Collection ? ((Collection<ByteBuf>) buffers).size() : 0);
98
99 addComponents(false, 0, buffers);
100 setIndex(0, capacity());
101 }
102
103
104 interface ByteWrapper<T> {
105 ByteBuf wrap(T bytes);
106 boolean isEmpty(T bytes);
107 }
108
109 static final ByteWrapper<byte[]> BYTE_ARRAY_WRAPPER = new ByteWrapper<byte[]>() {
110 @Override
111 public ByteBuf wrap(byte[] bytes) {
112 return Unpooled.wrappedBuffer(bytes);
113 }
114 @Override
115 public boolean isEmpty(byte[] bytes) {
116 return bytes.length == 0;
117 }
118 };
119
120 static final ByteWrapper<ByteBuffer> BYTE_BUFFER_WRAPPER = new ByteWrapper<ByteBuffer>() {
121 @Override
122 public ByteBuf wrap(ByteBuffer bytes) {
123 return Unpooled.wrappedBuffer(bytes);
124 }
125 @Override
126 public boolean isEmpty(ByteBuffer bytes) {
127 return !bytes.hasRemaining();
128 }
129 };
130
131 <T> CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents,
132 ByteWrapper<T> wrapper, T[] buffers, int offset) {
133 this(alloc, direct, maxNumComponents, buffers.length - offset);
134
135 addComponents0(false, 0, wrapper, buffers, offset);
136 consolidateIfNeeded();
137 setIndex(0, capacity());
138 }
139
140 private static Component[] newCompArray(int initComponents, int maxNumComponents) {
141 int capacityGuess = Math.min(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, maxNumComponents);
142 return new Component[Math.max(initComponents, capacityGuess)];
143 }
144
145
146 CompositeByteBuf(ByteBufAllocator alloc) {
147 super(Integer.MAX_VALUE);
148 this.alloc = alloc;
149 direct = false;
150 maxNumComponents = 0;
151 components = null;
152 }
153
154
155
156
157
158
159
160
161
162
163
164 public CompositeByteBuf addComponent(ByteBuf buffer) {
165 return addComponent(false, buffer);
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179 public CompositeByteBuf addComponents(ByteBuf... buffers) {
180 return addComponents(false, buffers);
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194 public CompositeByteBuf addComponents(Iterable<ByteBuf> buffers) {
195 return addComponents(false, buffers);
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209 public CompositeByteBuf addComponent(int cIndex, ByteBuf buffer) {
210 return addComponent(false, cIndex, buffer);
211 }
212
213
214
215
216
217
218
219
220
221 public CompositeByteBuf addComponent(boolean increaseWriterIndex, ByteBuf buffer) {
222 return addComponent(increaseWriterIndex, componentCount, buffer);
223 }
224
225
226
227
228
229
230
231
232
233
234 public CompositeByteBuf addComponents(boolean increaseWriterIndex, ByteBuf... buffers) {
235 checkNotNull(buffers, "buffers");
236 addComponents0(increaseWriterIndex, componentCount, buffers, 0);
237 consolidateIfNeeded();
238 return this;
239 }
240
241
242
243
244
245
246
247
248
249
250 public CompositeByteBuf addComponents(boolean increaseWriterIndex, Iterable<ByteBuf> buffers) {
251 return addComponents(increaseWriterIndex, componentCount, buffers);
252 }
253
254
255
256
257
258
259
260
261
262
263 public CompositeByteBuf addComponent(boolean increaseWriterIndex, int cIndex, ByteBuf buffer) {
264 checkNotNull(buffer, "buffer");
265 addComponent0(increaseWriterIndex, cIndex, buffer);
266 consolidateIfNeeded();
267 return this;
268 }
269
270 private static void checkForOverflow(int capacity, int readableBytes) {
271 if (capacity + readableBytes < 0) {
272 throw new IllegalArgumentException("Can't increase by " + readableBytes + " as capacity(" + capacity + ")" +
273 " would overflow " + Integer.MAX_VALUE);
274 }
275 }
276
277
278
279
280 private int addComponent0(boolean increaseWriterIndex, int cIndex, ByteBuf buffer) {
281 assert buffer != null;
282 boolean wasAdded = false;
283 try {
284 checkComponentIndex(cIndex);
285
286
287 Component c = newComponent(ensureAccessible(buffer), 0);
288 int readableBytes = c.length();
289
290
291
292 checkForOverflow(capacity(), readableBytes);
293
294 addComp(cIndex, c);
295 wasAdded = true;
296 if (readableBytes > 0 && cIndex < componentCount - 1) {
297 updateComponentOffsets(cIndex);
298 } else if (cIndex > 0) {
299 c.reposition(components[cIndex - 1].endOffset);
300 }
301 if (increaseWriterIndex) {
302 writerIndex += readableBytes;
303 }
304 return cIndex;
305 } finally {
306 if (!wasAdded) {
307 buffer.release();
308 }
309 }
310 }
311
312 private static ByteBuf ensureAccessible(final ByteBuf buf) {
313 if (checkAccessible && !buf.isAccessible()) {
314 throw new IllegalReferenceCountException(0);
315 }
316 return buf;
317 }
318
319 @SuppressWarnings("deprecation")
320 private Component newComponent(final ByteBuf buf, final int offset) {
321 final int srcIndex = buf.readerIndex();
322 final int len = buf.readableBytes();
323
324
325 ByteBuf unwrapped = buf;
326 int unwrappedIndex = srcIndex;
327 while (unwrapped instanceof WrappedByteBuf || unwrapped instanceof SwappedByteBuf) {
328 unwrapped = unwrapped.unwrap();
329 }
330
331
332 if (unwrapped instanceof AbstractUnpooledSlicedByteBuf) {
333 unwrappedIndex += ((AbstractUnpooledSlicedByteBuf) unwrapped).idx(0);
334 unwrapped = unwrapped.unwrap();
335 } else if (unwrapped instanceof PooledSlicedByteBuf) {
336 unwrappedIndex += ((PooledSlicedByteBuf) unwrapped).adjustment;
337 unwrapped = unwrapped.unwrap();
338 } else if (unwrapped instanceof DuplicatedByteBuf || unwrapped instanceof PooledDuplicatedByteBuf) {
339 unwrapped = unwrapped.unwrap();
340 }
341
342
343
344 final ByteBuf slice = buf.capacity() == len ? buf : null;
345
346 return new Component(buf.order(ByteOrder.BIG_ENDIAN), srcIndex,
347 unwrapped.order(ByteOrder.BIG_ENDIAN), unwrappedIndex, offset, len, slice);
348 }
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364 public CompositeByteBuf addComponents(int cIndex, ByteBuf... buffers) {
365 checkNotNull(buffers, "buffers");
366 addComponents0(false, cIndex, buffers, 0);
367 consolidateIfNeeded();
368 return this;
369 }
370
371 private CompositeByteBuf addComponents0(boolean increaseWriterIndex,
372 final int cIndex, ByteBuf[] buffers, int arrOffset) {
373 final int len = buffers.length, count = len - arrOffset;
374
375 int readableBytes = 0;
376 int capacity = capacity();
377 for (int i = arrOffset; i < buffers.length; i++) {
378 ByteBuf b = buffers[i];
379 if (b == null) {
380 break;
381 }
382 readableBytes += b.readableBytes();
383
384
385
386 checkForOverflow(capacity, readableBytes);
387 }
388
389 int ci = Integer.MAX_VALUE;
390 try {
391 checkComponentIndex(cIndex);
392 shiftComps(cIndex, count);
393 int nextOffset = cIndex > 0 ? components[cIndex - 1].endOffset : 0;
394 for (ci = cIndex; arrOffset < len; arrOffset++, ci++) {
395 ByteBuf b = buffers[arrOffset];
396 if (b == null) {
397 break;
398 }
399 Component c = newComponent(ensureAccessible(b), nextOffset);
400 components[ci] = c;
401 nextOffset = c.endOffset;
402 }
403 return this;
404 } finally {
405
406 if (ci < componentCount) {
407 if (ci < cIndex + count) {
408
409 removeCompRange(ci, cIndex + count);
410 for (; arrOffset < len; ++arrOffset) {
411 ReferenceCountUtil.safeRelease(buffers[arrOffset]);
412 }
413 }
414 updateComponentOffsets(ci);
415 }
416 if (increaseWriterIndex && ci > cIndex && ci <= componentCount) {
417 writerIndex += components[ci - 1].endOffset - components[cIndex].offset;
418 }
419 }
420 }
421
422 private <T> int addComponents0(boolean increaseWriterIndex, int cIndex,
423 ByteWrapper<T> wrapper, T[] buffers, int offset) {
424 checkComponentIndex(cIndex);
425
426
427 for (int i = offset, len = buffers.length; i < len; i++) {
428 T b = buffers[i];
429 if (b == null) {
430 break;
431 }
432 if (!wrapper.isEmpty(b)) {
433 cIndex = addComponent0(increaseWriterIndex, cIndex, wrapper.wrap(b)) + 1;
434 int size = componentCount;
435 if (cIndex > size) {
436 cIndex = size;
437 }
438 }
439 }
440 return cIndex;
441 }
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456 public CompositeByteBuf addComponents(int cIndex, Iterable<ByteBuf> buffers) {
457 return addComponents(false, cIndex, buffers);
458 }
459
460
461
462
463
464
465
466
467
468
469
470 public CompositeByteBuf addFlattenedComponents(boolean increaseWriterIndex, ByteBuf buffer) {
471 checkNotNull(buffer, "buffer");
472 final int ridx = buffer.readerIndex();
473 final int widx = buffer.writerIndex();
474 if (ridx == widx) {
475 buffer.release();
476 return this;
477 }
478 if (!(buffer instanceof CompositeByteBuf)) {
479 addComponent0(increaseWriterIndex, componentCount, buffer);
480 consolidateIfNeeded();
481 return this;
482 }
483 final CompositeByteBuf from;
484 if (buffer instanceof WrappedCompositeByteBuf) {
485 from = (CompositeByteBuf) buffer.unwrap();
486 } else {
487 from = (CompositeByteBuf) buffer;
488 }
489 from.checkIndex(ridx, widx - ridx);
490 final Component[] fromComponents = from.components;
491 final int compCountBefore = componentCount;
492 final int writerIndexBefore = writerIndex;
493 try {
494 for (int cidx = from.toComponentIndex0(ridx), newOffset = capacity();; cidx++) {
495 final Component component = fromComponents[cidx];
496 final int compOffset = component.offset;
497 final int fromIdx = Math.max(ridx, compOffset);
498 final int toIdx = Math.min(widx, component.endOffset);
499 final int len = toIdx - fromIdx;
500 if (len > 0) {
501 addComp(componentCount, new Component(
502 component.srcBuf.retain(), component.srcIdx(fromIdx),
503 component.buf, component.idx(fromIdx), newOffset, len, null));
504 }
505 if (widx == toIdx) {
506 break;
507 }
508 newOffset += len;
509 }
510 if (increaseWriterIndex) {
511 writerIndex = writerIndexBefore + (widx - ridx);
512 }
513 consolidateIfNeeded();
514 buffer.release();
515 buffer = null;
516 return this;
517 } finally {
518 if (buffer != null) {
519
520 if (increaseWriterIndex) {
521 writerIndex = writerIndexBefore;
522 }
523 for (int cidx = componentCount - 1; cidx >= compCountBefore; cidx--) {
524 components[cidx].free();
525 removeComp(cidx);
526 }
527 }
528 }
529 }
530
531
532
533
534 private CompositeByteBuf addComponents(boolean increaseIndex, int cIndex, Iterable<ByteBuf> buffers) {
535 if (buffers instanceof ByteBuf) {
536
537 return addComponent(increaseIndex, cIndex, (ByteBuf) buffers);
538 }
539 checkNotNull(buffers, "buffers");
540 Iterator<ByteBuf> it = buffers.iterator();
541 try {
542 checkComponentIndex(cIndex);
543
544
545 while (it.hasNext()) {
546 ByteBuf b = it.next();
547 if (b == null) {
548 break;
549 }
550 cIndex = addComponent0(increaseIndex, cIndex, b) + 1;
551 cIndex = Math.min(cIndex, componentCount);
552 }
553 } finally {
554 while (it.hasNext()) {
555 ReferenceCountUtil.safeRelease(it.next());
556 }
557 }
558 consolidateIfNeeded();
559 return this;
560 }
561
562
563
564
565
566 private void consolidateIfNeeded() {
567
568
569 int size = componentCount;
570 if (size > maxNumComponents) {
571 consolidate0(0, size);
572 }
573 }
574
575 private void checkComponentIndex(int cIndex) {
576 ensureAccessible();
577 if (cIndex < 0 || cIndex > componentCount) {
578 throw new IndexOutOfBoundsException(String.format(
579 "cIndex: %d (expected: >= 0 && <= numComponents(%d))",
580 cIndex, componentCount));
581 }
582 }
583
584 private void checkComponentIndex(int cIndex, int numComponents) {
585 ensureAccessible();
586 if (cIndex < 0 || cIndex + numComponents > componentCount) {
587 throw new IndexOutOfBoundsException(String.format(
588 "cIndex: %d, numComponents: %d " +
589 "(expected: cIndex >= 0 && cIndex + numComponents <= totalNumComponents(%d))",
590 cIndex, numComponents, componentCount));
591 }
592 }
593
594 private void updateComponentOffsets(int cIndex) {
595 int size = componentCount;
596 if (size <= cIndex) {
597 return;
598 }
599
600 int nextIndex = cIndex > 0 ? components[cIndex - 1].endOffset : 0;
601 for (; cIndex < size; cIndex++) {
602 Component c = components[cIndex];
603 c.reposition(nextIndex);
604 nextIndex = c.endOffset;
605 }
606 }
607
608
609
610
611
612
613 public CompositeByteBuf removeComponent(int cIndex) {
614 checkComponentIndex(cIndex);
615 Component comp = components[cIndex];
616 if (lastAccessed == comp) {
617 lastAccessed = null;
618 }
619 comp.free();
620 removeComp(cIndex);
621 if (comp.length() > 0) {
622
623 updateComponentOffsets(cIndex);
624 }
625 return this;
626 }
627
628
629
630
631
632
633
634 public CompositeByteBuf removeComponents(int cIndex, int numComponents) {
635 checkComponentIndex(cIndex, numComponents);
636
637 if (numComponents == 0) {
638 return this;
639 }
640 int endIndex = cIndex + numComponents;
641 boolean needsUpdate = false;
642 for (int i = cIndex; i < endIndex; ++i) {
643 Component c = components[i];
644 if (c.length() > 0) {
645 needsUpdate = true;
646 }
647 if (lastAccessed == c) {
648 lastAccessed = null;
649 }
650 c.free();
651 }
652 removeCompRange(cIndex, endIndex);
653
654 if (needsUpdate) {
655
656 updateComponentOffsets(cIndex);
657 }
658 return this;
659 }
660
661 @Override
662 public Iterator<ByteBuf> iterator() {
663 ensureAccessible();
664 return componentCount == 0 ? EMPTY_ITERATOR : new CompositeByteBufIterator();
665 }
666
667 @Override
668 protected int forEachByteAsc0(int start, int end, ByteProcessor processor) throws Exception {
669 if (end <= start) {
670 return -1;
671 }
672 for (int i = toComponentIndex0(start), length = end - start; length > 0; i++) {
673 Component c = components[i];
674 if (c.offset == c.endOffset) {
675 continue;
676 }
677 ByteBuf s = c.buf;
678 int localStart = c.idx(start);
679 int localLength = Math.min(length, c.endOffset - start);
680
681 int result = s instanceof AbstractByteBuf
682 ? ((AbstractByteBuf) s).forEachByteAsc0(localStart, localStart + localLength, processor)
683 : s.forEachByte(localStart, localLength, processor);
684 if (result != -1) {
685 return result - c.adjustment;
686 }
687 start += localLength;
688 length -= localLength;
689 }
690 return -1;
691 }
692
693 @Override
694 protected int forEachByteDesc0(int rStart, int rEnd, ByteProcessor processor) throws Exception {
695 if (rEnd > rStart) {
696 return -1;
697 }
698 for (int i = toComponentIndex0(rStart), length = 1 + rStart - rEnd; length > 0; i--) {
699 Component c = components[i];
700 if (c.offset == c.endOffset) {
701 continue;
702 }
703 ByteBuf s = c.buf;
704 int localRStart = c.idx(length + rEnd);
705 int localLength = Math.min(length, localRStart), localIndex = localRStart - localLength;
706
707 int result = s instanceof AbstractByteBuf
708 ? ((AbstractByteBuf) s).forEachByteDesc0(localRStart - 1, localIndex, processor)
709 : s.forEachByteDesc(localIndex, localLength, processor);
710
711 if (result != -1) {
712 return result - c.adjustment;
713 }
714 length -= localLength;
715 }
716 return -1;
717 }
718
719
720
721
722 public List<ByteBuf> decompose(int offset, int length) {
723 checkIndex(offset, length);
724 if (length == 0) {
725 return Collections.emptyList();
726 }
727
728 int componentId = toComponentIndex0(offset);
729 int bytesToSlice = length;
730
731 Component firstC = components[componentId];
732
733
734
735
736 ByteBuf slice = firstC.srcBuf.slice(firstC.srcIdx(offset), Math.min(firstC.endOffset - offset, bytesToSlice));
737 bytesToSlice -= slice.readableBytes();
738
739 if (bytesToSlice == 0) {
740 return Collections.singletonList(slice);
741 }
742
743 List<ByteBuf> sliceList = new ArrayList<ByteBuf>(componentCount - componentId);
744 sliceList.add(slice);
745
746
747 do {
748 Component component = components[++componentId];
749
750
751
752 slice = component.srcBuf.slice(component.srcIdx(component.offset),
753 Math.min(component.length(), bytesToSlice));
754 bytesToSlice -= slice.readableBytes();
755 sliceList.add(slice);
756 } while (bytesToSlice > 0);
757
758 return sliceList;
759 }
760
761 @Override
762 public boolean isDirect() {
763 int size = componentCount;
764 if (size == 0) {
765 return false;
766 }
767 for (int i = 0; i < size; i++) {
768 if (!components[i].buf.isDirect()) {
769 return false;
770 }
771 }
772 return true;
773 }
774
775 @Override
776 public boolean hasArray() {
777 switch (componentCount) {
778 case 0:
779 return true;
780 case 1:
781 return components[0].buf.hasArray();
782 default:
783 return false;
784 }
785 }
786
787 @Override
788 public byte[] array() {
789 switch (componentCount) {
790 case 0:
791 return EmptyArrays.EMPTY_BYTES;
792 case 1:
793 return components[0].buf.array();
794 default:
795 throw new UnsupportedOperationException();
796 }
797 }
798
799 @Override
800 public int arrayOffset() {
801 switch (componentCount) {
802 case 0:
803 return 0;
804 case 1:
805 Component c = components[0];
806 return c.idx(c.buf.arrayOffset());
807 default:
808 throw new UnsupportedOperationException();
809 }
810 }
811
812 @Override
813 public boolean hasMemoryAddress() {
814 switch (componentCount) {
815 case 0:
816 return Unpooled.EMPTY_BUFFER.hasMemoryAddress();
817 case 1:
818 return components[0].buf.hasMemoryAddress();
819 default:
820 return false;
821 }
822 }
823
824 @Override
825 public long memoryAddress() {
826 switch (componentCount) {
827 case 0:
828 return Unpooled.EMPTY_BUFFER.memoryAddress();
829 case 1:
830 Component c = components[0];
831 return c.buf.memoryAddress() + c.adjustment;
832 default:
833 throw new UnsupportedOperationException();
834 }
835 }
836
837 @Override
838 public int capacity() {
839 int size = componentCount;
840 return size > 0 ? components[size - 1].endOffset : 0;
841 }
842
843 @Override
844 public CompositeByteBuf capacity(int newCapacity) {
845 checkNewCapacity(newCapacity);
846
847 final int size = componentCount, oldCapacity = capacity();
848 if (newCapacity > oldCapacity) {
849 final int paddingLength = newCapacity - oldCapacity;
850 ByteBuf padding = allocBuffer(paddingLength).setIndex(0, paddingLength);
851 addComponent0(false, size, padding);
852 if (componentCount >= maxNumComponents) {
853
854
855 consolidateIfNeeded();
856 }
857 } else if (newCapacity < oldCapacity) {
858 lastAccessed = null;
859 int i = size - 1;
860 for (int bytesToTrim = oldCapacity - newCapacity; i >= 0; i--) {
861 Component c = components[i];
862 final int cLength = c.length();
863 if (bytesToTrim < cLength) {
864
865 c.endOffset -= bytesToTrim;
866 ByteBuf slice = c.slice;
867 if (slice != null) {
868
869
870 c.slice = slice.slice(0, c.length());
871 }
872 break;
873 }
874 c.free();
875 bytesToTrim -= cLength;
876 }
877 removeCompRange(i + 1, size);
878
879 if (readerIndex() > newCapacity) {
880 setIndex0(newCapacity, newCapacity);
881 } else if (writerIndex > newCapacity) {
882 writerIndex = newCapacity;
883 }
884 }
885 return this;
886 }
887
888 @Override
889 public ByteBufAllocator alloc() {
890 return alloc;
891 }
892
893 @Override
894 public ByteOrder order() {
895 return ByteOrder.BIG_ENDIAN;
896 }
897
898
899
900
901 public int numComponents() {
902 return componentCount;
903 }
904
905
906
907
908 public int maxNumComponents() {
909 return maxNumComponents;
910 }
911
912
913
914
915 public int toComponentIndex(int offset) {
916 checkIndex(offset);
917 return toComponentIndex0(offset);
918 }
919
920 private int toComponentIndex0(int offset) {
921 int size = componentCount;
922 if (offset == 0) {
923 for (int i = 0; i < size; i++) {
924 if (components[i].endOffset > 0) {
925 return i;
926 }
927 }
928 }
929 if (size <= 2) {
930 return size == 1 || offset < components[0].endOffset ? 0 : 1;
931 }
932 for (int low = 0, high = size; low <= high;) {
933 int mid = low + high >>> 1;
934 Component c = components[mid];
935 if (offset >= c.endOffset) {
936 low = mid + 1;
937 } else if (offset < c.offset) {
938 high = mid - 1;
939 } else {
940 return mid;
941 }
942 }
943
944 throw new Error("should not reach here");
945 }
946
947 public int toByteIndex(int cIndex) {
948 checkComponentIndex(cIndex);
949 return components[cIndex].offset;
950 }
951
952 @Override
953 public byte getByte(int index) {
954 Component c = findComponent(index);
955 return c.buf.getByte(c.idx(index));
956 }
957
958 @Override
959 protected byte _getByte(int index) {
960 Component c = findComponent0(index);
961 return c.buf.getByte(c.idx(index));
962 }
963
964 @Override
965 protected short _getShort(int index) {
966 Component c = findComponent0(index);
967 if (index + 2 <= c.endOffset) {
968 return c.buf.getShort(c.idx(index));
969 } else if (order() == ByteOrder.BIG_ENDIAN) {
970 return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff);
971 } else {
972 return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8);
973 }
974 }
975
976 @Override
977 protected short _getShortLE(int index) {
978 Component c = findComponent0(index);
979 if (index + 2 <= c.endOffset) {
980 return c.buf.getShortLE(c.idx(index));
981 } else if (order() == ByteOrder.BIG_ENDIAN) {
982 return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8);
983 } else {
984 return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff);
985 }
986 }
987
988 @Override
989 protected int _getUnsignedMedium(int index) {
990 Component c = findComponent0(index);
991 if (index + 3 <= c.endOffset) {
992 return c.buf.getUnsignedMedium(c.idx(index));
993 } else if (order() == ByteOrder.BIG_ENDIAN) {
994 return (_getShort(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff;
995 } else {
996 return _getShort(index) & 0xFFFF | (_getByte(index + 2) & 0xFF) << 16;
997 }
998 }
999
1000 @Override
1001 protected int _getUnsignedMediumLE(int index) {
1002 Component c = findComponent0(index);
1003 if (index + 3 <= c.endOffset) {
1004 return c.buf.getUnsignedMediumLE(c.idx(index));
1005 } else if (order() == ByteOrder.BIG_ENDIAN) {
1006 return _getShortLE(index) & 0xffff | (_getByte(index + 2) & 0xff) << 16;
1007 } else {
1008 return (_getShortLE(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff;
1009 }
1010 }
1011
1012 @Override
1013 protected int _getInt(int index) {
1014 Component c = findComponent0(index);
1015 if (index + 4 <= c.endOffset) {
1016 return c.buf.getInt(c.idx(index));
1017 } else if (order() == ByteOrder.BIG_ENDIAN) {
1018 return (_getShort(index) & 0xffff) << 16 | _getShort(index + 2) & 0xffff;
1019 } else {
1020 return _getShort(index) & 0xFFFF | (_getShort(index + 2) & 0xFFFF) << 16;
1021 }
1022 }
1023
1024 @Override
1025 protected int _getIntLE(int index) {
1026 Component c = findComponent0(index);
1027 if (index + 4 <= c.endOffset) {
1028 return c.buf.getIntLE(c.idx(index));
1029 } else if (order() == ByteOrder.BIG_ENDIAN) {
1030 return _getShortLE(index) & 0xffff | (_getShortLE(index + 2) & 0xffff) << 16;
1031 } else {
1032 return (_getShortLE(index) & 0xffff) << 16 | _getShortLE(index + 2) & 0xffff;
1033 }
1034 }
1035
1036 @Override
1037 protected long _getLong(int index) {
1038 Component c = findComponent0(index);
1039 if (index + 8 <= c.endOffset) {
1040 return c.buf.getLong(c.idx(index));
1041 } else if (order() == ByteOrder.BIG_ENDIAN) {
1042 return (_getInt(index) & 0xffffffffL) << 32 | _getInt(index + 4) & 0xffffffffL;
1043 } else {
1044 return _getInt(index) & 0xFFFFFFFFL | (_getInt(index + 4) & 0xFFFFFFFFL) << 32;
1045 }
1046 }
1047
1048 @Override
1049 protected long _getLongLE(int index) {
1050 Component c = findComponent0(index);
1051 if (index + 8 <= c.endOffset) {
1052 return c.buf.getLongLE(c.idx(index));
1053 } else if (order() == ByteOrder.BIG_ENDIAN) {
1054 return _getIntLE(index) & 0xffffffffL | (_getIntLE(index + 4) & 0xffffffffL) << 32;
1055 } else {
1056 return (_getIntLE(index) & 0xffffffffL) << 32 | _getIntLE(index + 4) & 0xffffffffL;
1057 }
1058 }
1059
1060 @Override
1061 public CompositeByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
1062 checkDstIndex(index, length, dstIndex, dst.length);
1063 if (length == 0) {
1064 return this;
1065 }
1066
1067 int i = toComponentIndex0(index);
1068 while (length > 0) {
1069 Component c = components[i];
1070 int localLength = Math.min(length, c.endOffset - index);
1071 c.buf.getBytes(c.idx(index), dst, dstIndex, localLength);
1072 index += localLength;
1073 dstIndex += localLength;
1074 length -= localLength;
1075 i ++;
1076 }
1077 return this;
1078 }
1079
1080 @Override
1081 public CompositeByteBuf getBytes(int index, ByteBuffer dst) {
1082 int limit = dst.limit();
1083 int length = dst.remaining();
1084
1085 checkIndex(index, length);
1086 if (length == 0) {
1087 return this;
1088 }
1089
1090 int i = toComponentIndex0(index);
1091 try {
1092 while (length > 0) {
1093 Component c = components[i];
1094 int localLength = Math.min(length, c.endOffset - index);
1095 dst.limit(dst.position() + localLength);
1096 c.buf.getBytes(c.idx(index), dst);
1097 index += localLength;
1098 length -= localLength;
1099 i ++;
1100 }
1101 } finally {
1102 dst.limit(limit);
1103 }
1104 return this;
1105 }
1106
1107 @Override
1108 public CompositeByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
1109 checkDstIndex(index, length, dstIndex, dst.capacity());
1110 if (length == 0) {
1111 return this;
1112 }
1113
1114 int i = toComponentIndex0(index);
1115 while (length > 0) {
1116 Component c = components[i];
1117 int localLength = Math.min(length, c.endOffset - index);
1118 c.buf.getBytes(c.idx(index), dst, dstIndex, localLength);
1119 index += localLength;
1120 dstIndex += localLength;
1121 length -= localLength;
1122 i ++;
1123 }
1124 return this;
1125 }
1126
1127 @Override
1128 public int getBytes(int index, GatheringByteChannel out, int length)
1129 throws IOException {
1130 int count = nioBufferCount();
1131 if (count == 1) {
1132 return out.write(internalNioBuffer(index, length));
1133 } else {
1134 long writtenBytes = out.write(nioBuffers(index, length));
1135 if (writtenBytes > Integer.MAX_VALUE) {
1136 return Integer.MAX_VALUE;
1137 } else {
1138 return (int) writtenBytes;
1139 }
1140 }
1141 }
1142
1143 @Override
1144 public int getBytes(int index, FileChannel out, long position, int length)
1145 throws IOException {
1146 int count = nioBufferCount();
1147 if (count == 1) {
1148 return out.write(internalNioBuffer(index, length), position);
1149 } else {
1150 long writtenBytes = 0;
1151 for (ByteBuffer buf : nioBuffers(index, length)) {
1152 writtenBytes += out.write(buf, position + writtenBytes);
1153 }
1154 if (writtenBytes > Integer.MAX_VALUE) {
1155 return Integer.MAX_VALUE;
1156 }
1157 return (int) writtenBytes;
1158 }
1159 }
1160
1161 @Override
1162 public CompositeByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
1163 checkIndex(index, length);
1164 if (length == 0) {
1165 return this;
1166 }
1167
1168 int i = toComponentIndex0(index);
1169 while (length > 0) {
1170 Component c = components[i];
1171 int localLength = Math.min(length, c.endOffset - index);
1172 c.buf.getBytes(c.idx(index), out, localLength);
1173 index += localLength;
1174 length -= localLength;
1175 i ++;
1176 }
1177 return this;
1178 }
1179
1180 @Override
1181 public CompositeByteBuf setByte(int index, int value) {
1182 Component c = findComponent(index);
1183 c.buf.setByte(c.idx(index), value);
1184 return this;
1185 }
1186
1187 @Override
1188 protected void _setByte(int index, int value) {
1189 Component c = findComponent0(index);
1190 c.buf.setByte(c.idx(index), value);
1191 }
1192
1193 @Override
1194 public CompositeByteBuf setShort(int index, int value) {
1195 checkIndex(index, 2);
1196 _setShort(index, value);
1197 return this;
1198 }
1199
1200 @Override
1201 protected void _setShort(int index, int value) {
1202 Component c = findComponent0(index);
1203 if (index + 2 <= c.endOffset) {
1204 c.buf.setShort(c.idx(index), value);
1205 } else if (order() == ByteOrder.BIG_ENDIAN) {
1206 _setByte(index, (byte) (value >>> 8));
1207 _setByte(index + 1, (byte) value);
1208 } else {
1209 _setByte(index, (byte) value);
1210 _setByte(index + 1, (byte) (value >>> 8));
1211 }
1212 }
1213
1214 @Override
1215 protected void _setShortLE(int index, int value) {
1216 Component c = findComponent0(index);
1217 if (index + 2 <= c.endOffset) {
1218 c.buf.setShortLE(c.idx(index), value);
1219 } else if (order() == ByteOrder.BIG_ENDIAN) {
1220 _setByte(index, (byte) value);
1221 _setByte(index + 1, (byte) (value >>> 8));
1222 } else {
1223 _setByte(index, (byte) (value >>> 8));
1224 _setByte(index + 1, (byte) value);
1225 }
1226 }
1227
1228 @Override
1229 public CompositeByteBuf setMedium(int index, int value) {
1230 checkIndex(index, 3);
1231 _setMedium(index, value);
1232 return this;
1233 }
1234
1235 @Override
1236 protected void _setMedium(int index, int value) {
1237 Component c = findComponent0(index);
1238 if (index + 3 <= c.endOffset) {
1239 c.buf.setMedium(c.idx(index), value);
1240 } else if (order() == ByteOrder.BIG_ENDIAN) {
1241 _setShort(index, (short) (value >> 8));
1242 _setByte(index + 2, (byte) value);
1243 } else {
1244 _setShort(index, (short) value);
1245 _setByte(index + 2, (byte) (value >>> 16));
1246 }
1247 }
1248
1249 @Override
1250 protected void _setMediumLE(int index, int value) {
1251 Component c = findComponent0(index);
1252 if (index + 3 <= c.endOffset) {
1253 c.buf.setMediumLE(c.idx(index), value);
1254 } else if (order() == ByteOrder.BIG_ENDIAN) {
1255 _setShortLE(index, (short) value);
1256 _setByte(index + 2, (byte) (value >>> 16));
1257 } else {
1258 _setShortLE(index, (short) (value >> 8));
1259 _setByte(index + 2, (byte) value);
1260 }
1261 }
1262
1263 @Override
1264 public CompositeByteBuf setInt(int index, int value) {
1265 checkIndex(index, 4);
1266 _setInt(index, value);
1267 return this;
1268 }
1269
1270 @Override
1271 protected void _setInt(int index, int value) {
1272 Component c = findComponent0(index);
1273 if (index + 4 <= c.endOffset) {
1274 c.buf.setInt(c.idx(index), value);
1275 } else if (order() == ByteOrder.BIG_ENDIAN) {
1276 _setShort(index, (short) (value >>> 16));
1277 _setShort(index + 2, (short) value);
1278 } else {
1279 _setShort(index, (short) value);
1280 _setShort(index + 2, (short) (value >>> 16));
1281 }
1282 }
1283
1284 @Override
1285 protected void _setIntLE(int index, int value) {
1286 Component c = findComponent0(index);
1287 if (index + 4 <= c.endOffset) {
1288 c.buf.setIntLE(c.idx(index), value);
1289 } else if (order() == ByteOrder.BIG_ENDIAN) {
1290 _setShortLE(index, (short) value);
1291 _setShortLE(index + 2, (short) (value >>> 16));
1292 } else {
1293 _setShortLE(index, (short) (value >>> 16));
1294 _setShortLE(index + 2, (short) value);
1295 }
1296 }
1297
1298 @Override
1299 public CompositeByteBuf setLong(int index, long value) {
1300 checkIndex(index, 8);
1301 _setLong(index, value);
1302 return this;
1303 }
1304
1305 @Override
1306 protected void _setLong(int index, long value) {
1307 Component c = findComponent0(index);
1308 if (index + 8 <= c.endOffset) {
1309 c.buf.setLong(c.idx(index), value);
1310 } else if (order() == ByteOrder.BIG_ENDIAN) {
1311 _setInt(index, (int) (value >>> 32));
1312 _setInt(index + 4, (int) value);
1313 } else {
1314 _setInt(index, (int) value);
1315 _setInt(index + 4, (int) (value >>> 32));
1316 }
1317 }
1318
1319 @Override
1320 protected void _setLongLE(int index, long value) {
1321 Component c = findComponent0(index);
1322 if (index + 8 <= c.endOffset) {
1323 c.buf.setLongLE(c.idx(index), value);
1324 } else if (order() == ByteOrder.BIG_ENDIAN) {
1325 _setIntLE(index, (int) value);
1326 _setIntLE(index + 4, (int) (value >>> 32));
1327 } else {
1328 _setIntLE(index, (int) (value >>> 32));
1329 _setIntLE(index + 4, (int) value);
1330 }
1331 }
1332
1333 @Override
1334 public CompositeByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
1335 checkSrcIndex(index, length, srcIndex, src.length);
1336 if (length == 0) {
1337 return this;
1338 }
1339
1340 int i = toComponentIndex0(index);
1341 while (length > 0) {
1342 Component c = components[i];
1343 int localLength = Math.min(length, c.endOffset - index);
1344 c.buf.setBytes(c.idx(index), src, srcIndex, localLength);
1345 index += localLength;
1346 srcIndex += localLength;
1347 length -= localLength;
1348 i ++;
1349 }
1350 return this;
1351 }
1352
1353 @Override
1354 public CompositeByteBuf setBytes(int index, ByteBuffer src) {
1355 int limit = src.limit();
1356 int length = src.remaining();
1357
1358 checkIndex(index, length);
1359 if (length == 0) {
1360 return this;
1361 }
1362
1363 int i = toComponentIndex0(index);
1364 try {
1365 while (length > 0) {
1366 Component c = components[i];
1367 int localLength = Math.min(length, c.endOffset - index);
1368 src.limit(src.position() + localLength);
1369 c.buf.setBytes(c.idx(index), src);
1370 index += localLength;
1371 length -= localLength;
1372 i ++;
1373 }
1374 } finally {
1375 src.limit(limit);
1376 }
1377 return this;
1378 }
1379
1380 @Override
1381 public CompositeByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
1382 checkSrcIndex(index, length, srcIndex, src.capacity());
1383 if (length == 0) {
1384 return this;
1385 }
1386
1387 int i = toComponentIndex0(index);
1388 while (length > 0) {
1389 Component c = components[i];
1390 int localLength = Math.min(length, c.endOffset - index);
1391 c.buf.setBytes(c.idx(index), src, srcIndex, localLength);
1392 index += localLength;
1393 srcIndex += localLength;
1394 length -= localLength;
1395 i ++;
1396 }
1397 return this;
1398 }
1399
1400 @Override
1401 public int setBytes(int index, InputStream in, int length) throws IOException {
1402 checkIndex(index, length);
1403 if (length == 0) {
1404 return in.read(EmptyArrays.EMPTY_BYTES);
1405 }
1406
1407 int i = toComponentIndex0(index);
1408 int readBytes = 0;
1409 do {
1410 Component c = components[i];
1411 int localLength = Math.min(length, c.endOffset - index);
1412 if (localLength == 0) {
1413
1414 i++;
1415 continue;
1416 }
1417 int localReadBytes = c.buf.setBytes(c.idx(index), in, localLength);
1418 if (localReadBytes < 0) {
1419 if (readBytes == 0) {
1420 return -1;
1421 } else {
1422 break;
1423 }
1424 }
1425
1426 index += localReadBytes;
1427 length -= localReadBytes;
1428 readBytes += localReadBytes;
1429 if (localReadBytes == localLength) {
1430 i ++;
1431 }
1432 } while (length > 0);
1433
1434 return readBytes;
1435 }
1436
1437 @Override
1438 public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
1439 checkIndex(index, length);
1440 if (length == 0) {
1441 return in.read(EMPTY_NIO_BUFFER);
1442 }
1443
1444 int i = toComponentIndex0(index);
1445 int readBytes = 0;
1446 do {
1447 Component c = components[i];
1448 int localLength = Math.min(length, c.endOffset - index);
1449 if (localLength == 0) {
1450
1451 i++;
1452 continue;
1453 }
1454 int localReadBytes = c.buf.setBytes(c.idx(index), in, localLength);
1455
1456 if (localReadBytes == 0) {
1457 break;
1458 }
1459
1460 if (localReadBytes < 0) {
1461 if (readBytes == 0) {
1462 return -1;
1463 } else {
1464 break;
1465 }
1466 }
1467
1468 index += localReadBytes;
1469 length -= localReadBytes;
1470 readBytes += localReadBytes;
1471 if (localReadBytes == localLength) {
1472 i ++;
1473 }
1474 } while (length > 0);
1475
1476 return readBytes;
1477 }
1478
1479 @Override
1480 public int setBytes(int index, FileChannel in, long position, int length) throws IOException {
1481 checkIndex(index, length);
1482 if (length == 0) {
1483 return in.read(EMPTY_NIO_BUFFER, position);
1484 }
1485
1486 int i = toComponentIndex0(index);
1487 int readBytes = 0;
1488 do {
1489 Component c = components[i];
1490 int localLength = Math.min(length, c.endOffset - index);
1491 if (localLength == 0) {
1492
1493 i++;
1494 continue;
1495 }
1496 int localReadBytes = c.buf.setBytes(c.idx(index), in, position + readBytes, localLength);
1497
1498 if (localReadBytes == 0) {
1499 break;
1500 }
1501
1502 if (localReadBytes < 0) {
1503 if (readBytes == 0) {
1504 return -1;
1505 } else {
1506 break;
1507 }
1508 }
1509
1510 index += localReadBytes;
1511 length -= localReadBytes;
1512 readBytes += localReadBytes;
1513 if (localReadBytes == localLength) {
1514 i ++;
1515 }
1516 } while (length > 0);
1517
1518 return readBytes;
1519 }
1520
1521 @Override
1522 public ByteBuf copy(int index, int length) {
1523 checkIndex(index, length);
1524 ByteBuf dst = allocBuffer(length);
1525 if (length != 0) {
1526 copyTo(index, length, toComponentIndex0(index), dst);
1527 }
1528 return dst;
1529 }
1530
1531 private void copyTo(int index, int length, int componentId, ByteBuf dst) {
1532 int dstIndex = 0;
1533 int i = componentId;
1534
1535 while (length > 0) {
1536 Component c = components[i];
1537 int localLength = Math.min(length, c.endOffset - index);
1538 c.buf.getBytes(c.idx(index), dst, dstIndex, localLength);
1539 index += localLength;
1540 dstIndex += localLength;
1541 length -= localLength;
1542 i ++;
1543 }
1544
1545 dst.writerIndex(dst.capacity());
1546 }
1547
1548
1549
1550
1551
1552
1553
1554 public ByteBuf component(int cIndex) {
1555 checkComponentIndex(cIndex);
1556 return components[cIndex].duplicate();
1557 }
1558
1559
1560
1561
1562
1563
1564
1565 public ByteBuf componentAtOffset(int offset) {
1566 return findComponent(offset).duplicate();
1567 }
1568
1569
1570
1571
1572
1573
1574
1575 public ByteBuf internalComponent(int cIndex) {
1576 checkComponentIndex(cIndex);
1577 return components[cIndex].slice();
1578 }
1579
1580
1581
1582
1583
1584
1585
1586 public ByteBuf internalComponentAtOffset(int offset) {
1587 return findComponent(offset).slice();
1588 }
1589
1590
1591 private Component lastAccessed;
1592
1593 private Component findComponent(int offset) {
1594 Component la = lastAccessed;
1595 if (la != null && offset >= la.offset && offset < la.endOffset) {
1596 ensureAccessible();
1597 return la;
1598 }
1599 checkIndex(offset);
1600 return findIt(offset);
1601 }
1602
1603 private Component findComponent0(int offset) {
1604 Component la = lastAccessed;
1605 if (la != null && offset >= la.offset && offset < la.endOffset) {
1606 return la;
1607 }
1608 return findIt(offset);
1609 }
1610
1611 private Component findIt(int offset) {
1612 for (int low = 0, high = componentCount; low <= high;) {
1613 int mid = low + high >>> 1;
1614 Component c = components[mid];
1615 if (c == null) {
1616 throw new IllegalStateException("No component found for offset. " +
1617 "Composite buffer layout might be outdated, e.g. from a discardReadBytes call.");
1618 }
1619 if (offset >= c.endOffset) {
1620 low = mid + 1;
1621 } else if (offset < c.offset) {
1622 high = mid - 1;
1623 } else {
1624 lastAccessed = c;
1625 return c;
1626 }
1627 }
1628
1629 throw new Error("should not reach here");
1630 }
1631
1632 @Override
1633 public int nioBufferCount() {
1634 int size = componentCount;
1635 switch (size) {
1636 case 0:
1637 return 1;
1638 case 1:
1639 return components[0].buf.nioBufferCount();
1640 default:
1641 int count = 0;
1642 for (int i = 0; i < size; i++) {
1643 count += components[i].buf.nioBufferCount();
1644 }
1645 return count;
1646 }
1647 }
1648
1649 @Override
1650 public ByteBuffer internalNioBuffer(int index, int length) {
1651 switch (componentCount) {
1652 case 0:
1653 return EMPTY_NIO_BUFFER;
1654 case 1:
1655 return components[0].internalNioBuffer(index, length);
1656 default:
1657 throw new UnsupportedOperationException();
1658 }
1659 }
1660
1661 @Override
1662 public ByteBuffer nioBuffer(int index, int length) {
1663 checkIndex(index, length);
1664
1665 switch (componentCount) {
1666 case 0:
1667 return EMPTY_NIO_BUFFER;
1668 case 1:
1669 Component c = components[0];
1670 ByteBuf buf = c.buf;
1671 if (buf.nioBufferCount() == 1) {
1672 return buf.nioBuffer(c.idx(index), length);
1673 }
1674 break;
1675 default:
1676 break;
1677 }
1678
1679 ByteBuffer[] buffers = nioBuffers(index, length);
1680
1681 if (buffers.length == 1) {
1682 return buffers[0];
1683 }
1684
1685 ByteBuffer merged = ByteBuffer.allocate(length).order(order());
1686 for (ByteBuffer buf: buffers) {
1687 merged.put(buf);
1688 }
1689
1690 merged.flip();
1691 return merged;
1692 }
1693
1694 @Override
1695 public ByteBuffer[] nioBuffers(int index, int length) {
1696 checkIndex(index, length);
1697 if (length == 0) {
1698 return new ByteBuffer[] { EMPTY_NIO_BUFFER };
1699 }
1700
1701 RecyclableArrayList buffers = RecyclableArrayList.newInstance(componentCount);
1702 try {
1703 int i = toComponentIndex0(index);
1704 while (length > 0) {
1705 Component c = components[i];
1706 ByteBuf s = c.buf;
1707 int localLength = Math.min(length, c.endOffset - index);
1708 switch (s.nioBufferCount()) {
1709 case 0:
1710 throw new UnsupportedOperationException();
1711 case 1:
1712 buffers.add(s.nioBuffer(c.idx(index), localLength));
1713 break;
1714 default:
1715 Collections.addAll(buffers, s.nioBuffers(c.idx(index), localLength));
1716 }
1717
1718 index += localLength;
1719 length -= localLength;
1720 i ++;
1721 }
1722
1723 return buffers.toArray(EmptyArrays.EMPTY_BYTE_BUFFERS);
1724 } finally {
1725 buffers.recycle();
1726 }
1727 }
1728
1729
1730
1731
1732 public CompositeByteBuf consolidate() {
1733 ensureAccessible();
1734 consolidate0(0, componentCount);
1735 return this;
1736 }
1737
1738
1739
1740
1741
1742
1743
1744 public CompositeByteBuf consolidate(int cIndex, int numComponents) {
1745 checkComponentIndex(cIndex, numComponents);
1746 consolidate0(cIndex, numComponents);
1747 return this;
1748 }
1749
1750 private void consolidate0(int cIndex, int numComponents) {
1751 if (numComponents <= 1) {
1752 return;
1753 }
1754
1755 final int endCIndex = cIndex + numComponents;
1756 final int startOffset = cIndex != 0 ? components[cIndex].offset : 0;
1757 final int capacity = components[endCIndex - 1].endOffset - startOffset;
1758 final ByteBuf consolidated = allocBuffer(capacity);
1759
1760 for (int i = cIndex; i < endCIndex; i ++) {
1761 components[i].transferTo(consolidated);
1762 }
1763 lastAccessed = null;
1764 removeCompRange(cIndex + 1, endCIndex);
1765 components[cIndex] = newComponent(consolidated, 0);
1766 if (cIndex != 0 || numComponents != componentCount) {
1767 updateComponentOffsets(cIndex);
1768 }
1769 }
1770
1771
1772
1773
1774 public CompositeByteBuf discardReadComponents() {
1775 ensureAccessible();
1776 final int readerIndex = readerIndex();
1777 if (readerIndex == 0) {
1778 return this;
1779 }
1780
1781
1782 int writerIndex = writerIndex();
1783 if (readerIndex == writerIndex && writerIndex == capacity()) {
1784 for (int i = 0, size = componentCount; i < size; i++) {
1785 components[i].free();
1786 }
1787 lastAccessed = null;
1788 clearComps();
1789 setIndex(0, 0);
1790 adjustMarkers(readerIndex);
1791 return this;
1792 }
1793
1794
1795 int firstComponentId = 0;
1796 Component c = null;
1797 for (int size = componentCount; firstComponentId < size; firstComponentId++) {
1798 c = components[firstComponentId];
1799 if (c.endOffset > readerIndex) {
1800 break;
1801 }
1802 c.free();
1803 }
1804 if (firstComponentId == 0) {
1805 return this;
1806 }
1807 Component la = lastAccessed;
1808 if (la != null && la.endOffset <= readerIndex) {
1809 lastAccessed = null;
1810 }
1811 removeCompRange(0, firstComponentId);
1812
1813
1814 int offset = c.offset;
1815 updateComponentOffsets(0);
1816 setIndex(readerIndex - offset, writerIndex - offset);
1817 adjustMarkers(offset);
1818 return this;
1819 }
1820
1821 @Override
1822 public CompositeByteBuf discardReadBytes() {
1823 ensureAccessible();
1824 final int readerIndex = readerIndex();
1825 if (readerIndex == 0) {
1826 return this;
1827 }
1828
1829
1830 int writerIndex = writerIndex();
1831 if (readerIndex == writerIndex && writerIndex == capacity()) {
1832 for (int i = 0, size = componentCount; i < size; i++) {
1833 components[i].free();
1834 }
1835 lastAccessed = null;
1836 clearComps();
1837 setIndex(0, 0);
1838 adjustMarkers(readerIndex);
1839 return this;
1840 }
1841
1842 int firstComponentId = 0;
1843 Component c = null;
1844 for (int size = componentCount; firstComponentId < size; firstComponentId++) {
1845 c = components[firstComponentId];
1846 if (c.endOffset > readerIndex) {
1847 break;
1848 }
1849 c.free();
1850 }
1851
1852
1853 int trimmedBytes = readerIndex - c.offset;
1854 c.offset = 0;
1855 c.endOffset -= readerIndex;
1856 c.srcAdjustment += readerIndex;
1857 c.adjustment += readerIndex;
1858 ByteBuf slice = c.slice;
1859 if (slice != null) {
1860
1861
1862 c.slice = slice.slice(trimmedBytes, c.length());
1863 }
1864 Component la = lastAccessed;
1865 if (la != null && la.endOffset <= readerIndex) {
1866 lastAccessed = null;
1867 }
1868
1869 removeCompRange(0, firstComponentId);
1870
1871
1872 updateComponentOffsets(0);
1873 setIndex(0, writerIndex - readerIndex);
1874 adjustMarkers(readerIndex);
1875 return this;
1876 }
1877
1878 private ByteBuf allocBuffer(int capacity) {
1879 return direct ? alloc().directBuffer(capacity) : alloc().heapBuffer(capacity);
1880 }
1881
1882 @Override
1883 public String toString() {
1884 String result = super.toString();
1885 result = result.substring(0, result.length() - 1);
1886 return result + ", components=" + componentCount + ')';
1887 }
1888
1889 private static final class Component {
1890 final ByteBuf srcBuf;
1891 final ByteBuf buf;
1892
1893 int srcAdjustment;
1894 int adjustment;
1895
1896 int offset;
1897 int endOffset;
1898
1899 private ByteBuf slice;
1900
1901 Component(ByteBuf srcBuf, int srcOffset, ByteBuf buf, int bufOffset,
1902 int offset, int len, ByteBuf slice) {
1903 this.srcBuf = srcBuf;
1904 this.srcAdjustment = srcOffset - offset;
1905 this.buf = buf;
1906 this.adjustment = bufOffset - offset;
1907 this.offset = offset;
1908 this.endOffset = offset + len;
1909 this.slice = slice;
1910 }
1911
1912 int srcIdx(int index) {
1913 return index + srcAdjustment;
1914 }
1915
1916 int idx(int index) {
1917 return index + adjustment;
1918 }
1919
1920 int length() {
1921 return endOffset - offset;
1922 }
1923
1924 void reposition(int newOffset) {
1925 int move = newOffset - offset;
1926 endOffset += move;
1927 srcAdjustment -= move;
1928 adjustment -= move;
1929 offset = newOffset;
1930 }
1931
1932
1933 void transferTo(ByteBuf dst) {
1934 dst.writeBytes(buf, idx(offset), length());
1935 free();
1936 }
1937
1938 ByteBuf slice() {
1939 ByteBuf s = slice;
1940 if (s == null) {
1941 slice = s = srcBuf.slice(srcIdx(offset), length());
1942 }
1943 return s;
1944 }
1945
1946 ByteBuf duplicate() {
1947 return srcBuf.duplicate();
1948 }
1949
1950 ByteBuffer internalNioBuffer(int index, int length) {
1951
1952 return srcBuf.internalNioBuffer(srcIdx(index), length);
1953 }
1954
1955 void free() {
1956 slice = null;
1957
1958
1959 srcBuf.release();
1960 }
1961 }
1962
1963 @Override
1964 public CompositeByteBuf readerIndex(int readerIndex) {
1965 super.readerIndex(readerIndex);
1966 return this;
1967 }
1968
1969 @Override
1970 public CompositeByteBuf writerIndex(int writerIndex) {
1971 super.writerIndex(writerIndex);
1972 return this;
1973 }
1974
1975 @Override
1976 public CompositeByteBuf setIndex(int readerIndex, int writerIndex) {
1977 super.setIndex(readerIndex, writerIndex);
1978 return this;
1979 }
1980
1981 @Override
1982 public CompositeByteBuf clear() {
1983 super.clear();
1984 return this;
1985 }
1986
1987 @Override
1988 public CompositeByteBuf markReaderIndex() {
1989 super.markReaderIndex();
1990 return this;
1991 }
1992
1993 @Override
1994 public CompositeByteBuf resetReaderIndex() {
1995 super.resetReaderIndex();
1996 return this;
1997 }
1998
1999 @Override
2000 public CompositeByteBuf markWriterIndex() {
2001 super.markWriterIndex();
2002 return this;
2003 }
2004
2005 @Override
2006 public CompositeByteBuf resetWriterIndex() {
2007 super.resetWriterIndex();
2008 return this;
2009 }
2010
2011 @Override
2012 public CompositeByteBuf ensureWritable(int minWritableBytes) {
2013 super.ensureWritable(minWritableBytes);
2014 return this;
2015 }
2016
2017 @Override
2018 public CompositeByteBuf getBytes(int index, ByteBuf dst) {
2019 return getBytes(index, dst, dst.writableBytes());
2020 }
2021
2022 @Override
2023 public CompositeByteBuf getBytes(int index, ByteBuf dst, int length) {
2024 getBytes(index, dst, dst.writerIndex(), length);
2025 dst.writerIndex(dst.writerIndex() + length);
2026 return this;
2027 }
2028
2029 @Override
2030 public CompositeByteBuf getBytes(int index, byte[] dst) {
2031 return getBytes(index, dst, 0, dst.length);
2032 }
2033
2034 @Override
2035 public CompositeByteBuf setBoolean(int index, boolean value) {
2036 return setByte(index, value? 1 : 0);
2037 }
2038
2039 @Override
2040 public CompositeByteBuf setChar(int index, int value) {
2041 return setShort(index, value);
2042 }
2043
2044 @Override
2045 public CompositeByteBuf setFloat(int index, float value) {
2046 return setInt(index, Float.floatToRawIntBits(value));
2047 }
2048
2049 @Override
2050 public CompositeByteBuf setDouble(int index, double value) {
2051 return setLong(index, Double.doubleToRawLongBits(value));
2052 }
2053
2054 @Override
2055 public CompositeByteBuf setBytes(int index, ByteBuf src) {
2056 super.setBytes(index, src, src.readableBytes());
2057 return this;
2058 }
2059
2060 @Override
2061 public CompositeByteBuf setBytes(int index, ByteBuf src, int length) {
2062 super.setBytes(index, src, length);
2063 return this;
2064 }
2065
2066 @Override
2067 public CompositeByteBuf setBytes(int index, byte[] src) {
2068 return setBytes(index, src, 0, src.length);
2069 }
2070
2071 @Override
2072 public CompositeByteBuf setZero(int index, int length) {
2073 super.setZero(index, length);
2074 return this;
2075 }
2076
2077 @Override
2078 public CompositeByteBuf readBytes(ByteBuf dst) {
2079 super.readBytes(dst, dst.writableBytes());
2080 return this;
2081 }
2082
2083 @Override
2084 public CompositeByteBuf readBytes(ByteBuf dst, int length) {
2085 super.readBytes(dst, length);
2086 return this;
2087 }
2088
2089 @Override
2090 public CompositeByteBuf readBytes(ByteBuf dst, int dstIndex, int length) {
2091 super.readBytes(dst, dstIndex, length);
2092 return this;
2093 }
2094
2095 @Override
2096 public CompositeByteBuf readBytes(byte[] dst) {
2097 super.readBytes(dst, 0, dst.length);
2098 return this;
2099 }
2100
2101 @Override
2102 public CompositeByteBuf readBytes(byte[] dst, int dstIndex, int length) {
2103 super.readBytes(dst, dstIndex, length);
2104 return this;
2105 }
2106
2107 @Override
2108 public CompositeByteBuf readBytes(ByteBuffer dst) {
2109 super.readBytes(dst);
2110 return this;
2111 }
2112
2113 @Override
2114 public CompositeByteBuf readBytes(OutputStream out, int length) throws IOException {
2115 super.readBytes(out, length);
2116 return this;
2117 }
2118
2119 @Override
2120 public CompositeByteBuf skipBytes(int length) {
2121 super.skipBytes(length);
2122 return this;
2123 }
2124
2125 @Override
2126 public CompositeByteBuf writeBoolean(boolean value) {
2127 writeByte(value ? 1 : 0);
2128 return this;
2129 }
2130
2131 @Override
2132 public CompositeByteBuf writeByte(int value) {
2133 ensureWritable0(1);
2134 _setByte(writerIndex++, value);
2135 return this;
2136 }
2137
2138 @Override
2139 public CompositeByteBuf writeShort(int value) {
2140 super.writeShort(value);
2141 return this;
2142 }
2143
2144 @Override
2145 public CompositeByteBuf writeMedium(int value) {
2146 super.writeMedium(value);
2147 return this;
2148 }
2149
2150 @Override
2151 public CompositeByteBuf writeInt(int value) {
2152 super.writeInt(value);
2153 return this;
2154 }
2155
2156 @Override
2157 public CompositeByteBuf writeLong(long value) {
2158 super.writeLong(value);
2159 return this;
2160 }
2161
2162 @Override
2163 public CompositeByteBuf writeChar(int value) {
2164 super.writeShort(value);
2165 return this;
2166 }
2167
2168 @Override
2169 public CompositeByteBuf writeFloat(float value) {
2170 super.writeInt(Float.floatToRawIntBits(value));
2171 return this;
2172 }
2173
2174 @Override
2175 public CompositeByteBuf writeDouble(double value) {
2176 super.writeLong(Double.doubleToRawLongBits(value));
2177 return this;
2178 }
2179
2180 @Override
2181 public CompositeByteBuf writeBytes(ByteBuf src) {
2182 super.writeBytes(src, src.readableBytes());
2183 return this;
2184 }
2185
2186 @Override
2187 public CompositeByteBuf writeBytes(ByteBuf src, int length) {
2188 super.writeBytes(src, length);
2189 return this;
2190 }
2191
2192 @Override
2193 public CompositeByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
2194 super.writeBytes(src, srcIndex, length);
2195 return this;
2196 }
2197
2198 @Override
2199 public CompositeByteBuf writeBytes(byte[] src) {
2200 super.writeBytes(src, 0, src.length);
2201 return this;
2202 }
2203
2204 @Override
2205 public CompositeByteBuf writeBytes(byte[] src, int srcIndex, int length) {
2206 super.writeBytes(src, srcIndex, length);
2207 return this;
2208 }
2209
2210 @Override
2211 public CompositeByteBuf writeBytes(ByteBuffer src) {
2212 super.writeBytes(src);
2213 return this;
2214 }
2215
2216 @Override
2217 public CompositeByteBuf writeZero(int length) {
2218 super.writeZero(length);
2219 return this;
2220 }
2221
2222 @Override
2223 public CompositeByteBuf retain(int increment) {
2224 super.retain(increment);
2225 return this;
2226 }
2227
2228 @Override
2229 public CompositeByteBuf retain() {
2230 super.retain();
2231 return this;
2232 }
2233
2234 @Override
2235 public CompositeByteBuf touch() {
2236 return this;
2237 }
2238
2239 @Override
2240 public CompositeByteBuf touch(Object hint) {
2241 return this;
2242 }
2243
2244 @Override
2245 public ByteBuffer[] nioBuffers() {
2246 return nioBuffers(readerIndex(), readableBytes());
2247 }
2248
2249 @Override
2250 public CompositeByteBuf discardSomeReadBytes() {
2251 return discardReadComponents();
2252 }
2253
2254 @Override
2255 protected void deallocate() {
2256 if (freed) {
2257 return;
2258 }
2259
2260 freed = true;
2261
2262
2263 for (int i = 0, size = componentCount; i < size; i++) {
2264 components[i].free();
2265 }
2266 }
2267
2268 @Override
2269 boolean isAccessible() {
2270 return !freed;
2271 }
2272
2273 @Override
2274 public ByteBuf unwrap() {
2275 return null;
2276 }
2277
2278 private final class CompositeByteBufIterator implements Iterator<ByteBuf> {
2279 private final int size = numComponents();
2280 private int index;
2281
2282 @Override
2283 public boolean hasNext() {
2284 return size > index;
2285 }
2286
2287 @Override
2288 public ByteBuf next() {
2289 if (size != numComponents()) {
2290 throw new ConcurrentModificationException();
2291 }
2292 if (!hasNext()) {
2293 throw new NoSuchElementException();
2294 }
2295 try {
2296 return components[index++].slice();
2297 } catch (IndexOutOfBoundsException e) {
2298 throw new ConcurrentModificationException();
2299 }
2300 }
2301
2302 @Override
2303 public void remove() {
2304 throw new UnsupportedOperationException("Read-Only");
2305 }
2306 }
2307
2308
2309
2310 private void clearComps() {
2311 removeCompRange(0, componentCount);
2312 }
2313
2314 private void removeComp(int i) {
2315 removeCompRange(i, i + 1);
2316 }
2317
2318 private void removeCompRange(int from, int to) {
2319 if (from >= to) {
2320 return;
2321 }
2322 final int size = componentCount;
2323 assert from >= 0 && to <= size;
2324 if (to < size) {
2325 System.arraycopy(components, to, components, from, size - to);
2326 }
2327 int newSize = size - to + from;
2328 for (int i = newSize; i < size; i++) {
2329 components[i] = null;
2330 }
2331 componentCount = newSize;
2332 }
2333
2334 private void addComp(int i, Component c) {
2335 shiftComps(i, 1);
2336 components[i] = c;
2337 }
2338
2339 private void shiftComps(int i, int count) {
2340 final int size = componentCount, newSize = size + count;
2341 assert i >= 0 && i <= size && count > 0;
2342 if (newSize > components.length) {
2343
2344 int newArrSize = Math.max(size + (size >> 1), newSize);
2345 Component[] newArr;
2346 if (i == size) {
2347 newArr = Arrays.copyOf(components, newArrSize, Component[].class);
2348 } else {
2349 newArr = new Component[newArrSize];
2350 if (i > 0) {
2351 System.arraycopy(components, 0, newArr, 0, i);
2352 }
2353 if (i < size) {
2354 System.arraycopy(components, i, newArr, i + count, size - i);
2355 }
2356 }
2357 components = newArr;
2358 } else if (i < size) {
2359 System.arraycopy(components, i, components, i + count, size - i);
2360 }
2361 componentCount = newSize;
2362 }
2363 }