mirror of https://github.com/apache/jclouds.git
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.
This commit is contained in:
parent
b41c4c2ab0
commit
c85d728a5a
|
@ -98,17 +98,25 @@ public class BasePayloadSlicer implements PayloadSlicer {
|
||||||
|
|
||||||
private Payload getNextPayload() {
|
private Payload getNextPayload() {
|
||||||
byte[] content = new byte[readLen];
|
byte[] content = new byte[readLen];
|
||||||
int read = 0;
|
int offset = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((read = input.read(content)) == -1) {
|
while (true) {
|
||||||
|
int read = input.read(content, offset, readLen - offset);
|
||||||
|
if (read <= 0) {
|
||||||
|
if (offset == 0) {
|
||||||
return null;
|
return null;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += read;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw Throwables.propagate(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) {
|
private Payload createPayload(byte[] content) {
|
||||||
|
|
|
@ -24,13 +24,17 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.jclouds.io.ByteSources;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
import org.jclouds.io.PayloadSlicer;
|
import org.jclouds.io.PayloadSlicer;
|
||||||
|
import org.jclouds.io.payloads.ByteSourcePayload;
|
||||||
import org.jclouds.io.payloads.InputStreamPayload;
|
import org.jclouds.io.payloads.InputStreamPayload;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
|
|
||||||
@Test
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue