From 590e8f44e624a97ad0180db7f309eb9a448bf60d Mon Sep 17 00:00:00 2001 From: Ian Wetherbee Date: Thu, 7 Jun 2012 16:22:53 -0700 Subject: [PATCH] Fix UnionInputStream.read to be more Java-like Relax the read() method to not block until exactly "len" bytes have been read. Instead, return when one or more bytes have been read, up to "len", so UnionInputStream more closely resembles InputStream's read() method. Change-Id: I3f632be8eb85a4a0baf27c9f067c8d817162de2b --- .../jgit/util/io/UnionInputStreamTest.java | 23 +++++++++++++++++++ .../jgit/util/io/UnionInputStream.java | 21 +++++++---------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java index 9fb323c4d..daebffbc1 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java @@ -50,6 +50,7 @@ import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; import org.junit.Test; @@ -238,4 +239,26 @@ public class UnionInputStreamTest { assertEquals("I AM A TEST", e.getMessage()); } } + + @Test + public void testNonBlockingPartialRead() throws Exception { + InputStream errorReadStream = new InputStream() { + @Override + public int read() throws IOException { + throw new IOException("Expected"); + } + }; + final UnionInputStream u = new UnionInputStream( + new ByteArrayInputStream(new byte[]{1,2,3}), + errorReadStream); + byte buf[] = new byte[10]; + assertEquals(3, u.read(buf, 0, 10)); + assertTrue(Arrays.equals(new byte[] {1,2,3}, slice(buf, 3))); + try { + u.read(buf, 0, 1); + fail("Expected exception from errorReadStream"); + } catch (IOException e) { + assertEquals("Expected", e.getMessage()); + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java index 0df3775f1..20dcd4659 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java @@ -138,23 +138,18 @@ public class UnionInputStream extends InputStream { @Override public int read(byte[] b, int off, int len) throws IOException { - int cnt = 0; - while (0 < len) { + if (len == 0) + return 0; + for (;;) { final InputStream in = head(); final int n = in.read(b, off, len); - if (0 < n) { - cnt += n; - off += n; - len -= n; - } else if (in == EOF) - return 0 < cnt ? cnt : -1; - else { + if (0 < n) + return n; + else if (in == EOF) + return -1; + else pop(); - if (0 < cnt) - break; - } } - return cnt; } @Override