Class UTF8Reader

java.lang.Object
java.io.Reader
org.apache.derby.impl.jdbc.UTF8Reader
All Implemented Interfaces:
Closeable, AutoCloseable, Readable

public final class UTF8Reader extends Reader
Class for reading characters from streams encoded in the modified UTF-8 format.

Note that we often operate on a special Derby stream. A Derby stream is possibly different from a "normal" stream in two ways; an encoded length is inserted at the head of the stream, and if the encoded length is 0 a Derby-specific end of stream marker is appended to the data.

If the underlying stream is capable of repositioning itself on request, this class supports multiple readers on the same source stream in such a way that the various readers do not interfere with each other (except for serializing access). Each reader instance will have its own pointer into the stream, and request that the stream repositions itself before calling read/skip on the stream.

See Also:
  • Field Details

    • READER_CLOSED

      private static final String READER_CLOSED
      See Also:
    • MAXIMUM_BUFFER_SIZE

      private static final int MAXIMUM_BUFFER_SIZE
      Maximum size in number of chars for the internal character buffer.
      See Also:
    • in

      private InputStream in
      The underlying data stream.
    • positionedIn

      private final PositionedStream positionedIn
      Stream that can reposition itself on request (may be null).
    • rawStreamPos

      private long rawStreamPos
      Store the last visited position in the store stream, if it is capable of repositioning itself (positionedIn != null).
    • utfCount

      private long utfCount
      Number of bytes read from the stream, including any header bytes.
    • readerCharCount

      private long readerCharCount
      Number of characters read from the stream.
    • buffer

      private final char[] buffer
      Internal character buffer storing characters read from the stream.
    • charactersInBuffer

      private int charactersInBuffer
      The number of characters in the internal buffer.
    • readPositionInBuffer

      private int readPositionInBuffer
      The position of the next character to read in the internal buffer.
    • noMoreReads

      private boolean noMoreReads
      Tells if this reader has been closed.
    • parent

      private ConnectionChild parent
      A reference to the parent object of the stream.

      The reference is kept so that the parent object can't get garbage collected until we are done with the stream.

    • csd

      private final CharacterStreamDescriptor csd
      Descriptor containing information about the stream. Except for the current positions, the information in this object is considered permanent and valid for the life-time of the stream.
  • Constructor Details

    • UTF8Reader

      public UTF8Reader(CharacterStreamDescriptor csd, ConnectionChild conChild, Object sync) throws IOException
      Constructs a reader on top of the source UTF-8 encoded stream.
      Parameters:
      csd - a description of and reference to the source stream
      conChild - the parent object / connection child
      sync - synchronization object used when accessing the underlying data stream
      Throws:
      IOException - if reading from the underlying stream fails
  • Method Details

    • read

      public int read() throws IOException
      Reads a single character from the stream.
      Overrides:
      read in class Reader
      Returns:
      A character or -1 if end of stream has been reached.
      Throws:
      IOException - if the stream has been closed, or an exception is raised while reading from the underlying stream
    • read

      public int read(char[] cbuf, int off, int len) throws IOException
      Reads characters into an array.
      Specified by:
      read in class Reader
      Returns:
      The number of characters read, or -1 if the end of the stream has been reached.
      Throws:
      IOException
    • skip

      public long skip(long len) throws IOException
      Skips characters.
      Overrides:
      skip in class Reader
      Parameters:
      len - the numbers of characters to skip
      Returns:
      The number of characters actually skipped.
      Throws:
      IllegalArgumentException - if the number of characters to skip is negative
      IOException - if accessing the underlying stream fails
    • close

      public void close()
      Close the reader, disallowing further reads.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Specified by:
      close in class Reader
    • readInto

      public int readInto(StringBuffer sb, int len) throws IOException
      Reads characters from the stream.

      Due to internal buffering a smaller number of characters than what is requested might be returned. To ensure that the request is fulfilled, call this method in a loop until the requested number of characters is read or -1 is returned.

      Parameters:
      sb - the destination buffer
      len - maximum number of characters to read
      Returns:
      The number of characters read, or -1 if the end of the stream is reached.
      Throws:
      IOException
    • readAsciiInto

      int readAsciiInto(byte[] abuf, int off, int len) throws IOException
      Reads characters into an array as ASCII characters.

      Due to internal buffering a smaller number of characters than what is requested might be returned. To ensure that the request is fulfilled, call this method in a loop until the requested number of characters is read or -1 is returned.

      Characters outside the ASCII range are replaced with an out of range marker.

      Parameters:
      abuf - the buffer to read into
      off - the offset into the destination buffer
      len - maximum number of characters to read
      Returns:
      The number of characters read, or -1 if the end of the stream is reached.
      Throws:
      IOException
    • closeIn

      private void closeIn()
      Close the underlying stream if it is open.
    • utfFormatException

      private IOException utfFormatException(String s)
      Convenience method generating an UTFDataFormatException and cleaning up the reader state.
    • fillBuffer

      private boolean fillBuffer() throws IOException
      Fills the internal character buffer by decoding bytes from the stream.
      Returns:
      true if the end of the stream is reached, false if there is apparently more data to be read.
      Throws:
      IOException
    • resetUTF8Reader

      private void resetUTF8Reader() throws IOException, StandardException
      Resets the reader.

      This method is used internally to achieve better performance.

      Throws:
      IOException - if resetting or reading from the stream fails
      StandardException - if resetting the stream fails
      See Also:
    • reposition

      void reposition(long requestedCharPos) throws IOException, StandardException
      Repositions the stream so that the next character read will be the character at the requested position.

      There are three types of repositioning, ordered after increasing cost:

      1. Reposition within current character buffer (small hops forwards and potentially backwards - in range 1 char to MAXIMUM_BUFFER_SIZE chars)
      2. Forward stream from current position (hops forwards)
      3. Reset stream and skip data (hops backwards)
      Parameters:
      requestedCharPos - 1-based requested character position
      Throws:
      IOException - if resetting or reading from the stream fails
      StandardException - if resetting the stream fails
    • calculateBufferSize

      private final int calculateBufferSize(CharacterStreamDescriptor csd)
      Calculates an optimized buffer size.

      The maximum size allowed is returned if the specified values don't give enough information to say a smaller buffer size is preferable.

      Parameters:
      csd - stream descriptor
      Returns:
      An (sub)optimal buffer size.
    • persistentSkip

      private final void persistentSkip(long toSkip) throws IOException
      Skips the requested number of characters.
      Parameters:
      toSkip - number of characters to skip
      Throws:
      EOFException - if there are too few characters in the stream
      IOException - if reading from the stream fails