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 }