Created
August 9, 2011 12:02
-
-
Save christoph-jerolimov/1133860 to your computer and use it in GitHub Desktop.
LazyStartingInputStream
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.FilterInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
public class LazyStartingInputStream extends FilterInputStream { | |
private final byte[] startingAfter; | |
private int foundAlready = 0; | |
public LazyStartingInputStream(byte[] startingAfter, InputStream in) { | |
super(in); | |
if (startingAfter.length == 0) { | |
throw new IllegalArgumentException("LazyStartingInputStream must have an startingAfter value."); | |
} | |
this.startingAfter = startingAfter; | |
} | |
private boolean foundAll() { | |
return startingAfter.length == foundAlready; | |
} | |
@Override | |
public int read() throws IOException { | |
if (foundAll()) { | |
return in.read(); | |
} else { | |
int read; | |
while ((read = in.read()) != -1) { | |
if (read == startingAfter[foundAlready]) { | |
foundAlready++; | |
if (foundAll()) { | |
return in.read(); | |
} | |
} else { | |
foundAlready = 0; | |
} | |
} | |
return -1; | |
} | |
} | |
@Override | |
public int read(byte[] b) throws IOException { | |
return this.read(b, 0, b.length); | |
} | |
@Override | |
public int read(byte[] buffer, int off, int len) throws IOException { | |
if (foundAll()) { | |
return in.read(buffer, off, len); | |
} else { | |
int read; | |
while ((read = in.read(buffer, off, len)) != -1) { | |
for (int index = off; index < off + read; index++) { | |
if (buffer[index] == startingAfter[foundAlready]) { | |
System.out.println("."); | |
foundAlready++; | |
if (foundAll()) { | |
System.arraycopy(buffer, index + 1, buffer, off, off + read - index - 1); | |
return off + read - index - 1; | |
} | |
} else { | |
foundAlready = 0; | |
} | |
} | |
} | |
return -1; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.ByteArrayInputStream; | |
import java.io.IOException; | |
import org.junit.Assert; | |
import org.junit.Test; | |
public class LazyStartingInputStreamTest { | |
@Test(expected = IllegalArgumentException.class) | |
public void testWithoutStartingAfterParameter() throws IOException { | |
createInstance("", ""); | |
} | |
@Test | |
public void testEmptyStream() throws IOException { | |
LazyStartingInputStream lsis = createInstance("\r\n\r\n", ""); | |
Assert.assertEquals(-1, lsis.read()); | |
Assert.assertEquals(-1, lsis.read(new byte[1024])); | |
Assert.assertEquals(-1, lsis.read(new byte[1024], 1, 2)); | |
} | |
@Test | |
public void testIgnoreUnexpectedData() throws IOException { | |
LazyStartingInputStream lsis = createInstance("\r\n\r\n", "No new line!"); | |
Assert.assertEquals(-1, lsis.read()); | |
Assert.assertEquals(-1, lsis.read(new byte[1024])); | |
Assert.assertEquals(-1, lsis.read(new byte[1024], 1, 2)); | |
} | |
@Test | |
public void testFindResultViaRead() throws IOException { | |
LazyStartingInputStream lsis = createInstance("\r\n\r\n", "Header\r\n\r\nContent"); | |
Assert.assertEquals('C', lsis.read()); | |
Assert.assertEquals('o', lsis.read()); | |
Assert.assertEquals('n', lsis.read()); | |
Assert.assertEquals('t', lsis.read()); | |
Assert.assertEquals('e', lsis.read()); | |
Assert.assertEquals('n', lsis.read()); | |
Assert.assertEquals('t', lsis.read()); | |
Assert.assertEquals(-1, lsis.read()); | |
} | |
@Test | |
public void testFindResultViaReadCompleteBlock() throws IOException { | |
LazyStartingInputStream lsis = createInstance("\r\n\r\n", "Header\r\n\r\nContent"); | |
byte[] buffer = new byte[1024]; | |
int length = lsis.read(buffer); | |
Assert.assertEquals(7, length); | |
Assert.assertEquals('C', buffer[0]); | |
Assert.assertEquals('o', buffer[1]); | |
Assert.assertEquals('n', buffer[2]); | |
Assert.assertEquals('t', buffer[3]); | |
Assert.assertEquals('e', buffer[4]); | |
Assert.assertEquals('n', buffer[5]); | |
Assert.assertEquals('t', buffer[6]); | |
length = lsis.read(buffer); | |
Assert.assertEquals(-1, length); | |
} | |
@Test | |
public void testFindResultViaReadSplittedBlock() throws IOException { | |
LazyStartingInputStream lsis = createInstance("\r\n\r\n", "Header\r\n\r\nContent"); | |
byte[] buffer = new byte[4]; | |
// Ignore "Head", ignore "He\r\n" and return "Co" | |
int length = lsis.read(buffer); | |
Assert.assertEquals(2, length); | |
Assert.assertEquals('C', buffer[0]); | |
Assert.assertEquals('o', buffer[1]); | |
length = lsis.read(buffer); | |
Assert.assertEquals(4, length); | |
Assert.assertEquals('n', buffer[0]); | |
Assert.assertEquals('t', buffer[1]); | |
Assert.assertEquals('e', buffer[2]); | |
Assert.assertEquals('n', buffer[3]); | |
length = lsis.read(buffer); | |
Assert.assertEquals(1, length); | |
Assert.assertEquals('t', buffer[0]); | |
length = lsis.read(buffer); | |
Assert.assertEquals(-1, length); | |
} | |
@Test | |
public void testFindResultViaReadWithUsedBufferAndSplittedBlock() throws IOException { | |
LazyStartingInputStream lsis = createInstance("\r\n\r\n", "Header\r\n\r\nContent"); | |
byte[] buffer = new byte[8]; | |
// Ignore "Head", ignore "He\r\n" and return "Co" | |
int length = lsis.read(buffer, 2, 4); | |
Assert.assertEquals(2, length); | |
Assert.assertEquals('C', buffer[2]); | |
Assert.assertEquals('o', buffer[3]); | |
length = lsis.read(buffer, 2, 4); | |
Assert.assertEquals(4, length); | |
Assert.assertEquals('n', buffer[2]); | |
Assert.assertEquals('t', buffer[3]); | |
Assert.assertEquals('e', buffer[4]); | |
Assert.assertEquals('n', buffer[5]); | |
length = lsis.read(buffer, 2, 4); | |
Assert.assertEquals(1, length); | |
Assert.assertEquals('t', buffer[2]); | |
length = lsis.read(buffer, 2, 4); | |
Assert.assertEquals(-1, length); | |
} | |
private LazyStartingInputStream createInstance(String startingAfter, String data) { | |
ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes()); | |
return new LazyStartingInputStream(startingAfter.getBytes(), bais); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment