--- old/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template 2019-02-13 14:11:56.000000000 -0800 +++ new/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template 2019-02-13 14:11:56.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -29,6 +29,7 @@ import java.io.FileDescriptor; import java.lang.ref.Reference; +import java.util.Objects; import jdk.internal.misc.VM; import jdk.internal.ref.Cleaner; import sun.nio.ch.DirectBuffer; @@ -325,6 +326,41 @@ #end[rw] } + public $Type$Buffer get(int index, $type$[] dst, int offset, int length) { + //System.out.println("Direct absolute bulk get"); +#if[rw] + if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) { + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(offset, length, dst.length); + + long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$); + try { +#if[!byte] + if (order() != ByteOrder.nativeOrder()) + UNSAFE.copySwapMemory(null, + ix(index), + dst, + dstOffset, + (long)length << $LG_BYTES_PER_VALUE$, + (long)1 << $LG_BYTES_PER_VALUE$); + else +#end[!byte] + UNSAFE.copyMemory(null, + ix(index), + dst, + dstOffset, + (long)length << $LG_BYTES_PER_VALUE$); + } finally { + Reference.reachabilityFence(this); + } + } else { + super.get(index, dst, offset, length); + } + return this; +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } #end[rw] public $Type$Buffer put($type$ x) { @@ -440,6 +476,72 @@ #end[rw] } + public $Type$Buffer put(int index, $type$[] src, int offset, int length) { + //System.out.println("Direct absolute bulk put array"); +#if[rw] + if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) { + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(offset, length, src.length); + + + long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$); + try { +#if[!byte] + if (order() != ByteOrder.nativeOrder()) + UNSAFE.copySwapMemory(src, + srcOffset, + null, + ix(index), + (long)length << $LG_BYTES_PER_VALUE$, + (long)1 << $LG_BYTES_PER_VALUE$); + else +#end[!byte] + UNSAFE.copyMemory(src, + srcOffset, + null, + ix(index), + (long)length << $LG_BYTES_PER_VALUE$); + } finally { + Reference.reachabilityFence(this); + } + } else { + super.put(index, src, offset, length); + } + return this; +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } + + public $Type$Buffer put(int index, $Type$Buffer src, int srcIndex, + int length) { + //System.out.println("Direct absolute bulk buffer"); +#if[rw] + if (src instanceof Direct$Type$Buffer$BO$) { + Direct$Type$Buffer$RW$$BO$ sb = (Direct$Type$Buffer$RW$$BO$)src; + + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(srcIndex, length, sb.limit()); + try { + UNSAFE.copyMemory(sb.ix(srcIndex), ix(index), + (long)length << $LG_BYTES_PER_VALUE$); + } finally { + Reference.reachabilityFence(sb); + Reference.reachabilityFence(this); + } + } else if (src.hb != null) { + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(srcIndex, length, src.limit()); + put(index, src.hb, srcIndex, length); + } else { + super.put(index, src, srcIndex, length); + } + return this; +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } + public $Type$Buffer compact() { #if[rw] int pos = position(); --- old/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template 2019-02-13 14:11:57.000000000 -0800 +++ new/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template 2019-02-13 14:11:57.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -38,6 +38,8 @@ #end[rw] */ +import java.util.Objects; + class Heap$Type$Buffer$RW$ extends {#if[ro]?Heap}$Type$Buffer { @@ -181,6 +183,14 @@ return this; } + public $Type$Buffer get(int index, $type$[] dst, int offset, int length) { + //System.out.println("Heap absolute bulk get"); + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(offset, length, dst.length); + System.arraycopy(hb, ix(index), dst, offset, length); + return this; + } + public boolean isDirect() { return false; } @@ -250,6 +260,43 @@ #end[rw] } + public $Type$Buffer put(int index, $type$[] src, int offset, int length) { + //System.out.println("Heap absolute bulk put array"); +#if[rw] + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(offset, length, src.length); + System.arraycopy(src, offset, hb, ix(index), length); + return this; +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } + + public $Type$Buffer put(int index, $Type$Buffer src, int srcIndex, + int length) { + //System.out.println("Heap absolute bulk put buffer"); +#if[rw] + if (src instanceof Heap$Type$Buffer) { + if (index < 0) + throw new IndexOutOfBoundsException("Index negative: " + index); + Heap$Type$Buffer sb = (Heap$Type$Buffer)src; + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(srcIndex, length, sb.limit()); + System.arraycopy(sb.hb, sb.ix(srcIndex), + hb, ix(index), length); + } else if (src.isDirect()) { + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(srcIndex, length, src.limit()); + src.get(srcIndex, hb, ix(index), length); + } else { + super.put(index, src, srcIndex, length); + } + return this; +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } + public $Type$Buffer compact() { #if[rw] System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); --- old/src/java.base/share/classes/java/nio/X-Buffer.java.template 2019-02-13 14:11:58.000000000 -0800 +++ new/src/java.base/share/classes/java/nio/X-Buffer.java.template 2019-02-13 14:11:57.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -36,6 +36,7 @@ import java.util.stream.$Streamtype$Stream; #end[streamableType] +import java.util.Objects; import jdk.internal.util.ArraysSupport; /** @@ -50,11 +51,11 @@ * {@link #put($type$) put} methods that read and write * single $type$s;

* - *
  • Relative {@link #get($type$[]) bulk get} + *

  • Absolute and relative {@link #get($type$[]) bulk get} * methods that transfer contiguous sequences of $type$s from this buffer * into an array; {#if[!byte]?and}

  • * - *
  • Relative {@link #put($type$[]) bulk put} + *

  • Absolute and relative {@link #put($type$[]) bulk put} * methods that transfer contiguous sequences of $type$s from $a$ * $type$ array{#if[char]?, a string,} or some other $type$ * buffer into this buffer;{#if[!byte]? and}

  • @@ -434,7 +435,6 @@ * @return The number of characters added to the buffer, or * -1 if this source of characters is at its end * @throws IOException if an I/O error occurs - * @throws NullPointerException if target is null * @throws ReadOnlyBufferException if target is a read only buffer * @since 1.5 */ @@ -762,6 +762,91 @@ return get(dst, 0, dst.length); } + /** + * Absolute bulk get method. + * + *

    This method transfers {@code length} $type$s from this + * buffer into the given array, starting at the given index in this + * buffer and at the given offset in the array. The position of this + * buffer is unchanged. + * + *

    An invocation of this method of the form + * src.get(index, dst, offset, length) + * has exactly the same effect as the following loop except that it first + * checks the consistency of the supplied parameters and it is potentially + * much more efficient: + * + *

    {@code
    +     *     for (int i = offset, j = index; i < offset + length; i++, j++)
    +     *         dst[i] = src.get(j);
    +     * }
    + * + * @param index + * The index in this buffer from which the first $type$ will be + * read; must be non-negative and less than {@code limit()} + * + * @param dst + * The destination array + * + * @param offset + * The offset within the array of the first $type$ to be + * written; must be non-negative and less than + * {@code dst.length} + * + * @param length + * The number of $type$s to be written to the given array; + * must be non-negative and no larger than the smaller of + * {@code limit() - index} and {@code dst.length - offset} + * + * @return This buffer + * + * @throws IndexOutOfBoundsException + * If the preconditions on the {@code index}, {@code offset}, and + * {@code length} parameters do not hold + * + * @since 13 + */ + public $Type$Buffer get(int index, $type$[] dst, int offset, int length) { + //System.out.println("Absolute bulk get"); + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(offset, length, dst.length); + int end = offset + length; + for (int i = offset, j = index; i < end; i++, j++) + dst[i] = get(j); + return this; + } + + /** + * Absolute bulk get method. + * + *

    This method transfers $type$s from this buffer into the given + * destination array. The position of this buffer is unchanged. An + * invocation of this method of the form + * src.get(index, dst) behaves in exactly the same + * way as the invocation: + * + *

    +     *     src.get(index, dst, 0, dst.length) 
    + * + * @param index + * The index in this buffer from which the first $type$ will be + * read; must be non-negative and less than {@code limit()} + * + * @param dst + * The destination array + * + * @return This buffer + * + * @throws IndexOutOfBoundsException + * If {@code index} is negative, not smaller than {@code limit()}, + * or {@code limit() - index < dst.length} + * + * @since 13 + */ + public $Type$Buffer get(int index, $type$[] dst) { + return get(index, dst, 0, dst.length); + } + // -- Bulk put operations -- @@ -840,7 +925,7 @@ * *
    {@code
          *     for (int i = off; i < off + len; i++)
    -     *         dst.put(a[i]);
    +     *         dst.put(src[i]);
          * }
    * * except that it first checks that there is sufficient space in this @@ -851,12 +936,12 @@ * * @param offset * The offset within the array of the first $type$ to be read; - * must be non-negative and no larger than {@code array.length} + * must be non-negative and no larger than {@code src.length} * * @param length * The number of $type$s to be read from the given array; * must be non-negative and no larger than - * {@code array.length - offset} + * {@code src.length - offset} * * @return This buffer * @@ -906,6 +991,156 @@ return put(src, 0, src.length); } + /** + * Absolute bulk put method  (optional operation). + * + *

    This method transfers {@code length} $type$s from the given + * array, starting at the given offset in the array and at the given index + * in this buffer. The position of this buffer is unchanged. + * + *

    An invocation of this method of the form + * dst.put(index, src, offset, length) + * has exactly the same effect as the following loop except that it first + * checks the consistency of the supplied parameters and it is potentially + * much more efficient: + * + *

    {@code
    +     *     for (int i = offset, j = index; i < offset + length; i++, j++)
    +     *         dst.put(j, src[i]);
    +     * }
    + * + * @param index + * The index in this buffer at which the first $type$ will be + * written; must be non-negative and less than {@code limit()} + * + * @param src + * The array from which $type$s are to be read + * + * @param offset + * The offset within the array of the first $type$ to be read; + * must be non-negative and less than {@code src.length} + * + * @param length + * The number of $type$s to be read from the given array; + * must be non-negative and no larger than the smaller of + * {@code limit() - index} and {@code src.length - offset} + * + * @return This buffer + * + * @throws IndexOutOfBoundsException + * If the preconditions on the {@code index}, {@code offset}, and + * {@code length}, parameters do not hold + * + * @throws ReadOnlyBufferException + * If this buffer is read-only + * + * @since 13 + */ + public $Type$Buffer put(int index, $type$[] src, int offset, int length) { + //System.out.println("Absolute bulk put array"); + if (isReadOnly()) + throw new ReadOnlyBufferException(); + Objects.checkFromIndexSize(index, length, limit()); + Objects.checkFromIndexSize(offset, length, src.length); + int end = offset + length; + for (int i = offset, j = index; i < end; i++, j++) + this.put(j, src[i]); + return this; + } + + /** + * Absolute bulk put method  (optional operation). + * + *

    This method copies $type$s into this buffer from the given source + * array. The position of this buffer is unchanged. An invocation of this + * method of the form dst.put(index, src) + * behaves in exactly the same was as the invocation: + * + *

    +     *     dst.put(index, src, 0, src.length); 
    + * + * @param index + * The index in this buffer at which the first $type$ will be + * written; must be non-negative and less than {@code limit()} + * + * @param src + * The array from which $type$s are to be read + * + * @return This buffer + * + * @throws IndexOutOfBoundsException + * If the index is negative, not smaller than {@code limit()}, or + * {@code limit() - index < src.length} + * + * @throws ReadOnlyBufferException + * If this buffer is read-only + * + * @since 13 + */ + public $Type$Buffer put(int index, $type$[] src) { + return put(index, src, 0, src.length); + } + + /** + * Absolute bulk put method  (optional operation). + * + *

    This method transfers {@code length} $type$s into this buffer + * from the source buffer, starting at the given {@code srcIndex} in the + * source buffer and the given {@code index} in this buffer. The positions + * of both buffers are unchanged. The source buffer may be this buffer and + * the specified regions may overlap. + * + *

    An invocation of this method of the form + * dst.put(index, src, srcIndex, length) + * has exactly the same effect as the following loop except that it first + * checks the consistency of the supplied parameters and it is potentially + * much more efficient: + * + *

    {@code
    +     *     for (int i = srcIndex, j = index; i < srcIndex + length; i++, j++)
    +     *         dst.put(j, src.get(i));
    +     * }
    + * + * @param index + * The index in this buffer at which the first $type$ will be + * written; must be non-negative and less than {@code limit()} + * + * @param src + * The buffer from which $type$s are to be read + * + * @param srcIndex + * The index within the source buffer of the first $type$ to be + * read; must be non-negative and less than {@code src.limit()} + * + * @param length + * The number of $type$s to be read from the given buffer; + * must be non-negative and no larger than the smaller of + * {@code limit() - index} and {@code src.limit() - offset} + * + * @return This buffer + * + * @throws IndexOutOfBoundsException + * If the preconditions on the {@code index}, {@code srcIndex}, and + * {@code length}, parameters do not hold + * + * @throws ReadOnlyBufferException + * If this buffer is read-only + * + * @since 13 + */ + public $Type$Buffer put(int index, $Type$Buffer src, int srcIndex, + int length) { + //System.out.println("Absolute bulk put buffer"); + if (isReadOnly()) + throw new ReadOnlyBufferException(); + Objects.checkFromIndexSize(index, length, limit()); + int n = src.limit(); + Objects.checkFromIndexSize(srcIndex, length, n); + for (int i = srcIndex, j = index; i < n; i++, j++) + put(j, src.get(i)); + return this; + } + #if[char] /** --- old/test/jdk/java/nio/Buffer/Basic-X.java.template 2019-02-13 14:11:58.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/Basic-X.java.template 2019-02-13 14:11:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -87,6 +87,18 @@ } } + private static void absBulkGet($Type$Buffer b) { + int n = b.capacity(); + int len = n - 7*2; + $type$[] a = new $type$[n + 7]; + b.position(42); + b.get(7, a, 7, len); + ck(b, b.position() == 42); + for (int i = 0; i < len; i++) { + ck(b, (long)a[i + 7], (long)(($type$)ic(i))); + } + } + private static void relPut($Type$Buffer b) { int n = b.capacity(); b.clear(); @@ -136,6 +148,47 @@ } } + private static void absBulkPutArray($Type$Buffer b) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + $type$[] a = new $type$[len + 7]; + for (int i = 0; i < len; i++) + a[i + 7] = ($type$)ic(i); + b.position(42); + b.put(7, a, 7, len); + ck(b, b.position() == 42); + } + + private static void absBulkPutBuffer($Type$Buffer b, boolean direct) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + $Type$Buffer c = direct ? +#if[byte] + ByteBuffer.allocateDirect(len + 7) +#else[byte] + ByteBuffer.allocateDirect($Fulltype$.BYTES*(len + 7)) + .as$Type$Buffer() +#end[byte] + : $Type$Buffer.allocate(len + 7); +#if[!byte] + if (direct) + System.out.println("Direct buffer: " + c.getClass().getName()); +#end[!byte] + for (int i = 0; i < len; i++) + c.put(i + 7, ($type$)ic(i)); + b.position(42); + c.position(42); + b.put(7, c, 7, len); + ck(b, b.position() == 42); + ck(c, c.position() == 42); + } + //6231529 private static void callReset($Type$Buffer b) { b.position(0); @@ -452,6 +505,10 @@ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchNullArgument(Buffer b, Runnable thunk) { + tryCatch(b, NullPointerException.class, thunk); + } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { tryCatch(b, IllegalArgumentException.class, thunk); } @@ -476,7 +533,10 @@ if (ex.isAssignableFrom(x.getClass())) { caught = true; } else { - fail(x.getMessage() + " not expected"); + String s = x.getMessage(); + if (s == null) + s = x.getClass().getName(); + fail(s + " not expected"); } } if (!caught) { @@ -513,6 +573,15 @@ bulkPutBuffer(b); relGet(b); + absBulkPutArray(b); + absBulkGet(b); + + absBulkPutBuffer(b, direct); + absBulkGet(b); + + absBulkPutBuffer(b, !direct); + absBulkGet(b); + #if[char] bulkPutString(b); @@ -612,6 +681,37 @@ } } + // Exceptions in absolute bulk operations + + catchNullArgument(b, () -> b.get(7, null, 0, 42)); + catchNullArgument(b, () -> b.put(7, ($type$[])null, 0, 42)); + catchNullArgument(b, () -> b.put(7, ($Type$Buffer)null, 0, 42)); + + $type$[] tmpa = new $type$[42]; + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42)); + + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + + $Type$Buffer tmpb = $Type$Buffer.allocate(42); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, -1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 41, 2)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(0, tmpb, 0, -1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpb, 0, 42)); + // Values b.clear(); @@ -819,6 +919,8 @@ catchReadOnlyBuffer(b, () -> absPut(rb)); catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutBuffer(rb, direct)); // put($Type$Buffer) should not change source position final $Type$Buffer src = $Type$Buffer.allocate(1); --- old/test/jdk/java/nio/Buffer/Basic.java 2019-02-13 14:11:59.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/Basic.java 2019-02-13 14:11:59.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -24,9 +24,9 @@ /* @test * @summary Unit test for buffers * @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725 - * 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 6231529 - * 6221101 6234263 6535542 6591971 6593946 6795561 7190219 7199551 8065556 - * 8149469 + * 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 5029431 + * 6231529 6221101 6234263 6535542 6591971 6593946 6795561 7190219 7199551 + * 8065556 8149469 * @modules java.base/java.nio:open * java.base/jdk.internal.misc * @author Mark Reinhold --- old/test/jdk/java/nio/Buffer/BasicByte.java 2019-02-13 14:12:00.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/BasicByte.java 2019-02-13 14:11:59.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -87,6 +87,18 @@ } } + private static void absBulkGet(ByteBuffer b) { + int n = b.capacity(); + int len = n - 7*2; + byte[] a = new byte[n + 7]; + b.position(42); + b.get(7, a, 7, len); + ck(b, b.position() == 42); + for (int i = 0; i < len; i++) { + ck(b, (long)a[i + 7], (long)((byte)ic(i))); + } + } + private static void relPut(ByteBuffer b) { int n = b.capacity(); b.clear(); @@ -136,6 +148,47 @@ } } + private static void absBulkPutArray(ByteBuffer b) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + byte[] a = new byte[len + 7]; + for (int i = 0; i < len; i++) + a[i + 7] = (byte)ic(i); + b.position(42); + b.put(7, a, 7, len); + ck(b, b.position() == 42); + } + + private static void absBulkPutBuffer(ByteBuffer b, boolean direct) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + ByteBuffer c = direct ? + + ByteBuffer.allocateDirect(len + 7) + + + + + : ByteBuffer.allocate(len + 7); + + + + + for (int i = 0; i < len; i++) + c.put(i + 7, (byte)ic(i)); + b.position(42); + c.position(42); + b.put(7, c, 7, len); + ck(b, b.position() == 42); + ck(c, c.position() == 42); + } + //6231529 private static void callReset(ByteBuffer b) { b.position(0); @@ -452,6 +505,10 @@ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchNullArgument(Buffer b, Runnable thunk) { + tryCatch(b, NullPointerException.class, thunk); + } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { tryCatch(b, IllegalArgumentException.class, thunk); } @@ -476,7 +533,10 @@ if (ex.isAssignableFrom(x.getClass())) { caught = true; } else { - fail(x.getMessage() + " not expected"); + String s = x.getMessage(); + if (s == null) + s = x.getClass().getName(); + fail(s + " not expected"); } } if (!caught) { @@ -513,6 +573,15 @@ bulkPutBuffer(b); relGet(b); + absBulkPutArray(b); + absBulkGet(b); + + absBulkPutBuffer(b, direct); + absBulkGet(b); + + absBulkPutBuffer(b, !direct); + absBulkGet(b); + @@ -612,6 +681,37 @@ } } + // Exceptions in absolute bulk operations + + catchNullArgument(b, () -> b.get(7, null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (byte[])null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (ByteBuffer)null, 0, 42)); + + byte[] tmpa = new byte[42]; + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42)); + + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + + ByteBuffer tmpb = ByteBuffer.allocate(42); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, -1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 41, 2)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(0, tmpb, 0, -1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpb, 0, 42)); + // Values b.clear(); @@ -819,6 +919,8 @@ catchReadOnlyBuffer(b, () -> absPut(rb)); catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutBuffer(rb, direct)); // put(ByteBuffer) should not change source position final ByteBuffer src = ByteBuffer.allocate(1); --- old/test/jdk/java/nio/Buffer/BasicChar.java 2019-02-13 14:12:01.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/BasicChar.java 2019-02-13 14:12:00.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -87,6 +87,18 @@ } } + private static void absBulkGet(CharBuffer b) { + int n = b.capacity(); + int len = n - 7*2; + char[] a = new char[n + 7]; + b.position(42); + b.get(7, a, 7, len); + ck(b, b.position() == 42); + for (int i = 0; i < len; i++) { + ck(b, (long)a[i + 7], (long)((char)ic(i))); + } + } + private static void relPut(CharBuffer b) { int n = b.capacity(); b.clear(); @@ -136,6 +148,47 @@ } } + private static void absBulkPutArray(CharBuffer b) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + char[] a = new char[len + 7]; + for (int i = 0; i < len; i++) + a[i + 7] = (char)ic(i); + b.position(42); + b.put(7, a, 7, len); + ck(b, b.position() == 42); + } + + private static void absBulkPutBuffer(CharBuffer b, boolean direct) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + CharBuffer c = direct ? + + + + ByteBuffer.allocateDirect(Character.BYTES*(len + 7)) + .asCharBuffer() + + : CharBuffer.allocate(len + 7); + + if (direct) + System.out.println("Direct buffer: " + c.getClass().getName()); + + for (int i = 0; i < len; i++) + c.put(i + 7, (char)ic(i)); + b.position(42); + c.position(42); + b.put(7, c, 7, len); + ck(b, b.position() == 42); + ck(c, c.position() == 42); + } + //6231529 private static void callReset(CharBuffer b) { b.position(0); @@ -452,6 +505,10 @@ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchNullArgument(Buffer b, Runnable thunk) { + tryCatch(b, NullPointerException.class, thunk); + } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { tryCatch(b, IllegalArgumentException.class, thunk); } @@ -476,7 +533,10 @@ if (ex.isAssignableFrom(x.getClass())) { caught = true; } else { - fail(x.getMessage() + " not expected"); + String s = x.getMessage(); + if (s == null) + s = x.getClass().getName(); + fail(s + " not expected"); } } if (!caught) { @@ -513,6 +573,15 @@ bulkPutBuffer(b); relGet(b); + absBulkPutArray(b); + absBulkGet(b); + + absBulkPutBuffer(b, direct); + absBulkGet(b); + + absBulkPutBuffer(b, !direct); + absBulkGet(b); + bulkPutString(b); @@ -612,6 +681,37 @@ } } + // Exceptions in absolute bulk operations + + catchNullArgument(b, () -> b.get(7, null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (char[])null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (CharBuffer)null, 0, 42)); + + char[] tmpa = new char[42]; + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42)); + + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + + CharBuffer tmpb = CharBuffer.allocate(42); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, -1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 41, 2)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(0, tmpb, 0, -1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpb, 0, 42)); + // Values b.clear(); @@ -819,6 +919,8 @@ catchReadOnlyBuffer(b, () -> absPut(rb)); catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutBuffer(rb, direct)); // put(CharBuffer) should not change source position final CharBuffer src = CharBuffer.allocate(1); --- old/test/jdk/java/nio/Buffer/BasicDouble.java 2019-02-13 14:12:01.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/BasicDouble.java 2019-02-13 14:12:01.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -87,6 +87,18 @@ } } + private static void absBulkGet(DoubleBuffer b) { + int n = b.capacity(); + int len = n - 7*2; + double[] a = new double[n + 7]; + b.position(42); + b.get(7, a, 7, len); + ck(b, b.position() == 42); + for (int i = 0; i < len; i++) { + ck(b, (long)a[i + 7], (long)((double)ic(i))); + } + } + private static void relPut(DoubleBuffer b) { int n = b.capacity(); b.clear(); @@ -136,6 +148,47 @@ } } + private static void absBulkPutArray(DoubleBuffer b) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + double[] a = new double[len + 7]; + for (int i = 0; i < len; i++) + a[i + 7] = (double)ic(i); + b.position(42); + b.put(7, a, 7, len); + ck(b, b.position() == 42); + } + + private static void absBulkPutBuffer(DoubleBuffer b, boolean direct) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + DoubleBuffer c = direct ? + + + + ByteBuffer.allocateDirect(Double.BYTES*(len + 7)) + .asDoubleBuffer() + + : DoubleBuffer.allocate(len + 7); + + if (direct) + System.out.println("Direct buffer: " + c.getClass().getName()); + + for (int i = 0; i < len; i++) + c.put(i + 7, (double)ic(i)); + b.position(42); + c.position(42); + b.put(7, c, 7, len); + ck(b, b.position() == 42); + ck(c, c.position() == 42); + } + //6231529 private static void callReset(DoubleBuffer b) { b.position(0); @@ -452,6 +505,10 @@ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchNullArgument(Buffer b, Runnable thunk) { + tryCatch(b, NullPointerException.class, thunk); + } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { tryCatch(b, IllegalArgumentException.class, thunk); } @@ -476,7 +533,10 @@ if (ex.isAssignableFrom(x.getClass())) { caught = true; } else { - fail(x.getMessage() + " not expected"); + String s = x.getMessage(); + if (s == null) + s = x.getClass().getName(); + fail(s + " not expected"); } } if (!caught) { @@ -513,6 +573,15 @@ bulkPutBuffer(b); relGet(b); + absBulkPutArray(b); + absBulkGet(b); + + absBulkPutBuffer(b, direct); + absBulkGet(b); + + absBulkPutBuffer(b, !direct); + absBulkGet(b); + @@ -612,6 +681,37 @@ } } + // Exceptions in absolute bulk operations + + catchNullArgument(b, () -> b.get(7, null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (double[])null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (DoubleBuffer)null, 0, 42)); + + double[] tmpa = new double[42]; + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42)); + + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + + DoubleBuffer tmpb = DoubleBuffer.allocate(42); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, -1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 41, 2)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(0, tmpb, 0, -1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpb, 0, 42)); + // Values b.clear(); @@ -819,6 +919,8 @@ catchReadOnlyBuffer(b, () -> absPut(rb)); catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutBuffer(rb, direct)); // put(DoubleBuffer) should not change source position final DoubleBuffer src = DoubleBuffer.allocate(1); --- old/test/jdk/java/nio/Buffer/BasicFloat.java 2019-02-13 14:12:03.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/BasicFloat.java 2019-02-13 14:12:02.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -87,6 +87,18 @@ } } + private static void absBulkGet(FloatBuffer b) { + int n = b.capacity(); + int len = n - 7*2; + float[] a = new float[n + 7]; + b.position(42); + b.get(7, a, 7, len); + ck(b, b.position() == 42); + for (int i = 0; i < len; i++) { + ck(b, (long)a[i + 7], (long)((float)ic(i))); + } + } + private static void relPut(FloatBuffer b) { int n = b.capacity(); b.clear(); @@ -136,6 +148,47 @@ } } + private static void absBulkPutArray(FloatBuffer b) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + float[] a = new float[len + 7]; + for (int i = 0; i < len; i++) + a[i + 7] = (float)ic(i); + b.position(42); + b.put(7, a, 7, len); + ck(b, b.position() == 42); + } + + private static void absBulkPutBuffer(FloatBuffer b, boolean direct) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + FloatBuffer c = direct ? + + + + ByteBuffer.allocateDirect(Float.BYTES*(len + 7)) + .asFloatBuffer() + + : FloatBuffer.allocate(len + 7); + + if (direct) + System.out.println("Direct buffer: " + c.getClass().getName()); + + for (int i = 0; i < len; i++) + c.put(i + 7, (float)ic(i)); + b.position(42); + c.position(42); + b.put(7, c, 7, len); + ck(b, b.position() == 42); + ck(c, c.position() == 42); + } + //6231529 private static void callReset(FloatBuffer b) { b.position(0); @@ -452,6 +505,10 @@ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchNullArgument(Buffer b, Runnable thunk) { + tryCatch(b, NullPointerException.class, thunk); + } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { tryCatch(b, IllegalArgumentException.class, thunk); } @@ -476,7 +533,10 @@ if (ex.isAssignableFrom(x.getClass())) { caught = true; } else { - fail(x.getMessage() + " not expected"); + String s = x.getMessage(); + if (s == null) + s = x.getClass().getName(); + fail(s + " not expected"); } } if (!caught) { @@ -513,6 +573,15 @@ bulkPutBuffer(b); relGet(b); + absBulkPutArray(b); + absBulkGet(b); + + absBulkPutBuffer(b, direct); + absBulkGet(b); + + absBulkPutBuffer(b, !direct); + absBulkGet(b); + @@ -612,6 +681,37 @@ } } + // Exceptions in absolute bulk operations + + catchNullArgument(b, () -> b.get(7, null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (float[])null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (FloatBuffer)null, 0, 42)); + + float[] tmpa = new float[42]; + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42)); + + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + + FloatBuffer tmpb = FloatBuffer.allocate(42); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, -1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 41, 2)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(0, tmpb, 0, -1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpb, 0, 42)); + // Values b.clear(); @@ -819,6 +919,8 @@ catchReadOnlyBuffer(b, () -> absPut(rb)); catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutBuffer(rb, direct)); // put(FloatBuffer) should not change source position final FloatBuffer src = FloatBuffer.allocate(1); --- old/test/jdk/java/nio/Buffer/BasicInt.java 2019-02-13 14:12:04.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/BasicInt.java 2019-02-13 14:12:03.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -87,6 +87,18 @@ } } + private static void absBulkGet(IntBuffer b) { + int n = b.capacity(); + int len = n - 7*2; + int[] a = new int[n + 7]; + b.position(42); + b.get(7, a, 7, len); + ck(b, b.position() == 42); + for (int i = 0; i < len; i++) { + ck(b, (long)a[i + 7], (long)((int)ic(i))); + } + } + private static void relPut(IntBuffer b) { int n = b.capacity(); b.clear(); @@ -136,6 +148,47 @@ } } + private static void absBulkPutArray(IntBuffer b) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + int[] a = new int[len + 7]; + for (int i = 0; i < len; i++) + a[i + 7] = (int)ic(i); + b.position(42); + b.put(7, a, 7, len); + ck(b, b.position() == 42); + } + + private static void absBulkPutBuffer(IntBuffer b, boolean direct) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + IntBuffer c = direct ? + + + + ByteBuffer.allocateDirect(Integer.BYTES*(len + 7)) + .asIntBuffer() + + : IntBuffer.allocate(len + 7); + + if (direct) + System.out.println("Direct buffer: " + c.getClass().getName()); + + for (int i = 0; i < len; i++) + c.put(i + 7, (int)ic(i)); + b.position(42); + c.position(42); + b.put(7, c, 7, len); + ck(b, b.position() == 42); + ck(c, c.position() == 42); + } + //6231529 private static void callReset(IntBuffer b) { b.position(0); @@ -452,6 +505,10 @@ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchNullArgument(Buffer b, Runnable thunk) { + tryCatch(b, NullPointerException.class, thunk); + } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { tryCatch(b, IllegalArgumentException.class, thunk); } @@ -476,7 +533,10 @@ if (ex.isAssignableFrom(x.getClass())) { caught = true; } else { - fail(x.getMessage() + " not expected"); + String s = x.getMessage(); + if (s == null) + s = x.getClass().getName(); + fail(s + " not expected"); } } if (!caught) { @@ -513,6 +573,15 @@ bulkPutBuffer(b); relGet(b); + absBulkPutArray(b); + absBulkGet(b); + + absBulkPutBuffer(b, direct); + absBulkGet(b); + + absBulkPutBuffer(b, !direct); + absBulkGet(b); + @@ -612,6 +681,37 @@ } } + // Exceptions in absolute bulk operations + + catchNullArgument(b, () -> b.get(7, null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (int[])null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (IntBuffer)null, 0, 42)); + + int[] tmpa = new int[42]; + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42)); + + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + + IntBuffer tmpb = IntBuffer.allocate(42); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, -1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 41, 2)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(0, tmpb, 0, -1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpb, 0, 42)); + // Values b.clear(); @@ -819,6 +919,8 @@ catchReadOnlyBuffer(b, () -> absPut(rb)); catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutBuffer(rb, direct)); // put(IntBuffer) should not change source position final IntBuffer src = IntBuffer.allocate(1); --- old/test/jdk/java/nio/Buffer/BasicLong.java 2019-02-13 14:12:05.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/BasicLong.java 2019-02-13 14:12:04.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -87,6 +87,18 @@ } } + private static void absBulkGet(LongBuffer b) { + int n = b.capacity(); + int len = n - 7*2; + long[] a = new long[n + 7]; + b.position(42); + b.get(7, a, 7, len); + ck(b, b.position() == 42); + for (int i = 0; i < len; i++) { + ck(b, (long)a[i + 7], (long)((long)ic(i))); + } + } + private static void relPut(LongBuffer b) { int n = b.capacity(); b.clear(); @@ -136,6 +148,47 @@ } } + private static void absBulkPutArray(LongBuffer b) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + long[] a = new long[len + 7]; + for (int i = 0; i < len; i++) + a[i + 7] = (long)ic(i); + b.position(42); + b.put(7, a, 7, len); + ck(b, b.position() == 42); + } + + private static void absBulkPutBuffer(LongBuffer b, boolean direct) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + LongBuffer c = direct ? + + + + ByteBuffer.allocateDirect(Long.BYTES*(len + 7)) + .asLongBuffer() + + : LongBuffer.allocate(len + 7); + + if (direct) + System.out.println("Direct buffer: " + c.getClass().getName()); + + for (int i = 0; i < len; i++) + c.put(i + 7, (long)ic(i)); + b.position(42); + c.position(42); + b.put(7, c, 7, len); + ck(b, b.position() == 42); + ck(c, c.position() == 42); + } + //6231529 private static void callReset(LongBuffer b) { b.position(0); @@ -452,6 +505,10 @@ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchNullArgument(Buffer b, Runnable thunk) { + tryCatch(b, NullPointerException.class, thunk); + } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { tryCatch(b, IllegalArgumentException.class, thunk); } @@ -476,7 +533,10 @@ if (ex.isAssignableFrom(x.getClass())) { caught = true; } else { - fail(x.getMessage() + " not expected"); + String s = x.getMessage(); + if (s == null) + s = x.getClass().getName(); + fail(s + " not expected"); } } if (!caught) { @@ -513,6 +573,15 @@ bulkPutBuffer(b); relGet(b); + absBulkPutArray(b); + absBulkGet(b); + + absBulkPutBuffer(b, direct); + absBulkGet(b); + + absBulkPutBuffer(b, !direct); + absBulkGet(b); + @@ -612,6 +681,37 @@ } } + // Exceptions in absolute bulk operations + + catchNullArgument(b, () -> b.get(7, null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (long[])null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (LongBuffer)null, 0, 42)); + + long[] tmpa = new long[42]; + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42)); + + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + + LongBuffer tmpb = LongBuffer.allocate(42); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, -1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 41, 2)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(0, tmpb, 0, -1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpb, 0, 42)); + // Values b.clear(); @@ -819,6 +919,8 @@ catchReadOnlyBuffer(b, () -> absPut(rb)); catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutBuffer(rb, direct)); // put(LongBuffer) should not change source position final LongBuffer src = LongBuffer.allocate(1); --- old/test/jdk/java/nio/Buffer/BasicShort.java 2019-02-13 14:12:07.000000000 -0800 +++ new/test/jdk/java/nio/Buffer/BasicShort.java 2019-02-13 14:12:05.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -87,6 +87,18 @@ } } + private static void absBulkGet(ShortBuffer b) { + int n = b.capacity(); + int len = n - 7*2; + short[] a = new short[n + 7]; + b.position(42); + b.get(7, a, 7, len); + ck(b, b.position() == 42); + for (int i = 0; i < len; i++) { + ck(b, (long)a[i + 7], (long)((short)ic(i))); + } + } + private static void relPut(ShortBuffer b) { int n = b.capacity(); b.clear(); @@ -136,6 +148,47 @@ } } + private static void absBulkPutArray(ShortBuffer b) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + short[] a = new short[len + 7]; + for (int i = 0; i < len; i++) + a[i + 7] = (short)ic(i); + b.position(42); + b.put(7, a, 7, len); + ck(b, b.position() == 42); + } + + private static void absBulkPutBuffer(ShortBuffer b, boolean direct) { + int n = b.capacity(); + b.clear(); + int lim = n - 7; + int len = lim - 7; + b.limit(lim); + ShortBuffer c = direct ? + + + + ByteBuffer.allocateDirect(Short.BYTES*(len + 7)) + .asShortBuffer() + + : ShortBuffer.allocate(len + 7); + + if (direct) + System.out.println("Direct buffer: " + c.getClass().getName()); + + for (int i = 0; i < len; i++) + c.put(i + 7, (short)ic(i)); + b.position(42); + c.position(42); + b.put(7, c, 7, len); + ck(b, b.position() == 42); + ck(c, c.position() == 42); + } + //6231529 private static void callReset(ShortBuffer b) { b.position(0); @@ -452,6 +505,10 @@ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchNullArgument(Buffer b, Runnable thunk) { + tryCatch(b, NullPointerException.class, thunk); + } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { tryCatch(b, IllegalArgumentException.class, thunk); } @@ -476,7 +533,10 @@ if (ex.isAssignableFrom(x.getClass())) { caught = true; } else { - fail(x.getMessage() + " not expected"); + String s = x.getMessage(); + if (s == null) + s = x.getClass().getName(); + fail(s + " not expected"); } } if (!caught) { @@ -513,6 +573,15 @@ bulkPutBuffer(b); relGet(b); + absBulkPutArray(b); + absBulkGet(b); + + absBulkPutBuffer(b, direct); + absBulkGet(b); + + absBulkPutBuffer(b, !direct); + absBulkGet(b); + @@ -612,6 +681,37 @@ } } + // Exceptions in absolute bulk operations + + catchNullArgument(b, () -> b.get(7, null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (short[])null, 0, 42)); + catchNullArgument(b, () -> b.put(7, (ShortBuffer)null, 0, 42)); + + short[] tmpa = new short[42]; + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.get(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.get(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.get(b.limit() - 41, tmpa, 0, 42)); + + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpa, 41, -1)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + + ShortBuffer tmpb = ShortBuffer.allocate(42); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, -1, 42)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, 1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 42, -1)); + catchIndexOutOfBounds(b, () -> b.put(7, tmpb, 41, 2)); + catchIndexOutOfBounds(b, () -> b.put(-1, tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpb, 0, 1)); + catchIndexOutOfBounds(b, () -> b.put(0, tmpb, 0, -1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpb, 0, 42)); + // Values b.clear(); @@ -819,6 +919,8 @@ catchReadOnlyBuffer(b, () -> absPut(rb)); catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> absBulkPutBuffer(rb, direct)); // put(ShortBuffer) should not change source position final ShortBuffer src = ShortBuffer.allocate(1);