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 lastAccessedIndex = 0;
619 }
620 comp.free();
621 removeComp(cIndex);
622 if (comp.length() > 0) {
623
624 updateComponentOffsets(cIndex);
625 }
626 return this;
627 }
628
629
630
631
632
633
634
635 public CompositeByteBuf removeComponents(int cIndex, int numComponents) {
636 checkComponentIndex(cIndex, numComponents);
637
638 if (numComponents == 0) {
639 return this;
640 }
641 int endIndex = cIndex + numComponents;
642 boolean needsUpdate = false;
643 for (int i = cIndex; i < endIndex; ++i) {
644 Component c = components[i];
645 if (c.length() > 0) {
646 needsUpdate = true;
647 }
648 if (lastAccessed == c) {
649 lastAccessed = null;
650 lastAccessedIndex = 0;
651 }
652 c.free();
653 }
654 removeCompRange(cIndex, endIndex);
655
656 if (needsUpdate) {
657
658 updateComponentOffsets(cIndex);
659 }
660 return this;
661 }
662
663 @Override
664 public Iterator<ByteBuf> iterator() {
665 ensureAccessible();
666 return componentCount == 0 ? EMPTY_ITERATOR : new CompositeByteBufIterator();
667 }
668
669 @Override
670 protected int forEachByteAsc0(int start, int end, ByteProcessor processor) throws Exception {
671 if (end <= start) {
672 return -1;
673 }
674 for (int i = toComponentIndex0(start), length = end - start; length > 0; i++) {
675 Component c = components[i];
676 if (c.offset == c.endOffset) {
677 continue;
678 }
679 ByteBuf s = c.buf;
680 int localStart = c.idx(start);
681 int localLength = Math.min(length, c.endOffset - start);
682
683 int result = s instanceof AbstractByteBuf
684 ? ((AbstractByteBuf) s).forEachByteAsc0(localStart, localStart + localLength, processor)
685 : s.forEachByte(localStart, localLength, processor);
686 if (result != -1) {
687 return result - c.adjustment;
688 }
689 start += localLength;
690 length -= localLength;
691 }
692 return -1;
693 }
694
695 @Override
696 protected int forEachByteDesc0(int rStart, int rEnd, ByteProcessor processor) throws Exception {
697 if (rEnd > rStart) {
698 return -1;
699 }
700 for (int i = toComponentIndex0(rStart), length = 1 + rStart - rEnd; length > 0; i--) {
701 Component c = components[i];
702 if (c.offset == c.endOffset) {
703 continue;
704 }
705 ByteBuf s = c.buf;
706 int localRStart = c.idx(length + rEnd);
707 int localLength = Math.min(length, localRStart), localIndex = localRStart - localLength;
708
709 int result = s instanceof AbstractByteBuf
710 ? ((AbstractByteBuf) s).forEachByteDesc0(localRStart - 1, localIndex, processor)
711 : s.forEachByteDesc(localIndex, localLength, processor);
712
713 if (result != -1) {
714 return result - c.adjustment;
715 }
716 length -= localLength;
717 }
718 return -1;
719 }
720
721
722
723
724 public List<ByteBuf> decompose(int offset, int length) {
725 checkIndex(offset, length);
726 if (length == 0) {
727 return Collections.emptyList();
728 }
729
730 int componentId = toComponentIndex0(offset);
731 int bytesToSlice = length;
732
733 Component firstC = components[componentId];
734
735
736
737
738 ByteBuf slice = firstC.srcBuf.slice(firstC.srcIdx(offset), Math.min(firstC.endOffset - offset, bytesToSlice));
739 bytesToSlice -= slice.readableBytes();
740
741 if (bytesToSlice == 0) {
742 return Collections.singletonList(slice);
743 }
744
745 List<ByteBuf> sliceList = new ArrayList<ByteBuf>(componentCount - componentId);
746 sliceList.add(slice);
747
748
749 do {
750 Component component = components[++componentId];
751
752
753
754 slice = component.srcBuf.slice(component.srcIdx(component.offset),
755 Math.min(component.length(), bytesToSlice));
756 bytesToSlice -= slice.readableBytes();
757 sliceList.add(slice);
758 } while (bytesToSlice > 0);
759
760 return sliceList;
761 }
762
763 @Override
764 public boolean isDirect() {
765 int size = componentCount;
766 if (size == 0) {
767 return false;
768 }
769 for (int i = 0; i < size; i++) {
770 if (!components[i].buf.isDirect()) {
771 return false;
772 }
773 }
774 return true;
775 }
776
777 @Override
778 public boolean hasArray() {
779 switch (componentCount) {
780 case 0:
781 return true;
782 case 1:
783 return components[0].buf.hasArray();
784 default:
785 return false;
786 }
787 }
788
789 @Override
790 public byte[] array() {
791 switch (componentCount) {
792 case 0:
793 return EmptyArrays.EMPTY_BYTES;
794 case 1:
795 return components[0].buf.array();
796 default:
797 throw new UnsupportedOperationException();
798 }
799 }
800
801 @Override
802 public int arrayOffset() {
803 switch (componentCount) {
804 case 0:
805 return 0;
806 case 1:
807 Component c = components[0];
808 return c.idx(c.buf.arrayOffset());
809 default:
810 throw new UnsupportedOperationException();
811 }
812 }
813
814 @Override
815 public boolean hasMemoryAddress() {
816 switch (componentCount) {
817 case 0:
818 return Unpooled.EMPTY_BUFFER.hasMemoryAddress();
819 case 1:
820 return components[0].buf.hasMemoryAddress();
821 default:
822 return false;
823 }
824 }
825
826 @Override
827 public long memoryAddress() {
828 switch (componentCount) {
829 case 0:
830 return Unpooled.EMPTY_BUFFER.memoryAddress();
831 case 1:
832 Component c = components[0];
833 return c.buf.memoryAddress() + c.adjustment;
834 default:
835 throw new UnsupportedOperationException();
836 }
837 }
838
839 @Override
840 public int capacity() {
841 int size = componentCount;
842 return size > 0 ? components[size - 1].endOffset : 0;
843 }
844
845 @Override
846 public CompositeByteBuf capacity(int newCapacity) {
847 checkNewCapacity(newCapacity);
848
849 final int size = componentCount, oldCapacity = capacity();
850 if (newCapacity > oldCapacity) {
851 final int paddingLength = newCapacity - oldCapacity;
852 ByteBuf padding = allocBuffer(paddingLength).setIndex(0, paddingLength);
853 addComponent0(false, size, padding);
854 if (componentCount >= maxNumComponents) {
855
856
857 consolidateIfNeeded();
858 }
859 } else if (newCapacity < oldCapacity) {
860 lastAccessed = null;
861 lastAccessedIndex = 0;
862 int i = size - 1;
863 for (int bytesToTrim = oldCapacity - newCapacity; i >= 0; i--) {
864 Component c = components[i];
865 final int cLength = c.length();
866 if (bytesToTrim < cLength) {
867
868 c.endOffset -= bytesToTrim;
869 ByteBuf slice = c.slice;
870 if (slice != null) {
871
872
873 c.slice = slice.slice(0, c.length());
874 }
875 break;
876 }
877 c.free();
878 bytesToTrim -= cLength;
879 }
880 removeCompRange(i + 1, size);
881
882 if (readerIndex() > newCapacity) {
883 setIndex0(newCapacity, newCapacity);
884 } else if (writerIndex > newCapacity) {
885 writerIndex = newCapacity;
886 }
887 }
888 return this;
889 }
890
891 @Override
892 public ByteBufAllocator alloc() {
893 return alloc;
894 }
895
896 @Override
897 public ByteOrder order() {
898 return ByteOrder.BIG_ENDIAN;
899 }
900
901
902
903
904 public int numComponents() {
905 return componentCount;
906 }
907
908
909
910
911 public int maxNumComponents() {
912 return maxNumComponents;
913 }
914
915
916
917
918 public int toComponentIndex(int offset) {
919 checkIndex(offset);
920 return toComponentIndex0(offset);
921 }
922
923 private int toComponentIndex0(int offset) {
924 int size = componentCount;
925 if (offset == 0) {
926 for (int i = 0; i < size; i++) {
927 if (components[i].endOffset > 0) {
928 return i;
929 }
930 }
931 }
932 if (size <= 2) {
933 return size == 1 || offset < components[0].endOffset ? 0 : 1;
934 }
935 for (int low = 0, high = size; low <= high;) {
936 int mid = low + high >>> 1;
937 Component c = components[mid];
938 if (offset >= c.endOffset) {
939 low = mid + 1;
940 } else if (offset < c.offset) {
941 high = mid - 1;
942 } else {
943 return mid;
944 }
945 }
946
947 throw new Error("should not reach here");
948 }
949
950 public int toByteIndex(int cIndex) {
951 checkComponentIndex(cIndex);
952 return components[cIndex].offset;
953 }
954
955 @Override
956 public byte getByte(int index) {
957 Component c = findComponent(index);
958 return c.abuf != null ? c.abuf._getByte(c.idx(index)) : c.buf.getByte(c.idx(index));
959 }
960
961 @Override
962 public byte readByte() {
963 checkReadableBytes(1);
964 int rIdx = readerIndex;
965 Component c = lastAccessed;
966 if (c == null) {
967 c = findIt(rIdx);
968 } else if (rIdx >= c.endOffset) {
969 c = findComponentForRead(rIdx);
970 } else if (rIdx < c.offset) {
971 c = findIt(rIdx);
972 }
973 readerIndex = rIdx + 1;
974 return c.abuf != null ? c.abuf._getByte(rIdx + c.adjustment) : c.buf.getByte(rIdx + c.adjustment);
975 }
976
977 @Override
978 protected byte _getByte(int index) {
979 Component c = findComponent0(index);
980 return c.abuf != null ? c.abuf._getByte(c.idx(index)) : c.buf.getByte(c.idx(index));
981 }
982
983 @Override
984 protected short _getShort(int index) {
985 Component c = findComponent0(index);
986 if (index + 2 <= c.endOffset) {
987 return c.abuf != null ? c.abuf._getShort(c.idx(index)) : c.buf.getShort(c.idx(index));
988 } else if (order() == ByteOrder.BIG_ENDIAN) {
989 return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff);
990 } else {
991 return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8);
992 }
993 }
994
995 @Override
996 protected short _getShortLE(int index) {
997 Component c = findComponent0(index);
998 if (index + 2 <= c.endOffset) {
999 return c.abuf != null ? c.abuf._getShortLE(c.idx(index)) : c.buf.getShortLE(c.idx(index));
1000 } else if (order() == ByteOrder.BIG_ENDIAN) {
1001 return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8);
1002 } else {
1003 return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff);
1004 }
1005 }
1006
1007 @Override
1008 protected int _getUnsignedMedium(int index) {
1009 Component c = findComponent0(index);
1010 if (index + 3 <= c.endOffset) {
1011 return c.abuf != null ? c.abuf._getUnsignedMedium(c.idx(index))
1012 : c.buf.getUnsignedMedium(c.idx(index));
1013 } else if (order() == ByteOrder.BIG_ENDIAN) {
1014 return (_getShort(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff;
1015 } else {
1016 return _getShort(index) & 0xFFFF | (_getByte(index + 2) & 0xFF) << 16;
1017 }
1018 }
1019
1020 @Override
1021 protected int _getUnsignedMediumLE(int index) {
1022 Component c = findComponent0(index);
1023 if (index + 3 <= c.endOffset) {
1024 return c.abuf != null ? c.abuf._getUnsignedMediumLE(c.idx(index))
1025 : c.buf.getUnsignedMediumLE(c.idx(index));
1026 } else if (order() == ByteOrder.BIG_ENDIAN) {
1027 return _getShortLE(index) & 0xffff | (_getByte(index + 2) & 0xff) << 16;
1028 } else {
1029 return (_getShortLE(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff;
1030 }
1031 }
1032
1033 @Override
1034 protected int _getInt(int index) {
1035 Component c = findComponent0(index);
1036 if (index + 4 <= c.endOffset) {
1037 return c.abuf != null ? c.abuf._getInt(c.idx(index)) : c.buf.getInt(c.idx(index));
1038 } else if (order() == ByteOrder.BIG_ENDIAN) {
1039 return (_getShort(index) & 0xffff) << 16 | _getShort(index + 2) & 0xffff;
1040 } else {
1041 return _getShort(index) & 0xFFFF | (_getShort(index + 2) & 0xFFFF) << 16;
1042 }
1043 }
1044
1045 @Override
1046 protected int _getIntLE(int index) {
1047 Component c = findComponent0(index);
1048 if (index + 4 <= c.endOffset) {
1049 return c.abuf != null ? c.abuf._getIntLE(c.idx(index)) : c.buf.getIntLE(c.idx(index));
1050 } else if (order() == ByteOrder.BIG_ENDIAN) {
1051 return _getShortLE(index) & 0xffff | (_getShortLE(index + 2) & 0xffff) << 16;
1052 } else {
1053 return (_getShortLE(index) & 0xffff) << 16 | _getShortLE(index + 2) & 0xffff;
1054 }
1055 }
1056
1057 @Override
1058 protected long _getLong(int index) {
1059 Component c = findComponent0(index);
1060 if (index + 8 <= c.endOffset) {
1061 return c.abuf != null ? c.abuf._getLong(c.idx(index)) : c.buf.getLong(c.idx(index));
1062 } else if (order() == ByteOrder.BIG_ENDIAN) {
1063 return (_getInt(index) & 0xffffffffL) << 32 | _getInt(index + 4) & 0xffffffffL;
1064 } else {
1065 return _getInt(index) & 0xFFFFFFFFL | (_getInt(index + 4) & 0xFFFFFFFFL) << 32;
1066 }
1067 }
1068
1069 @Override
1070 protected long _getLongLE(int index) {
1071 Component c = findComponent0(index);
1072 if (index + 8 <= c.endOffset) {
1073 return c.abuf != null ? c.abuf._getLongLE(c.idx(index)) : c.buf.getLongLE(c.idx(index));
1074 } else if (order() == ByteOrder.BIG_ENDIAN) {
1075 return _getIntLE(index) & 0xffffffffL | (_getIntLE(index + 4) & 0xffffffffL) << 32;
1076 } else {
1077 return (_getIntLE(index) & 0xffffffffL) << 32 | _getIntLE(index + 4) & 0xffffffffL;
1078 }
1079 }
1080
1081 @Override
1082 public CompositeByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
1083 checkDstIndex(index, length, dstIndex, dst.length);
1084 if (length == 0) {
1085 return this;
1086 }
1087
1088 int i = toComponentIndex0(index);
1089 while (length > 0) {
1090 Component c = components[i];
1091 int localLength = Math.min(length, c.endOffset - index);
1092 c.buf.getBytes(c.idx(index), dst, dstIndex, localLength);
1093 index += localLength;
1094 dstIndex += localLength;
1095 length -= localLength;
1096 i ++;
1097 }
1098 return this;
1099 }
1100
1101 @Override
1102 public CompositeByteBuf getBytes(int index, ByteBuffer dst) {
1103 int limit = dst.limit();
1104 int length = dst.remaining();
1105
1106 checkIndex(index, length);
1107 if (length == 0) {
1108 return this;
1109 }
1110
1111 int i = toComponentIndex0(index);
1112 try {
1113 while (length > 0) {
1114 Component c = components[i];
1115 int localLength = Math.min(length, c.endOffset - index);
1116 dst.limit(dst.position() + localLength);
1117 c.buf.getBytes(c.idx(index), dst);
1118 index += localLength;
1119 length -= localLength;
1120 i ++;
1121 }
1122 } finally {
1123 dst.limit(limit);
1124 }
1125 return this;
1126 }
1127
1128 @Override
1129 public CompositeByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
1130 checkDstIndex(index, length, dstIndex, dst.capacity());
1131 if (length == 0) {
1132 return this;
1133 }
1134
1135 int i = toComponentIndex0(index);
1136 while (length > 0) {
1137 Component c = components[i];
1138 int localLength = Math.min(length, c.endOffset - index);
1139 c.buf.getBytes(c.idx(index), dst, dstIndex, localLength);
1140 index += localLength;
1141 dstIndex += localLength;
1142 length -= localLength;
1143 i ++;
1144 }
1145 return this;
1146 }
1147
1148 @Override
1149 public int getBytes(int index, GatheringByteChannel out, int length)
1150 throws IOException {
1151 int count = nioBufferCount();
1152 if (count == 1) {
1153 return out.write(internalNioBuffer(index, length));
1154 } else {
1155 long writtenBytes = out.write(nioBuffers(index, length));
1156 if (writtenBytes > Integer.MAX_VALUE) {
1157 return Integer.MAX_VALUE;
1158 } else {
1159 return (int) writtenBytes;
1160 }
1161 }
1162 }
1163
1164 @Override
1165 public int getBytes(int index, FileChannel out, long position, int length)
1166 throws IOException {
1167 int count = nioBufferCount();
1168 if (count == 1) {
1169 return out.write(internalNioBuffer(index, length), position);
1170 } else {
1171 long writtenBytes = 0;
1172 for (ByteBuffer buf : nioBuffers(index, length)) {
1173 writtenBytes += out.write(buf, position + writtenBytes);
1174 }
1175 if (writtenBytes > Integer.MAX_VALUE) {
1176 return Integer.MAX_VALUE;
1177 }
1178 return (int) writtenBytes;
1179 }
1180 }
1181
1182 @Override
1183 public CompositeByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
1184 checkIndex(index, length);
1185 if (length == 0) {
1186 return this;
1187 }
1188
1189 int i = toComponentIndex0(index);
1190 while (length > 0) {
1191 Component c = components[i];
1192 int localLength = Math.min(length, c.endOffset - index);
1193 c.buf.getBytes(c.idx(index), out, localLength);
1194 index += localLength;
1195 length -= localLength;
1196 i ++;
1197 }
1198 return this;
1199 }
1200
1201 @Override
1202 public CompositeByteBuf setByte(int index, int value) {
1203 Component c = findComponent(index);
1204 if (c.abuf != null) {
1205 c.abuf._setByte(c.idx(index), value);
1206 } else {
1207 c.buf.setByte(c.idx(index), value);
1208 }
1209 return this;
1210 }
1211
1212 @Override
1213 protected void _setByte(int index, int value) {
1214 Component c = findComponent0(index);
1215 if (c.abuf != null) {
1216 c.abuf._setByte(c.idx(index), value);
1217 } else {
1218 c.buf.setByte(c.idx(index), value);
1219 }
1220 }
1221
1222 @Override
1223 public CompositeByteBuf setShort(int index, int value) {
1224 checkIndex(index, 2);
1225 _setShort(index, value);
1226 return this;
1227 }
1228
1229 @Override
1230 protected void _setShort(int index, int value) {
1231 Component c = findComponent0(index);
1232 if (index + 2 <= c.endOffset) {
1233 if (c.abuf != null) {
1234 c.abuf._setShort(c.idx(index), value);
1235 } else {
1236 c.buf.setShort(c.idx(index), value);
1237 }
1238 } else if (order() == ByteOrder.BIG_ENDIAN) {
1239 _setByte(index, (byte) (value >>> 8));
1240 _setByte(index + 1, (byte) value);
1241 } else {
1242 _setByte(index, (byte) value);
1243 _setByte(index + 1, (byte) (value >>> 8));
1244 }
1245 }
1246
1247 @Override
1248 protected void _setShortLE(int index, int value) {
1249 Component c = findComponent0(index);
1250 if (index + 2 <= c.endOffset) {
1251 if (c.abuf != null) {
1252 c.abuf._setShortLE(c.idx(index), value);
1253 } else {
1254 c.buf.setShortLE(c.idx(index), value);
1255 }
1256 } else if (order() == ByteOrder.BIG_ENDIAN) {
1257 _setByte(index, (byte) value);
1258 _setByte(index + 1, (byte) (value >>> 8));
1259 } else {
1260 _setByte(index, (byte) (value >>> 8));
1261 _setByte(index + 1, (byte) value);
1262 }
1263 }
1264
1265 @Override
1266 public CompositeByteBuf setMedium(int index, int value) {
1267 checkIndex(index, 3);
1268 _setMedium(index, value);
1269 return this;
1270 }
1271
1272 @Override
1273 protected void _setMedium(int index, int value) {
1274 Component c = findComponent0(index);
1275 if (index + 3 <= c.endOffset) {
1276 if (c.abuf != null) {
1277 c.abuf._setMedium(c.idx(index), value);
1278 } else {
1279 c.buf.setMedium(c.idx(index), value);
1280 }
1281 } else if (order() == ByteOrder.BIG_ENDIAN) {
1282 _setShort(index, (short) (value >> 8));
1283 _setByte(index + 2, (byte) value);
1284 } else {
1285 _setShort(index, (short) value);
1286 _setByte(index + 2, (byte) (value >>> 16));
1287 }
1288 }
1289
1290 @Override
1291 protected void _setMediumLE(int index, int value) {
1292 Component c = findComponent0(index);
1293 if (index + 3 <= c.endOffset) {
1294 if (c.abuf != null) {
1295 c.abuf._setMediumLE(c.idx(index), value);
1296 } else {
1297 c.buf.setMediumLE(c.idx(index), value);
1298 }
1299 } else if (order() == ByteOrder.BIG_ENDIAN) {
1300 _setShortLE(index, (short) value);
1301 _setByte(index + 2, (byte) (value >>> 16));
1302 } else {
1303 _setShortLE(index, (short) (value >> 8));
1304 _setByte(index + 2, (byte) value);
1305 }
1306 }
1307
1308 @Override
1309 public CompositeByteBuf setInt(int index, int value) {
1310 checkIndex(index, 4);
1311 _setInt(index, value);
1312 return this;
1313 }
1314
1315 @Override
1316 protected void _setInt(int index, int value) {
1317 Component c = findComponent0(index);
1318 if (index + 4 <= c.endOffset) {
1319 if (c.abuf != null) {
1320 c.abuf._setInt(c.idx(index), value);
1321 } else {
1322 c.buf.setInt(c.idx(index), value);
1323 }
1324 } else if (order() == ByteOrder.BIG_ENDIAN) {
1325 _setShort(index, (short) (value >>> 16));
1326 _setShort(index + 2, (short) value);
1327 } else {
1328 _setShort(index, (short) value);
1329 _setShort(index + 2, (short) (value >>> 16));
1330 }
1331 }
1332
1333 @Override
1334 protected void _setIntLE(int index, int value) {
1335 Component c = findComponent0(index);
1336 if (index + 4 <= c.endOffset) {
1337 if (c.abuf != null) {
1338 c.abuf._setIntLE(c.idx(index), value);
1339 } else {
1340 c.buf.setIntLE(c.idx(index), value);
1341 }
1342 } else if (order() == ByteOrder.BIG_ENDIAN) {
1343 _setShortLE(index, (short) value);
1344 _setShortLE(index + 2, (short) (value >>> 16));
1345 } else {
1346 _setShortLE(index, (short) (value >>> 16));
1347 _setShortLE(index + 2, (short) value);
1348 }
1349 }
1350
1351 @Override
1352 public CompositeByteBuf setLong(int index, long value) {
1353 checkIndex(index, 8);
1354 _setLong(index, value);
1355 return this;
1356 }
1357
1358 @Override
1359 protected void _setLong(int index, long value) {
1360 Component c = findComponent0(index);
1361 if (index + 8 <= c.endOffset) {
1362 if (c.abuf != null) {
1363 c.abuf._setLong(c.idx(index), value);
1364 } else {
1365 c.buf.setLong(c.idx(index), value);
1366 }
1367 } else if (order() == ByteOrder.BIG_ENDIAN) {
1368 _setInt(index, (int) (value >>> 32));
1369 _setInt(index + 4, (int) value);
1370 } else {
1371 _setInt(index, (int) value);
1372 _setInt(index + 4, (int) (value >>> 32));
1373 }
1374 }
1375
1376 @Override
1377 protected void _setLongLE(int index, long value) {
1378 Component c = findComponent0(index);
1379 if (index + 8 <= c.endOffset) {
1380 if (c.abuf != null) {
1381 c.abuf._setLongLE(c.idx(index), value);
1382 } else {
1383 c.buf.setLongLE(c.idx(index), value);
1384 }
1385 } else if (order() == ByteOrder.BIG_ENDIAN) {
1386 _setIntLE(index, (int) value);
1387 _setIntLE(index + 4, (int) (value >>> 32));
1388 } else {
1389 _setIntLE(index, (int) (value >>> 32));
1390 _setIntLE(index + 4, (int) value);
1391 }
1392 }
1393
1394 @Override
1395 public CompositeByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
1396 checkSrcIndex(index, length, srcIndex, src.length);
1397 if (length == 0) {
1398 return this;
1399 }
1400
1401 int i = toComponentIndex0(index);
1402 while (length > 0) {
1403 Component c = components[i];
1404 int localLength = Math.min(length, c.endOffset - index);
1405 c.buf.setBytes(c.idx(index), src, srcIndex, localLength);
1406 index += localLength;
1407 srcIndex += localLength;
1408 length -= localLength;
1409 i ++;
1410 }
1411 return this;
1412 }
1413
1414 @Override
1415 public CompositeByteBuf setBytes(int index, ByteBuffer src) {
1416 int limit = src.limit();
1417 int length = src.remaining();
1418
1419 checkIndex(index, length);
1420 if (length == 0) {
1421 return this;
1422 }
1423
1424 int i = toComponentIndex0(index);
1425 try {
1426 while (length > 0) {
1427 Component c = components[i];
1428 int localLength = Math.min(length, c.endOffset - index);
1429 src.limit(src.position() + localLength);
1430 c.buf.setBytes(c.idx(index), src);
1431 index += localLength;
1432 length -= localLength;
1433 i ++;
1434 }
1435 } finally {
1436 src.limit(limit);
1437 }
1438 return this;
1439 }
1440
1441 @Override
1442 public CompositeByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
1443 checkSrcIndex(index, length, srcIndex, src.capacity());
1444 if (length == 0) {
1445 return this;
1446 }
1447
1448 int i = toComponentIndex0(index);
1449 while (length > 0) {
1450 Component c = components[i];
1451 int localLength = Math.min(length, c.endOffset - index);
1452 c.buf.setBytes(c.idx(index), src, srcIndex, localLength);
1453 index += localLength;
1454 srcIndex += localLength;
1455 length -= localLength;
1456 i ++;
1457 }
1458 return this;
1459 }
1460
1461 @Override
1462 public int setBytes(int index, InputStream in, int length) throws IOException {
1463 checkIndex(index, length);
1464 if (length == 0) {
1465 return in.read(EmptyArrays.EMPTY_BYTES);
1466 }
1467
1468 int i = toComponentIndex0(index);
1469 int readBytes = 0;
1470 do {
1471 Component c = components[i];
1472 int localLength = Math.min(length, c.endOffset - index);
1473 if (localLength == 0) {
1474
1475 i++;
1476 continue;
1477 }
1478 int localReadBytes = c.buf.setBytes(c.idx(index), in, localLength);
1479 if (localReadBytes < 0) {
1480 if (readBytes == 0) {
1481 return -1;
1482 } else {
1483 break;
1484 }
1485 }
1486
1487 index += localReadBytes;
1488 length -= localReadBytes;
1489 readBytes += localReadBytes;
1490 if (localReadBytes == localLength) {
1491 i ++;
1492 }
1493 } while (length > 0);
1494
1495 return readBytes;
1496 }
1497
1498 @Override
1499 public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
1500 checkIndex(index, length);
1501 if (length == 0) {
1502 return in.read(EMPTY_NIO_BUFFER);
1503 }
1504
1505 int i = toComponentIndex0(index);
1506 int readBytes = 0;
1507 do {
1508 Component c = components[i];
1509 int localLength = Math.min(length, c.endOffset - index);
1510 if (localLength == 0) {
1511
1512 i++;
1513 continue;
1514 }
1515 int localReadBytes = c.buf.setBytes(c.idx(index), in, localLength);
1516
1517 if (localReadBytes == 0) {
1518 break;
1519 }
1520
1521 if (localReadBytes < 0) {
1522 if (readBytes == 0) {
1523 return -1;
1524 } else {
1525 break;
1526 }
1527 }
1528
1529 index += localReadBytes;
1530 length -= localReadBytes;
1531 readBytes += localReadBytes;
1532 if (localReadBytes == localLength) {
1533 i ++;
1534 }
1535 } while (length > 0);
1536
1537 return readBytes;
1538 }
1539
1540 @Override
1541 public int setBytes(int index, FileChannel in, long position, int length) throws IOException {
1542 checkIndex(index, length);
1543 if (length == 0) {
1544 return in.read(EMPTY_NIO_BUFFER, position);
1545 }
1546
1547 int i = toComponentIndex0(index);
1548 int readBytes = 0;
1549 do {
1550 Component c = components[i];
1551 int localLength = Math.min(length, c.endOffset - index);
1552 if (localLength == 0) {
1553
1554 i++;
1555 continue;
1556 }
1557 int localReadBytes = c.buf.setBytes(c.idx(index), in, position + readBytes, localLength);
1558
1559 if (localReadBytes == 0) {
1560 break;
1561 }
1562
1563 if (localReadBytes < 0) {
1564 if (readBytes == 0) {
1565 return -1;
1566 } else {
1567 break;
1568 }
1569 }
1570
1571 index += localReadBytes;
1572 length -= localReadBytes;
1573 readBytes += localReadBytes;
1574 if (localReadBytes == localLength) {
1575 i ++;
1576 }
1577 } while (length > 0);
1578
1579 return readBytes;
1580 }
1581
1582 @Override
1583 public ByteBuf copy(int index, int length) {
1584 checkIndex(index, length);
1585 ByteBuf dst = allocBuffer(length);
1586 if (length != 0) {
1587 copyTo(index, length, toComponentIndex0(index), dst);
1588 }
1589 return dst;
1590 }
1591
1592 private void copyTo(int index, int length, int componentId, ByteBuf dst) {
1593 int dstIndex = 0;
1594 int i = componentId;
1595
1596 while (length > 0) {
1597 Component c = components[i];
1598 int localLength = Math.min(length, c.endOffset - index);
1599 c.buf.getBytes(c.idx(index), dst, dstIndex, localLength);
1600 index += localLength;
1601 dstIndex += localLength;
1602 length -= localLength;
1603 i ++;
1604 }
1605
1606 dst.writerIndex(dst.capacity());
1607 }
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623 public ByteBuf component(int cIndex) {
1624 checkComponentIndex(cIndex);
1625 return components[cIndex].duplicate();
1626 }
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639 public ByteBuf componentSlice(int cIndex) {
1640 checkComponentIndex(cIndex);
1641 return components[cIndex].slice();
1642 }
1643
1644
1645
1646
1647
1648
1649
1650 public ByteBuf componentAtOffset(int offset) {
1651 return findComponent(offset).duplicate();
1652 }
1653
1654
1655
1656
1657
1658
1659
1660 public ByteBuf internalComponent(int cIndex) {
1661 checkComponentIndex(cIndex);
1662 return components[cIndex].slice();
1663 }
1664
1665
1666
1667
1668
1669
1670
1671 public ByteBuf internalComponentAtOffset(int offset) {
1672 return findComponent(offset).slice();
1673 }
1674
1675
1676 private Component lastAccessed;
1677 private int lastAccessedIndex;
1678
1679 private Component findComponent(int offset) {
1680 Component la = lastAccessed;
1681 if (la != null && offset >= la.offset && offset < la.endOffset) {
1682 ensureAccessible();
1683 return la;
1684 }
1685 checkIndex(offset);
1686 return findIt(offset);
1687 }
1688
1689 private Component findComponent0(int offset) {
1690 Component la = lastAccessed;
1691 if (la != null && offset >= la.offset && offset < la.endOffset) {
1692 return la;
1693 }
1694 return findIt(offset);
1695 }
1696
1697
1698
1699
1700 private Component findComponentForRead(int offset) {
1701 int cc = componentCount;
1702 for (int next = lastAccessedIndex + 1; next < cc; next++) {
1703 Component c = components[next];
1704 if (offset < c.endOffset) {
1705 lastAccessed = c;
1706 lastAccessedIndex = next;
1707 return c;
1708 }
1709 }
1710 return findIt(offset);
1711 }
1712
1713 private Component findIt(int offset) {
1714 for (int low = 0, high = componentCount; low <= high;) {
1715 int mid = low + high >>> 1;
1716 Component c = components[mid];
1717 if (c == null) {
1718 throw new IllegalStateException("No component found for offset. " +
1719 "Composite buffer layout might be outdated, e.g. from a discardReadBytes call.");
1720 }
1721 if (offset >= c.endOffset) {
1722 low = mid + 1;
1723 } else if (offset < c.offset) {
1724 high = mid - 1;
1725 } else {
1726 lastAccessed = c;
1727 lastAccessedIndex = mid;
1728 return c;
1729 }
1730 }
1731
1732 throw new Error("should not reach here");
1733 }
1734
1735 @Override
1736 public int nioBufferCount() {
1737 int size = componentCount;
1738 switch (size) {
1739 case 0:
1740 return 1;
1741 case 1:
1742 return components[0].buf.nioBufferCount();
1743 default:
1744 int count = 0;
1745 for (int i = 0; i < size; i++) {
1746 count += components[i].buf.nioBufferCount();
1747 }
1748 return count;
1749 }
1750 }
1751
1752 @Override
1753 public ByteBuffer internalNioBuffer(int index, int length) {
1754 switch (componentCount) {
1755 case 0:
1756 return EMPTY_NIO_BUFFER;
1757 case 1:
1758 return components[0].internalNioBuffer(index, length);
1759 default:
1760 throw new UnsupportedOperationException();
1761 }
1762 }
1763
1764 @Override
1765 public ByteBuffer nioBuffer(int index, int length) {
1766 checkIndex(index, length);
1767
1768 switch (componentCount) {
1769 case 0:
1770 return EMPTY_NIO_BUFFER;
1771 case 1:
1772 Component c = components[0];
1773 ByteBuf buf = c.buf;
1774 if (buf.nioBufferCount() == 1) {
1775 return buf.nioBuffer(c.idx(index), length);
1776 }
1777 break;
1778 default:
1779 break;
1780 }
1781
1782 ByteBuffer[] buffers = nioBuffers(index, length);
1783
1784 if (buffers.length == 1) {
1785 return buffers[0];
1786 }
1787
1788 ByteBuffer merged = ByteBuffer.allocate(length).order(order());
1789 for (ByteBuffer buf: buffers) {
1790 merged.put(buf);
1791 }
1792
1793 merged.flip();
1794 return merged;
1795 }
1796
1797 @Override
1798 public ByteBuffer[] nioBuffers(int index, int length) {
1799 checkIndex(index, length);
1800 if (length == 0) {
1801 return new ByteBuffer[] { EMPTY_NIO_BUFFER };
1802 }
1803
1804 RecyclableArrayList buffers = RecyclableArrayList.newInstance(componentCount);
1805 try {
1806 int i = toComponentIndex0(index);
1807 while (length > 0) {
1808 Component c = components[i];
1809 ByteBuf s = c.buf;
1810 int localLength = Math.min(length, c.endOffset - index);
1811 switch (s.nioBufferCount()) {
1812 case 0:
1813 throw new UnsupportedOperationException();
1814 case 1:
1815 buffers.add(s.nioBuffer(c.idx(index), localLength));
1816 break;
1817 default:
1818 Collections.addAll(buffers, s.nioBuffers(c.idx(index), localLength));
1819 }
1820
1821 index += localLength;
1822 length -= localLength;
1823 i ++;
1824 }
1825
1826 return buffers.toArray(EmptyArrays.EMPTY_BYTE_BUFFERS);
1827 } finally {
1828 buffers.recycle();
1829 }
1830 }
1831
1832
1833
1834
1835 public CompositeByteBuf consolidate() {
1836 ensureAccessible();
1837 consolidate0(0, componentCount);
1838 return this;
1839 }
1840
1841
1842
1843
1844
1845
1846
1847 public CompositeByteBuf consolidate(int cIndex, int numComponents) {
1848 checkComponentIndex(cIndex, numComponents);
1849 consolidate0(cIndex, numComponents);
1850 return this;
1851 }
1852
1853 private void consolidate0(int cIndex, int numComponents) {
1854 if (numComponents <= 1) {
1855 return;
1856 }
1857
1858 final int endCIndex = cIndex + numComponents;
1859 final int startOffset = cIndex != 0 ? components[cIndex].offset : 0;
1860 final int capacity = components[endCIndex - 1].endOffset - startOffset;
1861 final ByteBuf consolidated = allocBuffer(capacity);
1862
1863 for (int i = cIndex; i < endCIndex; i ++) {
1864 components[i].transferTo(consolidated);
1865 }
1866 lastAccessed = null;
1867 lastAccessedIndex = 0;
1868 removeCompRange(cIndex + 1, endCIndex);
1869 components[cIndex] = newComponent(consolidated, 0);
1870 if (cIndex != 0 || numComponents != componentCount) {
1871 updateComponentOffsets(cIndex);
1872 }
1873 }
1874
1875
1876
1877
1878 public CompositeByteBuf discardReadComponents() {
1879 ensureAccessible();
1880 final int readerIndex = readerIndex();
1881 if (readerIndex == 0) {
1882 return this;
1883 }
1884
1885
1886 int writerIndex = writerIndex();
1887 if (readerIndex == writerIndex && writerIndex == capacity()) {
1888 for (int i = 0, size = componentCount; i < size; i++) {
1889 components[i].free();
1890 }
1891 lastAccessed = null;
1892 lastAccessedIndex = 0;
1893 clearComps();
1894 setIndex(0, 0);
1895 adjustMarkers(readerIndex);
1896 return this;
1897 }
1898
1899
1900 int firstComponentId = 0;
1901 Component c = null;
1902 for (int size = componentCount; firstComponentId < size; firstComponentId++) {
1903 c = components[firstComponentId];
1904 if (c.endOffset > readerIndex) {
1905 break;
1906 }
1907 c.free();
1908 }
1909 if (firstComponentId == 0) {
1910 return this;
1911 }
1912 Component la = lastAccessed;
1913 if (la != null && la.endOffset <= readerIndex) {
1914 lastAccessed = null;
1915 lastAccessedIndex = 0;
1916 }
1917 removeCompRange(0, firstComponentId);
1918
1919
1920 int offset = c.offset;
1921 updateComponentOffsets(0);
1922 setIndex(readerIndex - offset, writerIndex - offset);
1923 adjustMarkers(offset);
1924 return this;
1925 }
1926
1927 @Override
1928 public CompositeByteBuf discardReadBytes() {
1929 ensureAccessible();
1930 final int readerIndex = readerIndex();
1931 if (readerIndex == 0) {
1932 return this;
1933 }
1934
1935
1936 int writerIndex = writerIndex();
1937 if (readerIndex == writerIndex && writerIndex == capacity()) {
1938 for (int i = 0, size = componentCount; i < size; i++) {
1939 components[i].free();
1940 }
1941 lastAccessed = null;
1942 lastAccessedIndex = 0;
1943 clearComps();
1944 setIndex(0, 0);
1945 adjustMarkers(readerIndex);
1946 return this;
1947 }
1948
1949 int firstComponentId = 0;
1950 Component c = null;
1951 for (int size = componentCount; firstComponentId < size; firstComponentId++) {
1952 c = components[firstComponentId];
1953 if (c.endOffset > readerIndex) {
1954 break;
1955 }
1956 c.free();
1957 }
1958
1959
1960 int trimmedBytes = readerIndex - c.offset;
1961 c.offset = 0;
1962 c.endOffset -= readerIndex;
1963 c.srcAdjustment += readerIndex;
1964 c.adjustment += readerIndex;
1965 ByteBuf slice = c.slice;
1966 if (slice != null) {
1967
1968
1969 c.slice = slice.slice(trimmedBytes, c.length());
1970 }
1971 Component la = lastAccessed;
1972 if (la != null && la.endOffset <= readerIndex) {
1973 lastAccessed = null;
1974 lastAccessedIndex = 0;
1975 }
1976
1977 removeCompRange(0, firstComponentId);
1978
1979
1980 updateComponentOffsets(0);
1981 setIndex(0, writerIndex - readerIndex);
1982 adjustMarkers(readerIndex);
1983 return this;
1984 }
1985
1986 private ByteBuf allocBuffer(int capacity) {
1987 return direct ? alloc().directBuffer(capacity) : alloc().heapBuffer(capacity);
1988 }
1989
1990 @Override
1991 public String toString() {
1992 String result = super.toString();
1993 result = result.substring(0, result.length() - 1);
1994 return result + ", components=" + componentCount + ')';
1995 }
1996
1997 private static final class Component {
1998 final ByteBuf srcBuf;
1999 final ByteBuf buf;
2000 final AbstractByteBuf abuf;
2001
2002 int srcAdjustment;
2003 int adjustment;
2004
2005 int offset;
2006 int endOffset;
2007
2008 private ByteBuf slice;
2009
2010 Component(ByteBuf srcBuf, int srcOffset, ByteBuf buf, int bufOffset,
2011 int offset, int len, ByteBuf slice) {
2012 this.srcBuf = srcBuf;
2013 this.srcAdjustment = srcOffset - offset;
2014 this.buf = buf;
2015 this.abuf = buf instanceof AbstractByteBuf ? (AbstractByteBuf) buf : null;
2016 this.adjustment = bufOffset - offset;
2017 this.offset = offset;
2018 this.endOffset = offset + len;
2019 this.slice = slice;
2020 }
2021
2022 int srcIdx(int index) {
2023 return index + srcAdjustment;
2024 }
2025
2026 int idx(int index) {
2027 return index + adjustment;
2028 }
2029
2030 int length() {
2031 return endOffset - offset;
2032 }
2033
2034 void reposition(int newOffset) {
2035 int move = newOffset - offset;
2036 endOffset += move;
2037 srcAdjustment -= move;
2038 adjustment -= move;
2039 offset = newOffset;
2040 }
2041
2042
2043 void transferTo(ByteBuf dst) {
2044 dst.writeBytes(buf, idx(offset), length());
2045 free();
2046 }
2047
2048 ByteBuf slice() {
2049 ByteBuf s = slice;
2050 if (s == null) {
2051 slice = s = srcBuf.slice(srcIdx(offset), length());
2052 }
2053 return s;
2054 }
2055
2056 ByteBuf duplicate() {
2057 return srcBuf.duplicate();
2058 }
2059
2060 ByteBuffer internalNioBuffer(int index, int length) {
2061
2062 return srcBuf.internalNioBuffer(srcIdx(index), length);
2063 }
2064
2065 void free() {
2066 slice = null;
2067
2068
2069 srcBuf.release();
2070 }
2071 }
2072
2073 @Override
2074 public CompositeByteBuf readerIndex(int readerIndex) {
2075 super.readerIndex(readerIndex);
2076 return this;
2077 }
2078
2079 @Override
2080 public CompositeByteBuf writerIndex(int writerIndex) {
2081 super.writerIndex(writerIndex);
2082 return this;
2083 }
2084
2085 @Override
2086 public CompositeByteBuf setIndex(int readerIndex, int writerIndex) {
2087 super.setIndex(readerIndex, writerIndex);
2088 return this;
2089 }
2090
2091 @Override
2092 public CompositeByteBuf clear() {
2093 super.clear();
2094 return this;
2095 }
2096
2097 @Override
2098 public CompositeByteBuf markReaderIndex() {
2099 super.markReaderIndex();
2100 return this;
2101 }
2102
2103 @Override
2104 public CompositeByteBuf resetReaderIndex() {
2105 super.resetReaderIndex();
2106 return this;
2107 }
2108
2109 @Override
2110 public CompositeByteBuf markWriterIndex() {
2111 super.markWriterIndex();
2112 return this;
2113 }
2114
2115 @Override
2116 public CompositeByteBuf resetWriterIndex() {
2117 super.resetWriterIndex();
2118 return this;
2119 }
2120
2121 @Override
2122 public CompositeByteBuf ensureWritable(int minWritableBytes) {
2123 super.ensureWritable(minWritableBytes);
2124 return this;
2125 }
2126
2127 @Override
2128 public CompositeByteBuf getBytes(int index, ByteBuf dst) {
2129 return getBytes(index, dst, dst.writableBytes());
2130 }
2131
2132 @Override
2133 public CompositeByteBuf getBytes(int index, ByteBuf dst, int length) {
2134 getBytes(index, dst, dst.writerIndex(), length);
2135 dst.writerIndex(dst.writerIndex() + length);
2136 return this;
2137 }
2138
2139 @Override
2140 public CompositeByteBuf getBytes(int index, byte[] dst) {
2141 return getBytes(index, dst, 0, dst.length);
2142 }
2143
2144 @Override
2145 public CompositeByteBuf setBoolean(int index, boolean value) {
2146 return setByte(index, value? 1 : 0);
2147 }
2148
2149 @Override
2150 public CompositeByteBuf setChar(int index, int value) {
2151 return setShort(index, value);
2152 }
2153
2154 @Override
2155 public CompositeByteBuf setFloat(int index, float value) {
2156 return setInt(index, Float.floatToRawIntBits(value));
2157 }
2158
2159 @Override
2160 public CompositeByteBuf setDouble(int index, double value) {
2161 return setLong(index, Double.doubleToRawLongBits(value));
2162 }
2163
2164 @Override
2165 public CompositeByteBuf setBytes(int index, ByteBuf src) {
2166 super.setBytes(index, src, src.readableBytes());
2167 return this;
2168 }
2169
2170 @Override
2171 public CompositeByteBuf setBytes(int index, ByteBuf src, int length) {
2172 super.setBytes(index, src, length);
2173 return this;
2174 }
2175
2176 @Override
2177 public CompositeByteBuf setBytes(int index, byte[] src) {
2178 return setBytes(index, src, 0, src.length);
2179 }
2180
2181 @Override
2182 public CompositeByteBuf setZero(int index, int length) {
2183 super.setZero(index, length);
2184 return this;
2185 }
2186
2187 @Override
2188 public CompositeByteBuf readBytes(ByteBuf dst) {
2189 super.readBytes(dst, dst.writableBytes());
2190 return this;
2191 }
2192
2193 @Override
2194 public CompositeByteBuf readBytes(ByteBuf dst, int length) {
2195 super.readBytes(dst, length);
2196 return this;
2197 }
2198
2199 @Override
2200 public CompositeByteBuf readBytes(ByteBuf dst, int dstIndex, int length) {
2201 super.readBytes(dst, dstIndex, length);
2202 return this;
2203 }
2204
2205 @Override
2206 public CompositeByteBuf readBytes(byte[] dst) {
2207 super.readBytes(dst, 0, dst.length);
2208 return this;
2209 }
2210
2211 @Override
2212 public CompositeByteBuf readBytes(byte[] dst, int dstIndex, int length) {
2213 super.readBytes(dst, dstIndex, length);
2214 return this;
2215 }
2216
2217 @Override
2218 public CompositeByteBuf readBytes(ByteBuffer dst) {
2219 super.readBytes(dst);
2220 return this;
2221 }
2222
2223 @Override
2224 public CompositeByteBuf readBytes(OutputStream out, int length) throws IOException {
2225 super.readBytes(out, length);
2226 return this;
2227 }
2228
2229 @Override
2230 public CompositeByteBuf skipBytes(int length) {
2231 super.skipBytes(length);
2232 return this;
2233 }
2234
2235 @Override
2236 public CompositeByteBuf writeBoolean(boolean value) {
2237 writeByte(value ? 1 : 0);
2238 return this;
2239 }
2240
2241 @Override
2242 public CompositeByteBuf writeByte(int value) {
2243 ensureWritable0(1);
2244 _setByte(writerIndex++, value);
2245 return this;
2246 }
2247
2248 @Override
2249 public CompositeByteBuf writeShort(int value) {
2250 super.writeShort(value);
2251 return this;
2252 }
2253
2254 @Override
2255 public CompositeByteBuf writeMedium(int value) {
2256 super.writeMedium(value);
2257 return this;
2258 }
2259
2260 @Override
2261 public CompositeByteBuf writeInt(int value) {
2262 super.writeInt(value);
2263 return this;
2264 }
2265
2266 @Override
2267 public CompositeByteBuf writeLong(long value) {
2268 super.writeLong(value);
2269 return this;
2270 }
2271
2272 @Override
2273 public CompositeByteBuf writeChar(int value) {
2274 super.writeShort(value);
2275 return this;
2276 }
2277
2278 @Override
2279 public CompositeByteBuf writeFloat(float value) {
2280 super.writeInt(Float.floatToRawIntBits(value));
2281 return this;
2282 }
2283
2284 @Override
2285 public CompositeByteBuf writeDouble(double value) {
2286 super.writeLong(Double.doubleToRawLongBits(value));
2287 return this;
2288 }
2289
2290 @Override
2291 public CompositeByteBuf writeBytes(ByteBuf src) {
2292 super.writeBytes(src, src.readableBytes());
2293 return this;
2294 }
2295
2296 @Override
2297 public CompositeByteBuf writeBytes(ByteBuf src, int length) {
2298 super.writeBytes(src, length);
2299 return this;
2300 }
2301
2302 @Override
2303 public CompositeByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
2304 super.writeBytes(src, srcIndex, length);
2305 return this;
2306 }
2307
2308 @Override
2309 public CompositeByteBuf writeBytes(byte[] src) {
2310 super.writeBytes(src, 0, src.length);
2311 return this;
2312 }
2313
2314 @Override
2315 public CompositeByteBuf writeBytes(byte[] src, int srcIndex, int length) {
2316 super.writeBytes(src, srcIndex, length);
2317 return this;
2318 }
2319
2320 @Override
2321 public CompositeByteBuf writeBytes(ByteBuffer src) {
2322 super.writeBytes(src);
2323 return this;
2324 }
2325
2326 @Override
2327 public CompositeByteBuf writeZero(int length) {
2328 super.writeZero(length);
2329 return this;
2330 }
2331
2332 @Override
2333 public CompositeByteBuf retain(int increment) {
2334 super.retain(increment);
2335 return this;
2336 }
2337
2338 @Override
2339 public CompositeByteBuf retain() {
2340 super.retain();
2341 return this;
2342 }
2343
2344 @Override
2345 public CompositeByteBuf touch() {
2346 return this;
2347 }
2348
2349 @Override
2350 public CompositeByteBuf touch(Object hint) {
2351 return this;
2352 }
2353
2354 @Override
2355 public ByteBuffer[] nioBuffers() {
2356 return nioBuffers(readerIndex(), readableBytes());
2357 }
2358
2359 @Override
2360 public CompositeByteBuf discardSomeReadBytes() {
2361 return discardReadComponents();
2362 }
2363
2364 @Override
2365 protected void deallocate() {
2366 if (freed) {
2367 return;
2368 }
2369
2370 freed = true;
2371
2372
2373 for (int i = 0, size = componentCount; i < size; i++) {
2374 components[i].free();
2375 }
2376 }
2377
2378 @Override
2379 boolean isAccessible() {
2380 return !freed;
2381 }
2382
2383 @Override
2384 public ByteBuf unwrap() {
2385 return null;
2386 }
2387
2388 private final class CompositeByteBufIterator implements Iterator<ByteBuf> {
2389 private final int size = numComponents();
2390 private int index;
2391
2392 @Override
2393 public boolean hasNext() {
2394 return size > index;
2395 }
2396
2397 @Override
2398 public ByteBuf next() {
2399 if (size != numComponents()) {
2400 throw new ConcurrentModificationException();
2401 }
2402 if (!hasNext()) {
2403 throw new NoSuchElementException();
2404 }
2405 try {
2406 return components[index++].slice();
2407 } catch (IndexOutOfBoundsException e) {
2408 throw new ConcurrentModificationException();
2409 }
2410 }
2411
2412 @Override
2413 public void remove() {
2414 throw new UnsupportedOperationException("Read-Only");
2415 }
2416 }
2417
2418
2419
2420 private void clearComps() {
2421 removeCompRange(0, componentCount);
2422 }
2423
2424 private void removeComp(int i) {
2425 removeCompRange(i, i + 1);
2426 }
2427
2428 private void removeCompRange(int from, int to) {
2429 if (from >= to) {
2430 return;
2431 }
2432 final int size = componentCount;
2433 assert from >= 0 && to <= size;
2434 if (to < size) {
2435 System.arraycopy(components, to, components, from, size - to);
2436 }
2437 int newSize = size - to + from;
2438 for (int i = newSize; i < size; i++) {
2439 components[i] = null;
2440 }
2441 componentCount = newSize;
2442 }
2443
2444 private void addComp(int i, Component c) {
2445 shiftComps(i, 1);
2446 components[i] = c;
2447 }
2448
2449 private void shiftComps(int i, int count) {
2450 final int size = componentCount, newSize = size + count;
2451 assert i >= 0 && i <= size && count > 0;
2452 if (newSize > components.length) {
2453
2454 int newArrSize = Math.max(size + (size >> 1), newSize);
2455 Component[] newArr;
2456 if (i == size) {
2457 newArr = Arrays.copyOf(components, newArrSize, Component[].class);
2458 } else {
2459 newArr = new Component[newArrSize];
2460 if (i > 0) {
2461 System.arraycopy(components, 0, newArr, 0, i);
2462 }
2463 if (i < size) {
2464 System.arraycopy(components, i, newArr, i + count, size - i);
2465 }
2466 }
2467 components = newArr;
2468 } else if (i < size) {
2469 System.arraycopy(components, i, components, i + count, size - i);
2470 }
2471 componentCount = newSize;
2472 }
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482 @Override
2483 public boolean release(final int decrement) {
2484 return super.release(decrement);
2485 }
2486 }