diff --git a/CHANGELOG.md b/CHANGELOG.md
index 805767f6..92babdb3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## [0.25.1](https://github.com/osheroff/mysql-binlog-connector-java/compare/0.25.0...0.25.1) - 2021-04-20
+
+- performance improves in ByteArrayInputStream#read
+
## [0.25.0](https://github.com/osheroff/mysql-binlog-connector-java/compare/0.24.1...0.25.0) - 2021-03-04
- bring back jdk 8 support, this caused... ahem. Issues.
diff --git a/README.md b/README.md
index f665442c..407e27a3 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,18 @@
-# mysql-binlog-connector-java [](https://travis-ci.org/shyiko/mysql-binlog-connector-java) [](https://coveralls.io/r/shyiko/mysql-binlog-connector-java?branch=master) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.github.shyiko%22%20AND%20a%3A%22mysql-binlog-connector-java%22)
+# mysql-binlog-connector-java [](https://travis-ci.org/shyiko/mysql-binlog-connector-java) [](https://coveralls.io/r/shyiko/mysql-binlog-connector-java?branch=master) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.github.shyiko%22%20AND%20a%3A%22mysql-binlog-connector-java%22)
-MySQL Binary Log connector.
+MySQL Binary Log connector. @osheroff's fork of @shiyko's project, probably
+the "official" version of this. With help from the Debezium devs.
+
+## Usage
+
+```xml
+
* value ::= * object | diff --git a/src/main/java/com/github/shyiko/mysql/binlog/io/ByteArrayInputStream.java b/src/main/java/com/github/shyiko/mysql/binlog/io/ByteArrayInputStream.java index b883394f..3cfaf979 100644 --- a/src/main/java/com/github/shyiko/mysql/binlog/io/ByteArrayInputStream.java +++ b/src/main/java/com/github/shyiko/mysql/binlog/io/ByteArrayInputStream.java @@ -222,6 +222,50 @@ private int readWithinBlockBoundaries() throws IOException { return inputStream.read(); } + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + + if (peek != null) { + b[off] = (byte)(int)peek; + off += 1; + len -= 1; + } + + int read = readWithinBlockBoundaries(b, off, len); + + if (read > 0) { + this.pos += read; + } + + if (peek != null) { + peek = null; + read = read <= 0 ? 1 : read + 1; + } + + return read; + } + + private int readWithinBlockBoundaries(byte[] b, int off, int len) throws IOException { + if (blockLength == -1) { + return inputStream.read(b, off, len); + } else if (blockLength == 0) { + return -1; + } + + int read = inputStream.read(b, off, Math.min(len, blockLength)); + if (read > 0) { + blockLength -= read; + } + return read; + } + @Override public void close() throws IOException { inputStream.close(); diff --git a/src/test/java/com/github/shyiko/mysql/binlog/io/ByteArrayInputStreamTest.java b/src/test/java/com/github/shyiko/mysql/binlog/io/ByteArrayInputStreamTest.java new file mode 100644 index 00000000..8f0eb112 --- /dev/null +++ b/src/test/java/com/github/shyiko/mysql/binlog/io/ByteArrayInputStreamTest.java @@ -0,0 +1,102 @@ +package com.github.shyiko.mysql.binlog.io; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +public class ByteArrayInputStreamTest { + @Test + public void testReadToArray() throws Exception { + byte[] buff = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + ByteArrayInputStream in = new ByteArrayInputStream(buff); + assertEquals(in.getPosition(), 0); + + byte[] b = new byte[20]; + + int read = in.read(b, 0, 0); + assertEquals(read, 0); + assertEquals(in.getPosition(), 0); + + read = in.read(b, 0, 4); + assertEquals(read, 4); + assertEquals(b[3], 3); + assertEquals(in.getPosition(), 4); + + read = in.read(b, 4, 4); + assertEquals(read, 4); + assertEquals(b[7], 7); + assertEquals(in.getPosition(), 8); + + read = in.read(b, 8, 4); + assertEquals(read, 4); + assertEquals(b[11], 11); + assertEquals(in.getPosition(), 12); + + read = in.read(b, 12, 4); + assertEquals(read, 4); + assertEquals(b[15], 15); + assertEquals(in.getPosition(), 16); + + read = in.read(b, 16, 4); + assertEquals(read, -1); + assertEquals(in.getPosition(), 16); + } + + @Test + public void testReadToArrayWithinBlockBoundaries() throws Exception { + byte[] buff = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8}; + ByteArrayInputStream in = new ByteArrayInputStream(buff); + byte[] b = new byte[8]; + + in.enterBlock(4); + + int read = in.read(b, 0, 3); + assertEquals(read, 3); + assertEquals(b[2], 2); + + read = in.read(b, 3, 3); + assertEquals(read, 1); + assertEquals(b[3], 3); + + read = in.read(b, 4, 3); + assertEquals(read, -1); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testReadToArrayWithNullBuff() throws Exception { + ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{}); + in.read(null, 0, 4); + } + + @Test(expectedExceptions = IndexOutOfBoundsException.class) + public void testReadToArrayWhenLenExceedsBuffSize() throws Exception { + ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2}); + byte[] b = new byte[1]; + in.read(b, 0, 4); + } + + @Test(expectedExceptions = IndexOutOfBoundsException.class) + public void testReadToArrayWhenOffsetNegative() throws Exception { + ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2}); + byte[] b = new byte[1]; + in.read(b, -1, 1); + } + + @Test(expectedExceptions = IndexOutOfBoundsException.class) + public void testReadToArrayWhenLengthNegative() throws Exception { + ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{0, 1, 2}); + byte[] b = new byte[1]; + in.read(b, 0, -1); + } + + @Test + public void testPeekAndReadToArray() throws Exception { + ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{5, 6, 7}); + byte[] b = new byte[3]; + assertEquals(in.peek(), 5); + int read = in.read(b, 0, 3); + assertEquals(read, 3); + assertEquals(b[0], 5); + assertEquals(b[2], 7); + } +}