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);
+   }
 }

Reply via email to