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