code: public final int read(char []buf, int offset, int length)
      throws IOException
    {
      if (_readEncoding != null) {
        return _readEncoding.read(buf, offset, length);
      }
  
      byte []readBuffer = _readBuffer;
      if (readBuffer == null)
        return -1;
  
      int readOffset = _readOffset;
      int readLength = _readLength;
  
      int sublen = Math.min(length, readLength - readOffset);
  
      if (readLength <= readOffset) {
        if (! readBuffer()) {
          return -1;
        }
  
        readLength = _readLength;
        readOffset = _readOffset;
  
        sublen = Math.min(length, readLength - readOffset);
      }
  
      for (int i = sublen - 1; i >= 0; i--) {
        buf[offset + i] = (char) (readBuffer[readOffset + i] & 0xff);
      }
  
      _readOffset = readOffset + sublen;
  
      return sublen;
    }
docs: Reads into a character buffer from the stream.  Like the byte
  array version, read may return less characters even though more
  characters are available.
  
  @param buf character buffer to fill
  @param offset starting offset into the character buffer
  @param length maximum number of characters to read
  @return number of characters read or -1 on end of file.