@Override
    public int read() throws IOException {
      if (chunk == null || !readUntil(pos)) return -1;

      while (pos > chunk.lastIndex()) {
        chunk = chunk.next;
      }
      return chunk.get(pos++);
    }
  boolean readUntil(int pos) throws IOException {
    if (!eof) {
      while ((pos >= dataLen) && !eof) {
        if (lastChunk.full()) {
          lastChunk.setNext(new LinkedChunk(lastChunk.lastIndex() + 1, nextChunkSize));
          lastChunk = lastChunk.next();
          nextChunkSize *= 2;
        }

        int bytesRead = lastChunk.readFrom(impl, MAX_BYTES_PER_READ);
        if (bytesRead < 0) {
          eof = true;
        } else {
          dataLen += bytesRead;
        }
      }
    }
    if (pos < dataLen) {
      this.pos = Math.max(this.pos, pos + 1);
      return true;
    }
    return false;
  }
 @Override
 public int read() throws IOException {
   int curpos = pos;
   if (readUntil(curpos)) return lastChunk.get(curpos);
   return -1;
 }