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