diff options
author | Nick Burch <nick@apache.org> | 2008-01-09 16:31:25 +0000 |
---|---|---|
committer | Nick Burch <nick@apache.org> | 2008-01-09 16:31:25 +0000 |
commit | e27090859f2a5d2ef5997059e37024fcb9179c4f (patch) | |
tree | 10b289164f577d7add3db29bfee8445d8500515c /src/testcases/org/apache/poi/poifs/storage | |
parent | 4d4b3081ff1177015d11794dc1b0c0b18db5421a (diff) | |
download | poi-e27090859f2a5d2ef5997059e37024fcb9179c4f.tar.gz poi-e27090859f2a5d2ef5997059e37024fcb9179c4f.zip |
Tweak comments, layout and exceptions in IOUtils and RawDataBlock. It should now be clearer exactly what they do, and when they become unhappy. Also include a test that ensures that when reading from a slow inputstream (as per bug #42834), we really are ok with the data dribbling in, and do not require it to all come in in blocksize chunks at one
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@610439 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/testcases/org/apache/poi/poifs/storage')
-rw-r--r-- | src/testcases/org/apache/poi/poifs/storage/TestRawDataBlock.java | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlock.java b/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlock.java index 4756629e7a..1473fa82ea 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlock.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestRawDataBlock.java @@ -20,6 +20,7 @@ package org.apache.poi.poifs.storage; import java.io.*; +import java.util.Random; import junit.framework.*; @@ -124,6 +125,118 @@ public class TestRawDataBlock } } } + + /** + * Tests that when using a slow input stream, which + * won't return a full block at a time, we don't + * incorrectly think that there's not enough data + */ + public void testSlowInputStream() throws Exception { + for (int k = 1; k < 512; k++) { + byte[] data = new byte[ 512 ]; + for (int j = 0; j < data.length; j++) { + data[j] = (byte) j; + } + + // Shouldn't complain, as there is enough data, + // even if it dribbles through + RawDataBlock block = + new RawDataBlock(new SlowInputStream(data, k)); + assertFalse(block.eof()); + } + + // But if there wasn't enough data available, will + // complain + for (int k = 1; k < 512; k++) { + byte[] data = new byte[ 511 ]; + for (int j = 0; j < data.length; j++) { + data[j] = (byte) j; + } + + // Shouldn't complain, as there is enough data + try { + RawDataBlock block = + new RawDataBlock(new SlowInputStream(data, k)); + fail(); + } catch(IOException e) { + // as expected + } + } + } + + /** + * An input stream which will return a maximum of + * a given number of bytes to read, and often claims + * not to have any data + */ + public static class SlowInputStream extends InputStream { + private Random rnd = new Random(); + private byte[] data; + private int chunkSize; + private int pos = 0; + + public SlowInputStream(byte[] data, int chunkSize) { + this.chunkSize = chunkSize; + this.data = data; + } + + /** + * 75% of the time, claim there's no data available + */ + private boolean claimNoData() { + if(rnd.nextFloat() < 0.25f) { + return false; + } + return true; + } + + public int read() throws IOException { + if(pos >= data.length) { + return -1; + } + int ret = data[pos]; + pos++; + + if(ret < 0) ret += 256; + return ret; + } + + /** + * Reads the requested number of bytes, or the chunk + * size, whichever is lower. + * Quite often will simply claim to have no data + */ + public int read(byte[] b, int off, int len) throws IOException { + // Keep the length within the chunk size + if(len > chunkSize) { + len = chunkSize; + } + // Don't read off the end of the data + if(pos + len > data.length) { + len = data.length - pos; + + // Spot when we're out of data + if(len == 0) { + return -1; + } + } + + // 75% of the time, claim there's no data + if(claimNoData()) { + return 0; + } + + // Copy, and return what we read + System.arraycopy(data, pos, b, off, len); + pos += len; + return len; + } + + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + } /** * main method to run the unit tests |