Class ProcessingBufferedReader

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable, java.lang.Readable
    Direct Known Subclasses:
    ParseReader

    public class ProcessingBufferedReader
    extends java.io.Reader
    A reader that buffers data and allows this data to be processed before handing it to the consumer. This class also allows marking and resetting, as well as peeking upcoming buffered characters.

    The class maintains an internal buffer, which is of size bufferSize, part of which is used for the undo buffer of size undoBufferSize. The following indexes are maintained in the buffer:

    readIndex
    The index of the next character to be read.
    peekIndex
    The index of the next character to be peeked. After each read this is set to equal readIndex.
    bufferEndIndex
    The index directly after the last character in the buffer.
    fetchBufferIndex
    The index where a new buffer should be read. The default implementation is for fetchBufferIndex to equal bufferEndIndex, but processing of a stream may determine that rebuffering should occur earlier -- if a "\r\n" is split across buffers, for instance.
    Author:
    Garret Wilson
    See Also:
    Reader
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static int DEFAULT_BUFFER_SIZE
      The default size of buffered data.
      static int DEFAULT_UNDO_BUFFER_SIZE
      The default size of the buffer for unreading data.
      static int END_VALUE
      The value which indicates the end of the data has been reached.
      • Fields inherited from class java.io.Reader

        lock
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected void adjustIndexes​(int moveDelta)
      Adjusts all indexes by a certain amount.
      void close()
      Close the stream.
      protected void createBuffer()
      Creates a new buffer and initializes buffer indexes.
      protected int fetchBuffer()
      Fills a buffer with new information.
      protected char[] getBuffer()  
      protected int getBufferEndIndex()  
      int getBufferSize()  
      protected int getFetchBufferIndex()  
      protected int getMarkIndex()  
      protected int getPeekIndex()  
      protected java.io.Reader getReader()  
      protected int getReadIndex()  
      int getUndoBufferSize()  
      protected void initializeIndexes()
      Initializes relevant buffer indexes when, for example, the buffer is first created.
      boolean isEnd()  
      protected boolean isLastBuffer()  
      protected void loadBuffer​(java.lang.CharSequence bufferCharacters)
      Loads the buffer with the specified characters.
      void mark​(int readAheadLimit)
      boolean markSupported()
      protected void moveBuffer​(int sourceIndex, int destIndex, int len)
      Moves a portion of the buffer.
      int peek()
      Peeks at the next character to be read.
      int peek​(char[] cbuf, int off, int len)
      Peeks a specified number of characters into a portion of an array.
      protected void processBufferedData​(int newDataBeginIndex)
      Provides away to do initial processing on newly-buffered data.
      int read()
      Read a single character.
      int read​(char[] cbuf, int off, int len)
      Read characters into a portion of an array.
      boolean ready()
      void reset()
      void resetPeek()
      Resets any characters we've peeked so that the next peek will reflect the next character which will be read.
      protected void setBufferEndIndex​(int bufferEndIndex)
      Sets the index directly after the end of the last character in the buffer.
      protected void setEnd​(boolean isEnd)
      Sets whether the end of the data has been reached.
      protected void setFetchBufferIndex​(int fetchBufferIndex)
      Sets the index where a new buffer should be read.
      protected void setLastBuffer​(boolean lastBuffer)
      Sets whether or not the previously-read buffer was the last.
      protected void setPeekIndex​(int peekIndex)
      Sets the index of the next character to be peeked.
      protected void setReadIndex​(int readIndex)
      Sets the index of the next character to be read and checks to see if the end of the file has been reached.
      long skip​(long n)
      Skips the specified number of characters.
      void unread​(char[] cbuf)
      Pushes back an array of characters.
      void unread​(char[] cbuf, int off, int len)
      Pushes back a portion of an array of characters.
      void unread​(int c)
      Pushes back a single character.
      void unskip​(int n)
      Reverses the reading position to the previous characters read.
      protected boolean updateEnd()
      Checks to see if the end of the data has been reached, and updates the EOF property if so.
      • Methods inherited from class java.io.Reader

        nullReader, read, read, transferTo
      • Methods inherited from class java.lang.Object

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

      • END_VALUE

        public static final int END_VALUE
        The value which indicates the end of the data has been reached.
        See Also:
        read(), Constant Field Values
      • DEFAULT_UNDO_BUFFER_SIZE

        public static final int DEFAULT_UNDO_BUFFER_SIZE
        The default size of the buffer for unreading data.
        See Also:
        Constant Field Values
      • DEFAULT_BUFFER_SIZE

        public static final int DEFAULT_BUFFER_SIZE
        The default size of buffered data.
        See Also:
        Constant Field Values
    • Constructor Detail

      • ProcessingBufferedReader

        public ProcessingBufferedReader​(java.io.Reader reader)
        Constructor to create a ProcessingBufferedReader from another reader.
        Parameters:
        reader - The reader that contains the data.
      • ProcessingBufferedReader

        public ProcessingBufferedReader​(java.io.Reader reader,
                                        java.lang.CharSequence prereadCharacters)
                                 throws java.io.IOException
        Constructor to create a ProcessingBufferedReader from another reader, along with several characters that have already been read. prereadCharacters must be less than or equal to the length of the buffer.
        Parameters:
        reader - The reader that contains the data.
        prereadCharacters - The characters that have already been read.
        Throws:
        java.io.IOException - if prereadCharacters is too long for the buffer.
      • ProcessingBufferedReader

        public ProcessingBufferedReader​(java.lang.CharSequence characters)
                                 throws java.io.IOException
        Constructor to create a reader from the contents of a character sequence.
        Parameters:
        characters - The string that should be used for input.
        Throws:
        java.io.IOException - if an I/O error occurs.
    • Method Detail

      • getBufferSize

        public int getBufferSize()
        Returns:
        The size of buffered data, including undo buffer space.
        See Also:
        getUndoBufferSize()
      • getUndoBufferSize

        public int getUndoBufferSize()
        Returns:
        The size of the extra buffer for unreading data.
      • getBuffer

        protected char[] getBuffer()
        Returns:
        The internal buffer used to hold characters.
      • isLastBuffer

        protected boolean isLastBuffer()
        Returns:
        Whether or not we've read the last buffer. Technically the last buffer could have been read, but it might have been filled completely, in which case this function would still return false.
      • setLastBuffer

        protected void setLastBuffer​(boolean lastBuffer)
        Sets whether or not the previously-read buffer was the last.
        Parameters:
        lastBuffer - Whether the last buffer has been read.
      • getReadIndex

        protected int getReadIndex()
        Returns:
        The index of the next character to be read.
      • setReadIndex

        protected void setReadIndex​(int readIndex)
                             throws java.io.IOException
        Sets the index of the next character to be read and checks to see if the end of the file has been reached. Resets peeking.
        Parameters:
        readIndex - The index of the next character to be read.
        Throws:
        java.io.IOException - if an I/O error occurs.
        See Also:
        updateEnd()
      • getPeekIndex

        protected int getPeekIndex()
        Returns:
        The index of the next character to be peeked. After each read this is set to equal ReadIndex.
      • setPeekIndex

        protected void setPeekIndex​(int peekIndex)
        Sets the index of the next character to be peeked.
        Parameters:
        peekIndex - The index of the next character to be peeked.
      • getBufferEndIndex

        protected int getBufferEndIndex()
        Returns:
        The index directly after the end of the last character in the buffer.
      • setBufferEndIndex

        protected void setBufferEndIndex​(int bufferEndIndex)
        Sets the index directly after the end of the last character in the buffer.
        Parameters:
        bufferEndIndex - The index directly after the end of the last character in the buffer.
      • getFetchBufferIndex

        protected int getFetchBufferIndex()
        Returns:
        The index where a new buffer should be read. Usually equals BufferEndIndex.
        See Also:
        getBufferEndIndex()
      • setFetchBufferIndex

        protected void setFetchBufferIndex​(int fetchBufferIndex)
        Sets the index where a new buffer should be read.
        Parameters:
        fetchBufferIndex - The index where a new buffer should be read.
        See Also:
        setBufferEndIndex(int)
      • isEnd

        public boolean isEnd()
        Returns:
        Whether or not the end of the data has been reached.
      • setEnd

        protected void setEnd​(boolean isEnd)
        Sets whether the end of the data has been reached.
        Parameters:
        isEnd - Whether the end of the data has been reached.
      • ready

        public boolean ready()
                      throws java.io.IOException

        This implementation returns true if there are characters already in the buffer that would be used without fetching another buffer, or if the underlying reader is ready.

        Overrides:
        ready in class java.io.Reader
        Throws:
        java.io.IOException
      • markSupported

        public boolean markSupported()
        Overrides:
        markSupported in class java.io.Reader
      • getMarkIndex

        protected int getMarkIndex()
        Returns:
        The index in the buffer of the mark, which will be negative if the reader is not marked.
      • mark

        public void mark​(int readAheadLimit)
                  throws java.io.IOException
        Overrides:
        mark in class java.io.Reader
        Throws:
        java.lang.IllegalArgumentException - if the given read-ahead limit is greater than getUndoBufferSize().
        java.io.IOException
        See Also:
        getUndoBufferSize()
      • reset

        public void reset()
                   throws java.io.IOException

        This implementation resets peeking.

        This implementation does not support resetting without first marking.

        Overrides:
        reset in class java.io.Reader
        Throws:
        java.io.IOException - if the reader is not currently marked.
        See Also:
        resetPeek()
      • getReader

        protected java.io.Reader getReader()
        Returns:
        The reader from which we extract the information.
      • createBuffer

        protected void createBuffer()
        Creates a new buffer and initializes buffer indexes. Any data in previous buffers will be erased.
      • loadBuffer

        protected void loadBuffer​(java.lang.CharSequence bufferCharacters)
                           throws java.io.IOException
        Loads the buffer with the specified characters. bufferCharacters must be less than or equal to the room left in the buffer.
        Parameters:
        bufferCharacters - The characters which should be placed in the buffer.
        Throws:
        java.io.IOException - if bufferCharacters is too long for the buffer.
      • initializeIndexes

        protected void initializeIndexes()
        Initializes relevant buffer indexes when, for example, the buffer is first created. This implementation sets the read index and the peek index; the other buffer end and fetch buffer indexes will be set by methods that set the buffer itself, such as createBuffer(). This method is called from within setBuffer(char[]).
        See Also:
        createBuffer(), setBuffer(char[])
      • adjustIndexes

        protected void adjustIndexes​(int moveDelta)
        Adjusts all indexes by a certain amount. This method is currently called by fetchBuffer() after moving data in the buffer.

        The mark index is adjusted as well. If adjusting the indexes moves the mark index below the bottom of the buffer, the reader has effectively become unmarked.

        Parameters:
        moveDelta - The number of characters to move the indexes, positive for forwards, negative for backwards.
        See Also:
        fetchBuffer()
      • moveBuffer

        protected void moveBuffer​(int sourceIndex,
                                  int destIndex,
                                  int len)
        Moves a portion of the buffer. This method is called from fetchBuffer() before fetching data.
        Parameters:
        sourceIndex - The index in the buffer to be moved.
        destIndex - The destination in the buffer for the data being moved.
        len - The number of characters to move.
        See Also:
        fetchBuffer()
      • fetchBuffer

        protected int fetchBuffer()
                           throws java.io.IOException
        Fills a buffer with new information.

        This method will read as much data as it can without blocking, and return the number of characters read.

        If the current buffer is full, the last section of the buffer will be moved to the front to make room for more data; otherwise, the data will simply be appended to the buffer.

        This method does not change the EOF status.

        Returns:
        The number of characters fetched, or -1 if the end of the file was reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
        See Also:
        isLastBuffer()
      • processBufferedData

        protected void processBufferedData​(int newDataBeginIndex)
                                    throws java.io.IOException
        Provides away to do initial processing on newly-buffered data. The fetch index may be modified.
        Parameters:
        newDataBeginIndex - The starting index of the newly fetched data.
        Throws:
        java.io.IOException - if an I/O error occurs.
        See Also:
        getFetchBufferIndex()
      • updateEnd

        protected boolean updateEnd()
                             throws java.io.IOException
        Checks to see if the end of the data has been reached, and updates the EOF property if so. If the EOF property is already set to true, this function does nothing.
        Returns:
        Whether or not the end of the file has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
        See Also:
        isEnd()
      • read

        public int read()
                 throws java.io.IOException
        Read a single character. This method will block until a character is available, an I/O error occurs, or the end of the stream is reached.
        Overrides:
        read in class java.io.Reader
        Returns:
        The character read, as an integer in the range 0 to 16383 (0x00-0xffff), or -1 if the end of the stream has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • read

        public int read​(char[] cbuf,
                        int off,
                        int len)
                 throws java.io.IOException
        Read characters into a portion of an array. This method will block until some input is available, an I/O error occurs, or the end of the stream is reached. Resets peeking.
        Specified by:
        read in class java.io.Reader
        Parameters:
        cbuf - Destination buffer.
        off - Offset at which to start storing characters.
        len - Maximum number of characters to read.
        Returns:
        The number of characters read, or -1 if the end of the stream has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • unread

        public void unread​(int c)
                    throws java.io.IOException
        Pushes back a single character. Resets peeking.
        Parameters:
        c - The character to push back.
        Throws:
        java.io.IOException - if there is no room to push back characters (the undo buffer is full) or some other I/O error occurs.
      • unread

        public void unread​(char[] cbuf,
                           int off,
                           int len)
                    throws java.io.IOException
        Pushes back a portion of an array of characters. Resets peeking.
        Parameters:
        cbuf - The array of characters to push back.
        off - The offset of the first character to push back.
        len - The number of characters to push back.
        Throws:
        java.io.IOException - if there is no room to push back characters (the undo buffer is full) or some other I/O error occurs.
      • unread

        public void unread​(char[] cbuf)
                    throws java.io.IOException
        Pushes back an array of characters. Resets peeking.
        Parameters:
        cbuf - The array of characters to push back.
        Throws:
        java.io.IOException - if there is no room to push back characters (the undo buffer is full) or some other I/O error occurs.
      • close

        public void close()
                   throws java.io.IOException
        Close the stream. Once a stream has been closed, further read(), ready(), mark(), or reset() invocations will throw an IOException.

        Closing a previously-closed stream, however, has no effect.

        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Specified by:
        close in class java.io.Reader
        Throws:
        java.io.IOException - if an I/O error occurs.
      • peek

        public int peek()
                 throws java.io.IOException
        Peeks at the next character to be read. Each successive peek will return a successive character.

        This function is reset with every call to #read().

        Since every peek reads a successive character, resetPeek() should be called if it must be ensured that the next character peeked is the next character to be read.

        Returns:
        The next character that will be read after the character retrieved in the last read() or peek(), or -1 if there are no characters left to read.
        Throws:
        java.io.IOException - if an I/O error occurs.
        See Also:
        read(), resetPeek()
      • peek

        public int peek​(char[] cbuf,
                        int off,
                        int len)
                 throws java.io.IOException
        Peeks a specified number of characters into a portion of an array. This method will block until some input is available, an I/O error occurs, or the end of the stream is reached.

        Resets peeking.

        Parameters:
        cbuf - Destination buffer.
        off - Offset at which to start storing characters.
        len - Maximum number of characters to peek.
        Returns:
        The number of characters peeked, or 0 if the end of the stream has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • resetPeek

        public void resetPeek()
        Resets any characters we've peeked so that the next peek will reflect the next character which will be read.

        Does not affect the next character to be read.

      • skip

        public long skip​(long n)
                  throws java.io.IOException
        Skips the specified number of characters. This method will block until some characters are available, an I/O error occurs, or the end of the stream is reached.

        Resets peeking.

        Overrides:
        skip in class java.io.Reader
        Parameters:
        n - The number of characters to skip.
        Returns:
        The number of characters actually skipped.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • unskip

        public void unskip​(int n)
                    throws java.io.IOException
        Reverses the reading position to the previous characters read. Functions similar to unread() except that the unread characters will always be the characters that were previously read.

        Resets peeking.

        Parameters:
        n - The number of characters to unskip.
        Throws:
        java.io.IOException - if there is no room to push back characters (the undo buffer is full) or some other I/O error occurs.
        See Also:
        unread(char[])