Added support for offset/length in ByteArrayImageInputStream.

This commit is contained in:
Harald Kuhr 2012-04-16 10:19:15 +02:00
parent 2f07329296
commit 927723a472
2 changed files with 115 additions and 6 deletions

View File

@ -14,30 +14,41 @@ import java.io.IOException;
*/ */
public final class ByteArrayImageInputStream extends ImageInputStreamImpl { public final class ByteArrayImageInputStream extends ImageInputStreamImpl {
private final byte[] data; private final byte[] data;
private int dataOffset;
private int dataLength;
public ByteArrayImageInputStream(final byte[] pData) { public ByteArrayImageInputStream(final byte[] pData) {
this(pData, 0, pData != null ? pData.length : -1);
}
public ByteArrayImageInputStream(final byte[] pData, int offset, int length) {
Validate.notNull(pData, "data"); Validate.notNull(pData, "data");
Validate.isTrue(offset >= 0 && offset <= pData.length, offset, "offset out of range: %d");
Validate.isTrue(length >= 0 && length <= pData.length - offset, length, "length out of range: %d");
data = pData; data = pData;
dataOffset = offset;
dataLength = length;
} }
public int read() throws IOException { public int read() throws IOException {
if (streamPos >= data.length) { if (streamPos >= dataLength) {
return -1; return -1;
} }
bitOffset = 0; bitOffset = 0;
return data[((int) streamPos++)] & 0xff; return data[((int) streamPos++) + dataOffset] & 0xff;
} }
public int read(byte[] pBuffer, int pOffset, int pLength) throws IOException { public int read(byte[] pBuffer, int pOffset, int pLength) throws IOException {
if (streamPos >= data.length) { if (streamPos >= dataLength) {
return -1; return -1;
} }
int length = (int) Math.min(data.length - streamPos, pLength); int length = (int) Math.min(this.dataLength - streamPos, pLength);
bitOffset = 0; bitOffset = 0;
System.arraycopy(data, (int) streamPos, pBuffer, pOffset, length); System.arraycopy(data, (int) streamPos + dataOffset, pBuffer, pOffset, length);
streamPos += length; streamPos += length;
return length; return length;
@ -45,7 +56,7 @@ public final class ByteArrayImageInputStream extends ImageInputStreamImpl {
@Override @Override
public long length() { public long length() {
return data.length; return dataLength;
} }
@Override @Override

View File

@ -35,6 +35,71 @@ public class ByteArrayImageInputStreamTestCase extends TestCase {
} }
} }
public void testCreateNullOffLen() {
try {
new ByteArrayImageInputStream(null, 0, -1);
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
assertNotNull("Null exception message", expected.getMessage());
String message = expected.getMessage().toLowerCase();
assertTrue("Exception message does not contain parameter name", message.contains("data"));
assertTrue("Exception message does not contain null", message.contains("null"));
}
}
public void testCreateNegativeOff() {
try {
new ByteArrayImageInputStream(new byte[0], -1, 1);
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
assertNotNull("Null exception message", expected.getMessage());
String message = expected.getMessage().toLowerCase();
assertTrue("Exception message does not contain parameter name", message.contains("offset"));
assertTrue("Exception message does not contain -1", message.contains("-1"));
}
}
public void testCreateBadOff() {
try {
new ByteArrayImageInputStream(new byte[1], 2, 0);
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
assertNotNull("Null exception message", expected.getMessage());
String message = expected.getMessage().toLowerCase();
assertTrue("Exception message does not contain parameter name", message.contains("offset"));
assertTrue("Exception message does not contain 2", message.contains("2"));
}
}
public void testCreateNegativeLen() {
try {
new ByteArrayImageInputStream(new byte[0], 0, -1);
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
assertNotNull("Null exception message", expected.getMessage());
String message = expected.getMessage().toLowerCase();
assertTrue("Exception message does not contain parameter name", message.contains("length"));
assertTrue("Exception message does not contain -1", message.contains("-1"));
}
}
public void testCreateBadLen() {
try {
new ByteArrayImageInputStream(new byte[1], 0, 2);
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
assertNotNull("Null exception message", expected.getMessage());
String message = expected.getMessage().toLowerCase();
assertTrue("Exception message does not contain parameter name", message.contains("length"));
assertTrue("Exception message does not contain ™", message.contains("2"));
}
}
public void testRead() throws IOException { public void testRead() throws IOException {
byte[] data = new byte[1024 * 1024]; byte[] data = new byte[1024 * 1024];
random.nextBytes(data); random.nextBytes(data);
@ -48,6 +113,21 @@ public class ByteArrayImageInputStreamTestCase extends TestCase {
} }
} }
public void testReadOffsetLen() throws IOException {
byte[] data = new byte[1024 * 1024];
random.nextBytes(data);
int offset = random.nextInt(data.length / 10);
int length = random.nextInt(data.length - offset);
ByteArrayImageInputStream stream = new ByteArrayImageInputStream(data, offset, length);
assertEquals("Data length should be same as stream length", length, stream.length());
for (int i = offset; i < offset + length; i++) {
assertEquals("Wrong data read", data[i] & 0xff, stream.read());
}
}
public void testReadArray() throws IOException { public void testReadArray() throws IOException {
byte[] data = new byte[1024 * 1024]; byte[] data = new byte[1024 * 1024];
random.nextBytes(data); random.nextBytes(data);
@ -64,6 +144,24 @@ public class ByteArrayImageInputStreamTestCase extends TestCase {
} }
} }
public void testReadArrayOffLen() throws IOException {
byte[] data = new byte[1024 * 1024];
random.nextBytes(data);
int offset = random.nextInt(data.length - 10240);
int length = 10240;
ByteArrayImageInputStream stream = new ByteArrayImageInputStream(data, offset, length);
assertEquals("Data length should be same as stream length", length, stream.length());
byte[] result = new byte[1024];
for (int i = 0; i < length / result.length; i++) {
stream.readFully(result);
assertTrue("Wrong data read: " + i, rangeEquals(data, offset + i * result.length, result, 0, result.length));
}
}
public void testReadSkip() throws IOException { public void testReadSkip() throws IOException {
byte[] data = new byte[1024 * 14]; byte[] data = new byte[1024 * 14];
random.nextBytes(data); random.nextBytes(data);