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