Skip to content

Instantly share code, notes, and snippets.

@jerolimov
Created August 9, 2011 12:02
Show Gist options
  • Save jerolimov/1133860 to your computer and use it in GitHub Desktop.
Save jerolimov/1133860 to your computer and use it in GitHub Desktop.
LazyStartingInputStream
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;
}
}
}
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