--- old/src/java.base/share/classes/java/nio/X-Buffer.java.template 2018-06-12 02:16:29.058365636 -0700 +++ new/src/java.base/share/classes/java/nio/X-Buffer.java.template 2018-06-12 02:16:28.680330807 -0700 @@ -1353,6 +1353,38 @@ #end[floatingPointType] } + /** + * Finds and returns the relative index of the first mismatch between this + * buffer and a given buffer. The index is relative to the + * {@link #position() position} of each buffer and will be in the range of + * 0 (inclusive) up to the smaller of the {@link #remaining() remaining} + * elements in each buffer (exclusive). + * + *

If the two buffers share a common prefix then the returned index is + * the length of the common prefix and it follows that there is a mismatch + * between the two buffers at that index within the respective buffers. + * If one buffer is a proper prefix of the other then the returned index is + * the smaller of the remaining elements in each buffer, and it follows that + * the index is only valid for the buffer with the larger number of + * remaining elements. + * Otherwise, there is no mismatch. + * + * @param that + * The byte buffer to be tested for a mismatch with this buffer + * + * @return The relative index of the first mismatch between this and the + * given buffer, otherwise -1 if no mismatch. + * + * @since 11 + */ + public int mismatch($Type$Buffer that) { + int length = Math.min(this.remaining(), that.remaining()); + int r = BufferMismatch.mismatch(this, this.position(), + that, that.position(), + length); + return (r == -1 && this.remaining() != that.remaining()) ? length : r; + } + // -- Other char stuff -- #if[char] --- old/test/jdk/java/nio/Buffer/EqualsCompareTest.java 2018-06-12 02:16:29.833437044 -0700 +++ new/test/jdk/java/nio/Buffer/EqualsCompareTest.java 2018-06-12 02:16:29.462402861 -0700 @@ -86,6 +86,7 @@ final MethodHandle eq; final MethodHandle cmp; + final MethodHandle mismtch; final MethodHandle getter; final MethodHandle setter; @@ -99,6 +100,7 @@ try { eq = lookup.findVirtual(bufferType, "equals", MethodType.methodType(boolean.class, Object.class)); cmp = lookup.findVirtual(bufferType, "compareTo", MethodType.methodType(int.class, bufferType)); + mismtch = lookup.findVirtual(bufferType, "mismatch", MethodType.methodType(int.class, bufferType)); getter = lookup.findVirtual(bufferType, "get", MethodType.methodType(elementType, int.class)); setter = lookup.findVirtual(bufferType, "put", MethodType.methodType(bufferType, int.class, elementType)); @@ -186,6 +188,18 @@ return true; } + int mismatch(T a, T b) { + try { + return (int) mismtch.invoke(a, b); + } + catch (RuntimeException | Error e) { + throw e; + } + catch (Throwable t) { + throw new Error(t); + } + } + static class Bytes extends BufferType { Bytes(BufferKind k) { super(k, ByteBuffer.class, byte.class); @@ -423,7 +437,6 @@ } } - static Object[][] bufferTypes; @DataProvider @@ -635,12 +648,21 @@ if (eq) { Assert.assertEquals(bt.compare(as, bs), 0); Assert.assertEquals(bt.compare(bs, as), 0); + + // If buffers are equal, there shall be no mismatch + Assert.assertEquals(bt.mismatch(as, bs), -1); + Assert.assertEquals(bt.mismatch(bs, as), -1); } else { int aCb = bt.compare(as, bs); int bCa = bt.compare(bs, as); int v = Integer.signum(aCb) * Integer.signum(bCa); Assert.assertTrue(v == -1); + + int aMs = bt.mismatch(as, bs); + int bMs = bt.mismatch(bs, as); + Assert.assertNotEquals(aMs, -1); + Assert.assertEquals(aMs, bMs); } } } @@ -661,6 +683,11 @@ int aCc = bt.compare(as, cs); int v = Integer.signum(cCa) * Integer.signum(aCc); Assert.assertTrue(v == -1); + + int cMa = bt.mismatch(cs, as); + int aMc = bt.mismatch(as, cs); + Assert.assertEquals(cMa, aMc); + Assert.assertEquals(cMa, i - aFrom); } } }