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