code: public String read(int maxStringLength) throws IOException {
          if (maxStringLength < 4) {
              throw new IllegalArgumentException("maxStringLength must be 4 or more, not "
                      + maxStringLength);
          }
  
          if (!open) {
              throw new IllegalStateException("Stream has already been closed.");
          }
  
          int bytesRequestedForEncoding = maxStringLength / 4 * 3;
  
          if (bytesRequestedForEncoding > bytesInBuffer) {
              readMoreBytesFromStream();
          }
  
          if (bytesInBuffer == 0 && !innerStreamHasMoreData) {
              return null;
          }
  
          int bytesToEncode = Math.min(bytesRequestedForEncoding, bytesInBuffer);
          String result = encodeBytesFromBuffer(bytesToEncode);
          return result;
      }
docs: Read encoded data from the stream. Data is read in 3-byte multiples and
  encoded into 4-character sequences, per the Base64 specification. As many
  bytes as possible will be read, limited by the amount of data available
  and by the limitation of maxStringLength on the size of the resulting
  encoded String. Since the smallest unit of encoded data is 4 characters,
  maxStringLength must not be less than 4.
  
  @param maxStringLength
  the resulting String will be no longer than this.
  @return a String that is no longer than maxStringLength, or null if no
  data remains to be read.
  @throws IllegalArgumentException
  if maxStringLength is less than 4.
  @throws IllegalStateException
  if called after the stream is closed.
  @throws IOException
  from inner InputStream.