View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.buffer;
17  
18  import io.netty.util.AsciiString;
19  import io.netty.util.ByteProcessor;
20  import io.netty.util.CharsetUtil;
21  import io.netty.util.IllegalReferenceCountException;
22  import io.netty.util.ResourceLeakDetector;
23  import io.netty.util.ResourceLeakDetectorFactory;
24  import io.netty.util.internal.ObjectUtil;
25  import io.netty.util.internal.PlatformDependent;
26  import io.netty.util.internal.StringUtil;
27  import io.netty.util.internal.SystemPropertyUtil;
28  import io.netty.util.internal.logging.InternalLogger;
29  import io.netty.util.internal.logging.InternalLoggerFactory;
30  
31  import java.io.IOException;
32  import java.io.InputStream;
33  import java.io.OutputStream;
34  import java.nio.ByteBuffer;
35  import java.nio.ByteOrder;
36  import java.nio.channels.FileChannel;
37  import java.nio.channels.GatheringByteChannel;
38  import java.nio.channels.ScatteringByteChannel;
39  import java.nio.charset.Charset;
40  
41  import static io.netty.util.internal.MathUtil.isOutOfBounds;
42  import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero;
43  
44  /**
45   * A skeletal implementation of a buffer.
46   */
47  public abstract class AbstractByteBuf extends ByteBuf {
48      private static final InternalLogger logger = InternalLoggerFactory.getInstance(AbstractByteBuf.class);
49      private static final String LEGACY_PROP_CHECK_ACCESSIBLE = "io.netty.buffer.bytebuf.checkAccessible";
50      private static final String PROP_CHECK_ACCESSIBLE = "io.netty.buffer.checkAccessible";
51      static final boolean checkAccessible; // accessed from CompositeByteBuf
52      private static final String PROP_CHECK_BOUNDS = "io.netty.buffer.checkBounds";
53      private static final boolean checkBounds;
54  
55      static {
56          if (SystemPropertyUtil.contains(PROP_CHECK_ACCESSIBLE)) {
57              checkAccessible = SystemPropertyUtil.getBoolean(PROP_CHECK_ACCESSIBLE, true);
58          } else {
59              checkAccessible = SystemPropertyUtil.getBoolean(LEGACY_PROP_CHECK_ACCESSIBLE, true);
60          }
61          checkBounds = SystemPropertyUtil.getBoolean(PROP_CHECK_BOUNDS, true);
62          if (logger.isDebugEnabled()) {
63              logger.debug("-D{}: {}", PROP_CHECK_ACCESSIBLE, checkAccessible);
64              logger.debug("-D{}: {}", PROP_CHECK_BOUNDS, checkBounds);
65          }
66      }
67  
68      static final ResourceLeakDetector<ByteBuf> leakDetector =
69              ResourceLeakDetectorFactory.instance().newResourceLeakDetector(ByteBuf.class);
70  
71      int readerIndex;
72      int writerIndex;
73      private int markedReaderIndex;
74      private int markedWriterIndex;
75      private int maxCapacity;
76  
77      protected AbstractByteBuf(int maxCapacity) {
78          checkPositiveOrZero(maxCapacity, "maxCapacity");
79          this.maxCapacity = maxCapacity;
80      }
81  
82      @Override
83      public boolean isReadOnly() {
84          return false;
85      }
86  
87      @SuppressWarnings("deprecation")
88      @Override
89      public ByteBuf asReadOnly() {
90          if (isReadOnly()) {
91              return this;
92          }
93          return Unpooled.unmodifiableBuffer(this);
94      }
95  
96      @Override
97      public int maxCapacity() {
98          return maxCapacity;
99      }
100 
101     protected final void maxCapacity(int maxCapacity) {
102         this.maxCapacity = maxCapacity;
103     }
104 
105     @Override
106     public int readerIndex() {
107         return readerIndex;
108     }
109 
110     private static void checkIndexBounds(final int readerIndex, final int writerIndex, final int capacity) {
111         if (readerIndex < 0 || readerIndex > writerIndex || writerIndex > capacity) {
112             throw new IndexOutOfBoundsException(String.format(
113                     "readerIndex: %d, writerIndex: %d (expected: 0 <= readerIndex <= writerIndex <= capacity(%d))",
114                     readerIndex, writerIndex, capacity));
115         }
116     }
117 
118     @Override
119     public ByteBuf readerIndex(int readerIndex) {
120         if (checkBounds) {
121             checkIndexBounds(readerIndex, writerIndex, capacity());
122         }
123         this.readerIndex = readerIndex;
124         return this;
125     }
126 
127     @Override
128     public int writerIndex() {
129         return writerIndex;
130     }
131 
132     @Override
133     public ByteBuf writerIndex(int writerIndex) {
134         if (checkBounds) {
135             checkIndexBounds(readerIndex, writerIndex, capacity());
136         }
137         this.writerIndex = writerIndex;
138         return this;
139     }
140 
141     @Override
142     public ByteBuf setIndex(int readerIndex, int writerIndex) {
143         if (checkBounds) {
144             checkIndexBounds(readerIndex, writerIndex, capacity());
145         }
146         setIndex0(readerIndex, writerIndex);
147         return this;
148     }
149 
150     @Override
151     public ByteBuf clear() {
152         readerIndex = writerIndex = 0;
153         return this;
154     }
155 
156     @Override
157     public boolean isReadable() {
158         return writerIndex > readerIndex;
159     }
160 
161     @Override
162     public boolean isReadable(int numBytes) {
163         return writerIndex - readerIndex >= numBytes;
164     }
165 
166     @Override
167     public boolean isWritable() {
168         return capacity() > writerIndex;
169     }
170 
171     @Override
172     public boolean isWritable(int numBytes) {
173         return capacity() - writerIndex >= numBytes;
174     }
175 
176     @Override
177     public int readableBytes() {
178         return writerIndex - readerIndex;
179     }
180 
181     @Override
182     public int writableBytes() {
183         return capacity() - writerIndex;
184     }
185 
186     @Override
187     public int maxWritableBytes() {
188         return maxCapacity() - writerIndex;
189     }
190 
191     @Override
192     public ByteBuf markReaderIndex() {
193         markedReaderIndex = readerIndex;
194         return this;
195     }
196 
197     @Override
198     public ByteBuf resetReaderIndex() {
199         readerIndex(markedReaderIndex);
200         return this;
201     }
202 
203     @Override
204     public ByteBuf markWriterIndex() {
205         markedWriterIndex = writerIndex;
206         return this;
207     }
208 
209     @Override
210     public ByteBuf resetWriterIndex() {
211         writerIndex(markedWriterIndex);
212         return this;
213     }
214 
215     @Override
216     public ByteBuf discardReadBytes() {
217         if (readerIndex == 0) {
218             ensureAccessible();
219             return this;
220         }
221 
222         if (readerIndex != writerIndex) {
223             setBytes(0, this, readerIndex, writerIndex - readerIndex);
224             writerIndex -= readerIndex;
225             adjustMarkers(readerIndex);
226             readerIndex = 0;
227         } else {
228             ensureAccessible();
229             adjustMarkers(readerIndex);
230             writerIndex = readerIndex = 0;
231         }
232         return this;
233     }
234 
235     @Override
236     public ByteBuf discardSomeReadBytes() {
237         if (readerIndex > 0) {
238             if (readerIndex == writerIndex) {
239                 ensureAccessible();
240                 adjustMarkers(readerIndex);
241                 writerIndex = readerIndex = 0;
242                 return this;
243             }
244 
245             if (readerIndex >= capacity() >>> 1) {
246                 setBytes(0, this, readerIndex, writerIndex - readerIndex);
247                 writerIndex -= readerIndex;
248                 adjustMarkers(readerIndex);
249                 readerIndex = 0;
250                 return this;
251             }
252         }
253         ensureAccessible();
254         return this;
255     }
256 
257     protected final void adjustMarkers(int decrement) {
258         if (markedReaderIndex <= decrement) {
259             markedReaderIndex = 0;
260             if (markedWriterIndex <= decrement) {
261                 markedWriterIndex = 0;
262             } else {
263                 markedWriterIndex -= decrement;
264             }
265         } else {
266             markedReaderIndex -= decrement;
267             markedWriterIndex -= decrement;
268         }
269     }
270 
271     // Called after a capacity reduction
272     protected final void trimIndicesToCapacity(int newCapacity) {
273         if (writerIndex() > newCapacity) {
274             setIndex0(Math.min(readerIndex(), newCapacity), newCapacity);
275         }
276     }
277 
278     @Override
279     public ByteBuf ensureWritable(int minWritableBytes) {
280         ensureWritable0(checkPositiveOrZero(minWritableBytes, "minWritableBytes"));
281         return this;
282     }
283 
284     final void ensureWritable0(int minWritableBytes) {
285         final int writerIndex = writerIndex();
286         final int targetCapacity = writerIndex + minWritableBytes;
287         // using non-short-circuit & to reduce branching - this is a hot path and targetCapacity should rarely overflow
288         if (targetCapacity >= 0 & targetCapacity <= capacity()) {
289             ensureAccessible();
290             return;
291         }
292         if (checkBounds && (targetCapacity < 0 || targetCapacity > maxCapacity)) {
293             ensureAccessible();
294             throw new IndexOutOfBoundsException(String.format(
295                     "writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s",
296                     writerIndex, minWritableBytes, maxCapacity, this));
297         }
298 
299         // Normalize the target capacity to the power of 2.
300         final int fastWritable = maxFastWritableBytes();
301         int newCapacity = fastWritable >= minWritableBytes ? writerIndex + fastWritable
302                 : alloc().calculateNewCapacity(targetCapacity, maxCapacity);
303 
304         // Adjust to the new capacity.
305         capacity(newCapacity);
306     }
307 
308     @Override
309     public int ensureWritable(int minWritableBytes, boolean force) {
310         ensureAccessible();
311         checkPositiveOrZero(minWritableBytes, "minWritableBytes");
312 
313         if (minWritableBytes <= writableBytes()) {
314             return 0;
315         }
316 
317         final int maxCapacity = maxCapacity();
318         final int writerIndex = writerIndex();
319         if (minWritableBytes > maxCapacity - writerIndex) {
320             if (!force || capacity() == maxCapacity) {
321                 return 1;
322             }
323 
324             capacity(maxCapacity);
325             return 3;
326         }
327 
328         int fastWritable = maxFastWritableBytes();
329         int newCapacity = fastWritable >= minWritableBytes ? writerIndex + fastWritable
330                 : alloc().calculateNewCapacity(writerIndex + minWritableBytes, maxCapacity);
331 
332         // Adjust to the new capacity.
333         capacity(newCapacity);
334         return 2;
335     }
336 
337     @Override
338     public ByteBuf order(ByteOrder endianness) {
339         if (endianness == order()) {
340             return this;
341         }
342         ObjectUtil.checkNotNull(endianness, "endianness");
343         return newSwappedByteBuf();
344     }
345 
346     /**
347      * Creates a new {@link SwappedByteBuf} for this {@link ByteBuf} instance.
348      */
349     protected SwappedByteBuf newSwappedByteBuf() {
350         return new SwappedByteBuf(this);
351     }
352 
353     @Override
354     public byte getByte(int index) {
355         checkIndex(index);
356         return _getByte(index);
357     }
358 
359     protected abstract byte _getByte(int index);
360 
361     @Override
362     public boolean getBoolean(int index) {
363         return getByte(index) != 0;
364     }
365 
366     @Override
367     public short getUnsignedByte(int index) {
368         return (short) (getByte(index) & 0xFF);
369     }
370 
371     @Override
372     public short getShort(int index) {
373         checkIndex(index, 2);
374         return _getShort(index);
375     }
376 
377     protected abstract short _getShort(int index);
378 
379     @Override
380     public short getShortLE(int index) {
381         checkIndex(index, 2);
382         return _getShortLE(index);
383     }
384 
385     protected abstract short _getShortLE(int index);
386 
387     @Override
388     public int getUnsignedShort(int index) {
389         return getShort(index) & 0xFFFF;
390     }
391 
392     @Override
393     public int getUnsignedShortLE(int index) {
394         return getShortLE(index) & 0xFFFF;
395     }
396 
397     @Override
398     public int getUnsignedMedium(int index) {
399         checkIndex(index, 3);
400         return _getUnsignedMedium(index);
401     }
402 
403     protected abstract int _getUnsignedMedium(int index);
404 
405     @Override
406     public int getUnsignedMediumLE(int index) {
407         checkIndex(index, 3);
408         return _getUnsignedMediumLE(index);
409     }
410 
411     protected abstract int _getUnsignedMediumLE(int index);
412 
413     @Override
414     public int getMedium(int index) {
415         int value = getUnsignedMedium(index);
416         if ((value & 0x800000) != 0) {
417             value |= 0xff000000;
418         }
419         return value;
420     }
421 
422     @Override
423     public int getMediumLE(int index) {
424         int value = getUnsignedMediumLE(index);
425         if ((value & 0x800000) != 0) {
426             value |= 0xff000000;
427         }
428         return value;
429     }
430 
431     @Override
432     public int getInt(int index) {
433         checkIndex(index, 4);
434         return _getInt(index);
435     }
436 
437     protected abstract int _getInt(int index);
438 
439     @Override
440     public int getIntLE(int index) {
441         checkIndex(index, 4);
442         return _getIntLE(index);
443     }
444 
445     protected abstract int _getIntLE(int index);
446 
447     @Override
448     public long getUnsignedInt(int index) {
449         return getInt(index) & 0xFFFFFFFFL;
450     }
451 
452     @Override
453     public long getUnsignedIntLE(int index) {
454         return getIntLE(index) & 0xFFFFFFFFL;
455     }
456 
457     @Override
458     public long getLong(int index) {
459         checkIndex(index, 8);
460         return _getLong(index);
461     }
462 
463     protected abstract long _getLong(int index);
464 
465     @Override
466     public long getLongLE(int index) {
467         checkIndex(index, 8);
468         return _getLongLE(index);
469     }
470 
471     protected abstract long _getLongLE(int index);
472 
473     @Override
474     public char getChar(int index) {
475         return (char) getShort(index);
476     }
477 
478     @Override
479     public float getFloat(int index) {
480         return Float.intBitsToFloat(getInt(index));
481     }
482 
483     @Override
484     public double getDouble(int index) {
485         return Double.longBitsToDouble(getLong(index));
486     }
487 
488     @Override
489     public ByteBuf getBytes(int index, byte[] dst) {
490         getBytes(index, dst, 0, dst.length);
491         return this;
492     }
493 
494     @Override
495     public ByteBuf getBytes(int index, ByteBuf dst) {
496         getBytes(index, dst, dst.writableBytes());
497         return this;
498     }
499 
500     @Override
501     public ByteBuf getBytes(int index, ByteBuf dst, int length) {
502         getBytes(index, dst, dst.writerIndex(), length);
503         dst.writerIndex(dst.writerIndex() + length);
504         return this;
505     }
506 
507     @Override
508     public CharSequence getCharSequence(int index, int length, Charset charset) {
509         if (CharsetUtil.US_ASCII.equals(charset) || CharsetUtil.ISO_8859_1.equals(charset)) {
510             // ByteBufUtil.getBytes(...) will return a new copy which the AsciiString uses directly
511             return new AsciiString(ByteBufUtil.getBytes(this, index, length, true), false);
512         }
513         return toString(index, length, charset);
514     }
515 
516     @Override
517     public CharSequence readCharSequence(int length, Charset charset) {
518         checkReadableBytes(length);
519         CharSequence sequence = getCharSequence(readerIndex, length, charset);
520         readerIndex += length;
521         return sequence;
522     }
523 
524     @Override
525     public String readString(int length, Charset charset) {
526         checkReadableBytes(length);
527         String string = toString(readerIndex, length, charset);
528         readerIndex += length;
529         return string;
530     }
531 
532     @Override
533     public ByteBuf setByte(int index, int value) {
534         checkIndex(index);
535         _setByte(index, value);
536         return this;
537     }
538 
539     protected abstract void _setByte(int index, int value);
540 
541     @Override
542     public ByteBuf setBoolean(int index, boolean value) {
543         setByte(index, value? 1 : 0);
544         return this;
545     }
546 
547     @Override
548     public ByteBuf setShort(int index, int value) {
549         checkIndex(index, 2);
550         _setShort(index, value);
551         return this;
552     }
553 
554     protected abstract void _setShort(int index, int value);
555 
556     @Override
557     public ByteBuf setShortLE(int index, int value) {
558         checkIndex(index, 2);
559         _setShortLE(index, value);
560         return this;
561     }
562 
563     protected abstract void _setShortLE(int index, int value);
564 
565     @Override
566     public ByteBuf setChar(int index, int value) {
567         setShort(index, value);
568         return this;
569     }
570 
571     @Override
572     public ByteBuf setMedium(int index, int value) {
573         checkIndex(index, 3);
574         _setMedium(index, value);
575         return this;
576     }
577 
578     protected abstract void _setMedium(int index, int value);
579 
580     @Override
581     public ByteBuf setMediumLE(int index, int value) {
582         checkIndex(index, 3);
583         _setMediumLE(index, value);
584         return this;
585     }
586 
587     protected abstract void _setMediumLE(int index, int value);
588 
589     @Override
590     public ByteBuf setInt(int index, int value) {
591         checkIndex(index, 4);
592         _setInt(index, value);
593         return this;
594     }
595 
596     protected abstract void _setInt(int index, int value);
597 
598     @Override
599     public ByteBuf setIntLE(int index, int value) {
600         checkIndex(index, 4);
601         _setIntLE(index, value);
602         return this;
603     }
604 
605     protected abstract void _setIntLE(int index, int value);
606 
607     @Override
608     public ByteBuf setFloat(int index, float value) {
609         setInt(index, Float.floatToRawIntBits(value));
610         return this;
611     }
612 
613     @Override
614     public ByteBuf setLong(int index, long value) {
615         checkIndex(index, 8);
616         _setLong(index, value);
617         return this;
618     }
619 
620     protected abstract void _setLong(int index, long value);
621 
622     @Override
623     public ByteBuf setLongLE(int index, long value) {
624         checkIndex(index, 8);
625         _setLongLE(index, value);
626         return this;
627     }
628 
629     protected abstract void _setLongLE(int index, long value);
630 
631     @Override
632     public ByteBuf setDouble(int index, double value) {
633         setLong(index, Double.doubleToRawLongBits(value));
634         return this;
635     }
636 
637     @Override
638     public ByteBuf setBytes(int index, byte[] src) {
639         setBytes(index, src, 0, src.length);
640         return this;
641     }
642 
643     @Override
644     public ByteBuf setBytes(int index, ByteBuf src) {
645         setBytes(index, src, src.readableBytes());
646         return this;
647     }
648 
649     private static void checkReadableBounds(final ByteBuf src, final int length) {
650         if (length > src.readableBytes()) {
651             throw new IndexOutOfBoundsException(String.format(
652                     "length(%d) exceeds src.readableBytes(%d) where src is: %s", length, src.readableBytes(), src));
653         }
654     }
655 
656     @Override
657     public ByteBuf setBytes(int index, ByteBuf src, int length) {
658         checkIndex(index, length);
659         ObjectUtil.checkNotNull(src, "src");
660         if (checkBounds) {
661             checkReadableBounds(src, length);
662         }
663 
664         setBytes(index, src, src.readerIndex(), length);
665         src.readerIndex(src.readerIndex() + length);
666         return this;
667     }
668 
669     @Override
670     public ByteBuf setZero(int index, int length) {
671         if (length == 0) {
672             return this;
673         }
674 
675         checkIndex(index, length);
676 
677         int nLong = length >>> 3;
678         int nBytes = length & 7;
679         for (int i = nLong; i > 0; i --) {
680             _setLong(index, 0);
681             index += 8;
682         }
683         if (nBytes == 4) {
684             _setInt(index, 0);
685             // Not need to update the index as we not will use it after this.
686         } else if (nBytes < 4) {
687             for (int i = nBytes; i > 0; i --) {
688                 _setByte(index, 0);
689                 index ++;
690             }
691         } else {
692             _setInt(index, 0);
693             index += 4;
694             for (int i = nBytes - 4; i > 0; i --) {
695                 _setByte(index, 0);
696                 index ++;
697             }
698         }
699         return this;
700     }
701 
702     @Override
703     public int setCharSequence(int index, CharSequence sequence, Charset charset) {
704         return setCharSequence0(index, sequence, charset, false);
705     }
706 
707     private int setCharSequence0(int index, CharSequence sequence, Charset charset, boolean expand) {
708         if (charset.equals(CharsetUtil.UTF_8)) {
709             int length = ByteBufUtil.utf8MaxBytes(sequence);
710             if (expand) {
711                 ensureWritable0(length);
712                 checkIndex0(index, length);
713             } else {
714                 checkIndex(index, length);
715             }
716             return ByteBufUtil.writeUtf8(this, index, length, sequence, sequence.length());
717         }
718         if (charset.equals(CharsetUtil.US_ASCII) || charset.equals(CharsetUtil.ISO_8859_1)) {
719             int length = sequence.length();
720             if (expand) {
721                 ensureWritable0(length);
722                 checkIndex0(index, length);
723             } else {
724                 checkIndex(index, length);
725             }
726             return ByteBufUtil.writeAscii(this, index, sequence, length);
727         }
728         byte[] bytes = sequence.toString().getBytes(charset);
729         if (expand) {
730             ensureWritable0(bytes.length);
731             // setBytes(...) will take care of checking the indices.
732         }
733         setBytes(index, bytes);
734         return bytes.length;
735     }
736 
737     @Override
738     public byte readByte() {
739         checkReadableBytes0(1);
740         int i = readerIndex;
741         byte b = _getByte(i);
742         readerIndex = i + 1;
743         return b;
744     }
745 
746     @Override
747     public boolean readBoolean() {
748         return readByte() != 0;
749     }
750 
751     @Override
752     public short readUnsignedByte() {
753         return (short) (readByte() & 0xFF);
754     }
755 
756     @Override
757     public short readShort() {
758         checkReadableBytes0(2);
759         short v = _getShort(readerIndex);
760         readerIndex += 2;
761         return v;
762     }
763 
764     @Override
765     public short readShortLE() {
766         checkReadableBytes0(2);
767         short v = _getShortLE(readerIndex);
768         readerIndex += 2;
769         return v;
770     }
771 
772     @Override
773     public int readUnsignedShort() {
774         return readShort() & 0xFFFF;
775     }
776 
777     @Override
778     public int readUnsignedShortLE() {
779         return readShortLE() & 0xFFFF;
780     }
781 
782     @Override
783     public int readMedium() {
784         int value = readUnsignedMedium();
785         if ((value & 0x800000) != 0) {
786             value |= 0xff000000;
787         }
788         return value;
789     }
790 
791     @Override
792     public int readMediumLE() {
793         int value = readUnsignedMediumLE();
794         if ((value & 0x800000) != 0) {
795             value |= 0xff000000;
796         }
797         return value;
798     }
799 
800     @Override
801     public int readUnsignedMedium() {
802         checkReadableBytes0(3);
803         int v = _getUnsignedMedium(readerIndex);
804         readerIndex += 3;
805         return v;
806     }
807 
808     @Override
809     public int readUnsignedMediumLE() {
810         checkReadableBytes0(3);
811         int v = _getUnsignedMediumLE(readerIndex);
812         readerIndex += 3;
813         return v;
814     }
815 
816     @Override
817     public int readInt() {
818         checkReadableBytes0(4);
819         int v = _getInt(readerIndex);
820         readerIndex += 4;
821         return v;
822     }
823 
824     @Override
825     public int readIntLE() {
826         checkReadableBytes0(4);
827         int v = _getIntLE(readerIndex);
828         readerIndex += 4;
829         return v;
830     }
831 
832     @Override
833     public long readUnsignedInt() {
834         return readInt() & 0xFFFFFFFFL;
835     }
836 
837     @Override
838     public long readUnsignedIntLE() {
839         return readIntLE() & 0xFFFFFFFFL;
840     }
841 
842     @Override
843     public long readLong() {
844         checkReadableBytes0(8);
845         long v = _getLong(readerIndex);
846         readerIndex += 8;
847         return v;
848     }
849 
850     @Override
851     public long readLongLE() {
852         checkReadableBytes0(8);
853         long v = _getLongLE(readerIndex);
854         readerIndex += 8;
855         return v;
856     }
857 
858     @Override
859     public char readChar() {
860         return (char) readShort();
861     }
862 
863     @Override
864     public float readFloat() {
865         return Float.intBitsToFloat(readInt());
866     }
867 
868     @Override
869     public double readDouble() {
870         return Double.longBitsToDouble(readLong());
871     }
872 
873     @Override
874     public ByteBuf readBytes(int length) {
875         checkReadableBytes(length);
876         if (length == 0) {
877             return Unpooled.EMPTY_BUFFER;
878         }
879 
880         ByteBuf buf = alloc().buffer(length, maxCapacity);
881         buf.writeBytes(this, readerIndex, length);
882         readerIndex += length;
883         return buf;
884     }
885 
886     @Override
887     public ByteBuf readSlice(int length) {
888         checkReadableBytes(length);
889         ByteBuf slice = slice(readerIndex, length);
890         readerIndex += length;
891         return slice;
892     }
893 
894     @Override
895     public ByteBuf readRetainedSlice(int length) {
896         checkReadableBytes(length);
897         ByteBuf slice = retainedSlice(readerIndex, length);
898         readerIndex += length;
899         return slice;
900     }
901 
902     @Override
903     public ByteBuf readBytes(byte[] dst, int dstIndex, int length) {
904         checkReadableBytes(length);
905         getBytes(readerIndex, dst, dstIndex, length);
906         readerIndex += length;
907         return this;
908     }
909 
910     @Override
911     public ByteBuf readBytes(byte[] dst) {
912         readBytes(dst, 0, dst.length);
913         return this;
914     }
915 
916     @Override
917     public ByteBuf readBytes(ByteBuf dst) {
918         readBytes(dst, dst.writableBytes());
919         return this;
920     }
921 
922     @Override
923     public ByteBuf readBytes(ByteBuf dst, int length) {
924         if (checkBounds) {
925             if (length > dst.writableBytes()) {
926                 throw new IndexOutOfBoundsException(String.format(
927                         "length(%d) exceeds dst.writableBytes(%d) where dst is: %s", length, dst.writableBytes(), dst));
928             }
929         }
930         readBytes(dst, dst.writerIndex(), length);
931         dst.writerIndex(dst.writerIndex() + length);
932         return this;
933     }
934 
935     @Override
936     public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) {
937         checkReadableBytes(length);
938         getBytes(readerIndex, dst, dstIndex, length);
939         readerIndex += length;
940         return this;
941     }
942 
943     @Override
944     public ByteBuf readBytes(ByteBuffer dst) {
945         int length = dst.remaining();
946         checkReadableBytes(length);
947         getBytes(readerIndex, dst);
948         readerIndex += length;
949         return this;
950     }
951 
952     @Override
953     public int readBytes(GatheringByteChannel out, int length)
954             throws IOException {
955         checkReadableBytes(length);
956         int readBytes = getBytes(readerIndex, out, length);
957         readerIndex += readBytes;
958         return readBytes;
959     }
960 
961     @Override
962     public int readBytes(FileChannel out, long position, int length)
963             throws IOException {
964         checkReadableBytes(length);
965         int readBytes = getBytes(readerIndex, out, position, length);
966         readerIndex += readBytes;
967         return readBytes;
968     }
969 
970     @Override
971     public ByteBuf readBytes(OutputStream out, int length) throws IOException {
972         checkReadableBytes(length);
973         getBytes(readerIndex, out, length);
974         readerIndex += length;
975         return this;
976     }
977 
978     @Override
979     public ByteBuf skipBytes(int length) {
980         checkReadableBytes(length);
981         readerIndex += length;
982         return this;
983     }
984 
985     @Override
986     public ByteBuf writeBoolean(boolean value) {
987         writeByte(value ? 1 : 0);
988         return this;
989     }
990 
991     @Override
992     public ByteBuf writeByte(int value) {
993         ensureWritable0(1);
994         _setByte(writerIndex++, value);
995         return this;
996     }
997 
998     @Override
999     public ByteBuf writeShort(int value) {
1000         ensureWritable0(2);
1001         _setShort(writerIndex, value);
1002         writerIndex += 2;
1003         return this;
1004     }
1005 
1006     @Override
1007     public ByteBuf writeShortLE(int value) {
1008         ensureWritable0(2);
1009         _setShortLE(writerIndex, value);
1010         writerIndex += 2;
1011         return this;
1012     }
1013 
1014     @Override
1015     public ByteBuf writeMedium(int value) {
1016         ensureWritable0(3);
1017         _setMedium(writerIndex, value);
1018         writerIndex += 3;
1019         return this;
1020     }
1021 
1022     @Override
1023     public ByteBuf writeMediumLE(int value) {
1024         ensureWritable0(3);
1025         _setMediumLE(writerIndex, value);
1026         writerIndex += 3;
1027         return this;
1028     }
1029 
1030     @Override
1031     public ByteBuf writeInt(int value) {
1032         ensureWritable0(4);
1033         _setInt(writerIndex, value);
1034         writerIndex += 4;
1035         return this;
1036     }
1037 
1038     @Override
1039     public ByteBuf writeIntLE(int value) {
1040         ensureWritable0(4);
1041         _setIntLE(writerIndex, value);
1042         writerIndex += 4;
1043         return this;
1044     }
1045 
1046     @Override
1047     public ByteBuf writeLong(long value) {
1048         ensureWritable0(8);
1049         _setLong(writerIndex, value);
1050         writerIndex += 8;
1051         return this;
1052     }
1053 
1054     @Override
1055     public ByteBuf writeLongLE(long value) {
1056         ensureWritable0(8);
1057         _setLongLE(writerIndex, value);
1058         writerIndex += 8;
1059         return this;
1060     }
1061 
1062     @Override
1063     public ByteBuf writeChar(int value) {
1064         writeShort(value);
1065         return this;
1066     }
1067 
1068     @Override
1069     public ByteBuf writeFloat(float value) {
1070         writeInt(Float.floatToRawIntBits(value));
1071         return this;
1072     }
1073 
1074     @Override
1075     public ByteBuf writeDouble(double value) {
1076         writeLong(Double.doubleToRawLongBits(value));
1077         return this;
1078     }
1079 
1080     @Override
1081     public ByteBuf writeBytes(byte[] src, int srcIndex, int length) {
1082         ensureWritable(length);
1083         setBytes(writerIndex, src, srcIndex, length);
1084         writerIndex += length;
1085         return this;
1086     }
1087 
1088     @Override
1089     public ByteBuf writeBytes(byte[] src) {
1090         writeBytes(src, 0, src.length);
1091         return this;
1092     }
1093 
1094     @Override
1095     public ByteBuf writeBytes(ByteBuf src) {
1096         writeBytes(src, src.readableBytes());
1097         return this;
1098     }
1099 
1100     @Override
1101     public ByteBuf writeBytes(ByteBuf src, int length) {
1102         if (checkBounds) {
1103             checkReadableBounds(src, length);
1104         }
1105         writeBytes(src, src.readerIndex(), length);
1106         src.readerIndex(src.readerIndex() + length);
1107         return this;
1108     }
1109 
1110     @Override
1111     public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
1112         ensureWritable(length);
1113         setBytes(writerIndex, src, srcIndex, length);
1114         writerIndex += length;
1115         return this;
1116     }
1117 
1118     @Override
1119     public ByteBuf writeBytes(ByteBuffer src) {
1120         int length = src.remaining();
1121         ensureWritable0(length);
1122         setBytes(writerIndex, src);
1123         writerIndex += length;
1124         return this;
1125     }
1126 
1127     @Override
1128     public int writeBytes(InputStream in, int length)
1129             throws IOException {
1130         ensureWritable(length);
1131         int writtenBytes = setBytes(writerIndex, in, length);
1132         if (writtenBytes > 0) {
1133             writerIndex += writtenBytes;
1134         }
1135         return writtenBytes;
1136     }
1137 
1138     @Override
1139     public int writeBytes(ScatteringByteChannel in, int length) throws IOException {
1140         ensureWritable(length);
1141         int writtenBytes = setBytes(writerIndex, in, length);
1142         if (writtenBytes > 0) {
1143             writerIndex += writtenBytes;
1144         }
1145         return writtenBytes;
1146     }
1147 
1148     @Override
1149     public int writeBytes(FileChannel in, long position, int length) throws IOException {
1150         ensureWritable(length);
1151         int writtenBytes = setBytes(writerIndex, in, position, length);
1152         if (writtenBytes > 0) {
1153             writerIndex += writtenBytes;
1154         }
1155         return writtenBytes;
1156     }
1157 
1158     @Override
1159     public ByteBuf writeZero(int length) {
1160         if (length == 0) {
1161             return this;
1162         }
1163 
1164         ensureWritable(length);
1165         int wIndex = writerIndex;
1166         checkIndex0(wIndex, length);
1167 
1168         int nLong = length >>> 3;
1169         int nBytes = length & 7;
1170         for (int i = nLong; i > 0; i --) {
1171             _setLong(wIndex, 0);
1172             wIndex += 8;
1173         }
1174         if (nBytes == 4) {
1175             _setInt(wIndex, 0);
1176             wIndex += 4;
1177         } else if (nBytes < 4) {
1178             for (int i = nBytes; i > 0; i --) {
1179                 _setByte(wIndex, 0);
1180                 wIndex++;
1181             }
1182         } else {
1183             _setInt(wIndex, 0);
1184             wIndex += 4;
1185             for (int i = nBytes - 4; i > 0; i --) {
1186                 _setByte(wIndex, 0);
1187                 wIndex++;
1188             }
1189         }
1190         writerIndex = wIndex;
1191         return this;
1192     }
1193 
1194     @Override
1195     public int writeCharSequence(CharSequence sequence, Charset charset) {
1196         int written = setCharSequence0(writerIndex, sequence, charset, true);
1197         writerIndex += written;
1198         return written;
1199     }
1200 
1201     @Override
1202     public ByteBuf copy() {
1203         return copy(readerIndex, readableBytes());
1204     }
1205 
1206     @Override
1207     public ByteBuf duplicate() {
1208         ensureAccessible();
1209         return new UnpooledDuplicatedByteBuf(this);
1210     }
1211 
1212     @Override
1213     public ByteBuf retainedDuplicate() {
1214         return duplicate().retain();
1215     }
1216 
1217     @Override
1218     public ByteBuf slice() {
1219         return slice(readerIndex, readableBytes());
1220     }
1221 
1222     @Override
1223     public ByteBuf retainedSlice() {
1224         return slice().retain();
1225     }
1226 
1227     @Override
1228     public ByteBuf slice(int index, int length) {
1229         ensureAccessible();
1230         return new UnpooledSlicedByteBuf(this, index, length);
1231     }
1232 
1233     @Override
1234     public ByteBuf retainedSlice(int index, int length) {
1235         return slice(index, length).retain();
1236     }
1237 
1238     @Override
1239     public ByteBuffer nioBuffer() {
1240         return nioBuffer(readerIndex, readableBytes());
1241     }
1242 
1243     @Override
1244     public ByteBuffer[] nioBuffers() {
1245         return nioBuffers(readerIndex, readableBytes());
1246     }
1247 
1248     @Override
1249     public String toString(Charset charset) {
1250         return toString(readerIndex, readableBytes(), charset);
1251     }
1252 
1253     @Override
1254     public String toString(int index, int length, Charset charset) {
1255         checkIndex(index, length);
1256         return ByteBufUtil.decodeString(this, index, length, charset);
1257     }
1258 
1259     @Override
1260     public int indexOf(int fromIndex, int toIndex, byte value) {
1261         if (fromIndex <= toIndex) {
1262             return ByteBufUtil.firstIndexOf(this, fromIndex, toIndex, value);
1263         }
1264         return ByteBufUtil.lastIndexOf(this, fromIndex, toIndex, value);
1265     }
1266 
1267     @Override
1268     public int bytesBefore(byte value) {
1269         return bytesBefore(readerIndex(), readableBytes(), value);
1270     }
1271 
1272     @Override
1273     public int bytesBefore(int length, byte value) {
1274         checkReadableBytes(length);
1275         return bytesBefore(readerIndex(), length, value);
1276     }
1277 
1278     @Override
1279     public int bytesBefore(int index, int length, byte value) {
1280         int endIndex = indexOf(index, index + length, value);
1281         if (endIndex < 0) {
1282             return -1;
1283         }
1284         return endIndex - index;
1285     }
1286 
1287     @Override
1288     public int forEachByte(ByteProcessor processor) {
1289         ensureAccessible();
1290         try {
1291             return forEachByteAsc0(readerIndex, writerIndex, processor);
1292         } catch (Exception e) {
1293             PlatformDependent.throwException(e);
1294             return -1;
1295         }
1296     }
1297 
1298     @Override
1299     public int forEachByte(int index, int length, ByteProcessor processor) {
1300         checkIndex(index, length);
1301         try {
1302             return forEachByteAsc0(index, index + length, processor);
1303         } catch (Exception e) {
1304             PlatformDependent.throwException(e);
1305             return -1;
1306         }
1307     }
1308 
1309     int forEachByteAsc0(int start, int end, ByteProcessor processor) throws Exception {
1310         for (; start < end; ++start) {
1311             if (!processor.process(_getByte(start))) {
1312                 return start;
1313             }
1314         }
1315 
1316         return -1;
1317     }
1318 
1319     @Override
1320     public int forEachByteDesc(ByteProcessor processor) {
1321         ensureAccessible();
1322         try {
1323             return forEachByteDesc0(writerIndex - 1, readerIndex, processor);
1324         } catch (Exception e) {
1325             PlatformDependent.throwException(e);
1326             return -1;
1327         }
1328     }
1329 
1330     @Override
1331     public int forEachByteDesc(int index, int length, ByteProcessor processor) {
1332         checkIndex(index, length);
1333         try {
1334             return forEachByteDesc0(index + length - 1, index, processor);
1335         } catch (Exception e) {
1336             PlatformDependent.throwException(e);
1337             return -1;
1338         }
1339     }
1340 
1341     int forEachByteDesc0(int rStart, final int rEnd, ByteProcessor processor) throws Exception {
1342         for (; rStart >= rEnd; --rStart) {
1343             if (!processor.process(_getByte(rStart))) {
1344                 return rStart;
1345             }
1346         }
1347         return -1;
1348     }
1349 
1350     @Override
1351     public int hashCode() {
1352         return ByteBufUtil.hashCode(this);
1353     }
1354 
1355     @Override
1356     public boolean equals(Object o) {
1357         return o instanceof ByteBuf && ByteBufUtil.equals(this, (ByteBuf) o);
1358     }
1359 
1360     @Override
1361     public int compareTo(ByteBuf that) {
1362         return ByteBufUtil.compare(this, that);
1363     }
1364 
1365     @Override
1366     public String toString() {
1367         if (refCnt() == 0) {
1368             return StringUtil.simpleClassName(this) + "(freed)";
1369         }
1370 
1371         StringBuilder buf = new StringBuilder()
1372             .append(StringUtil.simpleClassName(this))
1373             .append("(ridx: ").append(readerIndex)
1374             .append(", widx: ").append(writerIndex)
1375             .append(", cap: ").append(capacity());
1376         if (maxCapacity != Integer.MAX_VALUE) {
1377             buf.append('/').append(maxCapacity);
1378         }
1379 
1380         ByteBuf unwrapped = unwrap();
1381         if (unwrapped != null) {
1382             buf.append(", unwrapped: ").append(unwrapped);
1383         }
1384         buf.append(')');
1385         return buf.toString();
1386     }
1387 
1388     protected final void checkIndex(int index) {
1389         checkIndex(index, 1);
1390     }
1391 
1392     protected final void checkIndex(int index, int fieldLength) {
1393         ensureAccessible();
1394         checkIndex0(index, fieldLength);
1395     }
1396 
1397     private static void checkRangeBoundsTrustedCapacity(final String indexName, final int index,
1398                                                  final int fieldLength, final int capacity) {
1399         if (isOutOfBoundsTrustedCapacity(index, fieldLength, capacity)) {
1400             rangeBoundsCheckFailed(indexName, index, fieldLength, capacity);
1401         }
1402     }
1403 
1404     /**
1405      * This is a simplified version of MathUtil.isOutOfBounds that does not check for capacity negative values.
1406      */
1407     private static boolean isOutOfBoundsTrustedCapacity(int index, int fieldLength, int capacity) {
1408         // keep these as branches since would make it easier to be constant-folded
1409         return index < 0 || fieldLength < 0 || index + fieldLength < 0 || index + fieldLength > capacity;
1410     }
1411 
1412     private static void checkRangeBounds(final String indexName, final int index,
1413             final int fieldLength, final int capacity) {
1414         if (isOutOfBounds(index, fieldLength, capacity)) {
1415             rangeBoundsCheckFailed(indexName, index, fieldLength, capacity);
1416         }
1417     }
1418 
1419     private static void rangeBoundsCheckFailed(String indexName, int index, int fieldLength, int capacity) {
1420         throw new IndexOutOfBoundsException(String.format(
1421                 "%s: %d, length: %d (expected: range(0, %d))", indexName, index, fieldLength, capacity));
1422     }
1423 
1424     final void checkIndex0(int index, int fieldLength) {
1425         if (checkBounds) {
1426             checkRangeBoundsTrustedCapacity("index", index, fieldLength, capacity());
1427         }
1428     }
1429 
1430     protected final void checkSrcIndex(int index, int length, int srcIndex, int srcCapacity) {
1431         checkIndex(index, length);
1432         if (checkBounds) {
1433             checkRangeBounds("srcIndex", srcIndex, length, srcCapacity);
1434         }
1435     }
1436 
1437     protected final void checkDstIndex(int index, int length, int dstIndex, int dstCapacity) {
1438         checkIndex(index, length);
1439         if (checkBounds) {
1440             checkRangeBounds("dstIndex", dstIndex, length, dstCapacity);
1441         }
1442     }
1443 
1444     protected final void checkDstIndex(int length, int dstIndex, int dstCapacity) {
1445         checkReadableBytes(length);
1446         if (checkBounds) {
1447             checkRangeBounds("dstIndex", dstIndex, length, dstCapacity);
1448         }
1449     }
1450 
1451     /**
1452      * Throws an {@link IndexOutOfBoundsException} if the current
1453      * {@linkplain #readableBytes() readable bytes} of this buffer is less
1454      * than the specified value.
1455      */
1456     protected final void checkReadableBytes(int minimumReadableBytes) {
1457         checkReadableBytes0(checkPositiveOrZero(minimumReadableBytes, "minimumReadableBytes"));
1458     }
1459 
1460     protected final void checkNewCapacity(int newCapacity) {
1461         ensureAccessible();
1462         if (checkBounds && (newCapacity < 0 || newCapacity > maxCapacity())) {
1463             throw new IllegalArgumentException("newCapacity: " + newCapacity +
1464                     " (expected: 0-" + maxCapacity() + ')');
1465         }
1466     }
1467 
1468     private void checkReadableBytes0(int minimumReadableBytes) {
1469         ensureAccessible();
1470         if (checkBounds && readerIndex > writerIndex - minimumReadableBytes) {
1471             throw new IndexOutOfBoundsException(String.format(
1472                     "readerIndex(%d) + length(%d) exceeds writerIndex(%d): %s",
1473                     readerIndex, minimumReadableBytes, writerIndex, this));
1474         }
1475     }
1476 
1477     /**
1478      * Should be called by every method that tries to access the buffers content to check
1479      * if the buffer was released before.
1480      */
1481     protected final void ensureAccessible() {
1482         if (checkAccessible && !isAccessible()) {
1483             throw new IllegalReferenceCountException(0);
1484         }
1485     }
1486 
1487     final void setIndex0(int readerIndex, int writerIndex) {
1488         this.readerIndex = readerIndex;
1489         this.writerIndex = writerIndex;
1490     }
1491 
1492     final void discardMarks() {
1493         markedReaderIndex = markedWriterIndex = 0;
1494     }
1495 
1496     /**
1497      * Obtain the memory address without checking {@link #ensureAccessible()} first, if possible.
1498      */
1499     long _memoryAddress() {
1500         return isAccessible() && hasMemoryAddress() ? memoryAddress() : 0L;
1501     }
1502 
1503     boolean _isDirect() {
1504         return isDirect();
1505     }
1506 
1507     ByteBuffer _internalNioBuffer() {
1508         return internalNioBuffer(0, capacity());
1509     }
1510 }