Repository: jclouds Updated Branches: refs/heads/1.7.x 10a1b230a -> c85d728a5
Handle short reads in BasePayloadSlicer InputStream.read(byte[]) can return fewer bytes than requested. Specifically ByteSource.concat(ByteSource...).openStream() will only return as many bytes as the current ByteSource contains. Thus ByteSources.repeatingArrayByteSource(byte[]).openStream() will return short reads despite the byte[] input from its single logical InputStream. Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/c85d728a Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/c85d728a Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/c85d728a Branch: refs/heads/1.7.x Commit: c85d728a5a6e8bec3283703aa2fda22aef4dd925 Parents: b41c4c2 Author: Andrew Gaul <[email protected]> Authored: Wed Jul 2 15:02:26 2014 -0700 Committer: Andrew Gaul <[email protected]> Committed: Wed Jul 2 15:30:15 2014 -0700 ---------------------------------------------------------------------- .../org/jclouds/io/internal/BasePayloadSlicer.java | 16 ++++++++++++---- .../jclouds/io/internal/BasePayloadSlicerTest.java | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/c85d728a/core/src/main/java/org/jclouds/io/internal/BasePayloadSlicer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/jclouds/io/internal/BasePayloadSlicer.java b/core/src/main/java/org/jclouds/io/internal/BasePayloadSlicer.java index 8c181c0..13b2624 100644 --- a/core/src/main/java/org/jclouds/io/internal/BasePayloadSlicer.java +++ b/core/src/main/java/org/jclouds/io/internal/BasePayloadSlicer.java @@ -98,17 +98,25 @@ public class BasePayloadSlicer implements PayloadSlicer { private Payload getNextPayload() { byte[] content = new byte[readLen]; - int read = 0; + int offset = 0; try { - if ((read = input.read(content)) == -1) { - return null; + while (true) { + int read = input.read(content, offset, readLen - offset); + if (read <= 0) { + if (offset == 0) { + return null; + } else { + break; + } + } + offset += read; } } catch (IOException e) { throw Throwables.propagate(e); } - return createPayload((content.length == read) ? content : Arrays.copyOf(content, read)); + return createPayload((content.length == offset) ? content : Arrays.copyOf(content, offset)); } private Payload createPayload(byte[] content) { http://git-wip-us.apache.org/repos/asf/jclouds/blob/c85d728a/core/src/test/java/org/jclouds/io/internal/BasePayloadSlicerTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/jclouds/io/internal/BasePayloadSlicerTest.java b/core/src/test/java/org/jclouds/io/internal/BasePayloadSlicerTest.java index b2d27b0..17e4076 100644 --- a/core/src/test/java/org/jclouds/io/internal/BasePayloadSlicerTest.java +++ b/core/src/test/java/org/jclouds/io/internal/BasePayloadSlicerTest.java @@ -24,13 +24,17 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Iterator; +import org.jclouds.io.ByteSources; import org.jclouds.io.Payload; import org.jclouds.io.PayloadSlicer; +import org.jclouds.io.payloads.ByteSourcePayload; import org.jclouds.io.payloads.InputStreamPayload; import org.jclouds.util.Strings2; import org.testng.annotations.Test; import com.google.common.base.Charsets; +import com.google.common.collect.Iterables; +import com.google.common.io.ByteSource; import com.google.common.io.ByteStreams; @Test @@ -67,4 +71,15 @@ public class BasePayloadSlicerTest { } + @Test + public void testIterableSliceWithRepeatingByteSource() throws IOException { + String content = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n"; /* 53 chars */ + byte[] contentBytes = content.getBytes(Charsets.UTF_8); + ByteSource byteSource = ByteSources.repeatingArrayByteSource(contentBytes).slice(0, 1024); + PayloadSlicer slicer = new BasePayloadSlicer(); + Payload payload = new ByteSourcePayload(byteSource); + + assertEquals(Iterables.size(slicer.slice(payload, 100)), 11); + assertEquals(Iterables.size(slicer.slice(payload, 53)), 20); + } }
