1/* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* @test 25 * @summary Binary data and view tests for byte buffers 26 * @bug 8159257 27 * @run testng ByteBufferViews 28 */ 29 30import org.testng.annotations.DataProvider; 31import org.testng.annotations.Test; 32 33import java.nio.Buffer; 34import java.nio.ByteBuffer; 35import java.nio.ByteOrder; 36import java.nio.CharBuffer; 37import java.nio.DoubleBuffer; 38import java.nio.FloatBuffer; 39import java.nio.IntBuffer; 40import java.nio.LongBuffer; 41import java.nio.ShortBuffer; 42import java.util.List; 43import java.util.Map; 44import java.util.function.Function; 45import java.util.function.IntFunction; 46import java.util.function.IntUnaryOperator; 47import java.util.function.UnaryOperator; 48import java.util.stream.Collectors; 49 50import static org.testng.Assert.*; 51 52public class ByteBufferViews { 53 static final int SIZE = 32; 54 55 // List of buffer allocator functions 56 static final List<Map.Entry<String, IntFunction<ByteBuffer>>> BYTE_BUFFER_ALLOCATE_FUNCTIONS = List.of( 57 // Heap 58 Map.entry("ByteBuffer.allocate(ba)", 59 size -> ByteBuffer.allocate(size)), 60 // Aligned 61 Map.entry("ByteBuffer.allocate(size).position(8)", 62 size -> ByteBuffer.allocate(size).position(8)), 63 Map.entry("ByteBuffer.allocate(size).position(8).slice()", 64 size -> ByteBuffer.allocate(size).position(8).slice()), 65 Map.entry("ByteBuffer.allocate(size).position(8).slice().duplicate()", 66 size -> ByteBuffer.allocate(size).position(8).slice().duplicate()), 67 // Unaligned 68 Map.entry("ByteBuffer.allocate(size).position(1)", 69 size -> ByteBuffer.allocate(size).position(1)), 70 Map.entry("ByteBuffer.allocate(size).position(1).slice()", 71 size -> ByteBuffer.allocate(size).position(1).slice()), 72 Map.entry("ByteBuffer.allocate(size).position(1).slice().duplicate()", 73 size -> ByteBuffer.allocate(size).position(1).slice().duplicate()), 74 75 // Off-heap 76 Map.entry("ByteBuffer.allocateDirect(size)", 77 size -> ByteBuffer.allocateDirect(size)), 78 // Aligned 79 Map.entry("ByteBuffer.allocateDirect(size).position(8)", 80 size -> ByteBuffer.allocateDirect(size).position(8)), 81 Map.entry("ByteBuffer.allocateDirect(size).position(8).slice()", 82 size -> ByteBuffer.allocateDirect(size).position(8).slice()), 83 Map.entry("ByteBuffer.allocateDirect(size).position(8).slice().duplicate()", 84 size -> ByteBuffer.allocateDirect(size).position(8).slice().duplicate()), 85 // Unaligned 86 Map.entry("ByteBuffer.allocateDirect(size).position(1)", 87 size -> ByteBuffer.allocateDirect(size).position(1)), 88 Map.entry("ByteBuffer.allocateDirect(size).position(1).slice()", 89 size -> ByteBuffer.allocateDirect(size).position(1).slice()), 90 Map.entry("ByteBuffer.allocateDirect(size).position(1).slice().duplicate()", 91 size -> ByteBuffer.allocateDirect(size).position(1).slice().duplicate()) 92 ); 93 94 // List of buffer byte order functions 95 static final List<Map.Entry<String, UnaryOperator<ByteBuffer>>> BYTE_BUFFER_ORDER_FUNCTIONS = List.of( 96 Map.entry("order(ByteOrder.BIG_ENDIAN)", 97 (ByteBuffer bb) -> bb.order(ByteOrder.BIG_ENDIAN)), 98 Map.entry("order(ByteOrder.LITTLE_ENDIAN)", 99 (ByteBuffer bb) -> bb.order(ByteOrder.LITTLE_ENDIAN)) 100 ); 101 102 // Produce a composition of allocation and byte order buffer functions 103 static List<Map.Entry<String, IntFunction<ByteBuffer>>> composeBufferFunctions( 104 List<Map.Entry<String, IntFunction<ByteBuffer>>> af, 105 List<Map.Entry<String, UnaryOperator<ByteBuffer>>> of) { 106 return af.stream().flatMap(afe -> of.stream(). 107 map(ofe -> { 108 String s = afe.getKey() + "." + ofe.getKey(); 109 IntFunction<ByteBuffer> f = size -> ofe.getValue(). 110 apply(afe.getValue().apply(size)); 111 return Map.entry(s, f); 112 }) 113 ).collect(Collectors.toList()); 114 } 115 116 // List of buffer allocator functions to test 117 static final List<Map.Entry<String, IntFunction<ByteBuffer>>> BYTE_BUFFER_FUNCTIONS = 118 composeBufferFunctions(BYTE_BUFFER_ALLOCATE_FUNCTIONS, BYTE_BUFFER_ORDER_FUNCTIONS); 119 120 // Creates a cross product of test arguments for 121 // buffer allocator functions and buffer view functions 122 static Object[][] product(List<? extends Map.Entry<String, ?>> la, 123 List<? extends Map.Entry<String, ?>> lb) { 124 return la.stream().flatMap(lae -> lb.stream(). 125 map(lbe -> List.of( 126 lae.getKey() + " -> " + lbe.getKey(), 127 lae.getValue(), 128 lbe.getValue()).toArray() 129 )).toArray(Object[][]::new); 130 } 131 132 static void assertValues(int i, Object bValue, Object bbValue, ByteBuffer bb) { 133 if (!bValue.equals(bbValue)) { 134 fail(String.format("Values %s and %s differ at index %d for %s", 135 bValue, bbValue, i, bb)); 136 } 137 } 138 139 static void assertValues(int i, Object bbValue, Object bvValue, ByteBuffer bb, Buffer bv) { 140 if (!bbValue.equals(bvValue)) { 141 fail(String.format("Values %s and %s differ at index %d for %s and %s", 142 bbValue, bvValue, i, bb, bv)); 143 } 144 } 145 146 static ByteBuffer allocate(IntFunction<ByteBuffer> f) { 147 return allocate(f, i -> i); 148 } 149 150 static ByteBuffer allocate(IntFunction<ByteBuffer> f, IntUnaryOperator o) { 151 return fill(f.apply(SIZE), o); 152 } 153 154 static ByteBuffer fill(ByteBuffer bb, IntUnaryOperator o) { 155 for (int i = 0; i < bb.limit(); i++) { 156 bb.put(i, (byte) o.applyAsInt(i)); 157 } 158 return bb; 159 } 160 161 162 @DataProvider 163 public static Object[][] shortViewProvider() { 164 List<Map.Entry<String, Function<ByteBuffer, ShortBuffer>>> bfs = List.of( 165 Map.entry("bb.asShortBuffer()", 166 bb -> bb.asShortBuffer()), 167 Map.entry("bb.asShortBuffer().slice()", 168 bb -> bb.asShortBuffer().slice()), 169 Map.entry("bb.asShortBuffer().slice().duplicate()", 170 bb -> bb.asShortBuffer().slice().duplicate()) 171 ); 172 173 return product(BYTE_BUFFER_FUNCTIONS, bfs); 174 } 175 176 @Test(dataProvider = "shortViewProvider") 177 public void testShortGet(String desc, IntFunction<ByteBuffer> fbb, 178 Function<ByteBuffer, ShortBuffer> fbi) { 179 ByteBuffer bb = allocate(fbb); 180 ShortBuffer vb = fbi.apply(bb); 181 int o = bb.position(); 182 183 for (int i = 0; i < vb.limit(); i++) { 184 short fromBytes = getShortFromBytes(bb, o + i * 2); 185 short fromMethodView = bb.getShort(o + i * 2); 186 assertValues(i, fromBytes, fromMethodView, bb); 187 188 short fromBufferView = vb.get(i); 189 assertValues(i, fromMethodView, fromBufferView, bb, vb); 190 } 191 192 for (int i = 0; i < vb.limit(); i++) { 193 short v = getShortFromBytes(bb, o + i * 2); 194 short a = bb.getShort(); 195 assertValues(i, v, a, bb); 196 197 short b = vb.get(); 198 assertValues(i, a, b, bb, vb); 199 } 200 201 } 202 203 @Test(dataProvider = "shortViewProvider") 204 public void testShortPut(String desc, IntFunction<ByteBuffer> fbb, 205 Function<ByteBuffer, ShortBuffer> fbi) { 206 ByteBuffer bbfilled = allocate(fbb); 207 ByteBuffer bb = allocate(fbb, i -> 0); 208 ShortBuffer vb = fbi.apply(bb); 209 int o = bb.position(); 210 211 for (int i = 0; i < vb.limit(); i++) { 212 short fromFilled = bbfilled.getShort(o + i * 2); 213 214 vb.put(i, fromFilled); 215 short fromMethodView = bb.getShort(o + i * 2); 216 assertValues(i, fromFilled, fromMethodView, bb, vb); 217 } 218 219 for (int i = 0; i < vb.limit(); i++) { 220 short fromFilled = bbfilled.getShort(o + i * 2); 221 222 vb.put(fromFilled); 223 short fromMethodView = bb.getShort(); 224 assertValues(i, fromFilled, fromMethodView, bb, vb); 225 } 226 227 228 fill(bb, i -> 0); 229 bb.clear().position(o); 230 vb.clear(); 231 232 for (int i = 0; i < vb.limit(); i++) { 233 short fromFilled = bbfilled.getShort(o + i * 2); 234 235 bb.putShort(o + i * 2, fromFilled); 236 short fromBufferView = vb.get(i); 237 assertValues(i, fromFilled, fromBufferView, bb, vb); 238 } 239 240 for (int i = 0; i < vb.limit(); i++) { 241 short fromFilled = bbfilled.getShort(o + i * 2); 242 243 bb.putShort(fromFilled); 244 short fromBufferView = vb.get(); 245 assertValues(i, fromFilled, fromBufferView, bb, vb); 246 } 247 } 248 249 static short getShortFromBytes(ByteBuffer bb, int i) { 250 int a = bb.get(i) & 0xFF; 251 int b = bb.get(i + 1) & 0xFF; 252 253 if (bb.order() == ByteOrder.BIG_ENDIAN) { 254 return (short) ((a << 8) | b); 255 } 256 else { 257 return (short) ((b << 8) | a); 258 } 259 } 260 261 @DataProvider 262 public static Object[][] charViewProvider() { 263 List<Map.Entry<String, Function<ByteBuffer, CharBuffer>>> bfs = List.of( 264 Map.entry("bb.asCharBuffer()", 265 bb -> bb.asCharBuffer()), 266 Map.entry("bb.asCharBuffer().slice()", 267 bb -> bb.asCharBuffer().slice()), 268 Map.entry("bb.asCharBuffer().slice().duplicate()", 269 bb -> bb.asCharBuffer().slice().duplicate()) 270 ); 271 272 return product(BYTE_BUFFER_FUNCTIONS, bfs); 273 } 274 275 @Test(dataProvider = "charViewProvider") 276 public void testCharGet(String desc, IntFunction<ByteBuffer> fbb, 277 Function<ByteBuffer, CharBuffer> fbi) { 278 ByteBuffer bb = allocate(fbb); 279 CharBuffer vb = fbi.apply(bb); 280 int o = bb.position(); 281 282 for (int i = 0; i < vb.limit(); i++) { 283 char fromBytes = getCharFromBytes(bb, o + i * 2); 284 char fromMethodView = bb.getChar(o + i * 2); 285 assertValues(i, fromBytes, fromMethodView, bb); 286 287 char fromBufferView = vb.get(i); 288 assertValues(i, fromMethodView, fromBufferView, bb, vb); 289 } 290 291 for (int i = 0; i < vb.limit(); i++) { 292 char fromBytes = getCharFromBytes(bb, o + i * 2); 293 char fromMethodView = bb.getChar(); 294 assertValues(i, fromBytes, fromMethodView, bb); 295 296 char fromBufferView = vb.get(); 297 assertValues(i, fromMethodView, fromBufferView, bb, vb); 298 } 299 300 } 301 302 @Test(dataProvider = "charViewProvider") 303 public void testCharPut(String desc, IntFunction<ByteBuffer> fbb, 304 Function<ByteBuffer, CharBuffer> fbi) { 305 ByteBuffer bbfilled = allocate(fbb); 306 ByteBuffer bb = allocate(fbb, i -> 0); 307 CharBuffer vb = fbi.apply(bb); 308 int o = bb.position(); 309 310 for (int i = 0; i < vb.limit(); i++) { 311 char fromFilled = bbfilled.getChar(o + i * 2); 312 313 vb.put(i, fromFilled); 314 char fromMethodView = bb.getChar(o + i * 2); 315 assertValues(i, fromFilled, fromMethodView, bb, vb); 316 } 317 318 for (int i = 0; i < vb.limit(); i++) { 319 char fromFilled = bbfilled.getChar(o + i * 2); 320 321 vb.put(fromFilled); 322 char fromMethodView = bb.getChar(); 323 assertValues(i, fromFilled, fromMethodView, bb, vb); 324 } 325 326 327 fill(bb, i -> 0); 328 bb.clear().position(o); 329 vb.clear(); 330 331 for (int i = 0; i < vb.limit(); i++) { 332 char fromFilled = bbfilled.getChar(o + i * 2); 333 334 bb.putChar(o + i * 2, fromFilled); 335 char fromBufferView = vb.get(i); 336 assertValues(i, fromFilled, fromBufferView, bb, vb); 337 } 338 339 for (int i = 0; i < vb.limit(); i++) { 340 char fromFilled = bbfilled.getChar(o + i * 2); 341 342 bb.putChar(fromFilled); 343 char fromBufferView = vb.get(); 344 assertValues(i, fromFilled, fromBufferView, bb, vb); 345 } 346 } 347 348 static char getCharFromBytes(ByteBuffer bb, int i) { 349 return (char) getShortFromBytes(bb, i); 350 } 351 352 353 @DataProvider 354 public static Object[][] intViewProvider() { 355 List<Map.Entry<String, Function<ByteBuffer, IntBuffer>>> bfs = List.of( 356 Map.entry("bb.asIntBuffer()", 357 bb -> bb.asIntBuffer()), 358 Map.entry("bb.asIntBuffer().slice()", 359 bb -> bb.asIntBuffer().slice()), 360 Map.entry("bb.asIntBuffer().slice().duplicate()", 361 bb -> bb.asIntBuffer().slice().duplicate()) 362 ); 363 364 return product(BYTE_BUFFER_FUNCTIONS, bfs); 365 } 366 367 @Test(dataProvider = "intViewProvider") 368 public void testIntGet(String desc, IntFunction<ByteBuffer> fbb, 369 Function<ByteBuffer, IntBuffer> fbi) { 370 ByteBuffer bb = allocate(fbb); 371 IntBuffer vb = fbi.apply(bb); 372 int o = bb.position(); 373 374 for (int i = 0; i < vb.limit(); i++) { 375 int fromBytes = getIntFromBytes(bb, o + i * 4); 376 int fromMethodView = bb.getInt(o + i * 4); 377 assertValues(i, fromBytes, fromMethodView, bb); 378 379 int fromBufferView = vb.get(i); 380 assertValues(i, fromMethodView, fromBufferView, bb, vb); 381 } 382 383 for (int i = 0; i < vb.limit(); i++) { 384 int v = getIntFromBytes(bb, o + i * 4); 385 int a = bb.getInt(); 386 assertValues(i, v, a, bb); 387 388 int b = vb.get(); 389 assertValues(i, a, b, bb, vb); 390 } 391 392 } 393 394 @Test(dataProvider = "intViewProvider") 395 public void testIntPut(String desc, IntFunction<ByteBuffer> fbb, 396 Function<ByteBuffer, IntBuffer> fbi) { 397 ByteBuffer bbfilled = allocate(fbb); 398 ByteBuffer bb = allocate(fbb, i -> 0); 399 IntBuffer vb = fbi.apply(bb); 400 int o = bb.position(); 401 402 for (int i = 0; i < vb.limit(); i++) { 403 int fromFilled = bbfilled.getInt(o + i * 4); 404 405 vb.put(i, fromFilled); 406 int fromMethodView = bb.getInt(o + i * 4); 407 assertValues(i, fromFilled, fromMethodView, bb, vb); 408 } 409 410 for (int i = 0; i < vb.limit(); i++) { 411 int fromFilled = bbfilled.getInt(o + i * 4); 412 413 vb.put(fromFilled); 414 int fromMethodView = bb.getInt(); 415 assertValues(i, fromFilled, fromMethodView, bb, vb); 416 } 417 418 419 fill(bb, i -> 0); 420 bb.clear().position(o); 421 vb.clear(); 422 423 for (int i = 0; i < vb.limit(); i++) { 424 int fromFilled = bbfilled.getInt(o + i * 4); 425 426 bb.putInt(o + i * 4, fromFilled); 427 int fromBufferView = vb.get(i); 428 assertValues(i, fromFilled, fromBufferView, bb, vb); 429 } 430 431 for (int i = 0; i < vb.limit(); i++) { 432 int fromFilled = bbfilled.getInt(o + i * 4); 433 434 bb.putInt(fromFilled); 435 int fromBufferView = vb.get(); 436 assertValues(i, fromFilled, fromBufferView, bb, vb); 437 } 438 } 439 440 static int getIntFromBytes(ByteBuffer bb, int i) { 441 int a = bb.get(i) & 0xFF; 442 int b = bb.get(i + 1) & 0xFF; 443 int c = bb.get(i + 2) & 0xFF; 444 int d = bb.get(i + 3) & 0xFF; 445 446 if (bb.order() == ByteOrder.BIG_ENDIAN) { 447 return ((a << 24) | (b << 16) | (c << 8) | d); 448 } 449 else { 450 return ((d << 24) | (c << 16) | (b << 8) | a); 451 } 452 } 453 454 455 @DataProvider 456 public static Object[][] longViewProvider() { 457 List<Map.Entry<String, Function<ByteBuffer, LongBuffer>>> bfs = List.of( 458 Map.entry("bb.asLongBuffer()", 459 bb -> bb.asLongBuffer()), 460 Map.entry("bb.asLongBuffer().slice()", 461 bb -> bb.asLongBuffer().slice()), 462 Map.entry("bb.asLongBuffer().slice().duplicate()", 463 bb -> bb.asLongBuffer().slice().duplicate()) 464 ); 465 466 return product(BYTE_BUFFER_FUNCTIONS, bfs); 467 } 468 469 @Test(dataProvider = "longViewProvider") 470 public void testLongGet(String desc, IntFunction<ByteBuffer> fbb, 471 Function<ByteBuffer, LongBuffer> fbi) { 472 ByteBuffer bb = allocate(fbb); 473 LongBuffer vb = fbi.apply(bb); 474 int o = bb.position(); 475 476 for (int i = 0; i < vb.limit(); i++) { 477 long fromBytes = getLongFromBytes(bb, o + i * 8); 478 long fromMethodView = bb.getLong(o + i * 8); 479 assertValues(i, fromBytes, fromMethodView, bb); 480 481 long fromBufferView = vb.get(i); 482 assertValues(i, fromMethodView, fromBufferView, bb, vb); 483 } 484 485 for (int i = 0; i < vb.limit(); i++) { 486 long v = getLongFromBytes(bb, o + i * 8); 487 long a = bb.getLong(); 488 assertValues(i, v, a, bb); 489 490 long b = vb.get(); 491 assertValues(i, a, b, bb, vb); 492 } 493 494 } 495 496 @Test(dataProvider = "longViewProvider") 497 public void testLongPut(String desc, IntFunction<ByteBuffer> fbb, 498 Function<ByteBuffer, LongBuffer> fbi) { 499 ByteBuffer bbfilled = allocate(fbb); 500 ByteBuffer bb = allocate(fbb, i -> 0); 501 LongBuffer vb = fbi.apply(bb); 502 int o = bb.position(); 503 504 for (int i = 0; i < vb.limit(); i++) { 505 long fromFilled = bbfilled.getLong(o + i * 8); 506 507 vb.put(i, fromFilled); 508 long fromMethodView = bb.getLong(o + i * 8); 509 assertValues(i, fromFilled, fromMethodView, bb, vb); 510 } 511 512 for (int i = 0; i < vb.limit(); i++) { 513 long fromFilled = bbfilled.getLong(o + i * 8); 514 515 vb.put(fromFilled); 516 long fromMethodView = bb.getLong(); 517 assertValues(i, fromFilled, fromMethodView, bb, vb); 518 } 519 520 521 fill(bb, i -> 0); 522 bb.clear().position(o); 523 vb.clear(); 524 525 for (int i = 0; i < vb.limit(); i++) { 526 long fromFilled = bbfilled.getLong(o + i * 8); 527 528 bb.putLong(o + i * 8, fromFilled); 529 long fromBufferView = vb.get(i); 530 assertValues(i, fromFilled, fromBufferView, bb, vb); 531 } 532 533 for (int i = 0; i < vb.limit(); i++) { 534 long fromFilled = bbfilled.getLong(o + i * 8); 535 536 bb.putLong(fromFilled); 537 long fromBufferView = vb.get(); 538 assertValues(i, fromFilled, fromBufferView, bb, vb); 539 } 540 } 541 542 static long getLongFromBytes(ByteBuffer bb, int i) { 543 long a = bb.get(i) & 0xFF; 544 long b = bb.get(i + 1) & 0xFF; 545 long c = bb.get(i + 2) & 0xFF; 546 long d = bb.get(i + 3) & 0xFF; 547 long e = bb.get(i + 4) & 0xFF; 548 long f = bb.get(i + 5) & 0xFF; 549 long g = bb.get(i + 6) & 0xFF; 550 long h = bb.get(i + 7) & 0xFF; 551 552 if (bb.order() == ByteOrder.BIG_ENDIAN) { 553 return ((a << 56) | (b << 48) | (c << 40) | (d << 32) | 554 (e << 24) | (f << 16) | (g << 8) | h); 555 } 556 else { 557 return ((h << 56) | (g << 48) | (f << 40) | (e << 32) | 558 (d << 24) | (c << 16) | (b << 8) | a); 559 } 560 } 561 562 563 @DataProvider 564 public static Object[][] floatViewProvider() { 565 List<Map.Entry<String, Function<ByteBuffer, FloatBuffer>>> bfs = List.of( 566 Map.entry("bb.asFloatBuffer()", 567 bb -> bb.asFloatBuffer()), 568 Map.entry("bb.asFloatBuffer().slice()", 569 bb -> bb.asFloatBuffer().slice()), 570 Map.entry("bb.asFloatBuffer().slice().duplicate()", 571 bb -> bb.asFloatBuffer().slice().duplicate()) 572 ); 573 574 return product(BYTE_BUFFER_FUNCTIONS, bfs); 575 } 576 577 @Test(dataProvider = "floatViewProvider") 578 public void testFloatGet(String desc, IntFunction<ByteBuffer> fbb, 579 Function<ByteBuffer, FloatBuffer> fbi) { 580 ByteBuffer bb = allocate(fbb); 581 FloatBuffer vb = fbi.apply(bb); 582 int o = bb.position(); 583 584 for (int i = 0; i < vb.limit(); i++) { 585 float fromBytes = getFloatFromBytes(bb, o + i * 4); 586 float fromMethodView = bb.getFloat(o + i * 4); 587 assertValues(i, fromBytes, fromMethodView, bb); 588 589 float fromBufferView = vb.get(i); 590 assertValues(i, fromMethodView, fromBufferView, bb, vb); 591 } 592 593 for (int i = 0; i < vb.limit(); i++) { 594 float v = getFloatFromBytes(bb, o + i * 4); 595 float a = bb.getFloat(); 596 assertValues(i, v, a, bb); 597 598 float b = vb.get(); 599 assertValues(i, a, b, bb, vb); 600 } 601 602 } 603 604 @Test(dataProvider = "floatViewProvider") 605 public void testFloatPut(String desc, IntFunction<ByteBuffer> fbb, 606 Function<ByteBuffer, FloatBuffer> fbi) { 607 ByteBuffer bbfilled = allocate(fbb); 608 ByteBuffer bb = allocate(fbb, i -> 0); 609 FloatBuffer vb = fbi.apply(bb); 610 int o = bb.position(); 611 612 for (int i = 0; i < vb.limit(); i++) { 613 float fromFilled = bbfilled.getFloat(o + i * 4); 614 615 vb.put(i, fromFilled); 616 float fromMethodView = bb.getFloat(o + i * 4); 617 assertValues(i, fromFilled, fromMethodView, bb, vb); 618 } 619 620 for (int i = 0; i < vb.limit(); i++) { 621 float fromFilled = bbfilled.getFloat(o + i * 4); 622 623 vb.put(fromFilled); 624 float fromMethodView = bb.getFloat(); 625 assertValues(i, fromFilled, fromMethodView, bb, vb); 626 } 627 628 629 fill(bb, i -> 0); 630 bb.clear().position(o); 631 vb.clear(); 632 633 for (int i = 0; i < vb.limit(); i++) { 634 float fromFilled = bbfilled.getFloat(o + i * 4); 635 636 bb.putFloat(o + i * 4, fromFilled); 637 float fromBufferView = vb.get(i); 638 assertValues(i, fromFilled, fromBufferView, bb, vb); 639 } 640 641 for (int i = 0; i < vb.limit(); i++) { 642 float fromFilled = bbfilled.getFloat(o + i * 4); 643 644 bb.putFloat(fromFilled); 645 float fromBufferView = vb.get(); 646 assertValues(i, fromFilled, fromBufferView, bb, vb); 647 } 648 } 649 650 static float getFloatFromBytes(ByteBuffer bb, int i) { 651 return Float.intBitsToFloat(getIntFromBytes(bb, i)); 652 } 653 654 655 656 @DataProvider 657 public static Object[][] doubleViewProvider() { 658 List<Map.Entry<String, Function<ByteBuffer, DoubleBuffer>>> bfs = List.of( 659 Map.entry("bb.asDoubleBuffer()", 660 bb -> bb.asDoubleBuffer()), 661 Map.entry("bb.asDoubleBuffer().slice()", 662 bb -> bb.asDoubleBuffer().slice()), 663 Map.entry("bb.asDoubleBuffer().slice().duplicate()", 664 bb -> bb.asDoubleBuffer().slice().duplicate()) 665 ); 666 667 return product(BYTE_BUFFER_FUNCTIONS, bfs); 668 } 669 670 @Test(dataProvider = "doubleViewProvider") 671 public void testDoubleGet(String desc, IntFunction<ByteBuffer> fbb, 672 Function<ByteBuffer, DoubleBuffer> fbi) { 673 ByteBuffer bb = allocate(fbb); 674 DoubleBuffer vb = fbi.apply(bb); 675 int o = bb.position(); 676 677 for (int i = 0; i < vb.limit(); i++) { 678 double fromBytes = getDoubleFromBytes(bb, o + i * 8); 679 double fromMethodView = bb.getDouble(o + i * 8); 680 assertValues(i, fromBytes, fromMethodView, bb); 681 682 double fromBufferView = vb.get(i); 683 assertValues(i, fromMethodView, fromBufferView, bb, vb); 684 } 685 686 for (int i = 0; i < vb.limit(); i++) { 687 double v = getDoubleFromBytes(bb, o + i * 8); 688 double a = bb.getDouble(); 689 assertValues(i, v, a, bb); 690 691 double b = vb.get(); 692 assertValues(i, a, b, bb, vb); 693 } 694 695 } 696 697 @Test(dataProvider = "doubleViewProvider") 698 public void testDoublePut(String desc, IntFunction<ByteBuffer> fbb, 699 Function<ByteBuffer, DoubleBuffer> fbi) { 700 ByteBuffer bbfilled = allocate(fbb); 701 ByteBuffer bb = allocate(fbb, i -> 0); 702 DoubleBuffer vb = fbi.apply(bb); 703 int o = bb.position(); 704 705 for (int i = 0; i < vb.limit(); i++) { 706 double fromFilled = bbfilled.getDouble(o + i * 8); 707 708 vb.put(i, fromFilled); 709 double fromMethodView = bb.getDouble(o + i * 8); 710 assertValues(i, fromFilled, fromMethodView, bb, vb); 711 } 712 713 for (int i = 0; i < vb.limit(); i++) { 714 double fromFilled = bbfilled.getDouble(o + i * 8); 715 716 vb.put(fromFilled); 717 double fromMethodView = bb.getDouble(); 718 assertValues(i, fromFilled, fromMethodView, bb, vb); 719 } 720 721 722 fill(bb, i -> 0); 723 bb.clear().position(o); 724 vb.clear(); 725 726 for (int i = 0; i < vb.limit(); i++) { 727 double fromFilled = bbfilled.getDouble(o + i * 8); 728 729 bb.putDouble(o + i * 8, fromFilled); 730 double fromBufferView = vb.get(i); 731 assertValues(i, fromFilled, fromBufferView, bb, vb); 732 } 733 734 for (int i = 0; i < vb.limit(); i++) { 735 double fromFilled = bbfilled.getDouble(o + i * 8); 736 737 bb.putDouble(fromFilled); 738 double fromBufferView = vb.get(); 739 assertValues(i, fromFilled, fromBufferView, bb, vb); 740 } 741 } 742 743 static double getDoubleFromBytes(ByteBuffer bb, int i) { 744 return Double.longBitsToDouble(getLongFromBytes(bb, i)); 745 } 746} 747