Class ReaderInputStream

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable

    @GwtIncompatible
    final class ReaderInputStream
    extends java.io.InputStream
    An InputStream that converts characters from a Reader into bytes using an arbitrary Charset.

    This is an alternative to copying the data to an OutputStream via a Writer, which is necessarily blocking. By implementing an InputStream it allows consumers to "pull" as much data as they can handle, which is more convenient when dealing with flow controlled, async APIs.

    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.nio.ByteBuffer byteBuffer
      byteBuffer holds encoded characters that have not yet been sent to the caller of the input stream.
      private java.nio.CharBuffer charBuffer
      charBuffer holds characters that have been read from the Reader but not encoded yet.
      private boolean doneFlushing
      Whether we've successfully flushed the encoder.
      private boolean draining
      Whether we're copying encoded bytes to the caller's buffer.
      private java.nio.charset.CharsetEncoder encoder  
      private boolean endOfInput
      Whether we've finished reading the reader.
      private java.io.Reader reader  
      private byte[] singleByte  
    • Constructor Summary

      Constructors 
      Constructor Description
      ReaderInputStream​(java.io.Reader reader, java.nio.charset.CharsetEncoder encoder, int bufferSize)
      Creates a new input stream that will encode the characters from reader into bytes using the given character set encoder.
      ReaderInputStream​(java.io.Reader reader, java.nio.charset.Charset charset, int bufferSize)
      Creates a new input stream that will encode the characters from reader into bytes using the given character set.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private static int availableCapacity​(java.nio.Buffer buffer)
      Returns the number of elements between the limit and capacity.
      void close()  
      private int drain​(byte[] b, int off, int len)
      Copy as much of the byte buffer into the output array as possible, returning the (positive) number of characters copied.
      private static java.nio.CharBuffer grow​(java.nio.CharBuffer buf)
      Returns a new CharBuffer identical to buf, except twice the capacity.
      int read()  
      int read​(byte[] b, int off, int len)  
      private void readMoreChars()
      Handle the case of underflow caused by needing more input characters.
      private void startDraining​(boolean overflow)
      Flips the buffer output buffer so we can start reading bytes from it.
      • Methods inherited from class java.io.InputStream

        available, mark, markSupported, nullInputStream, read, readAllBytes, readNBytes, readNBytes, reset, skip, transferTo
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • reader

        private final java.io.Reader reader
      • encoder

        private final java.nio.charset.CharsetEncoder encoder
      • singleByte

        private final byte[] singleByte
      • charBuffer

        private java.nio.CharBuffer charBuffer
        charBuffer holds characters that have been read from the Reader but not encoded yet. The buffer is perpetually "flipped" (unencoded characters between position and limit).
      • byteBuffer

        private java.nio.ByteBuffer byteBuffer
        byteBuffer holds encoded characters that have not yet been sent to the caller of the input stream. When encoding it is "unflipped" (encoded bytes between 0 and position) and when draining it is flipped (undrained bytes between position and limit).
      • endOfInput

        private boolean endOfInput
        Whether we've finished reading the reader.
      • draining

        private boolean draining
        Whether we're copying encoded bytes to the caller's buffer.
      • doneFlushing

        private boolean doneFlushing
        Whether we've successfully flushed the encoder.
    • Constructor Detail

      • ReaderInputStream

        ReaderInputStream​(java.io.Reader reader,
                          java.nio.charset.Charset charset,
                          int bufferSize)
        Creates a new input stream that will encode the characters from reader into bytes using the given character set. Malformed input and unmappable characters will be replaced.
        Parameters:
        reader - input source
        charset - character set used for encoding chars to bytes
        bufferSize - size of internal input and output buffers
        Throws:
        java.lang.IllegalArgumentException - if bufferSize is non-positive
      • ReaderInputStream

        ReaderInputStream​(java.io.Reader reader,
                          java.nio.charset.CharsetEncoder encoder,
                          int bufferSize)
        Creates a new input stream that will encode the characters from reader into bytes using the given character set encoder.
        Parameters:
        reader - input source
        encoder - character set encoder used for encoding chars to bytes
        bufferSize - size of internal input and output buffers
        Throws:
        java.lang.IllegalArgumentException - if bufferSize is non-positive
    • Method Detail

      • close

        public void close()
                   throws java.io.IOException
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Overrides:
        close in class java.io.InputStream
        Throws:
        java.io.IOException
      • read

        public int read()
                 throws java.io.IOException
        Specified by:
        read in class java.io.InputStream
        Throws:
        java.io.IOException
      • read

        public int read​(byte[] b,
                        int off,
                        int len)
                 throws java.io.IOException
        Overrides:
        read in class java.io.InputStream
        Throws:
        java.io.IOException
      • grow

        private static java.nio.CharBuffer grow​(java.nio.CharBuffer buf)
        Returns a new CharBuffer identical to buf, except twice the capacity.
      • readMoreChars

        private void readMoreChars()
                            throws java.io.IOException
        Handle the case of underflow caused by needing more input characters.
        Throws:
        java.io.IOException
      • availableCapacity

        private static int availableCapacity​(java.nio.Buffer buffer)
        Returns the number of elements between the limit and capacity.
      • startDraining

        private void startDraining​(boolean overflow)
        Flips the buffer output buffer so we can start reading bytes from it. If we are starting to drain because there was overflow, and there aren't actually any characters to drain, then the overflow must be due to a small output buffer.
      • drain

        private int drain​(byte[] b,
                          int off,
                          int len)
        Copy as much of the byte buffer into the output array as possible, returning the (positive) number of characters copied.