code: @Override
  	public int read(@NotNull char[] cbuf, int off, int len) throws IOException {
  		if (pos > limit)
  			return -1;
  
  		try {
  			int i;
  			int to = off + len;
  			for (i = off; i < to && pos < limit; i++) {
  				int c = buf[pos] & 0xff;
  				if (c < 0x80) {
  					cbuf[i] = (char) c;
  					pos++;
  				} else if (c < 0xE0) {
  					cbuf[i] = (char) ((c & 0x1F) << 6 | buf[pos + 1] & 0x3F);
  					pos += 2;
  				} else {
  					cbuf[i] = (char) ((c & 0x0F) << 12 | (buf[pos + 1] & 0x3F) << 6 | (buf[pos + 2] & 0x3F));
  					pos += 3;
  				}
  			}
  			if (pos > limit) {
  				throw new IOException();
  			}
  			if (pos == limit) {
  				pos = Integer.MAX_VALUE;
  			}
  			return i - off;
  		} catch (ArrayIndexOutOfBoundsException e) {
  			throw new IOException(e);
  		}
  	}
docs: Reads characters into a portion of an array
  
  @param cbuf destination buffer
  @param off  offset at which to start storing characters
  @param len  maximum number of characters to read
  @return the number of characters read, or -1 if the end of the stream has been reached
  @throws IOException if an I/O error occurs