From 927723a472e8d8b6381341aa8ac578daea13ecda Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Mon, 16 Apr 2012 10:19:15 +0200 Subject: [PATCH] Added support for offset/length in ByteArrayImageInputStream. --- .../stream/ByteArrayImageInputStream.java | 23 +++-- .../ByteArrayImageInputStreamTestCase.java | 98 +++++++++++++++++++ 2 files changed, 115 insertions(+), 6 deletions(-) diff --git a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/stream/ByteArrayImageInputStream.java b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/stream/ByteArrayImageInputStream.java index b4feb8bf..6a95a2f3 100755 --- a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/stream/ByteArrayImageInputStream.java +++ b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/stream/ByteArrayImageInputStream.java @@ -14,30 +14,41 @@ import java.io.IOException; */ public final class ByteArrayImageInputStream extends ImageInputStreamImpl { private final byte[] data; + private int dataOffset; + private int dataLength; 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.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; + dataOffset = offset; + dataLength = length; } public int read() throws IOException { - if (streamPos >= data.length) { + if (streamPos >= dataLength) { return -1; } bitOffset = 0; - return data[((int) streamPos++)] & 0xff; + return data[((int) streamPos++) + dataOffset] & 0xff; } public int read(byte[] pBuffer, int pOffset, int pLength) throws IOException { - if (streamPos >= data.length) { + if (streamPos >= dataLength) { return -1; } - int length = (int) Math.min(data.length - streamPos, pLength); + int length = (int) Math.min(this.dataLength - streamPos, pLength); bitOffset = 0; - System.arraycopy(data, (int) streamPos, pBuffer, pOffset, length); + System.arraycopy(data, (int) streamPos + dataOffset, pBuffer, pOffset, length); streamPos += length; return length; @@ -45,7 +56,7 @@ public final class ByteArrayImageInputStream extends ImageInputStreamImpl { @Override public long length() { - return data.length; + return dataLength; } @Override diff --git a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/stream/ByteArrayImageInputStreamTestCase.java b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/stream/ByteArrayImageInputStreamTestCase.java index 2405ede3..868b082c 100755 --- a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/stream/ByteArrayImageInputStreamTestCase.java +++ b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/stream/ByteArrayImageInputStreamTestCase.java @@ -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 { byte[] data = new byte[1024 * 1024]; 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 { byte[] data = new byte[1024 * 1024]; 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 { byte[] data = new byte[1024 * 14]; random.nextBytes(data);