Author: tn Date: Mon Mar 19 18:33:42 2012 New Revision: 1302585 URL: http://svn.apache.org/viewvc?rev=1302585&view=rev Log: [CODEC-130] Provided implementation of skip and available for BaseNCodecInputStream, added unit tests.
Modified: commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java Modified: commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java?rev=1302585&r1=1302584&r2=1302585&view=diff ============================================================================== --- commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java (original) +++ commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java Mon Mar 19 18:33:42 2012 @@ -134,4 +134,54 @@ public class BaseNCodecInputStream exten return false; // not an easy job to support marks } + /** + * {@inheritDoc} + * + * @throws IllegalArgumentException if the provided skip length is negative + */ + @Override + public long skip(long n) throws IOException { + if (n < 0) { + throw new IllegalArgumentException("Negative skip length"); + } + + // skip in chunks of 512 bytes + final byte[] b = new byte[512]; + final int max = (int) Math.min(n, Integer.MAX_VALUE); + int total = 0; + + while (total < max) { + int len = max - total; + if (len > b.length) { + len = b.length; + } + len = read(b, 0, len); + if (len == EOF) { + break; + } + total += len; + } + + return total; + } + + /** + * {@inheritDoc} + * + * @return <code>0</code> if the {@link InputStream} has reached <code>EOF</code>, + * <code>1</code> otherwise + */ + public int available() throws IOException { + // Note: the logic is similar to the InflaterInputStream: + // as long as we have not reached EOF, indicate that there is more + // data available. As we do not know for sure how much data is left, + // just return 1 as a safe guess. + + // use the EOF flag of the underlying codec instance + if (baseNCodec.eof) { + return 0; + } else { + return 1; + } + } } Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java?rev=1302585&r1=1302584&r2=1302585&view=diff ============================================================================== --- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java (original) +++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java Mon Mar 19 18:33:42 2012 @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.util.Arrays; -import org.junit.Ignore; import org.junit.Test; public class Base32InputStreamTest { @@ -46,7 +45,6 @@ public class Base32InputStreamTest { * Tests the problem reported in CODEC-130. Missing / wrong implementation of skip. */ @Test - @Ignore public void testCodec130() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); Base32OutputStream base32os = new Base32OutputStream(bos); @@ -147,6 +145,24 @@ public class Base32InputStreamTest { // } /** + * Tests skipping past the end of a stream. + * + * @throws Throwable + */ + @Test + public void testAvailable() throws Throwable { + InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO)); + Base32InputStream b32stream = new Base32InputStream(ins); + assertEquals(1, b32stream.available()); + assertEquals(3, b32stream.skip(10)); + // End of stream reached + assertEquals(0, b32stream.available()); + assertEquals(-1, b32stream.read()); + assertEquals(-1, b32stream.read()); + assertEquals(0, b32stream.available()); + } + + /** * Tests the Base32InputStream implementation against empty input. * * @throws Exception @@ -467,6 +483,21 @@ public class Base32InputStreamTest { } /** + * Tests skipping number of characters larger than the internal buffer. + * + * @throws Throwable + */ + @Test + public void testSkipBig() throws Throwable { + InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO)); + Base32InputStream b32stream = new Base32InputStream(ins); + assertEquals(3, b32stream.skip(1024)); + // End of stream reached + assertEquals(-1, b32stream.read()); + assertEquals(-1, b32stream.read()); + } + + /** * Tests skipping past the end of a stream. * * @throws Throwable @@ -475,7 +506,8 @@ public class Base32InputStreamTest { public void testSkipPastEnd() throws Throwable { InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO)); Base32InputStream b32stream = new Base32InputStream(ins); - assertEquals(8, b32stream.skip(10)); + // due to CODEC-130, skip now skips correctly decoded characters rather than encoded + assertEquals(3, b32stream.skip(10)); // End of stream reached assertEquals(-1, b32stream.read()); assertEquals(-1, b32stream.read()); @@ -490,9 +522,22 @@ public class Base32InputStreamTest { public void testSkipToEnd() throws Throwable { InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO)); Base32InputStream b32stream = new Base32InputStream(ins); - assertEquals(8, b32stream.skip(8)); + // due to CODEC-130, skip now skips correctly decoded characters rather than encoded + assertEquals(3, b32stream.skip(3)); // End of stream reached assertEquals(-1, b32stream.read()); assertEquals(-1, b32stream.read()); } + + /** + * Tests if negative arguments to skip are handled correctly. + * + * @throws Throwable + */ + @Test(expected=IllegalArgumentException.class) + public void testSkipWrongArgument() throws Throwable { + InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO)); + Base32InputStream b32stream = new Base32InputStream(ins); + b32stream.skip(-10); + } } Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java?rev=1302585&r1=1302584&r2=1302585&view=diff ============================================================================== --- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java (original) +++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java Mon Mar 19 18:33:42 2012 @@ -32,7 +32,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; -import org.junit.Ignore; import org.junit.Test; /** @@ -56,7 +55,6 @@ public class Base64InputStreamTest { * Tests the problem reported in CODEC-130. Missing / wrong implementation of skip. */ @Test - @Ignore public void testCodec130() throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); Base64OutputStream base64os = new Base64OutputStream(bos); @@ -155,6 +153,24 @@ public class Base64InputStreamTest { } /** + * Tests skipping past the end of a stream. + * + * @throws Throwable + */ + @Test + public void testAvailable() throws Throwable { + InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64)); + Base64InputStream b64stream = new Base64InputStream(ins); + assertEquals(1, b64stream.available()); + assertEquals(6, b64stream.skip(10)); + // End of stream reached + assertEquals(0, b64stream.available()); + assertEquals(-1, b64stream.read()); + assertEquals(-1, b64stream.read()); + assertEquals(0, b64stream.available()); + } + + /** * Tests the Base64InputStream implementation against empty input. * * @throws Exception @@ -461,6 +477,21 @@ public class Base64InputStreamTest { } /** + * Tests skipping number of characters larger than the internal buffer. + * + * @throws Throwable + */ + @Test + public void testSkipBig() throws Throwable { + InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64)); + Base64InputStream b64stream = new Base64InputStream(ins); + assertEquals(6, b64stream.skip(1024)); + // End of stream reached + assertEquals(-1, b64stream.read()); + assertEquals(-1, b64stream.read()); + } + + /** * Tests skipping as a noop * * @throws Throwable @@ -486,7 +517,8 @@ public class Base64InputStreamTest { public void testSkipPastEnd() throws Throwable { InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64)); Base64InputStream b64stream = new Base64InputStream(ins); - assertEquals(8, b64stream.skip(10)); + // due to CODEC-130, skip now skips correctly decoded characters rather than encoded + assertEquals(6, b64stream.skip(10)); // End of stream reached assertEquals(-1, b64stream.read()); assertEquals(-1, b64stream.read()); @@ -501,9 +533,22 @@ public class Base64InputStreamTest { public void testSkipToEnd() throws Throwable { InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64)); Base64InputStream b64stream = new Base64InputStream(ins); - assertEquals(8, b64stream.skip(8)); + // due to CODEC-130, skip now skips correctly decoded characters rather than encoded + assertEquals(6, b64stream.skip(6)); // End of stream reached assertEquals(-1, b64stream.read()); assertEquals(-1, b64stream.read()); } + + /** + * Tests if negative arguments to skip are handled correctly. + * + * @throws Throwable + */ + @Test(expected=IllegalArgumentException.class) + public void testSkipWrongArgument() throws Throwable { + InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64)); + Base64InputStream b64stream = new Base64InputStream(ins); + b64stream.skip(-10); + } }