I’m currently writing my own Brainfuck interpreter in Java and because I want it to be able to read code from files I wrote a BFInputStream that filters unnecessary symbols out. It looks like this:
import java.io.FilterInputStream;
import java.io.InputStream;
import java.io.IOException;
public class BFInputStream extends FilterInputStream {
public BFInputStream(InputStream in) {
super(in);
}
public int read() throws IOException {
while(true) {
int i = super.read();
// keep LF for line number checking.
if(i == -1 || i == 10 ||( i >= 43 && i <= 46) || i == 60 || i == 62 || i == 91 || i == 93)
return i;
}
}
public int read(byte[] b, int off, int len) throws IOException {
if(off < 0 || len < 0 || len > b.length - off) throw new IndexOutOfBoundsException();
for(int i=0; i<len; i++) {
int j = read();
if(j < 1) return i;
b[off+i] = (byte)j;
}
return len;
}
}
My Interpreter uses LineNumberReader<-InputStreamReader<-BFInputStream<-FileInputStream to read the file. But everytime it reaches the end of the file it throws:
java.io.IOException: Underlying input stream returned zero bytes
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:268) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158) at java.io.InputStreamReader.read(InputStreamReader.java:167) at java.io.BufferedReader.fill(BufferedReader.java:136) at java.io.BufferedReader.read(BufferedReader.java:157) at java.io.LineNumberReader.read(LineNumberReader.java:108) at Interpreter.run(Interpreter.java:101) at Interpreter.main(Interpreter.java:180)
Interpreter.java:101 contains a call to BFInputStream.read().
I’m not sure if I understand the exception correctly. I think the stream returned no bytes at all (because of a timeout). I guess if there was a huge chunk of non-BF characters then that could be possible but at the end of the file? FileInputStream and therefore FilterInputStream and BFInputStream should return -1.
What is wrong with my code?
if (j < 1)should beif (j < 0), because EOF is indicated by-1. Also, your method never returns -1 at EOF.The correct implementation would look like this: