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         CharSequence sequence = getCharSequence(readerIndex, length, charset);
519         readerIndex += length;
520         return sequence;
521     }
522 
523     @Override
524     public String readString(int length, Charset charset) {
525         String string = toString(readerIndex, length, charset);
526         readerIndex += length;
527         return string;
528     }
529 
530     @Override
531     public ByteBuf setByte(int index, int value) {
532         checkIndex(index);
533         _setByte(index, value);
534         return this;
535     }
536 
537     protected abstract void _setByte(int index, int value);
538 
539     @Override
540     public ByteBuf setBoolean(int index, boolean value) {
541         setByte(index, value? 1 : 0);
542         return this;
543     }
544 
545     @Override
546     public ByteBuf setShort(int index, int value) {
547         checkIndex(index, 2);
548         _setShort(index, value);
549         return this;
550     }
551 
552     protected abstract void _setShort(int index, int value);
553 
554     @Override
555     public ByteBuf setShortLE(int index, int value) {
556         checkIndex(index, 2);
557         _setShortLE(index, value);
558         return this;
559     }
560 
561     protected abstract void _setShortLE(int index, int value);
562 
563     @Override
564     public ByteBuf setChar(int index, int value) {
565         setShort(index, value);
566         return this;
567     }
568 
569     @Override
570     public ByteBuf setMedium(int index, int value) {
571         checkIndex(index, 3);
572         _setMedium(index, value);
573         return this;
574     }
575 
576     protected abstract void _setMedium(int index, int value);
577 
578     @Override
579     public ByteBuf setMediumLE(int index, int value) {
580         checkIndex(index, 3);
581         _setMediumLE(index, value);
582         return this;
583     }
584 
585     protected abstract void _setMediumLE(int index, int value);
586 
587     @Override
588     public ByteBuf setInt(int index, int value) {
589         checkIndex(index, 4);
590         _setInt(index, value);
591         return this;
592     }
593 
594     protected abstract void _setInt(int index, int value);
595 
596     @Override
597     public ByteBuf setIntLE(int index, int value) {
598         checkIndex(index, 4);
599         _setIntLE(index, value);
600         return this;
601     }
602 
603     protected abstract void _setIntLE(int index, int value);
604 
605     @Override
606     public ByteBuf setFloat(int index, float value) {
607         setInt(index, Float.floatToRawIntBits(value));
608         return this;
609     }
610 
611     @Override
612     public ByteBuf setLong(int index, long value) {
613         checkIndex(index, 8);
614         _setLong(index, value);
615         return this;
616     }
617 
618     protected abstract void _setLong(int index, long value);
619 
620     @Override
621     public ByteBuf setLongLE(int index, long value) {
622         checkIndex(index, 8);
623         _setLongLE(index, value);
624         return this;
625     }
626 
627     protected abstract void _setLongLE(int index, long value);
628 
629     @Override
630     public ByteBuf setDouble(int index, double value) {
631         setLong(index, Double.doubleToRawLongBits(value));
632         return this;
633     }
634 
635     @Override
636     public ByteBuf setBytes(int index, byte[] src) {
637         setBytes(index, src, 0, src.length);
638         return this;
639     }
640 
641     @Override
642     public ByteBuf setBytes(int index, ByteBuf src) {
643         setBytes(index, src, src.readableBytes());
644         return this;
645     }
646 
647     private static void checkReadableBounds(final ByteBuf src, final int length) {
648         if (length > src.readableBytes()) {
649             throw new IndexOutOfBoundsException(String.format(
650                     "length(%d) exceeds src.readableBytes(%d) where src is: %s", length, src.readableBytes(), src));
651         }
652     }
653 
654     @Override
655     public ByteBuf setBytes(int index, ByteBuf src, int length) {
656         checkIndex(index, length);
657         ObjectUtil.checkNotNull(src, "src");
658         if (checkBounds) {
659             checkReadableBounds(src, length);
660         }
661 
662         setBytes(index, src, src.readerIndex(), length);
663         src.readerIndex(src.readerIndex() + length);
664         return this;
665     }
666 
667     @Override
668     public ByteBuf setZero(int index, int length) {
669         if (length == 0) {
670             return this;
671         }
672 
673         checkIndex(index, length);
674 
675         int nLong = length >>> 3;
676         int nBytes = length & 7;
677         for (int i = nLong; i > 0; i --) {
678             _setLong(index, 0);
679             index += 8;
680         }
681         if (nBytes == 4) {
682             _setInt(index, 0);
683             // Not need to update the index as we not will use it after this.
684         } else if (nBytes < 4) {
685             for (int i = nBytes; i > 0; i --) {
686                 _setByte(index, 0);
687                 index ++;
688             }
689         } else {
690             _setInt(index, 0);
691             index += 4;
692             for (int i = nBytes - 4; i > 0; i --) {
693                 _setByte(index, 0);
694                 index ++;
695             }
696         }
697         return this;
698     }
699 
700     @Override
701     public int setCharSequence(int index, CharSequence sequence, Charset charset) {
702         return setCharSequence0(index, sequence, charset, false);
703     }
704 
705     private int setCharSequence0(int index, CharSequence sequence, Charset charset, boolean expand) {
706         if (charset.equals(CharsetUtil.UTF_8)) {
707             int length = ByteBufUtil.utf8MaxBytes(sequence);
708             if (expand) {
709                 ensureWritable0(length);
710                 checkIndex0(index, length);
711             } else {
712                 checkIndex(index, length);
713             }
714             return ByteBufUtil.writeUtf8(this, index, length, sequence, sequence.length());
715         }
716         if (charset.equals(CharsetUtil.US_ASCII) || charset.equals(CharsetUtil.ISO_8859_1)) {
717             int length = sequence.length();
718             if (expand) {
719                 ensureWritable0(length);
720                 checkIndex0(index, length);
721             } else {
722                 checkIndex(index, length);
723             }
724             return ByteBufUtil.writeAscii(this, index, sequence, length);
725         }
726         byte[] bytes = sequence.toString().getBytes(charset);
727         if (expand) {
728             ensureWritable0(bytes.length);
729             // setBytes(...) will take care of checking the indices.
730         }
731         setBytes(index, bytes);
732         return bytes.length;
733     }
734 
735     @Override
736     public byte readByte() {
737         checkReadableBytes0(1);
738         int i = readerIndex;
739         byte b = _getByte(i);
740         readerIndex = i + 1;
741         return b;
742     }
743 
744     @Override
745     public boolean readBoolean() {
746         return readByte() != 0;
747     }
748 
749     @Override
750     public short readUnsignedByte() {
751         return (short) (readByte() & 0xFF);
752     }
753 
754     @Override
755     public short readShort() {
756         checkReadableBytes0(2);
757         short v = _getShort(readerIndex);
758         readerIndex += 2;
759         return v;
760     }
761 
762     @Override
763     public short readShortLE() {
764         checkReadableBytes0(2);
765         short v = _getShortLE(readerIndex);
766         readerIndex += 2;
767         return v;
768     }
769 
770     @Override
771     public int readUnsignedShort() {
772         return readShort() & 0xFFFF;
773     }
774 
775     @Override
776     public int readUnsignedShortLE() {
777         return readShortLE() & 0xFFFF;
778     }
779 
780     @Override
781     public int readMedium() {
782         int value = readUnsignedMedium();
783         if ((value & 0x800000) != 0) {
784             value |= 0xff000000;
785         }
786         return value;
787     }
788 
789     @Override
790     public int readMediumLE() {
791         int value = readUnsignedMediumLE();
792         if ((value & 0x800000) != 0) {
793             value |= 0xff000000;
794         }
795         return value;
796     }
797 
798     @Override
799     public int readUnsignedMedium() {
800         checkReadableBytes0(3);
801         int v = _getUnsignedMedium(readerIndex);
802         readerIndex += 3;
803         return v;
804     }
805 
806     @Override
807     public int readUnsignedMediumLE() {
808         checkReadableBytes0(3);
809         int v = _getUnsignedMediumLE(readerIndex);
810         readerIndex += 3;
811         return v;
812     }
813 
814     @Override
815     public int readInt() {
816         checkReadableBytes0(4);
817         int v = _getInt(readerIndex);
818         readerIndex += 4;
819         return v;
820     }
821 
822     @Override
823     public int readIntLE() {
824         checkReadableBytes0(4);
825         int v = _getIntLE(readerIndex);
826         readerIndex += 4;
827         return v;
828     }
829 
830     @Override
831     public long readUnsignedInt() {
832         return readInt() & 0xFFFFFFFFL;
833     }
834 
835     @Override
836     public long readUnsignedIntLE() {
837         return readIntLE() & 0xFFFFFFFFL;
838     }
839 
840     @Override
841     public long readLong() {
842         checkReadableBytes0(8);
843         long v = _getLong(readerIndex);
844         readerIndex += 8;
845         return v;
846     }
847 
848     @Override
849     public long readLongLE() {
850         checkReadableBytes0(8);
851         long v = _getLongLE(readerIndex);
852         readerIndex += 8;
853         return v;
854     }
855 
856     @Override
857     public char readChar() {
858         return (char) readShort();
859     }
860 
861     @Override
862     public float readFloat() {
863         return Float.intBitsToFloat(readInt());
864     }
865 
866     @Override
867     public double readDouble() {
868         return Double.longBitsToDouble(readLong());
869     }
870 
871     @Override
872     public ByteBuf readBytes(int length) {
873         checkReadableBytes(length);
874         if (length == 0) {
875             return Unpooled.EMPTY_BUFFER;
876         }
877 
878         ByteBuf buf = alloc().buffer(length, maxCapacity);
879         buf.writeBytes(this, readerIndex, length);
880         readerIndex += length;
881         return buf;
882     }
883 
884     @Override
885     public ByteBuf readSlice(int length) {
886         checkReadableBytes(length);
887         ByteBuf slice = slice(readerIndex, length);
888         readerIndex += length;
889         return slice;
890     }
891 
892     @Override
893     public ByteBuf readRetainedSlice(int length) {
894         checkReadableBytes(length);
895         ByteBuf slice = retainedSlice(readerIndex, length);
896         readerIndex += length;
897         return slice;
898     }
899 
900     @Override
901     public ByteBuf readBytes(byte[] dst, int dstIndex, int length) {
902         checkReadableBytes(length);
903         getBytes(readerIndex, dst, dstIndex, length);
904         readerIndex += length;
905         return this;
906     }
907 
908     @Override
909     public ByteBuf readBytes(byte[] dst) {
910         readBytes(dst, 0, dst.length);
911         return this;
912     }
913 
914     @Override
915     public ByteBuf readBytes(ByteBuf dst) {
916         readBytes(dst, dst.writableBytes());
917         return this;
918     }
919 
920     @Override
921     public ByteBuf readBytes(ByteBuf dst, int length) {
922         if (checkBounds) {
923             if (length > dst.writableBytes()) {
924                 throw new IndexOutOfBoundsException(String.format(
925                         "length(%d) exceeds dst.writableBytes(%d) where dst is: %s", length, dst.writableBytes(), dst));
926             }
927         }
928         readBytes(dst, dst.writerIndex(), length);
929         dst.writerIndex(dst.writerIndex() + length);
930         return this;
931     }
932 
933     @Override
934     public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) {
935         checkReadableBytes(length);
936         getBytes(readerIndex, dst, dstIndex, length);
937         readerIndex += length;
938         return this;
939     }
940 
941     @Override
942     public ByteBuf readBytes(ByteBuffer dst) {
943         int length = dst.remaining();
944         checkReadableBytes(length);
945         getBytes(readerIndex, dst);
946         readerIndex += length;
947         return this;
948     }
949 
950     @Override
951     public int readBytes(GatheringByteChannel out, int length)
952             throws IOException {
953         checkReadableBytes(length);
954         int readBytes = getBytes(readerIndex, out, length);
955         readerIndex += readBytes;
956         return readBytes;
957     }
958 
959     @Override
960     public int readBytes(FileChannel out, long position, int length)
961             throws IOException {
962         checkReadableBytes(length);
963         int readBytes = getBytes(readerIndex, out, position, length);
964         readerIndex += readBytes;
965         return readBytes;
966     }
967 
968     @Override
969     public ByteBuf readBytes(OutputStream out, int length) throws IOException {
970         checkReadableBytes(length);
971         getBytes(readerIndex, out, length);
972         readerIndex += length;
973         return this;
974     }
975 
976     @Override
977     public ByteBuf skipBytes(int length) {
978         checkReadableBytes(length);
979         readerIndex += length;
980         return this;
981     }
982 
983     @Override
984     public ByteBuf writeBoolean(boolean value) {
985         writeByte(value ? 1 : 0);
986         return this;
987     }
988 
989     @Override
990     public ByteBuf writeByte(int value) {
991         ensureWritable0(1);
992         _setByte(writerIndex++, value);
993         return this;
994     }
995 
996     @Override
997     public ByteBuf writeShort(int value) {
998         ensureWritable0(2);
999         _setShort(writerIndex, value);
1000         writerIndex += 2;
1001         return this;
1002     }
1003 
1004     @Override
1005     public ByteBuf writeShortLE(int value) {
1006         ensureWritable0(2);
1007         _setShortLE(writerIndex, value);
1008         writerIndex += 2;
1009         return this;
1010     }
1011 
1012     @Override
1013     public ByteBuf writeMedium(int value) {
1014         ensureWritable0(3);
1015         _setMedium(writerIndex, value);
1016         writerIndex += 3;
1017         return this;
1018     }
1019 
1020     @Override
1021     public ByteBuf writeMediumLE(int value) {
1022         ensureWritable0(3);
1023         _setMediumLE(writerIndex, value);
1024         writerIndex += 3;
1025         return this;
1026     }
1027 
1028     @Override
1029     public ByteBuf writeInt(int value) {
1030         ensureWritable0(4);
1031         _setInt(writerIndex, value);
1032         writerIndex += 4;
1033         return this;
1034     }
1035 
1036     @Override
1037     public ByteBuf writeIntLE(int value) {
1038         ensureWritable0(4);
1039         _setIntLE(writerIndex, value);
1040         writerIndex += 4;
1041         return this;
1042     }
1043 
1044     @Override
1045     public ByteBuf writeLong(long value) {
1046         ensureWritable0(8);
1047         _setLong(writerIndex, value);
1048         writerIndex += 8;
1049         return this;
1050     }
1051 
1052     @Override
1053     public ByteBuf writeLongLE(long value) {
1054         ensureWritable0(8);
1055         _setLongLE(writerIndex, value);
1056         writerIndex += 8;
1057         return this;
1058     }
1059 
1060     @Override
1061     public ByteBuf writeChar(int value) {
1062         writeShort(value);
1063         return this;
1064     }
1065 
1066     @Override
1067     public ByteBuf writeFloat(float value) {
1068         writeInt(Float.floatToRawIntBits(value));
1069         return this;
1070     }
1071 
1072     @Override
1073     public ByteBuf writeDouble(double value) {
1074         writeLong(Double.doubleToRawLongBits(value));
1075         return this;
1076     }
1077 
1078     @Override
1079     public ByteBuf writeBytes(byte[] src, int srcIndex, int length) {
1080         ensureWritable(length);
1081         setBytes(writerIndex, src, srcIndex, length);
1082         writerIndex += length;
1083         return this;
1084     }
1085 
1086     @Override
1087     public ByteBuf writeBytes(byte[] src) {
1088         writeBytes(src, 0, src.length);
1089         return this;
1090     }
1091 
1092     @Override
1093     public ByteBuf writeBytes(ByteBuf src) {
1094         writeBytes(src, src.readableBytes());
1095         return this;
1096     }
1097 
1098     @Override
1099     public ByteBuf writeBytes(ByteBuf src, int length) {
1100         if (checkBounds) {
1101             checkReadableBounds(src, length);
1102         }
1103         writeBytes(src, src.readerIndex(), length);
1104         src.readerIndex(src.readerIndex() + length);
1105         return this;
1106     }
1107 
1108     @Override
1109     public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
1110         ensureWritable(length);
1111         setBytes(writerIndex, src, srcIndex, length);
1112         writerIndex += length;
1113         return this;
1114     }
1115 
1116     @Override
1117     public ByteBuf writeBytes(ByteBuffer src) {
1118         int length = src.remaining();
1119         ensureWritable0(length);
1120         setBytes(writerIndex, src);
1121         writerIndex += length;
1122         return this;
1123     }
1124 
1125     @Override
1126     public int writeBytes(InputStream in, int length)
1127             throws IOException {
1128         ensureWritable(length);
1129         int writtenBytes = setBytes(writerIndex, in, length);
1130         if (writtenBytes > 0) {
1131             writerIndex += writtenBytes;
1132         }
1133         return writtenBytes;
1134     }
1135 
1136     @Override
1137     public int writeBytes(ScatteringByteChannel in, int length) throws IOException {
1138         ensureWritable(length);
1139         int writtenBytes = setBytes(writerIndex, in, length);
1140         if (writtenBytes > 0) {
1141             writerIndex += writtenBytes;
1142         }
1143         return writtenBytes;
1144     }
1145 
1146     @Override
1147     public int writeBytes(FileChannel in, long position, int length) throws IOException {
1148         ensureWritable(length);
1149         int writtenBytes = setBytes(writerIndex, in, position, length);
1150         if (writtenBytes > 0) {
1151             writerIndex += writtenBytes;
1152         }
1153         return writtenBytes;
1154     }
1155 
1156     @Override
1157     public ByteBuf writeZero(int length) {
1158         if (length == 0) {
1159             return this;
1160         }
1161 
1162         ensureWritable(length);
1163         int wIndex = writerIndex;
1164         checkIndex0(wIndex, length);
1165 
1166         int nLong = length >>> 3;
1167         int nBytes = length & 7;
1168         for (int i = nLong; i > 0; i --) {
1169             _setLong(wIndex, 0);
1170             wIndex += 8;
1171         }
1172         if (nBytes == 4) {
1173             _setInt(wIndex, 0);
1174             wIndex += 4;
1175         } else if (nBytes < 4) {
1176             for (int i = nBytes; i > 0; i --) {
1177                 _setByte(wIndex, 0);
1178                 wIndex++;
1179             }
1180         } else {
1181             _setInt(wIndex, 0);
1182             wIndex += 4;
1183             for (int i = nBytes - 4; i > 0; i --) {
1184                 _setByte(wIndex, 0);
1185                 wIndex++;
1186             }
1187         }
1188         writerIndex = wIndex;
1189         return this;
1190     }
1191 
1192     @Override
1193     public int writeCharSequence(CharSequence sequence, Charset charset) {
1194         int written = setCharSequence0(writerIndex, sequence, charset, true);
1195         writerIndex += written;
1196         return written;
1197     }
1198 
1199     @Override
1200     public ByteBuf copy() {
1201         return copy(readerIndex, readableBytes());
1202     }
1203 
1204     @Override
1205     public ByteBuf duplicate() {
1206         ensureAccessible();
1207         return new UnpooledDuplicatedByteBuf(this);
1208     }
1209 
1210     @Override
1211     public ByteBuf retainedDuplicate() {
1212         return duplicate().retain();
1213     }
1214 
1215     @Override
1216     public ByteBuf slice() {
1217         return slice(readerIndex, readableBytes());
1218     }
1219 
1220     @Override
1221     public ByteBuf retainedSlice() {
1222         return slice().retain();
1223     }
1224 
1225     @Override
1226     public ByteBuf slice(int index, int length) {
1227         ensureAccessible();
1228         return new UnpooledSlicedByteBuf(this, index, length);
1229     }
1230 
1231     @Override
1232     public ByteBuf retainedSlice(int index, int length) {
1233         return slice(index, length).retain();
1234     }
1235 
1236     @Override
1237     public ByteBuffer nioBuffer() {
1238         return nioBuffer(readerIndex, readableBytes());
1239     }
1240 
1241     @Override
1242     public ByteBuffer[] nioBuffers() {
1243         return nioBuffers(readerIndex, readableBytes());
1244     }
1245 
1246     @Override
1247     public String toString(Charset charset) {
1248         return toString(readerIndex, readableBytes(), charset);
1249     }
1250 
1251     @Override
1252     public String toString(int index, int length, Charset charset) {
1253         return ByteBufUtil.decodeString(this, index, length, charset);
1254     }
1255 
1256     @Override
1257     public int indexOf(int fromIndex, int toIndex, byte value) {
1258         if (fromIndex <= toIndex) {
1259             return ByteBufUtil.firstIndexOf(this, fromIndex, toIndex, value);
1260         }
1261         return ByteBufUtil.lastIndexOf(this, fromIndex, toIndex, value);
1262     }
1263 
1264     @Override
1265     public int bytesBefore(byte value) {
1266         return bytesBefore(readerIndex(), readableBytes(), value);
1267     }
1268 
1269     @Override
1270     public int bytesBefore(int length, byte value) {
1271         checkReadableBytes(length);
1272         return bytesBefore(readerIndex(), length, value);
1273     }
1274 
1275     @Override
1276     public int bytesBefore(int index, int length, byte value) {
1277         int endIndex = indexOf(index, index + length, value);
1278         if (endIndex < 0) {
1279             return -1;
1280         }
1281         return endIndex - index;
1282     }
1283 
1284     @Override
1285     public int forEachByte(ByteProcessor processor) {
1286         ensureAccessible();
1287         try {
1288             return forEachByteAsc0(readerIndex, writerIndex, processor);
1289         } catch (Exception e) {
1290             PlatformDependent.throwException(e);
1291             return -1;
1292         }
1293     }
1294 
1295     @Override
1296     public int forEachByte(int index, int length, ByteProcessor processor) {
1297         checkIndex(index, length);
1298         try {
1299             return forEachByteAsc0(index, index + length, processor);
1300         } catch (Exception e) {
1301             PlatformDependent.throwException(e);
1302             return -1;
1303         }
1304     }
1305 
1306     int forEachByteAsc0(int start, int end, ByteProcessor processor) throws Exception {
1307         for (; start < end; ++start) {
1308             if (!processor.process(_getByte(start))) {
1309                 return start;
1310             }
1311         }
1312 
1313         return -1;
1314     }
1315 
1316     @Override
1317     public int forEachByteDesc(ByteProcessor processor) {
1318         ensureAccessible();
1319         try {
1320             return forEachByteDesc0(writerIndex - 1, readerIndex, processor);
1321         } catch (Exception e) {
1322             PlatformDependent.throwException(e);
1323             return -1;
1324         }
1325     }
1326 
1327     @Override
1328     public int forEachByteDesc(int index, int length, ByteProcessor processor) {
1329         checkIndex(index, length);
1330         try {
1331             return forEachByteDesc0(index + length - 1, index, processor);
1332         } catch (Exception e) {
1333             PlatformDependent.throwException(e);
1334             return -1;
1335         }
1336     }
1337 
1338     int forEachByteDesc0(int rStart, final int rEnd, ByteProcessor processor) throws Exception {
1339         for (; rStart >= rEnd; --rStart) {
1340             if (!processor.process(_getByte(rStart))) {
1341                 return rStart;
1342             }
1343         }
1344         return -1;
1345     }
1346 
1347     @Override
1348     public int hashCode() {
1349         return ByteBufUtil.hashCode(this);
1350     }
1351 
1352     @Override
1353     public boolean equals(Object o) {
1354         return o instanceof ByteBuf && ByteBufUtil.equals(this, (ByteBuf) o);
1355     }
1356 
1357     @Override
1358     public int compareTo(ByteBuf that) {
1359         return ByteBufUtil.compare(this, that);
1360     }
1361 
1362     @Override
1363     public String toString() {
1364         if (refCnt() == 0) {
1365             return StringUtil.simpleClassName(this) + "(freed)";
1366         }
1367 
1368         StringBuilder buf = new StringBuilder()
1369             .append(StringUtil.simpleClassName(this))
1370             .append("(ridx: ").append(readerIndex)
1371             .append(", widx: ").append(writerIndex)
1372             .append(", cap: ").append(capacity());
1373         if (maxCapacity != Integer.MAX_VALUE) {
1374             buf.append('/').append(maxCapacity);
1375         }
1376 
1377         ByteBuf unwrapped = unwrap();
1378         if (unwrapped != null) {
1379             buf.append(", unwrapped: ").append(unwrapped);
1380         }
1381         buf.append(')');
1382         return buf.toString();
1383     }
1384 
1385     protected final void checkIndex(int index) {
1386         checkIndex(index, 1);
1387     }
1388 
1389     protected final void checkIndex(int index, int fieldLength) {
1390         ensureAccessible();
1391         checkIndex0(index, fieldLength);
1392     }
1393 
1394     private static void checkRangeBoundsTrustedCapacity(final String indexName, final int index,
1395                                                  final int fieldLength, final int capacity) {
1396         if (isOutOfBoundsTrustedCapacity(index, fieldLength, capacity)) {
1397             rangeBoundsCheckFailed(indexName, index, fieldLength, capacity);
1398         }
1399     }
1400 
1401     /**
1402      * This is a simplified version of MathUtil.isOutOfBounds that does not check for capacity negative values.
1403      */
1404     private static boolean isOutOfBoundsTrustedCapacity(int index, int fieldLength, int capacity) {
1405         // keep these as branches since would make it easier to be constant-folded
1406         return index < 0 || fieldLength < 0 || index + fieldLength < 0 || index + fieldLength > capacity;
1407     }
1408 
1409     private static void checkRangeBounds(final String indexName, final int index,
1410             final int fieldLength, final int capacity) {
1411         if (isOutOfBounds(index, fieldLength, capacity)) {
1412             rangeBoundsCheckFailed(indexName, index, fieldLength, capacity);
1413         }
1414     }
1415 
1416     private static void rangeBoundsCheckFailed(String indexName, int index, int fieldLength, int capacity) {
1417         throw new IndexOutOfBoundsException(String.format(
1418                 "%s: %d, length: %d (expected: range(0, %d))", indexName, index, fieldLength, capacity));
1419     }
1420 
1421     final void checkIndex0(int index, int fieldLength) {
1422         if (checkBounds) {
1423             checkRangeBoundsTrustedCapacity("index", index, fieldLength, capacity());
1424         }
1425     }
1426 
1427     protected final void checkSrcIndex(int index, int length, int srcIndex, int srcCapacity) {
1428         checkIndex(index, length);
1429         if (checkBounds) {
1430             checkRangeBounds("srcIndex", srcIndex, length, srcCapacity);
1431         }
1432     }
1433 
1434     protected final void checkDstIndex(int index, int length, int dstIndex, int dstCapacity) {
1435         checkIndex(index, length);
1436         if (checkBounds) {
1437             checkRangeBounds("dstIndex", dstIndex, length, dstCapacity);
1438         }
1439     }
1440 
1441     protected final void checkDstIndex(int length, int dstIndex, int dstCapacity) {
1442         checkReadableBytes(length);
1443         if (checkBounds) {
1444             checkRangeBounds("dstIndex", dstIndex, length, dstCapacity);
1445         }
1446     }
1447 
1448     /**
1449      * Throws an {@link IndexOutOfBoundsException} if the current
1450      * {@linkplain #readableBytes() readable bytes} of this buffer is less
1451      * than the specified value.
1452      */
1453     protected final void checkReadableBytes(int minimumReadableBytes) {
1454         checkReadableBytes0(checkPositiveOrZero(minimumReadableBytes, "minimumReadableBytes"));
1455     }
1456 
1457     protected final void checkNewCapacity(int newCapacity) {
1458         ensureAccessible();
1459         if (checkBounds && (newCapacity < 0 || newCapacity > maxCapacity())) {
1460             throw new IllegalArgumentException("newCapacity: " + newCapacity +
1461                     " (expected: 0-" + maxCapacity() + ')');
1462         }
1463     }
1464 
1465     private void checkReadableBytes0(int minimumReadableBytes) {
1466         ensureAccessible();
1467         if (checkBounds && readerIndex > writerIndex - minimumReadableBytes) {
1468             throw new IndexOutOfBoundsException(String.format(
1469                     "readerIndex(%d) + length(%d) exceeds writerIndex(%d): %s",
1470                     readerIndex, minimumReadableBytes, writerIndex, this));
1471         }
1472     }
1473 
1474     /**
1475      * Should be called by every method that tries to access the buffers content to check
1476      * if the buffer was released before.
1477      */
1478     protected final void ensureAccessible() {
1479         if (checkAccessible && !isAccessible()) {
1480             throw new IllegalReferenceCountException(0);
1481         }
1482     }
1483 
1484     final void setIndex0(int readerIndex, int writerIndex) {
1485         this.readerIndex = readerIndex;
1486         this.writerIndex = writerIndex;
1487     }
1488 
1489     final void discardMarks() {
1490         markedReaderIndex = markedWriterIndex = 0;
1491     }
1492 
1493     /**
1494      * Obtain the memory address without checking {@link #ensureAccessible()} first, if possible.
1495      */
1496     long _memoryAddress() {
1497         return isAccessible() && hasMemoryAddress() ? memoryAddress() : 0L;
1498     }
1499 }