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