Skip to content

Commit 1fc451c

Browse files
committed
[CODEC-130] Provided implementation of skip and available for BaseNCodecInputStream, added unit tests.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/codec/trunk@1302585 13f79535-47bb-0310-9956-ffa450edef68
1 parent caa142d commit 1fc451c

3 files changed

Lines changed: 148 additions & 8 deletions

File tree

src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,54 @@ public boolean markSupported() {
134134
return false; // not an easy job to support marks
135135
}
136136

137+
/**
138+
* {@inheritDoc}
139+
*
140+
* @throws IllegalArgumentException if the provided skip length is negative
141+
*/
142+
@Override
143+
public long skip(long n) throws IOException {
144+
if (n < 0) {
145+
throw new IllegalArgumentException("Negative skip length");
146+
}
147+
148+
// skip in chunks of 512 bytes
149+
final byte[] b = new byte[512];
150+
final int max = (int) Math.min(n, Integer.MAX_VALUE);
151+
int total = 0;
152+
153+
while (total < max) {
154+
int len = max - total;
155+
if (len > b.length) {
156+
len = b.length;
157+
}
158+
len = read(b, 0, len);
159+
if (len == EOF) {
160+
break;
161+
}
162+
total += len;
163+
}
164+
165+
return total;
166+
}
167+
168+
/**
169+
* {@inheritDoc}
170+
*
171+
* @return <code>0</code> if the {@link InputStream} has reached <code>EOF</code>,
172+
* <code>1</code> otherwise
173+
*/
174+
public int available() throws IOException {
175+
// Note: the logic is similar to the InflaterInputStream:
176+
// as long as we have not reached EOF, indicate that there is more
177+
// data available. As we do not know for sure how much data is left,
178+
// just return 1 as a safe guess.
179+
180+
// use the EOF flag of the underlying codec instance
181+
if (baseNCodec.eof) {
182+
return 0;
183+
} else {
184+
return 1;
185+
}
186+
}
137187
}

src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.io.InputStream;
3030
import java.util.Arrays;
3131

32-
import org.junit.Ignore;
3332
import org.junit.Test;
3433

3534
public class Base32InputStreamTest {
@@ -46,7 +45,6 @@ public class Base32InputStreamTest {
4645
* Tests the problem reported in CODEC-130. Missing / wrong implementation of skip.
4746
*/
4847
@Test
49-
@Ignore
5048
public void testCodec130() throws IOException {
5149
ByteArrayOutputStream bos = new ByteArrayOutputStream();
5250
Base32OutputStream base32os = new Base32OutputStream(bos);
@@ -146,6 +144,24 @@ public void testCodec105() throws IOException {
146144
// );
147145
// }
148146

147+
/**
148+
* Tests skipping past the end of a stream.
149+
*
150+
* @throws Throwable
151+
*/
152+
@Test
153+
public void testAvailable() throws Throwable {
154+
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
155+
Base32InputStream b32stream = new Base32InputStream(ins);
156+
assertEquals(1, b32stream.available());
157+
assertEquals(3, b32stream.skip(10));
158+
// End of stream reached
159+
assertEquals(0, b32stream.available());
160+
assertEquals(-1, b32stream.read());
161+
assertEquals(-1, b32stream.read());
162+
assertEquals(0, b32stream.available());
163+
}
164+
149165
/**
150166
* Tests the Base32InputStream implementation against empty input.
151167
*
@@ -466,6 +482,21 @@ public void testSkipNone() throws Throwable {
466482
assertEquals(-1, b32stream.read());
467483
}
468484

485+
/**
486+
* Tests skipping number of characters larger than the internal buffer.
487+
*
488+
* @throws Throwable
489+
*/
490+
@Test
491+
public void testSkipBig() throws Throwable {
492+
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
493+
Base32InputStream b32stream = new Base32InputStream(ins);
494+
assertEquals(3, b32stream.skip(1024));
495+
// End of stream reached
496+
assertEquals(-1, b32stream.read());
497+
assertEquals(-1, b32stream.read());
498+
}
499+
469500
/**
470501
* Tests skipping past the end of a stream.
471502
*
@@ -475,7 +506,8 @@ public void testSkipNone() throws Throwable {
475506
public void testSkipPastEnd() throws Throwable {
476507
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
477508
Base32InputStream b32stream = new Base32InputStream(ins);
478-
assertEquals(8, b32stream.skip(10));
509+
// due to CODEC-130, skip now skips correctly decoded characters rather than encoded
510+
assertEquals(3, b32stream.skip(10));
479511
// End of stream reached
480512
assertEquals(-1, b32stream.read());
481513
assertEquals(-1, b32stream.read());
@@ -490,9 +522,22 @@ public void testSkipPastEnd() throws Throwable {
490522
public void testSkipToEnd() throws Throwable {
491523
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
492524
Base32InputStream b32stream = new Base32InputStream(ins);
493-
assertEquals(8, b32stream.skip(8));
525+
// due to CODEC-130, skip now skips correctly decoded characters rather than encoded
526+
assertEquals(3, b32stream.skip(3));
494527
// End of stream reached
495528
assertEquals(-1, b32stream.read());
496529
assertEquals(-1, b32stream.read());
497530
}
531+
532+
/**
533+
* Tests if negative arguments to skip are handled correctly.
534+
*
535+
* @throws Throwable
536+
*/
537+
@Test(expected=IllegalArgumentException.class)
538+
public void testSkipWrongArgument() throws Throwable {
539+
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
540+
Base32InputStream b32stream = new Base32InputStream(ins);
541+
b32stream.skip(-10);
542+
}
498543
}

src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.io.InputStreamReader;
3333
import java.util.Arrays;
3434

35-
import org.junit.Ignore;
3635
import org.junit.Test;
3736

3837
/**
@@ -56,7 +55,6 @@ public class Base64InputStreamTest {
5655
* Tests the problem reported in CODEC-130. Missing / wrong implementation of skip.
5756
*/
5857
@Test
59-
@Ignore
6058
public void testCodec130() throws IOException {
6159
ByteArrayOutputStream bos = new ByteArrayOutputStream();
6260
Base64OutputStream base64os = new Base64OutputStream(bos);
@@ -154,6 +152,24 @@ public void testCodec98NPE() throws Exception {
154152
assertEquals("codec-98 NPE Base64InputStream", Base64TestData.CODEC_98_NPE_DECODED, decoded);
155153
}
156154

155+
/**
156+
* Tests skipping past the end of a stream.
157+
*
158+
* @throws Throwable
159+
*/
160+
@Test
161+
public void testAvailable() throws Throwable {
162+
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64));
163+
Base64InputStream b64stream = new Base64InputStream(ins);
164+
assertEquals(1, b64stream.available());
165+
assertEquals(6, b64stream.skip(10));
166+
// End of stream reached
167+
assertEquals(0, b64stream.available());
168+
assertEquals(-1, b64stream.read());
169+
assertEquals(-1, b64stream.read());
170+
assertEquals(0, b64stream.available());
171+
}
172+
157173
/**
158174
* Tests the Base64InputStream implementation against empty input.
159175
*
@@ -460,6 +476,21 @@ public void testReadOutOfBounds() throws Exception {
460476
}
461477
}
462478

479+
/**
480+
* Tests skipping number of characters larger than the internal buffer.
481+
*
482+
* @throws Throwable
483+
*/
484+
@Test
485+
public void testSkipBig() throws Throwable {
486+
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64));
487+
Base64InputStream b64stream = new Base64InputStream(ins);
488+
assertEquals(6, b64stream.skip(1024));
489+
// End of stream reached
490+
assertEquals(-1, b64stream.read());
491+
assertEquals(-1, b64stream.read());
492+
}
493+
463494
/**
464495
* Tests skipping as a noop
465496
*
@@ -486,7 +517,8 @@ public void testSkipNone() throws Throwable {
486517
public void testSkipPastEnd() throws Throwable {
487518
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64));
488519
Base64InputStream b64stream = new Base64InputStream(ins);
489-
assertEquals(8, b64stream.skip(10));
520+
// due to CODEC-130, skip now skips correctly decoded characters rather than encoded
521+
assertEquals(6, b64stream.skip(10));
490522
// End of stream reached
491523
assertEquals(-1, b64stream.read());
492524
assertEquals(-1, b64stream.read());
@@ -501,9 +533,22 @@ public void testSkipPastEnd() throws Throwable {
501533
public void testSkipToEnd() throws Throwable {
502534
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64));
503535
Base64InputStream b64stream = new Base64InputStream(ins);
504-
assertEquals(8, b64stream.skip(8));
536+
// due to CODEC-130, skip now skips correctly decoded characters rather than encoded
537+
assertEquals(6, b64stream.skip(6));
505538
// End of stream reached
506539
assertEquals(-1, b64stream.read());
507540
assertEquals(-1, b64stream.read());
508541
}
542+
543+
/**
544+
* Tests if negative arguments to skip are handled correctly.
545+
*
546+
* @throws Throwable
547+
*/
548+
@Test(expected=IllegalArgumentException.class)
549+
public void testSkipWrongArgument() throws Throwable {
550+
InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_B64));
551+
Base64InputStream b64stream = new Base64InputStream(ins);
552+
b64stream.skip(-10);
553+
}
509554
}

0 commit comments

Comments
 (0)