001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.nio; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertFalse; 022import static org.junit.jupiter.api.Assertions.assertNotEquals; 023import static org.junit.jupiter.api.Assertions.assertTrue; 024import static org.junit.jupiter.api.Assertions.fail; 025 026import java.io.IOException; 027import java.nio.BufferOverflowException; 028import java.nio.BufferUnderflowException; 029import java.nio.ByteBuffer; 030import org.apache.hadoop.hbase.testclassification.MiscTests; 031import org.apache.hadoop.hbase.testclassification.SmallTests; 032import org.apache.hadoop.hbase.util.ByteBufferUtils; 033import org.apache.hadoop.hbase.util.Bytes; 034import org.apache.hadoop.hbase.util.ObjectIntPair; 035import org.junit.jupiter.api.Tag; 036import org.junit.jupiter.api.Test; 037 038@Tag(MiscTests.TAG) 039@Tag(SmallTests.TAG) 040public class TestMultiByteBuff { 041 042 /** 043 * Test right answer though we span many sub-buffers. 044 */ 045 @Test 046 public void testGetShort() { 047 ByteBuffer bb1 = ByteBuffer.allocate(1); 048 bb1.put((byte) 1); 049 ByteBuffer bb2 = ByteBuffer.allocate(1); 050 bb2.put((byte) 0); 051 ByteBuffer bb3 = ByteBuffer.allocate(1); 052 bb3.put((byte) 2); 053 ByteBuffer bb4 = ByteBuffer.allocate(1); 054 bb4.put((byte) 3); 055 MultiByteBuff mbb = new MultiByteBuff(bb1, bb2, bb3, bb4); 056 assertEquals(256, mbb.getShortAfterPosition(0)); 057 assertEquals(2, mbb.getShortAfterPosition(1)); 058 assertEquals(515, mbb.getShortAfterPosition(2)); 059 } 060 061 @Test 062 public void testWritesAndReads() { 063 // Absolute reads 064 ByteBuffer bb1 = ByteBuffer.allocate(15); 065 ByteBuffer bb2 = ByteBuffer.allocate(15); 066 int i1 = 4; 067 bb1.putInt(i1); 068 long l1 = 45L, l2 = 100L, l3 = 12345L; 069 bb1.putLong(l1); 070 short s1 = 2; 071 bb1.putShort(s1); 072 byte[] b = Bytes.toBytes(l2); 073 bb1.put(b, 0, 1); 074 bb2.put(b, 1, 7); 075 bb2.putLong(l3); 076 MultiByteBuff mbb = new MultiByteBuff(bb1, bb2); 077 assertEquals(l1, mbb.getLong(4)); 078 assertEquals(l2, mbb.getLong(14)); 079 assertEquals(l3, mbb.getLong(22)); 080 assertEquals(i1, mbb.getInt(0)); 081 assertEquals(s1, mbb.getShort(12)); 082 // Relative reads 083 assertEquals(i1, mbb.getInt()); 084 assertEquals(l1, mbb.getLong()); 085 assertEquals(s1, mbb.getShort()); 086 assertEquals(l2, mbb.getLong()); 087 assertEquals(l3, mbb.getLong()); 088 // Absolute writes 089 bb1 = ByteBuffer.allocate(15); 090 bb2 = ByteBuffer.allocate(15); 091 mbb = new MultiByteBuff(bb1, bb2); 092 byte b1 = 5, b2 = 31; 093 mbb.put(b1); 094 mbb.putLong(l1); 095 mbb.putInt(i1); 096 mbb.putLong(l2); 097 mbb.put(b2); 098 mbb.position(mbb.position() + 2); 099 try { 100 mbb.putLong(l3); 101 fail("'Should have thrown BufferOverflowException"); 102 } catch (BufferOverflowException e) { 103 } 104 mbb.position(mbb.position() - 2); 105 mbb.putLong(l3); 106 mbb.rewind(); 107 assertEquals(b1, mbb.get()); 108 assertEquals(l1, mbb.getLong()); 109 assertEquals(i1, mbb.getInt()); 110 assertEquals(l2, mbb.getLong()); 111 assertEquals(b2, mbb.get()); 112 assertEquals(l3, mbb.getLong()); 113 mbb.put(21, b1); 114 mbb.position(21); 115 assertEquals(b1, mbb.get()); 116 mbb.put(b); 117 assertEquals(l2, mbb.getLong(22)); 118 } 119 120 @Test 121 public void testPutPrimitives() { 122 ByteBuffer bb = ByteBuffer.allocate(10); 123 SingleByteBuff s = new SingleByteBuff(bb); 124 s.putLong(-4465109508325701663L); 125 bb.rewind(); 126 long long1 = bb.getLong(); 127 assertEquals(-4465109508325701663L, long1); 128 s.position(8); 129 } 130 131 @Test 132 public void testArrayBasedMethods() { 133 byte[] b = new byte[15]; 134 ByteBuffer bb1 = ByteBuffer.wrap(b, 1, 10).slice(); 135 ByteBuffer bb2 = ByteBuffer.allocate(15); 136 ByteBuff mbb1 = new MultiByteBuff(bb1, bb2); 137 assertFalse(mbb1.hasArray()); 138 try { 139 mbb1.array(); 140 fail(); 141 } catch (UnsupportedOperationException e) { 142 } 143 try { 144 mbb1.arrayOffset(); 145 fail(); 146 } catch (UnsupportedOperationException e) { 147 } 148 mbb1 = new SingleByteBuff(bb1); 149 assertTrue(mbb1.hasArray()); 150 assertEquals(1, mbb1.arrayOffset()); 151 assertEquals(b, mbb1.array()); 152 mbb1 = new SingleByteBuff(ByteBuffer.allocateDirect(10)); 153 assertFalse(mbb1.hasArray()); 154 try { 155 mbb1.array(); 156 fail(); 157 } catch (UnsupportedOperationException e) { 158 } 159 try { 160 mbb1.arrayOffset(); 161 fail(); 162 } catch (UnsupportedOperationException e) { 163 } 164 } 165 166 @Test 167 public void testMarkAndResetWithMBB() { 168 ByteBuffer bb1 = ByteBuffer.allocateDirect(15); 169 ByteBuffer bb2 = ByteBuffer.allocateDirect(15); 170 bb1.putInt(4); 171 long l1 = 45L, l2 = 100L, l3 = 12345L; 172 bb1.putLong(l1); 173 bb1.putShort((short) 2); 174 byte[] b = Bytes.toBytes(l2); 175 bb1.put(b, 0, 1); 176 bb2.put(b, 1, 7); 177 bb2.putLong(l3); 178 ByteBuff multi = new MultiByteBuff(bb1, bb2); 179 assertEquals(4, multi.getInt()); 180 assertEquals(l1, multi.getLong()); 181 multi.mark(); 182 assertEquals((short) 2, multi.getShort()); 183 multi.reset(); 184 assertEquals((short) 2, multi.getShort()); 185 multi.mark(); 186 assertEquals(l2, multi.getLong()); 187 multi.reset(); 188 assertEquals(l2, multi.getLong()); 189 multi.mark(); 190 assertEquals(l3, multi.getLong()); 191 multi.reset(); 192 assertEquals(l3, multi.getLong()); 193 // Try absolute gets with mark and reset 194 multi.mark(); 195 assertEquals(l2, multi.getLong(14)); 196 multi.reset(); 197 assertEquals(l3, multi.getLong(22)); 198 // Just reset to see what happens 199 multi.reset(); 200 assertEquals(l2, multi.getLong(14)); 201 multi.mark(); 202 assertEquals(l3, multi.getLong(22)); 203 multi.reset(); 204 } 205 206 @Test 207 public void testSkipNBytes() { 208 ByteBuffer bb1 = ByteBuffer.allocate(15); 209 ByteBuffer bb2 = ByteBuffer.allocate(15); 210 bb1.putInt(4); 211 long l1 = 45L, l2 = 100L, l3 = 12345L; 212 bb1.putLong(l1); 213 bb1.putShort((short) 2); 214 byte[] b = Bytes.toBytes(l2); 215 bb1.put(b, 0, 1); 216 bb2.put(b, 1, 7); 217 bb2.putLong(l3); 218 MultiByteBuff multi = new MultiByteBuff(bb1, bb2); 219 assertEquals(4, multi.getInt()); 220 assertEquals(l1, multi.getLong()); 221 multi.skip(10); 222 assertEquals(l3, multi.getLong()); 223 } 224 225 @Test 226 public void testMoveBack() { 227 ByteBuffer bb1 = ByteBuffer.allocate(15); 228 ByteBuffer bb2 = ByteBuffer.allocate(15); 229 bb1.putInt(4); 230 long l1 = 45L, l2 = 100L, l3 = 12345L; 231 bb1.putLong(l1); 232 bb1.putShort((short) 2); 233 byte[] b = Bytes.toBytes(l2); 234 bb1.put(b, 0, 1); 235 bb2.put(b, 1, 7); 236 bb2.putLong(l3); 237 MultiByteBuff multi = new MultiByteBuff(bb1, bb2); 238 assertEquals(4, multi.getInt()); 239 assertEquals(l1, multi.getLong()); 240 multi.skip(10); 241 multi.moveBack(4); 242 multi.moveBack(6); 243 multi.moveBack(8); 244 assertEquals(l1, multi.getLong()); 245 } 246 247 @Test 248 public void testSubBuffer() { 249 ByteBuffer bb1 = ByteBuffer.allocateDirect(10); 250 ByteBuffer bb2 = ByteBuffer.allocateDirect(10); 251 MultiByteBuff multi = new MultiByteBuff(bb1, bb2); 252 long l1 = 1234L, l2 = 100L; 253 multi.putLong(l1); 254 multi.putLong(l2); 255 multi.rewind(); 256 ByteBuffer sub = multi.asSubByteBuffer(Bytes.SIZEOF_LONG); 257 assertEquals(bb1, sub); 258 assertEquals(l1, ByteBufferUtils.toLong(sub, sub.position())); 259 multi.skip(Bytes.SIZEOF_LONG); 260 sub = multi.asSubByteBuffer(Bytes.SIZEOF_LONG); 261 assertNotEquals(bb1, sub); 262 assertNotEquals(bb2, sub); 263 assertEquals(l2, ByteBufferUtils.toLong(sub, sub.position())); 264 multi.rewind(); 265 ObjectIntPair<ByteBuffer> p = new ObjectIntPair<>(); 266 multi.asSubByteBuffer(8, Bytes.SIZEOF_LONG, p); 267 assertNotEquals(bb1, p.getFirst()); 268 assertNotEquals(bb2, p.getFirst()); 269 assertEquals(0, p.getSecond()); 270 assertEquals(l2, ByteBufferUtils.toLong(sub, p.getSecond())); 271 } 272 273 @Test 274 public void testSliceDuplicateMethods() throws Exception { 275 ByteBuffer bb1 = ByteBuffer.allocateDirect(10); 276 ByteBuffer bb2 = ByteBuffer.allocateDirect(15); 277 MultiByteBuff multi = new MultiByteBuff(bb1, bb2); 278 long l1 = 1234L, l2 = 100L; 279 multi.put((byte) 2); 280 multi.putLong(l1); 281 multi.putLong(l2); 282 multi.putInt(45); 283 multi.position(1); 284 multi.limit(multi.position() + (2 * Bytes.SIZEOF_LONG)); 285 ByteBuff sliced = multi.slice(); 286 assertEquals(0, sliced.position()); 287 assertEquals((2 * Bytes.SIZEOF_LONG), sliced.limit()); 288 assertEquals(l1, sliced.getLong()); 289 assertEquals(l2, sliced.getLong()); 290 ByteBuff dup = multi.duplicate(); 291 assertEquals(1, dup.position()); 292 assertEquals(dup.position() + (2 * Bytes.SIZEOF_LONG), dup.limit()); 293 assertEquals(l1, dup.getLong()); 294 assertEquals(l2, dup.getLong()); 295 } 296 297 @Test 298 public void testGetWithPosOnMultiBuffers() throws IOException { 299 byte[] b = new byte[4]; 300 byte[] b1 = new byte[4]; 301 ByteBuffer bb1 = ByteBuffer.wrap(b); 302 ByteBuffer bb2 = ByteBuffer.wrap(b1); 303 MultiByteBuff mbb1 = new MultiByteBuff(bb1, bb2); 304 mbb1.position(2); 305 mbb1.putInt(4); 306 int res = mbb1.getInt(2); 307 byte[] bres = new byte[4]; 308 bres[0] = mbb1.get(2); 309 bres[1] = mbb1.get(3); 310 bres[2] = mbb1.get(4); 311 bres[3] = mbb1.get(5); 312 int expected = Bytes.toInt(bres); 313 assertEquals(expected, res); 314 } 315 316 @Test 317 public void testGetIntStrictlyForwardWithPosOnMultiBuffers() throws IOException { 318 byte[] b = new byte[4]; 319 byte[] b1 = new byte[8]; 320 ByteBuffer bb1 = ByteBuffer.wrap(b); 321 ByteBuffer bb2 = ByteBuffer.wrap(b1); 322 MultiByteBuff mbb1 = new MultiByteBuff(bb1, bb2); 323 mbb1.position(2); 324 mbb1.putInt(4); 325 mbb1.position(7); 326 mbb1.put((byte) 2); 327 mbb1.putInt(3); 328 mbb1.rewind(); 329 mbb1.getIntAfterPosition(4); 330 byte res = mbb1.get(7); 331 assertEquals((byte) 2, res); 332 mbb1.position(7); 333 int intRes = mbb1.getIntAfterPosition(1); 334 assertEquals(3, intRes); 335 } 336 337 @Test 338 public void testPositonalCopyToByteArray() throws Exception { 339 byte[] b = new byte[4]; 340 byte[] b1 = new byte[8]; 341 ByteBuffer bb1 = ByteBuffer.wrap(b); 342 ByteBuffer bb2 = ByteBuffer.wrap(b1); 343 MultiByteBuff mbb1 = new MultiByteBuff(bb1, bb2); 344 mbb1.position(2); 345 mbb1.putInt(4); 346 mbb1.position(7); 347 mbb1.put((byte) 2); 348 mbb1.putInt(3); 349 byte[] dst = new byte[4]; 350 mbb1.get(2, dst, 0, 4); 351 assertEquals(4, Bytes.toInt(dst)); 352 assertEquals(12, mbb1.position()); 353 mbb1.position(1); 354 dst = new byte[4]; 355 mbb1.get(8, dst, 0, 4); 356 assertEquals(3, Bytes.toInt(dst)); 357 assertEquals(1, mbb1.position()); 358 mbb1.position(12); 359 dst = new byte[1]; 360 mbb1.get(7, dst, 0, 1); 361 assertEquals(2, dst[0]); 362 assertEquals(12, mbb1.position()); 363 } 364 365 @Test 366 public void testToBytes() throws Exception { 367 byte[] b = new byte[4]; 368 byte[] b1 = new byte[8]; 369 for (int i = 0; i < b.length; i++) { 370 b[i] = (byte) i; 371 } 372 for (int i = 0; i < b1.length; i++) { 373 b1[i] = (byte) (b1.length + i); 374 } 375 ByteBuffer bb1 = ByteBuffer.wrap(b); 376 ByteBuffer bb2 = ByteBuffer.wrap(b1); 377 MultiByteBuff mbb1 = new MultiByteBuff(bb1, bb2); 378 379 // Test 1 Offset hitting exclusive second element 380 byte[] actual = mbb1.toBytes(6, 4); 381 assertTrue(Bytes.equals(actual, 0, actual.length, b1, 2, 4)); 382 // Test 2 offset hitting exclusive second element 383 // but continuing to the end of the second one 384 actual = mbb1.toBytes(5, 7); 385 assertTrue(Bytes.equals(actual, 0, actual.length, b1, 1, 7)); 386 // Test 3 with offset hitting in first element, 387 // continuing to next 388 actual = mbb1.toBytes(2, 7); 389 byte[] expected = new byte[7]; 390 System.arraycopy(b, 2, expected, 0, 2); 391 System.arraycopy(b1, 0, expected, 2, 5); 392 assertTrue(Bytes.equals(actual, expected)); 393 // Test 4 hitting only in first exclusively 394 actual = mbb1.toBytes(1, 3); 395 assertTrue(Bytes.equals(actual, 0, actual.length, b, 1, 3)); 396 } 397 398 @Test 399 public void testHasRemaining() { 400 ByteBuffer b1 = ByteBuffer.allocate(8); 401 ByteBuffer b2 = ByteBuffer.allocate(8); 402 ByteBuffer b3 = ByteBuffer.allocate(8); 403 MultiByteBuff mbb1 = new MultiByteBuff(b1, b2, b3); 404 assertTrue(mbb1.hasRemaining()); 405 mbb1.limit(20); // Limit in mid of last of BB 406 mbb1.position(15); 407 mbb1.get();// We are at the end of second BB 408 assertTrue(mbb1.hasRemaining()); 409 mbb1.position(20); 410 assertFalse(mbb1.hasRemaining()); 411 mbb1.limit(12); // Limit in mid of second BB 412 mbb1.position(11); 413 assertTrue(mbb1.hasRemaining()); 414 mbb1.get(); // Now we have reached the limit 415 assertFalse(mbb1.hasRemaining()); 416 mbb1.limit(16);// Limit at begin of the last BB 417 mbb1.position(15); 418 assertTrue(mbb1.hasRemaining()); 419 mbb1.get(); // Now we have reached the limit 420 assertFalse(mbb1.hasRemaining()); 421 } 422 423 @Test 424 public void testGetPrimitivesWithSmallIndividualBBs() { 425 short s = 45; 426 int i = 2345; 427 long l = 75681526L; 428 ByteBuffer bb = ByteBuffer.allocate(14); 429 bb.putShort(s); 430 bb.putInt(i); 431 bb.putLong(l); 432 433 ByteBuffer bb1 = ((ByteBuffer) bb.duplicate().position(0).limit(1)).slice(); 434 ByteBuffer bb2 = ((ByteBuffer) bb.duplicate().position(1).limit(3)).slice(); 435 ByteBuffer bb3 = ((ByteBuffer) bb.duplicate().position(3).limit(5)).slice(); 436 ByteBuffer bb4 = ((ByteBuffer) bb.duplicate().position(5).limit(11)).slice(); 437 ByteBuffer bb5 = ((ByteBuffer) bb.duplicate().position(11).limit(12)).slice(); 438 ByteBuffer bb6 = ((ByteBuffer) bb.duplicate().position(12).limit(14)).slice(); 439 MultiByteBuff mbb = new MultiByteBuff(bb1, bb2, bb3, bb4, bb5, bb6); 440 assertEquals(s, mbb.getShortAfterPosition(0)); 441 assertEquals(i, mbb.getIntAfterPosition(2)); 442 assertEquals(l, mbb.getLongAfterPosition(6)); 443 444 assertEquals(s, mbb.getShort(0)); 445 assertEquals(i, mbb.getInt(2)); 446 assertEquals(l, mbb.getLong(6)); 447 448 mbb.position(0); 449 assertEquals(s, mbb.getShort()); 450 assertEquals(i, mbb.getInt()); 451 assertEquals(l, mbb.getLong()); 452 } 453 454 @Test 455 public void testGetByteBufferWithOffsetAndPos() { 456 byte[] a = Bytes.toBytes("abcd"); 457 byte[] b = Bytes.toBytes("efghijkl"); 458 ByteBuffer aa = ByteBuffer.wrap(a); 459 ByteBuffer bb = ByteBuffer.wrap(b); 460 MultiByteBuff mbb = new MultiByteBuff(aa, bb); 461 ByteBuffer out = ByteBuffer.allocate(12); 462 mbb.get(out, 0, 1); 463 assertEquals(out.position(), 1); 464 assertTrue(Bytes.equals(Bytes.toBytes("a"), 0, 1, out.array(), 0, 1)); 465 466 mbb.get(out, 1, 4); 467 assertEquals(out.position(), 5); 468 assertTrue(Bytes.equals(Bytes.toBytes("abcde"), 0, 5, out.array(), 0, 5)); 469 470 mbb.get(out, 10, 1); 471 assertEquals(out.position(), 6); 472 assertTrue(Bytes.equals(Bytes.toBytes("abcdek"), 0, 6, out.array(), 0, 6)); 473 474 mbb.get(out, 0, 6); 475 assertEquals(out.position(), 12); 476 assertTrue(Bytes.equals(Bytes.toBytes("abcdekabcdef"), 0, 12, out.array(), 0, 12)); 477 } 478 479 @Test 480 public void testPositionalPutByteBuff() throws Exception { 481 ByteBuffer bb1 = ByteBuffer.allocate(100); 482 ByteBuffer bb2 = ByteBuffer.allocate(100); 483 MultiByteBuff srcMultiByteBuff = new MultiByteBuff(bb1, bb2); 484 for (int i = 0; i < 25; i++) { 485 srcMultiByteBuff.putLong(i * 8L); 486 } 487 // Test MultiByteBuff To MultiByteBuff 488 doTestPositionalPutByteBuff(srcMultiByteBuff); 489 490 ByteBuffer bb3 = ByteBuffer.allocate(200); 491 SingleByteBuff srcSingleByteBuff = new SingleByteBuff(bb3); 492 for (int i = 0; i < 25; i++) { 493 srcSingleByteBuff.putLong(i * 8L); 494 } 495 // Test SingleByteBuff To MultiByteBuff 496 doTestPositionalPutByteBuff(srcSingleByteBuff); 497 } 498 499 private void doTestPositionalPutByteBuff(ByteBuff srcByteBuff) throws Exception { 500 ByteBuffer bb3 = ByteBuffer.allocate(50); 501 ByteBuffer bb4 = ByteBuffer.allocate(50); 502 ByteBuffer bb5 = ByteBuffer.allocate(50); 503 ByteBuffer bb6 = ByteBuffer.allocate(50); 504 MultiByteBuff destMultiByteBuff = new MultiByteBuff(bb3, bb4, bb5, bb6); 505 506 // full copy 507 destMultiByteBuff.put(0, srcByteBuff, 0, 200); 508 int compareTo = ByteBuff.compareTo(srcByteBuff, 0, 200, destMultiByteBuff, 0, 200); 509 assertTrue(compareTo == 0); 510 511 // Test src to dest first ByteBuffer 512 destMultiByteBuff.put(0, srcByteBuff, 32, 63); 513 compareTo = ByteBuff.compareTo(srcByteBuff, 32, 63, destMultiByteBuff, 0, 63); 514 assertTrue(compareTo == 0); 515 516 // Test src to dest first and second ByteBuffer 517 destMultiByteBuff.put(0, srcByteBuff, 0, 63); 518 compareTo = ByteBuff.compareTo(srcByteBuff, 0, 63, destMultiByteBuff, 0, 63); 519 assertTrue(compareTo == 0); 520 521 // Test src to dest third ByteBuffer 522 destMultiByteBuff.put(100, srcByteBuff, 100, 50); 523 compareTo = ByteBuff.compareTo(srcByteBuff, 100, 50, destMultiByteBuff, 100, 50); 524 assertTrue(compareTo == 0); 525 526 // Test src to dest first,second and third ByteBuffer 527 destMultiByteBuff.put(48, srcByteBuff, 32, 63); 528 compareTo = ByteBuff.compareTo(srcByteBuff, 32, 63, destMultiByteBuff, 48, 63); 529 assertTrue(compareTo == 0); 530 531 // Test src to dest first,second,third and fourth ByteBuffer 532 destMultiByteBuff.put(48, srcByteBuff, 32, 120); 533 compareTo = ByteBuff.compareTo(srcByteBuff, 32, 120, destMultiByteBuff, 48, 120); 534 assertTrue(compareTo == 0); 535 536 // Test src to dest first and second ByteBuffer 537 destMultiByteBuff.put(0, srcByteBuff, 132, 63); 538 compareTo = ByteBuff.compareTo(srcByteBuff, 132, 63, destMultiByteBuff, 0, 63); 539 assertTrue(compareTo == 0); 540 541 // Test src to dest second,third and fourth ByteBuffer 542 destMultiByteBuff.put(95, srcByteBuff, 132, 67); 543 compareTo = ByteBuff.compareTo(srcByteBuff, 132, 67, destMultiByteBuff, 95, 67); 544 assertTrue(compareTo == 0); 545 546 // Test src to dest fourth ByteBuffer 547 destMultiByteBuff.put(162, srcByteBuff, 132, 24); 548 compareTo = ByteBuff.compareTo(srcByteBuff, 132, 24, destMultiByteBuff, 162, 24); 549 assertTrue(compareTo == 0); 550 551 // Test src BufferUnderflowException 552 try { 553 destMultiByteBuff.put(0, srcByteBuff, 0, 300); 554 fail(); 555 } catch (BufferUnderflowException e) { 556 assertTrue(e != null); 557 } 558 559 try { 560 destMultiByteBuff.put(95, srcByteBuff, 132, 89); 561 fail(); 562 } catch (BufferUnderflowException e) { 563 assertTrue(e != null); 564 } 565 566 // Test dest BufferOverflowException 567 try { 568 destMultiByteBuff.put(100, srcByteBuff, 0, 101); 569 fail(); 570 } catch (BufferOverflowException e) { 571 assertTrue(e != null); 572 } 573 574 try { 575 destMultiByteBuff.put(151, srcByteBuff, 132, 68); 576 fail(); 577 } catch (BufferOverflowException e) { 578 assertTrue(e != null); 579 } 580 581 destMultiByteBuff = new MultiByteBuff(bb3, bb4); 582 try { 583 destMultiByteBuff.put(0, srcByteBuff, 0, 101); 584 fail(); 585 } catch (BufferOverflowException e) { 586 assertTrue(e != null); 587 } 588 } 589 590 @Test 591 public void testPositionalPutByte() throws Exception { 592 ByteBuffer bb1 = ByteBuffer.allocate(50); 593 ByteBuffer bb2 = ByteBuffer.allocate(50); 594 ByteBuffer bb3 = ByteBuffer.allocate(50); 595 ByteBuffer bb4 = ByteBuffer.allocate(50); 596 MultiByteBuff srcMultiByteBuff = new MultiByteBuff(bb1, bb2, bb3, bb4); 597 for (int i = 1; i <= 200; i++) { 598 srcMultiByteBuff.put((byte) 0xff); 599 } 600 601 srcMultiByteBuff.put(20, (byte) 0); 602 byte val = srcMultiByteBuff.get(20); 603 assertTrue(val == 0); 604 605 srcMultiByteBuff.put(50, (byte) 0); 606 val = srcMultiByteBuff.get(50); 607 assertTrue(val == 0); 608 609 srcMultiByteBuff.put(80, (byte) 0); 610 val = srcMultiByteBuff.get(80); 611 assertTrue(val == 0); 612 613 srcMultiByteBuff.put(100, (byte) 0); 614 val = srcMultiByteBuff.get(100); 615 assertTrue(val == 0); 616 617 srcMultiByteBuff.put(121, (byte) 0); 618 val = srcMultiByteBuff.get(121); 619 assertTrue(val == 0); 620 621 srcMultiByteBuff.put(150, (byte) 0); 622 val = srcMultiByteBuff.get(150); 623 assertTrue(val == 0); 624 625 srcMultiByteBuff.put(180, (byte) 0); 626 val = srcMultiByteBuff.get(180); 627 assertTrue(val == 0); 628 629 try { 630 srcMultiByteBuff.put(200, (byte) 0); 631 fail(); 632 } catch (IndexOutOfBoundsException e) { 633 assertTrue(e != null); 634 } 635 636 try { 637 srcMultiByteBuff.put(260, (byte) 0); 638 fail(); 639 } catch (IndexOutOfBoundsException e) { 640 assertTrue(e != null); 641 } 642 } 643}