3838public final class ByteBufAdaptor extends ByteBuf {
3939 private final ByteBufAllocatorAdaptor alloc ;
4040 private final Buffer buffer ;
41+ private final boolean hasMemoryAddress ;
4142
4243 public ByteBufAdaptor (ByteBufAllocatorAdaptor alloc , Buffer buffer ) {
4344 this .alloc = alloc ;
4445 this .buffer = buffer ;
46+ hasMemoryAddress = buffer .nativeAddress () != 0 ;
4547 }
4648
4749 /**
@@ -70,7 +72,14 @@ public int capacity() {
7072 public ByteBuf capacity (int newCapacity ) {
7173 int diff = newCapacity - capacity () - buffer .writableBytes ();
7274 if (diff > 0 ) {
73- buffer .ensureWritable (diff );
75+ try {
76+ buffer .ensureWritable (diff );
77+ } catch (IllegalStateException e ) {
78+ if (!buffer .isOwned ()) {
79+ throw new UnsupportedOperationException (e );
80+ }
81+ throw e ;
82+ }
7483 }
7584 return this ;
7685 }
@@ -103,7 +112,7 @@ public ByteBuf unwrap() {
103112
104113 @ Override
105114 public boolean isDirect () {
106- return buffer . nativeAddress () != 0 ;
115+ return hasMemoryAddress ;
107116 }
108117
109118 @ Override
@@ -186,6 +195,7 @@ public ByteBuf clear() {
186195
187196 @ Override
188197 public ByteBuf discardReadBytes () {
198+ checkAccess ();
189199 buffer .compact ();
190200 return this ;
191201 }
@@ -197,9 +207,10 @@ public ByteBuf discardSomeReadBytes() {
197207
198208 @ Override
199209 public ByteBuf ensureWritable (int minWritableBytes ) {
200- try {
201- if (writableBytes () < minWritableBytes ) {
202- int borrows = buffer .countBorrows ();
210+ checkAccess ();
211+ if (writableBytes () < minWritableBytes ) {
212+ int borrows = buffer .countBorrows ();
213+ try {
203214 if (borrows == 0 ) {
204215 // Good place.
205216 buffer .ensureWritable (minWritableBytes );
@@ -212,9 +223,9 @@ public ByteBuf ensureWritable(int minWritableBytes) {
212223 retain (borrows );
213224 }
214225 }
226+ } catch (IllegalArgumentException e ) {
227+ throw new IndexOutOfBoundsException (e .getMessage ());
215228 }
216- } catch (IllegalStateException e ) {
217- throw new IllegalReferenceCountException (e );
218229 }
219230 return this ;
220231 }
@@ -453,6 +464,9 @@ public ByteBuf getBytes(int index, byte[] dst) {
453464
454465 @ Override
455466 public ByteBuf getBytes (int index , byte [] dst , int dstIndex , int length ) {
467+ if (index < 0 || capacity () < index + length ) {
468+ throw new IndexOutOfBoundsException ();
469+ }
456470 for (int i = 0 ; i < length ; i ++) {
457471 dst [dstIndex + i ] = getByte (index + i );
458472 }
@@ -636,9 +650,7 @@ public ByteBuf setDouble(int index, double value) {
636650
637651 @ Override
638652 public ByteBuf setBytes (int index , ByteBuf src ) {
639- if (!buffer .isAccessible ()) {
640- throw new IllegalReferenceCountException ();
641- }
653+ checkAccess ();
642654 while (src .isReadable () && index < capacity ()) {
643655 setByte (index ++, src .readByte ());
644656 }
@@ -647,6 +659,7 @@ public ByteBuf setBytes(int index, ByteBuf src) {
647659
648660 @ Override
649661 public ByteBuf setBytes (int index , ByteBuf src , int length ) {
662+ checkAccess ();
650663 for (int i = 0 ; i < length ; i ++) {
651664 setByte (index + i , src .readByte ());
652665 }
@@ -685,13 +698,15 @@ public ByteBuf setBytes(int index, ByteBuffer src) {
685698
686699 @ Override
687700 public int setBytes (int index , InputStream in , int length ) throws IOException {
701+ checkAccess ();
688702 byte [] bytes = in .readNBytes (length );
689703 setBytes (index , bytes , 0 , length );
690704 return bytes .length ;
691705 }
692706
693707 @ Override
694708 public int setBytes (int index , ScatteringByteChannel in , int length ) throws IOException {
709+ checkAccess ();
695710 ByteBuffer transfer = ByteBuffer .allocate (length );
696711 int bytes = in .read (transfer );
697712 transfer .flip ();
@@ -701,6 +716,7 @@ public int setBytes(int index, ScatteringByteChannel in, int length) throws IOEx
701716
702717 @ Override
703718 public int setBytes (int index , FileChannel in , long position , int length ) throws IOException {
719+ checkAccess ();
704720 ByteBuffer transfer = ByteBuffer .allocate (length );
705721 int bytes = in .read (transfer , position );
706722 transfer .flip ();
@@ -925,8 +941,9 @@ public double readDouble() {
925941 @ Override
926942 public ByteBuf readBytes (int length ) {
927943 Buffer copy = preferredBufferAllocator ().allocate (length );
928- buffer .copyInto (0 , copy , 0 , length );
929- return wrap (copy );
944+ buffer .copyInto (0 , copy , readerIndex (), length );
945+ readerIndex (readerIndex () + length );
946+ return wrap (copy ).writerIndex (length );
930947 }
931948
932949 @ Override
@@ -1262,6 +1279,9 @@ public int writeBytes(FileChannel in, long position, int length) throws IOExcept
12621279
12631280 @ Override
12641281 public ByteBuf writeZero (int length ) {
1282+ if (length < 0 ) {
1283+ throw new IllegalArgumentException ();
1284+ }
12651285 ensureWritable (length );
12661286 for (int i = 0 ; i < length ; i ++) {
12671287 writeByte (0 );
@@ -1278,7 +1298,32 @@ public int writeCharSequence(CharSequence sequence, Charset charset) {
12781298
12791299 @ Override
12801300 public int indexOf (int fromIndex , int toIndex , byte value ) {
1281- for (int i = fromIndex ; i < toIndex ; i ++) {
1301+ if (!buffer .isAccessible ()) {
1302+ return -1 ;
1303+ }
1304+ int inc , start , end ;
1305+ if (fromIndex <= toIndex ) {
1306+ inc = 1 ;
1307+ start = fromIndex ;
1308+ end = toIndex - 1 ;
1309+ if (start < 0 ) {
1310+ start = 0 ; // Required to pass regression tests.
1311+ }
1312+ if (capacity () <= end ) {
1313+ throw new IndexOutOfBoundsException ();
1314+ }
1315+ } else {
1316+ inc = -1 ;
1317+ start = fromIndex - 1 ;
1318+ end = toIndex ;
1319+ if (capacity () <= start ) {
1320+ start = capacity () - 1 ; // Required to pass regression tests.
1321+ }
1322+ if (end < 0 ) {
1323+ throw new IndexOutOfBoundsException ();
1324+ }
1325+ }
1326+ for (int i = start ; i != end ; i += inc ) {
12821327 if (getByte (i ) == value ) {
12831328 return i ;
12841329 }
@@ -1307,38 +1352,30 @@ public int bytesBefore(int index, int length, byte value) {
13071352
13081353 @ Override
13091354 public int forEachByte (ByteProcessor processor ) {
1310- if (!buffer .isAccessible ()) {
1311- throw new IllegalReferenceCountException ();
1312- }
1355+ checkAccess ();
13131356 int index = readerIndex ();
13141357 int bytes = buffer .openCursor ().process (processor );
13151358 return bytes == -1 ? -1 : index + bytes ;
13161359 }
13171360
13181361 @ Override
13191362 public int forEachByte (int index , int length , ByteProcessor processor ) {
1320- if (!buffer .isAccessible ()) {
1321- throw new IllegalReferenceCountException ();
1322- }
1363+ checkAccess ();
13231364 int bytes = buffer .openCursor (index , length ).process (processor );
13241365 return bytes == -1 ? -1 : index + bytes ;
13251366 }
13261367
13271368 @ Override
13281369 public int forEachByteDesc (ByteProcessor processor ) {
1329- if (!buffer .isAccessible ()) {
1330- throw new IllegalReferenceCountException ();
1331- }
1370+ checkAccess ();
13321371 int index = readerIndex ();
13331372 int bytes = buffer .openReverseCursor ().process (processor );
13341373 return bytes == -1 ? -1 : index - bytes ;
13351374 }
13361375
13371376 @ Override
13381377 public int forEachByteDesc (int index , int length , ByteProcessor processor ) {
1339- if (!buffer .isAccessible ()) {
1340- throw new IllegalReferenceCountException ();
1341- }
1378+ checkAccess ();
13421379 int bytes = buffer .openReverseCursor (index , length ).process (processor );
13431380 return bytes == -1 ? -1 : index - bytes ;
13441381 }
@@ -1350,9 +1387,7 @@ public ByteBuf copy() {
13501387
13511388 @ Override
13521389 public ByteBuf copy (int index , int length ) {
1353- if (!buffer .isAccessible ()) {
1354- throw new IllegalReferenceCountException ();
1355- }
1390+ checkAccess ();
13561391 try {
13571392 BufferAllocator allocator = preferredBufferAllocator ();
13581393 Buffer copy = allocator .allocate (length );
@@ -1374,9 +1409,7 @@ public ByteBuf slice() {
13741409
13751410 @ Override
13761411 public ByteBuf retainedSlice () {
1377- if (!buffer .isAccessible ()) {
1378- throw new IllegalReferenceCountException ();
1379- }
1412+ checkAccess ();
13801413 return wrap (buffer .slice ());
13811414 }
13821415
@@ -1389,6 +1422,7 @@ public ByteBuf slice(int index, int length) {
13891422
13901423 @ Override
13911424 public ByteBuf retainedSlice (int index , int length ) {
1425+ checkAccess ();
13921426 try {
13931427 return wrap (buffer .slice (index , length ));
13941428 } catch (IllegalStateException e ) {
@@ -1405,7 +1439,7 @@ public ByteBuf duplicate() {
14051439
14061440 @ Override
14071441 public ByteBuf retainedDuplicate () {
1408- return retainedSlice (0 , capacity ());
1442+ return retainedSlice (0 , capacity ()). setIndex ( readerIndex (), writerIndex ()) ;
14091443 }
14101444
14111445 @ Override
@@ -1420,9 +1454,7 @@ public ByteBuffer nioBuffer() {
14201454
14211455 @ Override
14221456 public ByteBuffer nioBuffer (int index , int length ) {
1423- if (!buffer .isAccessible ()) {
1424- throw new IllegalReferenceCountException ();
1425- }
1457+ checkAccess ();
14261458 ByteBuffer copy = isDirect () ? ByteBuffer .allocateDirect (length ) : ByteBuffer .allocate (length );
14271459 while (index < length ) {
14281460 copy .put (getByte (index ++));
@@ -1432,9 +1464,7 @@ public ByteBuffer nioBuffer(int index, int length) {
14321464
14331465 @ Override
14341466 public ByteBuffer internalNioBuffer (int index , int length ) {
1435- if (!buffer .isAccessible ()) {
1436- throw new IllegalReferenceCountException ();
1437- }
1467+ checkAccess ();
14381468 if (readerIndex () <= index && index < writerIndex () && length <= readableBytes ()) {
14391469 // We wish to read from the internal buffer.
14401470 if (buffer .countReadableComponents () != 1 ) {
@@ -1504,7 +1534,7 @@ public int arrayOffset() {
15041534
15051535 @ Override
15061536 public boolean hasMemoryAddress () {
1507- return buffer . nativeAddress () != 0 ;
1537+ return hasMemoryAddress ;
15081538 }
15091539
15101540 @ Override
@@ -1612,6 +1642,12 @@ public boolean release(int decrement) {
16121642 return !buffer .isAccessible ();
16131643 }
16141644
1645+ private void checkAccess () {
1646+ if (!buffer .isAccessible ()) {
1647+ throw new IllegalReferenceCountException ();
1648+ }
1649+ }
1650+
16151651 private ByteBufAdaptor wrap (Buffer copy ) {
16161652 return new ByteBufAdaptor (alloc , copy );
16171653 }
0 commit comments