test.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 );
}
}
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 );
}
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 ) );
}
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 - 2024 Weber Informatics LLC | Privacy Policy