test/jdk/java/nio/Buffer/ByteBufferViews.java
changeset 47216 71c04702a3d5
parent 40195 a13e4945de1d
child 53959 1542e63eb537
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/Buffer/ByteBufferViews.java	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,746 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @summary Binary data and view tests for byte buffers
+ * @bug 8159257
+ * @run testng ByteBufferViews
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.IntUnaryOperator;
+import java.util.function.UnaryOperator;
+import java.util.stream.Collectors;
+
+import static org.testng.Assert.*;
+
+public class ByteBufferViews {
+    static final int SIZE = 32;
+
+    // List of buffer allocator functions
+    static final List<Map.Entry<String, IntFunction<ByteBuffer>>> BYTE_BUFFER_ALLOCATE_FUNCTIONS = List.of(
+            // Heap
+            Map.entry("ByteBuffer.allocate(ba)",
+                      size -> ByteBuffer.allocate(size)),
+            // Aligned
+            Map.entry("ByteBuffer.allocate(size).position(8)",
+                      size -> ByteBuffer.allocate(size).position(8)),
+            Map.entry("ByteBuffer.allocate(size).position(8).slice()",
+                      size -> ByteBuffer.allocate(size).position(8).slice()),
+            Map.entry("ByteBuffer.allocate(size).position(8).slice().duplicate()",
+                      size -> ByteBuffer.allocate(size).position(8).slice().duplicate()),
+            // Unaligned
+            Map.entry("ByteBuffer.allocate(size).position(1)",
+                      size -> ByteBuffer.allocate(size).position(1)),
+            Map.entry("ByteBuffer.allocate(size).position(1).slice()",
+                      size -> ByteBuffer.allocate(size).position(1).slice()),
+            Map.entry("ByteBuffer.allocate(size).position(1).slice().duplicate()",
+                      size -> ByteBuffer.allocate(size).position(1).slice().duplicate()),
+
+            // Off-heap
+            Map.entry("ByteBuffer.allocateDirect(size)",
+                      size -> ByteBuffer.allocateDirect(size)),
+            // Aligned
+            Map.entry("ByteBuffer.allocateDirect(size).position(8)",
+                      size -> ByteBuffer.allocateDirect(size).position(8)),
+            Map.entry("ByteBuffer.allocateDirect(size).position(8).slice()",
+                      size -> ByteBuffer.allocateDirect(size).position(8).slice()),
+            Map.entry("ByteBuffer.allocateDirect(size).position(8).slice().duplicate()",
+                      size -> ByteBuffer.allocateDirect(size).position(8).slice().duplicate()),
+            // Unaligned
+            Map.entry("ByteBuffer.allocateDirect(size).position(1)",
+                      size -> ByteBuffer.allocateDirect(size).position(1)),
+            Map.entry("ByteBuffer.allocateDirect(size).position(1).slice()",
+                      size -> ByteBuffer.allocateDirect(size).position(1).slice()),
+            Map.entry("ByteBuffer.allocateDirect(size).position(1).slice().duplicate()",
+                      size -> ByteBuffer.allocateDirect(size).position(1).slice().duplicate())
+    );
+
+    // List of buffer byte order functions
+    static final List<Map.Entry<String, UnaryOperator<ByteBuffer>>> BYTE_BUFFER_ORDER_FUNCTIONS = List.of(
+            Map.entry("order(ByteOrder.BIG_ENDIAN)",
+                      (ByteBuffer bb) -> bb.order(ByteOrder.BIG_ENDIAN)),
+            Map.entry("order(ByteOrder.LITTLE_ENDIAN)",
+                      (ByteBuffer bb) -> bb.order(ByteOrder.LITTLE_ENDIAN))
+    );
+
+    // Produce a composition of allocation and byte order buffer functions
+    static List<Map.Entry<String, IntFunction<ByteBuffer>>> composeBufferFunctions(
+            List<Map.Entry<String, IntFunction<ByteBuffer>>> af,
+            List<Map.Entry<String, UnaryOperator<ByteBuffer>>> of) {
+        return af.stream().flatMap(afe -> of.stream().
+                map(ofe -> {
+                    String s = afe.getKey() + "." + ofe.getKey();
+                    IntFunction<ByteBuffer> f = size -> ofe.getValue().
+                            apply(afe.getValue().apply(size));
+                    return Map.entry(s, f);
+                })
+        ).collect(Collectors.toList());
+    }
+
+    // List of buffer allocator functions to test
+    static final List<Map.Entry<String, IntFunction<ByteBuffer>>> BYTE_BUFFER_FUNCTIONS =
+            composeBufferFunctions(BYTE_BUFFER_ALLOCATE_FUNCTIONS, BYTE_BUFFER_ORDER_FUNCTIONS);
+
+    // Creates a cross product of test arguments for
+    // buffer allocator functions and buffer view functions
+    static Object[][] product(List<? extends Map.Entry<String, ?>> la,
+                              List<? extends Map.Entry<String, ?>> lb) {
+        return la.stream().flatMap(lae -> lb.stream().
+                map(lbe -> List.of(
+                        lae.getKey() + " -> " + lbe.getKey(),
+                        lae.getValue(),
+                        lbe.getValue()).toArray()
+                )).toArray(Object[][]::new);
+    }
+
+    static void assertValues(int i, Object bValue, Object bbValue, ByteBuffer bb) {
+        if (!bValue.equals(bbValue)) {
+            fail(String.format("Values %s and %s differ at index %d for %s",
+                               bValue, bbValue, i, bb));
+        }
+    }
+
+    static void assertValues(int i, Object bbValue, Object bvValue, ByteBuffer bb, Buffer bv) {
+        if (!bbValue.equals(bvValue)) {
+            fail(String.format("Values %s and %s differ at index %d for %s and %s",
+                               bbValue, bvValue, i, bb, bv));
+        }
+    }
+
+    static ByteBuffer allocate(IntFunction<ByteBuffer> f) {
+        return allocate(f, i -> i);
+    }
+
+    static ByteBuffer allocate(IntFunction<ByteBuffer> f, IntUnaryOperator o) {
+        return fill(f.apply(SIZE), o);
+    }
+
+    static ByteBuffer fill(ByteBuffer bb, IntUnaryOperator o) {
+        for (int i = 0; i < bb.limit(); i++) {
+            bb.put(i, (byte) o.applyAsInt(i));
+        }
+        return bb;
+    }
+
+
+    @DataProvider
+    public static Object[][] shortViewProvider() {
+        List<Map.Entry<String, Function<ByteBuffer, ShortBuffer>>> bfs = List.of(
+                Map.entry("bb.asShortBuffer()",
+                          bb -> bb.asShortBuffer()),
+                Map.entry("bb.asShortBuffer().slice()",
+                          bb -> bb.asShortBuffer().slice()),
+                Map.entry("bb.asShortBuffer().slice().duplicate()",
+                          bb -> bb.asShortBuffer().slice().duplicate())
+        );
+
+        return product(BYTE_BUFFER_FUNCTIONS, bfs);
+    }
+
+    @Test(dataProvider = "shortViewProvider")
+    public void testShortGet(String desc, IntFunction<ByteBuffer> fbb,
+                             Function<ByteBuffer, ShortBuffer> fbi) {
+        ByteBuffer bb = allocate(fbb);
+        ShortBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            short fromBytes = getShortFromBytes(bb, o + i * 2);
+            short fromMethodView = bb.getShort(o + i * 2);
+            assertValues(i, fromBytes, fromMethodView, bb);
+
+            short fromBufferView = vb.get(i);
+            assertValues(i, fromMethodView, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            short v = getShortFromBytes(bb, o + i * 2);
+            short a = bb.getShort();
+            assertValues(i, v, a, bb);
+
+            short b = vb.get();
+            assertValues(i, a, b, bb, vb);
+        }
+
+    }
+
+    @Test(dataProvider = "shortViewProvider")
+    public void testShortPut(String desc, IntFunction<ByteBuffer> fbb,
+                             Function<ByteBuffer, ShortBuffer> fbi) {
+        ByteBuffer bbfilled = allocate(fbb);
+        ByteBuffer bb = allocate(fbb, i -> 0);
+        ShortBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            short fromFilled = bbfilled.getShort(o + i * 2);
+
+            vb.put(i, fromFilled);
+            short fromMethodView = bb.getShort(o + i * 2);
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            short fromFilled = bbfilled.getShort(o + i * 2);
+
+            vb.put(fromFilled);
+            short fromMethodView = bb.getShort();
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+
+        fill(bb, i -> 0);
+        bb.clear().position(o);
+        vb.clear();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            short fromFilled = bbfilled.getShort(o + i * 2);
+
+            bb.putShort(o + i * 2, fromFilled);
+            short fromBufferView = vb.get(i);
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            short fromFilled = bbfilled.getShort(o + i * 2);
+
+            bb.putShort(fromFilled);
+            short fromBufferView = vb.get();
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+    }
+
+    static short getShortFromBytes(ByteBuffer bb, int i) {
+        int a = bb.get(i) & 0xFF;
+        int b = bb.get(i + 1) & 0xFF;
+
+        if (bb.order() == ByteOrder.BIG_ENDIAN) {
+            return (short) ((a << 8) | b);
+        }
+        else {
+            return (short) ((b << 8) | a);
+        }
+    }
+
+    @DataProvider
+    public static Object[][] charViewProvider() {
+        List<Map.Entry<String, Function<ByteBuffer, CharBuffer>>> bfs = List.of(
+                Map.entry("bb.asCharBuffer()",
+                          bb -> bb.asCharBuffer()),
+                Map.entry("bb.asCharBuffer().slice()",
+                          bb -> bb.asCharBuffer().slice()),
+                Map.entry("bb.asCharBuffer().slice().duplicate()",
+                          bb -> bb.asCharBuffer().slice().duplicate())
+        );
+
+        return product(BYTE_BUFFER_FUNCTIONS, bfs);
+    }
+
+    @Test(dataProvider = "charViewProvider")
+    public void testCharGet(String desc, IntFunction<ByteBuffer> fbb,
+                            Function<ByteBuffer, CharBuffer> fbi) {
+        ByteBuffer bb = allocate(fbb);
+        CharBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            char fromBytes = getCharFromBytes(bb, o + i * 2);
+            char fromMethodView = bb.getChar(o + i * 2);
+            assertValues(i, fromBytes, fromMethodView, bb);
+
+            char fromBufferView = vb.get(i);
+            assertValues(i, fromMethodView, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            char fromBytes = getCharFromBytes(bb, o + i * 2);
+            char fromMethodView = bb.getChar();
+            assertValues(i, fromBytes, fromMethodView, bb);
+
+            char fromBufferView = vb.get();
+            assertValues(i, fromMethodView, fromBufferView, bb, vb);
+        }
+
+    }
+
+    @Test(dataProvider = "charViewProvider")
+    public void testCharPut(String desc, IntFunction<ByteBuffer> fbb,
+                            Function<ByteBuffer, CharBuffer> fbi) {
+        ByteBuffer bbfilled = allocate(fbb);
+        ByteBuffer bb = allocate(fbb, i -> 0);
+        CharBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            char fromFilled = bbfilled.getChar(o + i * 2);
+
+            vb.put(i, fromFilled);
+            char fromMethodView = bb.getChar(o + i * 2);
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            char fromFilled = bbfilled.getChar(o + i * 2);
+
+            vb.put(fromFilled);
+            char fromMethodView = bb.getChar();
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+
+        fill(bb, i -> 0);
+        bb.clear().position(o);
+        vb.clear();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            char fromFilled = bbfilled.getChar(o + i * 2);
+
+            bb.putChar(o + i * 2, fromFilled);
+            char fromBufferView = vb.get(i);
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            char fromFilled = bbfilled.getChar(o + i * 2);
+
+            bb.putChar(fromFilled);
+            char fromBufferView = vb.get();
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+    }
+
+    static char getCharFromBytes(ByteBuffer bb, int i) {
+        return (char) getShortFromBytes(bb, i);
+    }
+
+
+    @DataProvider
+    public static Object[][] intViewProvider() {
+        List<Map.Entry<String, Function<ByteBuffer, IntBuffer>>> bfs = List.of(
+                Map.entry("bb.asIntBuffer()",
+                          bb -> bb.asIntBuffer()),
+                Map.entry("bb.asIntBuffer().slice()",
+                          bb -> bb.asIntBuffer().slice()),
+                Map.entry("bb.asIntBuffer().slice().duplicate()",
+                          bb -> bb.asIntBuffer().slice().duplicate())
+        );
+
+        return product(BYTE_BUFFER_FUNCTIONS, bfs);
+    }
+
+    @Test(dataProvider = "intViewProvider")
+    public void testIntGet(String desc, IntFunction<ByteBuffer> fbb,
+                           Function<ByteBuffer, IntBuffer> fbi) {
+        ByteBuffer bb = allocate(fbb);
+        IntBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            int fromBytes = getIntFromBytes(bb, o + i * 4);
+            int fromMethodView = bb.getInt(o + i * 4);
+            assertValues(i, fromBytes, fromMethodView, bb);
+
+            int fromBufferView = vb.get(i);
+            assertValues(i, fromMethodView, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            int v = getIntFromBytes(bb, o + i * 4);
+            int a = bb.getInt();
+            assertValues(i, v, a, bb);
+
+            int b = vb.get();
+            assertValues(i, a, b, bb, vb);
+        }
+
+    }
+
+    @Test(dataProvider = "intViewProvider")
+    public void testIntPut(String desc, IntFunction<ByteBuffer> fbb,
+                           Function<ByteBuffer, IntBuffer> fbi) {
+        ByteBuffer bbfilled = allocate(fbb);
+        ByteBuffer bb = allocate(fbb, i -> 0);
+        IntBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            int fromFilled = bbfilled.getInt(o + i * 4);
+
+            vb.put(i, fromFilled);
+            int fromMethodView = bb.getInt(o + i * 4);
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            int fromFilled = bbfilled.getInt(o + i * 4);
+
+            vb.put(fromFilled);
+            int fromMethodView = bb.getInt();
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+
+        fill(bb, i -> 0);
+        bb.clear().position(o);
+        vb.clear();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            int fromFilled = bbfilled.getInt(o + i * 4);
+
+            bb.putInt(o + i * 4, fromFilled);
+            int fromBufferView = vb.get(i);
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            int fromFilled = bbfilled.getInt(o + i * 4);
+
+            bb.putInt(fromFilled);
+            int fromBufferView = vb.get();
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+    }
+
+    static int getIntFromBytes(ByteBuffer bb, int i) {
+        int a = bb.get(i) & 0xFF;
+        int b = bb.get(i + 1) & 0xFF;
+        int c = bb.get(i + 2) & 0xFF;
+        int d = bb.get(i + 3) & 0xFF;
+
+        if (bb.order() == ByteOrder.BIG_ENDIAN) {
+            return ((a << 24) | (b << 16) | (c << 8) | d);
+        }
+        else {
+            return ((d << 24) | (c << 16) | (b << 8) | a);
+        }
+    }
+
+
+    @DataProvider
+    public static Object[][] longViewProvider() {
+        List<Map.Entry<String, Function<ByteBuffer, LongBuffer>>> bfs = List.of(
+                Map.entry("bb.asLongBuffer()",
+                          bb -> bb.asLongBuffer()),
+                Map.entry("bb.asLongBuffer().slice()",
+                          bb -> bb.asLongBuffer().slice()),
+                Map.entry("bb.asLongBuffer().slice().duplicate()",
+                          bb -> bb.asLongBuffer().slice().duplicate())
+        );
+
+        return product(BYTE_BUFFER_FUNCTIONS, bfs);
+    }
+
+    @Test(dataProvider = "longViewProvider")
+    public void testLongGet(String desc, IntFunction<ByteBuffer> fbb,
+                            Function<ByteBuffer, LongBuffer> fbi) {
+        ByteBuffer bb = allocate(fbb);
+        LongBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            long fromBytes = getLongFromBytes(bb, o + i * 8);
+            long fromMethodView = bb.getLong(o + i * 8);
+            assertValues(i, fromBytes, fromMethodView, bb);
+
+            long fromBufferView = vb.get(i);
+            assertValues(i, fromMethodView, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            long v = getLongFromBytes(bb, o + i * 8);
+            long a = bb.getLong();
+            assertValues(i, v, a, bb);
+
+            long b = vb.get();
+            assertValues(i, a, b, bb, vb);
+        }
+
+    }
+
+    @Test(dataProvider = "longViewProvider")
+    public void testLongPut(String desc, IntFunction<ByteBuffer> fbb,
+                            Function<ByteBuffer, LongBuffer> fbi) {
+        ByteBuffer bbfilled = allocate(fbb);
+        ByteBuffer bb = allocate(fbb, i -> 0);
+        LongBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            long fromFilled = bbfilled.getLong(o + i * 8);
+
+            vb.put(i, fromFilled);
+            long fromMethodView = bb.getLong(o + i * 8);
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            long fromFilled = bbfilled.getLong(o + i * 8);
+
+            vb.put(fromFilled);
+            long fromMethodView = bb.getLong();
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+
+        fill(bb, i -> 0);
+        bb.clear().position(o);
+        vb.clear();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            long fromFilled = bbfilled.getLong(o + i * 8);
+
+            bb.putLong(o + i * 8, fromFilled);
+            long fromBufferView = vb.get(i);
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            long fromFilled = bbfilled.getLong(o + i * 8);
+
+            bb.putLong(fromFilled);
+            long fromBufferView = vb.get();
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+    }
+
+    static long getLongFromBytes(ByteBuffer bb, int i) {
+        long a = bb.get(i) & 0xFF;
+        long b = bb.get(i + 1) & 0xFF;
+        long c = bb.get(i + 2) & 0xFF;
+        long d = bb.get(i + 3) & 0xFF;
+        long e = bb.get(i + 4) & 0xFF;
+        long f = bb.get(i + 5) & 0xFF;
+        long g = bb.get(i + 6) & 0xFF;
+        long h = bb.get(i + 7) & 0xFF;
+
+        if (bb.order() == ByteOrder.BIG_ENDIAN) {
+            return ((a << 56) | (b << 48) | (c << 40) | (d << 32) |
+                    (e << 24) | (f << 16) | (g << 8) | h);
+        }
+        else {
+            return ((h << 56) | (g << 48) | (f << 40) | (e << 32) |
+                    (d << 24) | (c << 16) | (b << 8) | a);
+        }
+    }
+
+
+    @DataProvider
+    public static Object[][] floatViewProvider() {
+        List<Map.Entry<String, Function<ByteBuffer, FloatBuffer>>> bfs = List.of(
+                Map.entry("bb.asFloatBuffer()",
+                          bb -> bb.asFloatBuffer()),
+                Map.entry("bb.asFloatBuffer().slice()",
+                          bb -> bb.asFloatBuffer().slice()),
+                Map.entry("bb.asFloatBuffer().slice().duplicate()",
+                          bb -> bb.asFloatBuffer().slice().duplicate())
+        );
+
+        return product(BYTE_BUFFER_FUNCTIONS, bfs);
+    }
+
+    @Test(dataProvider = "floatViewProvider")
+    public void testFloatGet(String desc, IntFunction<ByteBuffer> fbb,
+                             Function<ByteBuffer, FloatBuffer> fbi) {
+        ByteBuffer bb = allocate(fbb);
+        FloatBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            float fromBytes = getFloatFromBytes(bb, o + i * 4);
+            float fromMethodView = bb.getFloat(o + i * 4);
+            assertValues(i, fromBytes, fromMethodView, bb);
+
+            float fromBufferView = vb.get(i);
+            assertValues(i, fromMethodView, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            float v = getFloatFromBytes(bb, o + i * 4);
+            float a = bb.getFloat();
+            assertValues(i, v, a, bb);
+
+            float b = vb.get();
+            assertValues(i, a, b, bb, vb);
+        }
+
+    }
+
+    @Test(dataProvider = "floatViewProvider")
+    public void testFloatPut(String desc, IntFunction<ByteBuffer> fbb,
+                             Function<ByteBuffer, FloatBuffer> fbi) {
+        ByteBuffer bbfilled = allocate(fbb);
+        ByteBuffer bb = allocate(fbb, i -> 0);
+        FloatBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            float fromFilled = bbfilled.getFloat(o + i * 4);
+
+            vb.put(i, fromFilled);
+            float fromMethodView = bb.getFloat(o + i * 4);
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            float fromFilled = bbfilled.getFloat(o + i * 4);
+
+            vb.put(fromFilled);
+            float fromMethodView = bb.getFloat();
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+
+        fill(bb, i -> 0);
+        bb.clear().position(o);
+        vb.clear();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            float fromFilled = bbfilled.getFloat(o + i * 4);
+
+            bb.putFloat(o + i * 4, fromFilled);
+            float fromBufferView = vb.get(i);
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            float fromFilled = bbfilled.getFloat(o + i * 4);
+
+            bb.putFloat(fromFilled);
+            float fromBufferView = vb.get();
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+    }
+
+    static float getFloatFromBytes(ByteBuffer bb, int i) {
+        return Float.intBitsToFloat(getIntFromBytes(bb, i));
+    }
+
+
+
+    @DataProvider
+    public static Object[][] doubleViewProvider() {
+        List<Map.Entry<String, Function<ByteBuffer, DoubleBuffer>>> bfs = List.of(
+                Map.entry("bb.asDoubleBuffer()",
+                          bb -> bb.asDoubleBuffer()),
+                Map.entry("bb.asDoubleBuffer().slice()",
+                          bb -> bb.asDoubleBuffer().slice()),
+                Map.entry("bb.asDoubleBuffer().slice().duplicate()",
+                          bb -> bb.asDoubleBuffer().slice().duplicate())
+        );
+
+        return product(BYTE_BUFFER_FUNCTIONS, bfs);
+    }
+
+    @Test(dataProvider = "doubleViewProvider")
+    public void testDoubleGet(String desc, IntFunction<ByteBuffer> fbb,
+                              Function<ByteBuffer, DoubleBuffer> fbi) {
+        ByteBuffer bb = allocate(fbb);
+        DoubleBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            double fromBytes = getDoubleFromBytes(bb, o + i * 8);
+            double fromMethodView = bb.getDouble(o + i * 8);
+            assertValues(i, fromBytes, fromMethodView, bb);
+
+            double fromBufferView = vb.get(i);
+            assertValues(i, fromMethodView, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            double v = getDoubleFromBytes(bb, o + i * 8);
+            double a = bb.getDouble();
+            assertValues(i, v, a, bb);
+
+            double b = vb.get();
+            assertValues(i, a, b, bb, vb);
+        }
+
+    }
+
+    @Test(dataProvider = "doubleViewProvider")
+    public void testDoublePut(String desc, IntFunction<ByteBuffer> fbb,
+                              Function<ByteBuffer, DoubleBuffer> fbi) {
+        ByteBuffer bbfilled = allocate(fbb);
+        ByteBuffer bb = allocate(fbb, i -> 0);
+        DoubleBuffer vb = fbi.apply(bb);
+        int o = bb.position();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            double fromFilled = bbfilled.getDouble(o + i * 8);
+
+            vb.put(i, fromFilled);
+            double fromMethodView = bb.getDouble(o + i * 8);
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            double fromFilled = bbfilled.getDouble(o + i * 8);
+
+            vb.put(fromFilled);
+            double fromMethodView = bb.getDouble();
+            assertValues(i, fromFilled, fromMethodView, bb, vb);
+        }
+
+
+        fill(bb, i -> 0);
+        bb.clear().position(o);
+        vb.clear();
+
+        for (int i = 0; i < vb.limit(); i++) {
+            double fromFilled = bbfilled.getDouble(o + i * 8);
+
+            bb.putDouble(o + i * 8, fromFilled);
+            double fromBufferView = vb.get(i);
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+
+        for (int i = 0; i < vb.limit(); i++) {
+            double fromFilled = bbfilled.getDouble(o + i * 8);
+
+            bb.putDouble(fromFilled);
+            double fromBufferView = vb.get();
+            assertValues(i, fromFilled, fromBufferView, bb, vb);
+        }
+    }
+
+    static double getDoubleFromBytes(ByteBuffer bb, int i) {
+        return Double.longBitsToDouble(getLongFromBytes(bb, i));
+    }
+}