public int read(byte[] b, int off, int len) throws IOException {
    checkClosed();

    if (b == null) {
      throw new NullPointerException("b == null!");
    }
    if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
      throw new IndexOutOfBoundsException(
          "off < 0 || len < 0 || off+len > b.length || off+len < 0!");
    }

    bitOffset = 0;

    if (len == 0) {
      return 0;
    }

    long pos = cache.loadFromStream(stream, streamPos + len);

    len = (int) (pos - streamPos); // In case stream ended early

    if (len > 0) {
      cache.read(b, off, len, streamPos);
      streamPos += len;
      return len;
    } else {
      return -1;
    }
  }
 public int read() throws IOException {
   checkClosed();
   bitOffset = 0;
   long pos = cache.loadFromStream(stream, streamPos + 1);
   if (pos >= streamPos + 1) {
     return cache.read(streamPos++);
   } else {
     return -1;
   }
 }