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.IllegalReferenceCountException;
19 import io.netty.util.ResourceLeakDetector;
20 import io.netty.util.ResourceLeakDetectorFactory;
21 import io.netty.util.internal.PlatformDependent;
22 import io.netty.util.internal.StringUtil;
23 import io.netty.util.internal.SystemPropertyUtil;
24 import io.netty.util.internal.logging.InternalLogger;
25 import io.netty.util.internal.logging.InternalLoggerFactory;
26
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.nio.ByteBuffer;
31 import java.nio.ByteOrder;
32 import java.nio.channels.GatheringByteChannel;
33 import java.nio.channels.ScatteringByteChannel;
34 import java.nio.charset.Charset;
35
36 import static io.netty.util.internal.MathUtil.isOutOfBounds;
37
38
39
40
41 public abstract class AbstractByteBuf extends ByteBuf {
42 private static final InternalLogger logger = InternalLoggerFactory.getInstance(AbstractByteBuf.class);
43 private static final String PROP_MODE = "io.netty.buffer.bytebuf.checkAccessible";
44 private static final boolean checkAccessible;
45
46 static {
47 checkAccessible = SystemPropertyUtil.getBoolean(PROP_MODE, true);
48 if (logger.isDebugEnabled()) {
49 logger.debug("-D{}: {}", PROP_MODE, checkAccessible);
50 }
51 }
52
53 static final ResourceLeakDetector<ByteBuf> leakDetector =
54 ResourceLeakDetectorFactory.instance().newResourceLeakDetector(ByteBuf.class);
55
56 int readerIndex;
57 int writerIndex;
58 private int markedReaderIndex;
59 private int markedWriterIndex;
60
61 private int maxCapacity;
62
63 private SwappedByteBuf swappedBuf;
64
65 protected AbstractByteBuf(int maxCapacity) {
66 if (maxCapacity < 0) {
67 throw new IllegalArgumentException("maxCapacity: " + maxCapacity + " (expected: >= 0)");
68 }
69 this.maxCapacity = maxCapacity;
70 }
71
72 @Override
73 public int maxCapacity() {
74 return maxCapacity;
75 }
76
77 protected final void maxCapacity(int maxCapacity) {
78 this.maxCapacity = maxCapacity;
79 }
80
81 @Override
82 public int readerIndex() {
83 return readerIndex;
84 }
85
86 @Override
87 public ByteBuf readerIndex(int readerIndex) {
88 if (readerIndex < 0 || readerIndex > writerIndex) {
89 throw new IndexOutOfBoundsException(String.format(
90 "readerIndex: %d (expected: 0 <= readerIndex <= writerIndex(%d))", readerIndex, writerIndex));
91 }
92 this.readerIndex = readerIndex;
93 return this;
94 }
95
96 @Override
97 public int writerIndex() {
98 return writerIndex;
99 }
100
101 @Override
102 public ByteBuf writerIndex(int writerIndex) {
103 if (writerIndex < readerIndex || writerIndex > capacity()) {
104 throw new IndexOutOfBoundsException(String.format(
105 "writerIndex: %d (expected: readerIndex(%d) <= writerIndex <= capacity(%d))",
106 writerIndex, readerIndex, capacity()));
107 }
108 this.writerIndex = writerIndex;
109 return this;
110 }
111
112 @Override
113 public ByteBuf setIndex(int readerIndex, int writerIndex) {
114 if (readerIndex < 0 || readerIndex > writerIndex || writerIndex > capacity()) {
115 throw new IndexOutOfBoundsException(String.format(
116 "readerIndex: %d, writerIndex: %d (expected: 0 <= readerIndex <= writerIndex <= capacity(%d))",
117 readerIndex, writerIndex, capacity()));
118 }
119 setIndex0(readerIndex, writerIndex);
120 return this;
121 }
122
123 @Override
124 public ByteBuf clear() {
125 readerIndex = writerIndex = 0;
126 return this;
127 }
128
129 @Override
130 public boolean isReadable() {
131 return writerIndex > readerIndex;
132 }
133
134 @Override
135 public boolean isReadable(int numBytes) {
136 return writerIndex - readerIndex >= numBytes;
137 }
138
139 @Override
140 public boolean isWritable() {
141 return capacity() > writerIndex;
142 }
143
144 @Override
145 public boolean isWritable(int numBytes) {
146 return capacity() - writerIndex >= numBytes;
147 }
148
149 @Override
150 public int readableBytes() {
151 return writerIndex - readerIndex;
152 }
153
154 @Override
155 public int writableBytes() {
156 return capacity() - writerIndex;
157 }
158
159 @Override
160 public int maxWritableBytes() {
161 return maxCapacity() - writerIndex;
162 }
163
164 @Override
165 public ByteBuf markReaderIndex() {
166 markedReaderIndex = readerIndex;
167 return this;
168 }
169
170 @Override
171 public ByteBuf resetReaderIndex() {
172 readerIndex(markedReaderIndex);
173 return this;
174 }
175
176 @Override
177 public ByteBuf markWriterIndex() {
178 markedWriterIndex = writerIndex;
179 return this;
180 }
181
182 @Override
183 public ByteBuf resetWriterIndex() {
184 writerIndex = markedWriterIndex;
185 return this;
186 }
187
188 @Override
189 public ByteBuf discardReadBytes() {
190 ensureAccessible();
191 if (readerIndex == 0) {
192 return this;
193 }
194
195 if (readerIndex != writerIndex) {
196 setBytes(0, this, readerIndex, writerIndex - readerIndex);
197 writerIndex -= readerIndex;
198 adjustMarkers(readerIndex);
199 readerIndex = 0;
200 } else {
201 adjustMarkers(readerIndex);
202 writerIndex = readerIndex = 0;
203 }
204 return this;
205 }
206
207 @Override
208 public ByteBuf discardSomeReadBytes() {
209 ensureAccessible();
210 if (readerIndex == 0) {
211 return this;
212 }
213
214 if (readerIndex == writerIndex) {
215 adjustMarkers(readerIndex);
216 writerIndex = readerIndex = 0;
217 return this;
218 }
219
220 if (readerIndex >= capacity() >>> 1) {
221 setBytes(0, this, readerIndex, writerIndex - readerIndex);
222 writerIndex -= readerIndex;
223 adjustMarkers(readerIndex);
224 readerIndex = 0;
225 }
226 return this;
227 }
228
229 protected final void adjustMarkers(int decrement) {
230 int markedReaderIndex = this.markedReaderIndex;
231 if (markedReaderIndex <= decrement) {
232 this.markedReaderIndex = 0;
233 int markedWriterIndex = this.markedWriterIndex;
234 if (markedWriterIndex <= decrement) {
235 this.markedWriterIndex = 0;
236 } else {
237 this.markedWriterIndex = markedWriterIndex - decrement;
238 }
239 } else {
240 this.markedReaderIndex = markedReaderIndex - decrement;
241 markedWriterIndex -= decrement;
242 }
243 }
244
245 @Override
246 public ByteBuf ensureWritable(int minWritableBytes) {
247 if (minWritableBytes < 0) {
248 throw new IllegalArgumentException(String.format(
249 "minWritableBytes: %d (expected: >= 0)", minWritableBytes));
250 }
251 ensureWritable0(minWritableBytes);
252 return this;
253 }
254
255 final void ensureWritable0(int minWritableBytes) {
256 ensureAccessible();
257 if (minWritableBytes <= writableBytes()) {
258 return;
259 }
260
261 if (minWritableBytes > maxCapacity - writerIndex) {
262 throw new IndexOutOfBoundsException(String.format(
263 "writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s",
264 writerIndex, minWritableBytes, maxCapacity, this));
265 }
266
267
268 int newCapacity = calculateNewCapacity(writerIndex + minWritableBytes);
269
270
271 capacity(newCapacity);
272 }
273
274 @Override
275 public int ensureWritable(int minWritableBytes, boolean force) {
276 ensureAccessible();
277 if (minWritableBytes < 0) {
278 throw new IllegalArgumentException(String.format(
279 "minWritableBytes: %d (expected: >= 0)", minWritableBytes));
280 }
281
282 if (minWritableBytes <= writableBytes()) {
283 return 0;
284 }
285
286 final int maxCapacity = maxCapacity();
287 final int writerIndex = writerIndex();
288 if (minWritableBytes > maxCapacity - writerIndex) {
289 if (!force || capacity() == maxCapacity) {
290 return 1;
291 }
292
293 capacity(maxCapacity);
294 return 3;
295 }
296
297
298 int newCapacity = calculateNewCapacity(writerIndex + minWritableBytes);
299
300
301 capacity(newCapacity);
302 return 2;
303 }
304
305 private int calculateNewCapacity(int minNewCapacity) {
306 final int maxCapacity = this.maxCapacity;
307 final int threshold = 1048576 * 4;
308
309 if (minNewCapacity == threshold) {
310 return threshold;
311 }
312
313
314 if (minNewCapacity > threshold) {
315 int newCapacity = minNewCapacity / threshold * threshold;
316 if (newCapacity > maxCapacity - threshold) {
317 newCapacity = maxCapacity;
318 } else {
319 newCapacity += threshold;
320 }
321 return newCapacity;
322 }
323
324
325 int newCapacity = 64;
326 while (newCapacity < minNewCapacity) {
327 newCapacity <<= 1;
328 }
329
330 return Math.min(newCapacity, maxCapacity);
331 }
332
333 @Override
334 public ByteBuf order(ByteOrder endianness) {
335 if (endianness == null) {
336 throw new NullPointerException("endianness");
337 }
338 if (endianness == order()) {
339 return this;
340 }
341
342 SwappedByteBuf swappedBuf = this.swappedBuf;
343 if (swappedBuf == null) {
344 this.swappedBuf = swappedBuf = newSwappedByteBuf();
345 }
346 return swappedBuf;
347 }
348
349
350
351
352 protected SwappedByteBuf newSwappedByteBuf() {
353 return new SwappedByteBuf(this);
354 }
355
356 @Override
357 public byte getByte(int index) {
358 checkIndex(index);
359 return _getByte(index);
360 }
361
362 protected abstract byte _getByte(int index);
363
364 @Override
365 public boolean getBoolean(int index) {
366 return getByte(index) != 0;
367 }
368
369 @Override
370 public short getUnsignedByte(int index) {
371 return (short) (getByte(index) & 0xFF);
372 }
373
374 @Override
375 public short getShort(int index) {
376 checkIndex(index, 2);
377 return _getShort(index);
378 }
379
380 protected abstract short _getShort(int index);
381
382 @Override
383 public int getUnsignedShort(int index) {
384 return getShort(index) & 0xFFFF;
385 }
386
387 @Override
388 public int getUnsignedMedium(int index) {
389 checkIndex(index, 3);
390 return _getUnsignedMedium(index);
391 }
392
393 protected abstract int _getUnsignedMedium(int index);
394
395 @Override
396 public int getMedium(int index) {
397 int value = getUnsignedMedium(index);
398 if ((value & 0x800000) != 0) {
399 value |= 0xff000000;
400 }
401 return value;
402 }
403
404 @Override
405 public int getInt(int index) {
406 checkIndex(index, 4);
407 return _getInt(index);
408 }
409
410 protected abstract int _getInt(int index);
411
412 @Override
413 public long getUnsignedInt(int index) {
414 return getInt(index) & 0xFFFFFFFFL;
415 }
416
417 @Override
418 public long getLong(int index) {
419 checkIndex(index, 8);
420 return _getLong(index);
421 }
422
423 protected abstract long _getLong(int index);
424
425 @Override
426 public char getChar(int index) {
427 return (char) getShort(index);
428 }
429
430 @Override
431 public float getFloat(int index) {
432 return Float.intBitsToFloat(getInt(index));
433 }
434
435 @Override
436 public double getDouble(int index) {
437 return Double.longBitsToDouble(getLong(index));
438 }
439
440 @Override
441 public ByteBuf getBytes(int index, byte[] dst) {
442 getBytes(index, dst, 0, dst.length);
443 return this;
444 }
445
446 @Override
447 public ByteBuf getBytes(int index, ByteBuf dst) {
448 getBytes(index, dst, dst.writableBytes());
449 return this;
450 }
451
452 @Override
453 public ByteBuf getBytes(int index, ByteBuf dst, int length) {
454 getBytes(index, dst, dst.writerIndex(), length);
455 dst.writerIndex(dst.writerIndex() + length);
456 return this;
457 }
458
459 @Override
460 public ByteBuf setByte(int index, int value) {
461 checkIndex(index);
462 _setByte(index, value);
463 return this;
464 }
465
466 protected abstract void _setByte(int index, int value);
467
468 @Override
469 public ByteBuf setBoolean(int index, boolean value) {
470 setByte(index, value? 1 : 0);
471 return this;
472 }
473
474 @Override
475 public ByteBuf setShort(int index, int value) {
476 checkIndex(index, 2);
477 _setShort(index, value);
478 return this;
479 }
480
481 protected abstract void _setShort(int index, int value);
482
483 @Override
484 public ByteBuf setChar(int index, int value) {
485 setShort(index, value);
486 return this;
487 }
488
489 @Override
490 public ByteBuf setMedium(int index, int value) {
491 checkIndex(index, 3);
492 _setMedium(index, value);
493 return this;
494 }
495
496 protected abstract void _setMedium(int index, int value);
497
498 @Override
499 public ByteBuf setInt(int index, int value) {
500 checkIndex(index, 4);
501 _setInt(index, value);
502 return this;
503 }
504
505 protected abstract void _setInt(int index, int value);
506
507 @Override
508 public ByteBuf setFloat(int index, float value) {
509 setInt(index, Float.floatToRawIntBits(value));
510 return this;
511 }
512
513 @Override
514 public ByteBuf setLong(int index, long value) {
515 checkIndex(index, 8);
516 _setLong(index, value);
517 return this;
518 }
519
520 protected abstract void _setLong(int index, long value);
521
522 @Override
523 public ByteBuf setDouble(int index, double value) {
524 setLong(index, Double.doubleToRawLongBits(value));
525 return this;
526 }
527
528 @Override
529 public ByteBuf setBytes(int index, byte[] src) {
530 setBytes(index, src, 0, src.length);
531 return this;
532 }
533
534 @Override
535 public ByteBuf setBytes(int index, ByteBuf src) {
536 setBytes(index, src, src.readableBytes());
537 return this;
538 }
539
540 @Override
541 public ByteBuf setBytes(int index, ByteBuf src, int length) {
542 checkIndex(index, length);
543 if (src == null) {
544 throw new NullPointerException("src");
545 }
546 if (length > src.readableBytes()) {
547 throw new IndexOutOfBoundsException(String.format(
548 "length(%d) exceeds src.readableBytes(%d) where src is: %s", length, src.readableBytes(), src));
549 }
550
551 setBytes(index, src, src.readerIndex(), length);
552 src.readerIndex(src.readerIndex() + length);
553 return this;
554 }
555
556 @Override
557 public ByteBuf setZero(int index, int length) {
558 if (length == 0) {
559 return this;
560 }
561
562 checkIndex(index, length);
563
564 int nLong = length >>> 3;
565 int nBytes = length & 7;
566 for (int i = nLong; i > 0; i --) {
567 _setLong(index, 0);
568 index += 8;
569 }
570 if (nBytes == 4) {
571 _setInt(index, 0);
572
573 } else if (nBytes < 4) {
574 for (int i = nBytes; i > 0; i --) {
575 _setByte(index, (byte) 0);
576 index ++;
577 }
578 } else {
579 _setInt(index, 0);
580 index += 4;
581 for (int i = nBytes - 4; i > 0; i --) {
582 _setByte(index, (byte) 0);
583 index ++;
584 }
585 }
586 return this;
587 }
588
589 @Override
590 public byte readByte() {
591 checkReadableBytes0(1);
592 int i = readerIndex;
593 byte b = _getByte(i);
594 readerIndex = i + 1;
595 return b;
596 }
597
598 @Override
599 public boolean readBoolean() {
600 return readByte() != 0;
601 }
602
603 @Override
604 public short readUnsignedByte() {
605 return (short) (readByte() & 0xFF);
606 }
607
608 @Override
609 public short readShort() {
610 checkReadableBytes0(2);
611 short v = _getShort(readerIndex);
612 readerIndex += 2;
613 return v;
614 }
615
616 @Override
617 public int readUnsignedShort() {
618 return readShort() & 0xFFFF;
619 }
620
621 @Override
622 public int readMedium() {
623 int value = readUnsignedMedium();
624 if ((value & 0x800000) != 0) {
625 value |= 0xff000000;
626 }
627 return value;
628 }
629
630 @Override
631 public int readUnsignedMedium() {
632 checkReadableBytes0(3);
633 int v = _getUnsignedMedium(readerIndex);
634 readerIndex += 3;
635 return v;
636 }
637
638 @Override
639 public int readInt() {
640 checkReadableBytes0(4);
641 int v = _getInt(readerIndex);
642 readerIndex += 4;
643 return v;
644 }
645
646 @Override
647 public long readUnsignedInt() {
648 return readInt() & 0xFFFFFFFFL;
649 }
650
651 @Override
652 public long readLong() {
653 checkReadableBytes0(8);
654 long v = _getLong(readerIndex);
655 readerIndex += 8;
656 return v;
657 }
658
659 @Override
660 public char readChar() {
661 return (char) readShort();
662 }
663
664 @Override
665 public float readFloat() {
666 return Float.intBitsToFloat(readInt());
667 }
668
669 @Override
670 public double readDouble() {
671 return Double.longBitsToDouble(readLong());
672 }
673
674 @Override
675 public ByteBuf readBytes(int length) {
676 checkReadableBytes(length);
677 if (length == 0) {
678 return Unpooled.EMPTY_BUFFER;
679 }
680
681 ByteBuf buf = alloc().buffer(length, maxCapacity);
682 buf.writeBytes(this, readerIndex, length);
683 readerIndex += length;
684 return buf;
685 }
686
687 @Override
688 public ByteBuf readSlice(int length) {
689 checkReadableBytes(length);
690 ByteBuf slice = slice(readerIndex, length);
691 readerIndex += length;
692 return slice;
693 }
694
695 @Override
696 public ByteBuf readBytes(byte[] dst, int dstIndex, int length) {
697 checkReadableBytes(length);
698 getBytes(readerIndex, dst, dstIndex, length);
699 readerIndex += length;
700 return this;
701 }
702
703 @Override
704 public ByteBuf readBytes(byte[] dst) {
705 readBytes(dst, 0, dst.length);
706 return this;
707 }
708
709 @Override
710 public ByteBuf readBytes(ByteBuf dst) {
711 readBytes(dst, dst.writableBytes());
712 return this;
713 }
714
715 @Override
716 public ByteBuf readBytes(ByteBuf dst, int length) {
717 if (length > dst.writableBytes()) {
718 throw new IndexOutOfBoundsException(String.format(
719 "length(%d) exceeds dst.writableBytes(%d) where dst is: %s", length, dst.writableBytes(), dst));
720 }
721 readBytes(dst, dst.writerIndex(), length);
722 dst.writerIndex(dst.writerIndex() + length);
723 return this;
724 }
725
726 @Override
727 public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) {
728 checkReadableBytes(length);
729 getBytes(readerIndex, dst, dstIndex, length);
730 readerIndex += length;
731 return this;
732 }
733
734 @Override
735 public ByteBuf readBytes(ByteBuffer dst) {
736 int length = dst.remaining();
737 checkReadableBytes(length);
738 getBytes(readerIndex, dst);
739 readerIndex += length;
740 return this;
741 }
742
743 @Override
744 public int readBytes(GatheringByteChannel out, int length)
745 throws IOException {
746 checkReadableBytes(length);
747 int readBytes = getBytes(readerIndex, out, length);
748 readerIndex += readBytes;
749 return readBytes;
750 }
751
752 @Override
753 public ByteBuf readBytes(OutputStream out, int length) throws IOException {
754 checkReadableBytes(length);
755 getBytes(readerIndex, out, length);
756 readerIndex += length;
757 return this;
758 }
759
760 @Override
761 public ByteBuf skipBytes(int length) {
762 checkReadableBytes(length);
763 readerIndex += length;
764 return this;
765 }
766
767 @Override
768 public ByteBuf writeBoolean(boolean value) {
769 writeByte(value ? 1 : 0);
770 return this;
771 }
772
773 @Override
774 public ByteBuf writeByte(int value) {
775 ensureWritable0(1);
776 _setByte(writerIndex++, value);
777 return this;
778 }
779
780 @Override
781 public ByteBuf writeShort(int value) {
782 ensureWritable0(2);
783 _setShort(writerIndex, value);
784 writerIndex += 2;
785 return this;
786 }
787
788 @Override
789 public ByteBuf writeMedium(int value) {
790 ensureWritable0(3);
791 _setMedium(writerIndex, value);
792 writerIndex += 3;
793 return this;
794 }
795
796 @Override
797 public ByteBuf writeInt(int value) {
798 ensureWritable0(4);
799 _setInt(writerIndex, value);
800 writerIndex += 4;
801 return this;
802 }
803
804 @Override
805 public ByteBuf writeLong(long value) {
806 ensureWritable0(8);
807 _setLong(writerIndex, value);
808 writerIndex += 8;
809 return this;
810 }
811
812 @Override
813 public ByteBuf writeChar(int value) {
814 writeShort(value);
815 return this;
816 }
817
818 @Override
819 public ByteBuf writeFloat(float value) {
820 writeInt(Float.floatToRawIntBits(value));
821 return this;
822 }
823
824 @Override
825 public ByteBuf writeDouble(double value) {
826 writeLong(Double.doubleToRawLongBits(value));
827 return this;
828 }
829
830 @Override
831 public ByteBuf writeBytes(byte[] src, int srcIndex, int length) {
832 ensureWritable(length);
833 setBytes(writerIndex, src, srcIndex, length);
834 writerIndex += length;
835 return this;
836 }
837
838 @Override
839 public ByteBuf writeBytes(byte[] src) {
840 writeBytes(src, 0, src.length);
841 return this;
842 }
843
844 @Override
845 public ByteBuf writeBytes(ByteBuf src) {
846 writeBytes(src, src.readableBytes());
847 return this;
848 }
849
850 @Override
851 public ByteBuf writeBytes(ByteBuf src, int length) {
852 if (length > src.readableBytes()) {
853 throw new IndexOutOfBoundsException(String.format(
854 "length(%d) exceeds src.readableBytes(%d) where src is: %s", length, src.readableBytes(), src));
855 }
856 writeBytes(src, src.readerIndex(), length);
857 src.readerIndex(src.readerIndex() + length);
858 return this;
859 }
860
861 @Override
862 public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
863 ensureWritable(length);
864 setBytes(writerIndex, src, srcIndex, length);
865 writerIndex += length;
866 return this;
867 }
868
869 @Override
870 public ByteBuf writeBytes(ByteBuffer src) {
871 int length = src.remaining();
872 ensureWritable0(length);
873 setBytes(writerIndex, src);
874 writerIndex += length;
875 return this;
876 }
877
878 @Override
879 public int writeBytes(InputStream in, int length)
880 throws IOException {
881 ensureWritable(length);
882 int writtenBytes = setBytes(writerIndex, in, length);
883 if (writtenBytes > 0) {
884 writerIndex += writtenBytes;
885 }
886 return writtenBytes;
887 }
888
889 @Override
890 public int writeBytes(ScatteringByteChannel in, int length) throws IOException {
891 ensureWritable(length);
892 int writtenBytes = setBytes(writerIndex, in, length);
893 if (writtenBytes > 0) {
894 writerIndex += writtenBytes;
895 }
896 return writtenBytes;
897 }
898
899 @Override
900 public ByteBuf writeZero(int length) {
901 if (length == 0) {
902 return this;
903 }
904
905 ensureWritable(length);
906 int wIndex = writerIndex;
907 checkIndex0(wIndex, length);
908
909 int nLong = length >>> 3;
910 int nBytes = length & 7;
911 for (int i = nLong; i > 0; i --) {
912 _setLong(wIndex, 0);
913 wIndex += 8;
914 }
915 if (nBytes == 4) {
916 _setInt(wIndex, 0);
917 wIndex += 4;
918 } else if (nBytes < 4) {
919 for (int i = nBytes; i > 0; i --) {
920 _setByte(wIndex, (byte) 0);
921 wIndex++;
922 }
923 } else {
924 _setInt(wIndex, 0);
925 wIndex += 4;
926 for (int i = nBytes - 4; i > 0; i --) {
927 _setByte(wIndex, (byte) 0);
928 wIndex++;
929 }
930 }
931 writerIndex = wIndex;
932 return this;
933 }
934
935 @Override
936 public ByteBuf copy() {
937 return copy(readerIndex, readableBytes());
938 }
939
940 @Override
941 public ByteBuf duplicate() {
942 return new DuplicatedAbstractByteBuf(this);
943 }
944
945 @Override
946 public ByteBuf slice() {
947 return slice(readerIndex, readableBytes());
948 }
949
950 @Override
951 public ByteBuf slice(int index, int length) {
952 return new SlicedAbstractByteBuf(this, index, length);
953 }
954
955 @Override
956 public ByteBuffer nioBuffer() {
957 return nioBuffer(readerIndex, readableBytes());
958 }
959
960 @Override
961 public ByteBuffer[] nioBuffers() {
962 return nioBuffers(readerIndex, readableBytes());
963 }
964
965 @Override
966 public String toString(Charset charset) {
967 return toString(readerIndex, readableBytes(), charset);
968 }
969
970 @Override
971 public String toString(int index, int length, Charset charset) {
972 return ByteBufUtil.decodeString(this, index, length, charset);
973 }
974
975 @Override
976 public int indexOf(int fromIndex, int toIndex, byte value) {
977 return ByteBufUtil.indexOf(this, fromIndex, toIndex, value);
978 }
979
980 @Override
981 public int bytesBefore(byte value) {
982 return bytesBefore(readerIndex(), readableBytes(), value);
983 }
984
985 @Override
986 public int bytesBefore(int length, byte value) {
987 checkReadableBytes(length);
988 return bytesBefore(readerIndex(), length, value);
989 }
990
991 @Override
992 public int bytesBefore(int index, int length, byte value) {
993 int endIndex = indexOf(index, index + length, value);
994 if (endIndex < 0) {
995 return -1;
996 }
997 return endIndex - index;
998 }
999
1000 @Override
1001 public int forEachByte(ByteBufProcessor processor) {
1002 ensureAccessible();
1003 try {
1004 return forEachByteAsc0(readerIndex, writerIndex, processor);
1005 } catch (Exception e) {
1006 PlatformDependent.throwException(e);
1007 return -1;
1008 }
1009 }
1010
1011 @Override
1012 public int forEachByte(int index, int length, ByteBufProcessor processor) {
1013 checkIndex(index, length);
1014 try {
1015 return forEachByteAsc0(index, index + length, processor);
1016 } catch (Exception e) {
1017 PlatformDependent.throwException(e);
1018 return -1;
1019 }
1020 }
1021
1022 private int forEachByteAsc0(int start, int end, ByteBufProcessor processor) throws Exception {
1023 for (; start < end; ++start) {
1024 if (!processor.process(_getByte(start))) {
1025 return start;
1026 }
1027 }
1028
1029 return -1;
1030 }
1031
1032 @Override
1033 public int forEachByteDesc(ByteBufProcessor processor) {
1034 ensureAccessible();
1035 try {
1036 return forEachByteDesc0(writerIndex - 1, readerIndex, processor);
1037 } catch (Exception e) {
1038 PlatformDependent.throwException(e);
1039 return -1;
1040 }
1041 }
1042
1043 @Override
1044 public int forEachByteDesc(int index, int length, ByteBufProcessor processor) {
1045 checkIndex(index, length);
1046 try {
1047 return forEachByteDesc0(index + length - 1, index, processor);
1048 } catch (Exception e) {
1049 PlatformDependent.throwException(e);
1050 return -1;
1051 }
1052 }
1053
1054 private int forEachByteDesc0(int rStart, final int rEnd, ByteBufProcessor processor) throws Exception {
1055 for (; rStart >= rEnd; --rStart) {
1056 if (!processor.process(_getByte(rStart))) {
1057 return rStart;
1058 }
1059 }
1060 return -1;
1061 }
1062
1063 @Override
1064 public int hashCode() {
1065 return ByteBufUtil.hashCode(this);
1066 }
1067
1068 @Override
1069 public boolean equals(Object o) {
1070 if (this == o) {
1071 return true;
1072 }
1073 if (o instanceof ByteBuf) {
1074 return ByteBufUtil.equals(this, (ByteBuf) o);
1075 }
1076 return false;
1077 }
1078
1079 @Override
1080 public int compareTo(ByteBuf that) {
1081 return ByteBufUtil.compare(this, that);
1082 }
1083
1084 @Override
1085 public String toString() {
1086 if (refCnt() == 0) {
1087 return StringUtil.simpleClassName(this) + "(freed)";
1088 }
1089
1090 StringBuilder buf = new StringBuilder()
1091 .append(StringUtil.simpleClassName(this))
1092 .append("(ridx: ").append(readerIndex)
1093 .append(", widx: ").append(writerIndex)
1094 .append(", cap: ").append(capacity());
1095 if (maxCapacity != Integer.MAX_VALUE) {
1096 buf.append('/').append(maxCapacity);
1097 }
1098
1099 ByteBuf unwrapped = unwrap();
1100 if (unwrapped != null) {
1101 buf.append(", unwrapped: ").append(unwrapped);
1102 }
1103 buf.append(')');
1104 return buf.toString();
1105 }
1106
1107 protected final void checkIndex(int index) {
1108 checkIndex(index, 1);
1109 }
1110
1111 protected final void checkIndex(int index, int fieldLength) {
1112 ensureAccessible();
1113 checkIndex0(index, fieldLength);
1114 }
1115
1116 final void checkIndex0(int index, int fieldLength) {
1117 if (isOutOfBounds(index, fieldLength, capacity())) {
1118 throw new IndexOutOfBoundsException(String.format(
1119 "index: %d, length: %d (expected: range(0, %d))", index, fieldLength, capacity()));
1120 }
1121 }
1122
1123 protected final void checkSrcIndex(int index, int length, int srcIndex, int srcCapacity) {
1124 checkIndex(index, length);
1125 if (isOutOfBounds(srcIndex, length, srcCapacity)) {
1126 throw new IndexOutOfBoundsException(String.format(
1127 "srcIndex: %d, length: %d (expected: range(0, %d))", srcIndex, length, srcCapacity));
1128 }
1129 }
1130
1131 protected final void checkDstIndex(int index, int length, int dstIndex, int dstCapacity) {
1132 checkIndex(index, length);
1133 if (isOutOfBounds(dstIndex, length, dstCapacity)) {
1134 throw new IndexOutOfBoundsException(String.format(
1135 "dstIndex: %d, length: %d (expected: range(0, %d))", dstIndex, length, dstCapacity));
1136 }
1137 }
1138
1139
1140
1141
1142
1143
1144 protected final void checkReadableBytes(int minimumReadableBytes) {
1145 if (minimumReadableBytes < 0) {
1146 throw new IllegalArgumentException("minimumReadableBytes: " + minimumReadableBytes + " (expected: >= 0)");
1147 }
1148 checkReadableBytes0(minimumReadableBytes);
1149 }
1150
1151 protected final void checkNewCapacity(int newCapacity) {
1152 ensureAccessible();
1153 if (newCapacity < 0 || newCapacity > maxCapacity()) {
1154 throw new IllegalArgumentException("newCapacity: " + newCapacity + " (expected: 0-" + maxCapacity() + ')');
1155 }
1156 }
1157
1158 private void checkReadableBytes0(int minimumReadableBytes) {
1159 ensureAccessible();
1160 if (readerIndex > writerIndex - minimumReadableBytes) {
1161 throw new IndexOutOfBoundsException(String.format(
1162 "readerIndex(%d) + length(%d) exceeds writerIndex(%d): %s",
1163 readerIndex, minimumReadableBytes, writerIndex, this));
1164 }
1165 }
1166
1167
1168
1169
1170
1171 protected final void ensureAccessible() {
1172 if (checkAccessible && refCnt() == 0) {
1173 throw new IllegalReferenceCountException(0);
1174 }
1175 }
1176
1177 final void setIndex0(int readerIndex, int writerIndex) {
1178 this.readerIndex = readerIndex;
1179 this.writerIndex = writerIndex;
1180 }
1181
1182 final void discardMarks() {
1183 markedReaderIndex = markedWriterIndex = 0;
1184 }
1185 }