Class ReaderToUTF8Stream

java.lang.Object
java.io.InputStream
org.apache.derby.iapi.types.ReaderToUTF8Stream
All Implemented Interfaces:
Closeable, AutoCloseable

public final class ReaderToUTF8Stream extends InputStream
Converts the characters served by a java.io.Reader to a stream returning the data in the on-disk modified UTF-8 encoded representation used by Derby.

Length validation is performed. If required and allowed by the target column type, truncation of blanks will also be performed.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private int
     
    private int
     
    private byte[]
    Buffer to hold the data read from stream and converted to the modified UTF-8 format.
    private int
    The number of chars encoded.
    private final int
    Number of characters to truncate from this stream.
    private boolean
     
    private static final int
    Constant indicating the first iteration of fillBuffer.
    private final StreamHeaderGenerator
    The generator for the stream header to use for this stream.
    private int
    The length of the header.
    private int
    Stream mark, set through mark(int).
    private static final int
    Constant indicating that no mark is set in the stream, or that the read ahead limit of the mark has been exceeded.
    private boolean
    Tells if the stream content is/was larger than the buffer size.
    private static final int
    Buffer space reserved for one 3 byte encoded char and the EOF marker.
    private int
    Read ahead limit for mark, set through mark(int).
    private LimitReader
    Application's reader wrapped in a LimitReader.
    private static final char
     
    private final String
    The type name for the column data is inserted into.
    private final int
    If positive, length of the expected final value, after truncation if any, in characters.
  • Constructor Summary

    Constructors
    Constructor
    Description
    ReaderToUTF8Stream(Reader appReader, int valueLength, int numCharsToTruncate, String typeName, StreamHeaderGenerator headerGenerator)
    Create a stream that will truncate trailing blanks if required/allowed.
    ReaderToUTF8Stream(Reader appReader, int maximumLength, String typeName, StreamHeaderGenerator headerGenerator)
    Creates a UTF-8 stream for an application reader whose length isn't known at insertion time.
  • Method Summary

    Modifier and Type
    Method
    Description
    final int
    Return an optimized version of bytes available to read from the stream.
    private boolean
    Determine if trailing blank truncation is allowed.
    private void
    Validate the length of the stream, take corrective action if allowed.
    void
    return resources
    private void
    fillBuffer(int startingOffset)
    Fills the internal buffer with data read from the source stream.
    void
    mark(int readAheadLimit)
    Marks the current position in the stream.
    boolean
    Tests if this stream supports mark/reset.
    int
    Reads a byte from the stream.
    int
    read(byte[] b, int off, int len)
    Reads up to len bytes from the stream.
    void
    Repositions this stream to the position at the time the mark method was last called on this input stream.
    private void
    Attempt to truncate the stream by removing trailing blanks.

    Methods inherited from class java.lang.Object

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

    • reader

      private LimitReader reader
      Application's reader wrapped in a LimitReader.
    • FIRST_READ

      private static final int FIRST_READ
      Constant indicating the first iteration of fillBuffer.
      See Also:
    • READ_BUFFER_RESERVATION

      private static final int READ_BUFFER_RESERVATION
      Buffer space reserved for one 3 byte encoded char and the EOF marker.
      See Also:
    • MARK_UNSET_OR_EXCEEDED

      private static final int MARK_UNSET_OR_EXCEEDED
      Constant indicating that no mark is set in the stream, or that the read ahead limit of the mark has been exceeded.
      See Also:
    • buffer

      private byte[] buffer
      Buffer to hold the data read from stream and converted to the modified UTF-8 format. The initial size is dependent on whether the data value length is known (limited upwards to 32 KB), but it may grow if mark(int) is invoked.
    • boff

      private int boff
    • blen

      private int blen
    • mark

      private int mark
      Stream mark, set through mark(int).
    • readAheadLimit

      private int readAheadLimit
      Read ahead limit for mark, set through mark(int).
    • eof

      private boolean eof
    • multipleBuffer

      private boolean multipleBuffer
      Tells if the stream content is/was larger than the buffer size.
    • hdrGen

      private final StreamHeaderGenerator hdrGen
      The generator for the stream header to use for this stream.
      See Also:
    • headerLength

      private int headerLength
      The length of the header.
    • charsToTruncate

      private final int charsToTruncate
      Number of characters to truncate from this stream. The SQL standard allows for truncation of trailing spaces for CLOB, VARCHAR and CHAR. If zero, no characters are truncated, unless the stream length exceeds the maximum length of the column we are inserting into.
    • SPACE

      private static final char SPACE
      See Also:
    • valueLength

      private final int valueLength
      If positive, length of the expected final value, after truncation if any, in characters. If negative, the maximum length allowed in the column we are inserting into. A negative value means we are working with a stream of unknown length, inserted through one of the JDBC 4.0 "lengthless override" methods.
    • typeName

      private final String typeName
      The type name for the column data is inserted into.
    • charCount

      private int charCount
      The number of chars encoded.
  • Constructor Details

    • ReaderToUTF8Stream

      public ReaderToUTF8Stream(Reader appReader, int valueLength, int numCharsToTruncate, String typeName, StreamHeaderGenerator headerGenerator)
      Create a stream that will truncate trailing blanks if required/allowed. If the stream must be truncated, the number of blanks to truncate is specified to allow the stream to be checked for exact length, as required by JDBC 3.0. If the stream is shorter or longer than specified, an exception is thrown during read.
      Parameters:
      appReader - application reader
      valueLength - the expected length of the reader in characters (positive), or the inverse (maxColWidth * -1) of the maximum column width if the expected stream length is unknown
      numCharsToTruncate - the number of trailing blanks to truncate
      typeName - type name of the column data is inserted into
      headerGenerator - the stream header generator
    • ReaderToUTF8Stream

      public ReaderToUTF8Stream(Reader appReader, int maximumLength, String typeName, StreamHeaderGenerator headerGenerator)
      Creates a UTF-8 stream for an application reader whose length isn't known at insertion time.

      The application reader is coming in through one of the "lengthless overrides" added in JDBC 4.0, for instance java.sql.PreparedStatement.setCharacterStream(int,Reader). A limit is placed on the length of the application reader. If the reader exceeds the maximum length, truncation of trailing blanks is attempted. If truncation fails, an exception is thrown.

      Parameters:
      appReader - application reader
      maximumLength - maximum allowed length in number of characters for the reader, typically the maximum field size
      typeName - type name of the column data is inserted into
      headerGenerator - the stream header generator
      Throws:
      IllegalArgumentException - if maximum length is negative
  • Method Details

    • read

      public int read() throws IOException
      Reads a byte from the stream.

      Characters read from the source stream are converted to the UTF-8 Derby specific encoding.

      Specified by:
      read in class InputStream
      Returns:
      The byte read, or -1 if the end-of-stream is reached.
      Throws:
      EOFException - if the end-of-stream has already been reached or the stream has been closed
      IOException - if reading from the source stream fails
      See Also:
    • read

      public int read(byte[] b, int off, int len) throws IOException
      Reads up to len bytes from the stream.

      Characters read from the source stream are converted to the UTF-8 Derby specific encoding.

      Overrides:
      read in class InputStream
      Returns:
      The number of bytes read, or -1 if the end-of-stream is reached.
      Throws:
      EOFException - if the end-of-stream has already been reached or the stream has been closed
      IOException - if reading from the source stream fails
      See Also:
    • fillBuffer

      private void fillBuffer(int startingOffset) throws IOException
      Fills the internal buffer with data read from the source stream.

      The characters read from the source are converted to the modified UTF-8 encoding, used as the on-disk format by Derby.

      Parameters:
      startingOffset - offset at which to start filling the buffer, used to avoid overwriting the stream header data on the first iteration
      Throws:
      DerbyIOException - if the source stream has an invalid length (different than specified), or if truncation of blanks fails
      IOException - if reading from the source stream fails
    • checkSufficientData

      private void checkSufficientData() throws IOException
      Validate the length of the stream, take corrective action if allowed. JDBC 3.0 (from tutorial book) requires that an input stream has the correct number of bytes in the stream. If the stream is too long, trailing blank truncation is attempted if allowed. If truncation fails, or is disallowed, an exception is thrown.
      Throws:
      IOException - if an errors occurs in the application stream
      DerbyIOException - if Derby finds a problem with the stream; stream is too long and cannot be truncated, or the stream length does not match the specified length
    • canTruncate

      private boolean canTruncate()
      Determine if trailing blank truncation is allowed.
    • truncate

      private void truncate() throws IOException
      Attempt to truncate the stream by removing trailing blanks.
      Throws:
      IOException
    • close

      public void close()
      return resources
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Overrides:
      close in class InputStream
    • available

      public final int available()
      Return an optimized version of bytes available to read from the stream.

      Note, it is not exactly per java.io.InputStream#available().

      Overrides:
      available in class InputStream
    • mark

      public void mark(int readAheadLimit)
      Marks the current position in the stream.

      Note that this stream is not marked at position zero by default (i.e. in the constructor).

      Overrides:
      mark in class InputStream
      Parameters:
      readAheadLimit - the maximum limit of bytes that can be read before the mark position becomes invalid
    • reset

      public void reset() throws IOException
      Repositions this stream to the position at the time the mark method was last called on this input stream.
      Overrides:
      reset in class InputStream
      Throws:
      EOFException - if the stream has been closed
      IOException - if no mark has been set, or the read ahead limit of the mark has been exceeded
    • markSupported

      public boolean markSupported()
      Tests if this stream supports mark/reset.

      The markSupported method of ByteArrayInputStream always returns true.

      Overrides:
      markSupported in class InputStream
      Returns:
      true, mark/reset is always supported.