code: @Override
    public int read(final byte[] b, int off, int len) throws IOException {
      int read = 0;
      while (len > 0) {
        if (encoderOut.position() > 0) {
          encoderOut.flip();
          int c = Math.min(encoderOut.remaining(), len);
          encoderOut.get(b, off, c);
          off += c;
          len -= c;
          read += c;
          encoderOut.compact();
        } else {
          if (!endOfInput && (lastCoderResult == null || lastCoderResult.isUnderflow())) {
            encoderIn.compact();
            int position = encoderIn.position();
            // We don't use Reader#read(CharBuffer) here because it is more efficient
            // to write directly to the underlying char array (the default implementation
            // copies data to a temporary char array).
            int c = reader.read(encoderIn.array(), position, encoderIn.remaining());
            if (c == -1) {
              endOfInput = true;
            } else {
              encoderIn.position(position + c);
            }
            encoderIn.flip();
          }
          lastCoderResult = encoder.encode(encoderIn, encoderOut, endOfInput);
          if (endOfInput && encoderOut.position() == 0) {
            break;
          }
        }
      }
      return read == 0 && endOfInput ? -1 : read;
    }
docs: Read the specified number of bytes into an array.
  
  @param b the byte array to read into
  @param off the offset to start reading bytes into
  @param len the number of bytes to read
  @return the number of bytes read or <code>-1</code> if the end of the stream has been reached
  @throws IOException if an I/O error occurs