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