it.unimi.dsi.fastutil.io.FastBufferedInputStreamTest Maven / Gradle / Ivy
The newest version!
package it.unimi.dsi.fastutil.io;
import it.unimi.dsi.fastutil.io.FastBufferedInputStream;
import it.unimi.dsi.fastutil.io.FastBufferedInputStream.LineTerminator;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Random;
import org.junit.Test;
import static org.junit.Assert.*;
public class FastBufferedInputStreamTest {
private final static boolean DEBUG = false;
/** A byte array input stream that will return its data in small chunks,
* even it could actually return more data, and skips less bytes than it could.
*/
private static class BastardByteArrayInputStream extends ByteArrayInputStream {
private final static long seed = System.currentTimeMillis();
private final static Random r = new Random(seed);
static {
System.err.println("Seed: " + seed);
}
public BastardByteArrayInputStream(byte[] array) {
super(array);
}
@Override
public int read(byte[] buffer, int offset, int length) {
int k = r.nextInt(2) + 1;
return super.read(buffer, offset, length < k ? length : k);
}
public long skip(long n) {
int k = r.nextInt(2);
return super.skip(n < k ? n : k);
}
}
@SuppressWarnings("resource")
public void testReadline(int bufferSize) throws IOException {
FastBufferedInputStream stream;
byte[] b;
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r' }), bufferSize);
b = new byte[4];
stream.readLine(b, 0, b.length, EnumSet.of(LineTerminator.CR));
assertTrue(Arrays.toString(b), Arrays.equals(b, new byte[] { 'A', 'B', 'C', 0 }));
assertEquals(4, stream.position());
assertEquals(-1, stream.readLine(b, 0, b.length, EnumSet.of(LineTerminator.CR)));
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r' }), bufferSize);
assertEquals(4, stream.readLine(b, 0, b.length, EnumSet.of(LineTerminator.LF)));
assertEquals(4, stream.position());
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r' }), bufferSize);
assertEquals(4, stream.readLine(b, 0, b.length, EnumSet.of(LineTerminator.LF)));
assertEquals(4, stream.position());
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r' }), bufferSize);
assertEquals(4, stream.readLine(b, 0, b.length, EnumSet.of(LineTerminator.CR_LF)));
assertEquals(4, stream.position());
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r' }), bufferSize);
assertEquals(4, stream.readLine(b, 0, b.length, EnumSet.of(LineTerminator.CR_LF)));
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'C', '\r' }));
assertEquals(4, stream.position());
b = new byte[4];
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r' }), bufferSize);
stream.readLine(b, 0, 2, EnumSet.of(LineTerminator.CR));
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 0, 0 }));
assertEquals(2, stream.position());
// Reads with only LF as terminator
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r', '\n', 'D' }), bufferSize);
assertEquals(4, stream.readLine(b, 0, 4, EnumSet.of(LineTerminator.LF)));
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'C', '\r' }));
assertEquals(4, stream.position());
assertEquals(0, stream.readLine(b, 0, 4, EnumSet.of(LineTerminator.LF)));
assertEquals(5, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'C', '\r' }));
assertEquals(1, stream.readLine(b, 2, 2, EnumSet.of(LineTerminator.LF)));
assertEquals(6, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'D', '\r' }));
// Reads with both LF and CR/LF as terminators
b = new byte[4];
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r', '\n', 'D' }), bufferSize);
assertEquals(3, stream.readLine(b, 0, 4, EnumSet.of(LineTerminator.CR, LineTerminator.CR_LF)));
assertEquals(5, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'C', 0 }));
assertEquals(1, stream.readLine(b, 2, 2, EnumSet.of(LineTerminator.CR, LineTerminator.CR_LF)));
assertEquals(6, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'D', 0 }));
// Reads with only CR as terminator
b = new byte[4];
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r', '\n', 'D' }), bufferSize);
assertEquals(3, stream.readLine(b, 0, 4, EnumSet.of(LineTerminator.CR)));
assertEquals(4, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'C', 0 }));
assertEquals(2, stream.readLine(b, 2, 2, EnumSet.of(LineTerminator.CR)));
assertEquals(6, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', '\n', 'D' }));
// Reads with only CR/LF as terminator
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r', '\n', 'D' }), bufferSize);
b = new byte[4];
assertEquals(3, stream.readLine(b, 0, 4, EnumSet.of(LineTerminator.CR_LF)));
assertEquals(5, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'C', 0 }));
assertEquals(1, stream.readLine(b, 0, 4, EnumSet.of(LineTerminator.CR_LF)));
assertEquals(6, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'D', 'B', 'C', 0 }));
assertEquals(-1, stream.readLine(b, 0, 4, EnumSet.of(LineTerminator.CR_LF)));
// Reads with both CR and CR/LF as terminator
// CR at end-of-file
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r' }), bufferSize);
b = new byte[4];
assertEquals(3, stream.readLine(b, 0, 4, EnumSet.of(LineTerminator.CR_LF, LineTerminator.CR)));
assertEquals(4, stream.position());
assertTrue(Arrays.equals(b, new byte[] { 'A', 'B', 'C', 0 }));
}
@Test
public void testReadLine() throws IOException {
testReadline(1);
testReadline(2);
testReadline(3);
testReadline(4);
testReadline(5);
testReadline(6);
testReadline(7);
testReadline(100);
}
@SuppressWarnings("resource")
public void testSkip(int bufferSize) throws IOException {
FastBufferedInputStream stream;
stream = new FastBufferedInputStream(new BastardByteArrayInputStream(new byte[] { 'A', 'B', 'C', '\r', '\n', 'D' }), bufferSize);
assertEquals(2, stream.skip(2));
assertEquals(2, stream.position());
assertEquals(1, stream.skip(1));
assertEquals(3, stream.position());
assertEquals(3, stream.skip(4));
assertEquals(6, stream.position());
assertEquals(0, stream.skip(1));
assertEquals(6, stream.position());
}
@Test
public void testSkip() throws IOException {
testSkip(1);
testSkip(2);
testSkip(3);
testSkip(4);
testSkip(5);
testSkip(6);
testSkip(7);
testSkip(100);
}
@Test
public void testPosition() throws IOException {
File temp = File.createTempFile(this.getClass().getSimpleName(), ".tmp");
temp.deleteOnExit();
FileOutputStream fos = new FileOutputStream(temp);
fos.write(new byte[] { 0, 1, 2, 3, 4 });
fos.close();
FastBufferedInputStream stream = new FastBufferedInputStream(new FileInputStream(temp), 2);
byte[] b = new byte[2];
stream.read(b);
stream.flush();
stream.position(0);
assertEquals(0, stream.read());
stream.close();
stream = new FastBufferedInputStream(new FileInputStream(temp));
b = new byte[1];
stream.read(b);
stream.flush();
stream.position(0);
assertEquals(0, stream.read());
stream.close();
stream = new FastBufferedInputStream(new FileInputStream(temp));
b = new byte[5];
stream.read(b);
stream.flush();
assertEquals(-1, stream.read());
stream.position(5);
assertEquals(-1, stream.read());
stream.position(0);
assertEquals(0, stream.read());
stream.position(1);
assertEquals(1, stream.read());
stream.position(3);
assertEquals(3, stream.read());
stream.position(1);
assertEquals(1, stream.read());
stream.position(0);
assertEquals(0, stream.read());
stream.close();
}
@Test
public void testRead() throws IOException {
// Reads with length larger than buffer size
// No head, no stream
InputStream stream = new FastBufferedInputStream(new ByteArrayInputStream(new byte[] {}), 1);
byte[] b = new byte[4];
assertEquals(-1, stream.read(b, 0, 2));
// Some head, no stream
stream = new FastBufferedInputStream(new ByteArrayInputStream(new byte[] { 'A', 'B' }), 2);
b = new byte[4];
assertEquals(1, stream.read(b, 0, 1));
assertEquals(1, stream.read(b, 0, 3));
// Some head, some stream
stream = new FastBufferedInputStream(new ByteArrayInputStream(new byte[] { 'A', 'B', 'C', 'D' }), 2);
b = new byte[4];
assertEquals(1, stream.read(b, 0, 1));
assertEquals(3, stream.read(b, 0, 3));
// No head, some stream
stream = new FastBufferedInputStream(new ByteArrayInputStream(new byte[] { 'A', 'B', 'C', 'D' }), 2);
b = new byte[4];
assertEquals(3, stream.read(b, 0, 3));
// Reads with length smaller than or equal to buffer size
// No head, no stream
stream = new FastBufferedInputStream(new ByteArrayInputStream(new byte[] {}), 4);
b = new byte[4];
assertEquals(-1, stream.read(b, 0, 2));
}
@SuppressWarnings("resource")
public void testRandom(int bufferSize) throws IOException {
File temp = File.createTempFile(this.getClass().getSimpleName(), "tmp");
temp.deleteOnExit();
// Create temp random file
FileOutputStream out = new FileOutputStream(temp);
Random random = new Random();
int length = 100000 + random.nextInt(10000);
for(int i = 0; i < length; i++) out.write(random.nextInt());
out.close();
FastBufferedInputStream bis = new FastBufferedInputStream(new FileInputStream(temp), bufferSize);
FileInputStream test = new FileInputStream(temp);
FileChannel fc = test.getChannel();
int a1, a2, off, len, pos;
byte b1[] = new byte[32768];
byte b2[] = new byte[32768];
while(true) {
switch(random.nextInt(6)) {
case 0:
if (DEBUG) System.err.println("read()");
a1 = bis.read();
a2 = test.read();
assertEquals(a1, a2);
if (a1 == -1) return;
break;
case 1:
off = random.nextInt(b1.length);
len = random.nextInt(b1.length - off + 1);
a1 = bis.read(b1, off, len);
a2 = test.read(b2, off, len);
if (DEBUG) System.err.println("read(b, " + off + ", " + len + ")");
assertEquals(a1, a2);
for(int i = off; i < off + len; i++) assertEquals("Position " + i, b1[i], b2[i]);
break;
case 2:
if (DEBUG) System.err.println("available()");
assertEquals(bis.available(), test.available());
break;
case 3:
if (DEBUG) System.err.println("position()");
pos = (int)bis.position();
assertEquals((int)fc.position(), pos);
break;
case 4:
pos = random.nextInt(length);
bis.position(pos);
if (DEBUG) System.err.println("position(" + pos + ")");
(test = new FileInputStream(temp)).skip(pos);
fc = test.getChannel();
break;
case 5:
pos = random.nextInt((int)(length - bis.position() + 1));
a1 = (int)bis.skip(pos);
a2 = (int)test.skip(pos);
if (DEBUG) System.err.println("skip(" + pos + ")");
assertEquals(a1, a2);
break;
}
}
}
@Test
public void testRandom() throws IOException {
testRandom(1);
testRandom(2);
testRandom(3);
testRandom(100);
testRandom(2048);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy