Do we need `reachedEOF` field? I think we can assume InputStream.read always returns -1 once it returns -1.