Class ReaderToUTF8Stream
- All Implemented Interfaces:
Closeable, AutoCloseable
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
FieldsModifier and TypeFieldDescriptionprivate intprivate intprivate byte[]Buffer to hold the data read from stream and converted to the modified UTF-8 format.private intThe number of chars encoded.private final intNumber of characters to truncate from this stream.private booleanprivate static final intConstant indicating the first iteration offillBuffer.private final StreamHeaderGeneratorThe generator for the stream header to use for this stream.private intThe length of the header.private intStream mark, set through mark(int).private static final intConstant indicating that no mark is set in the stream, or that the read ahead limit of the mark has been exceeded.private booleanTells if the stream content is/was larger than the buffer size.private static final intBuffer space reserved for one 3 byte encoded char and the EOF marker.private intRead ahead limit for mark, set through mark(int).private LimitReaderApplication's reader wrapped in a LimitReader.private static final charprivate final StringThe type name for the column data is inserted into.private final intIf positive, length of the expected final value, after truncation if any, in characters. -
Constructor Summary
ConstructorsConstructorDescriptionReaderToUTF8Stream(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 TypeMethodDescriptionfinal intReturn an optimized version of bytes available to read from the stream.private booleanDetermine if trailing blank truncation is allowed.private voidValidate the length of the stream, take corrective action if allowed.voidclose()return resourcesprivate voidfillBuffer(int startingOffset) Fills the internal buffer with data read from the source stream.voidmark(int readAheadLimit) Marks the current position in the stream.booleanTests if this stream supports mark/reset.intread()Reads a byte from the stream.intread(byte[] b, int off, int len) Reads up tolenbytes from the stream.voidreset()Repositions this stream to the position at the time the mark method was last called on this input stream.private voidtruncate()Attempt to truncate the stream by removing trailing blanks.Methods inherited from class InputStream
nullInputStream, read, readAllBytes, readNBytes, readNBytes, skip, skipNBytes, transferTo
-
Field Details
-
reader
Application's reader wrapped in a LimitReader. -
FIRST_READ
private static final int FIRST_READConstant indicating the first iteration offillBuffer.- See Also:
-
READ_BUFFER_RESERVATION
private static final int READ_BUFFER_RESERVATIONBuffer 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_EXCEEDEDConstant 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[] bufferBuffer 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 markStream mark, set through mark(int). -
readAheadLimit
private int readAheadLimitRead ahead limit for mark, set through mark(int). -
eof
private boolean eof -
multipleBuffer
private boolean multipleBufferTells if the stream content is/was larger than the buffer size. -
hdrGen
The generator for the stream header to use for this stream.- See Also:
-
headerLength
private int headerLengthThe length of the header. -
charsToTruncate
private final int charsToTruncateNumber 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 valueLengthIf 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
The type name for the column data is inserted into. -
charCount
private int charCountThe 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 readervalueLength- 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 unknownnumCharsToTruncate- the number of trailing blanks to truncatetypeName- type name of the column data is inserted intoheaderGenerator- 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 readermaximumLength- maximum allowed length in number of characters for the reader, typically the maximum field sizetypeName- type name of the column data is inserted intoheaderGenerator- the stream header generator- Throws:
IllegalArgumentException- if maximum length is negative
-
-
Method Details
-
read
Reads a byte from the stream.Characters read from the source stream are converted to the UTF-8 Derby specific encoding.
- Specified by:
readin classInputStream- Returns:
- The byte read, or
-1if the end-of-stream is reached. - Throws:
EOFException- if the end-of-stream has already been reached or the stream has been closedIOException- if reading from the source stream fails- See Also:
-
read
Reads up tolenbytes from the stream.Characters read from the source stream are converted to the UTF-8 Derby specific encoding.
- Overrides:
readin classInputStream- Returns:
- The number of bytes read, or
-1if the end-of-stream is reached. - Throws:
EOFException- if the end-of-stream has already been reached or the stream has been closedIOException- if reading from the source stream fails- See Also:
-
fillBuffer
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 failsIOException- if reading from the source stream fails
-
checkSufficientData
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 streamDerbyIOException- 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
Attempt to truncate the stream by removing trailing blanks.- Throws:
IOException
-
close
public void close()return resources- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Overrides:
closein classInputStream
-
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:
availablein classInputStream
-
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:
markin classInputStream- Parameters:
readAheadLimit- the maximum limit of bytes that can be read before the mark position becomes invalid
-
reset
Repositions this stream to the position at the time the mark method was last called on this input stream.- Overrides:
resetin classInputStream- Throws:
EOFException- if the stream has been closedIOException- 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
markSupportedmethod ofByteArrayInputStreamalways returnstrue.- Overrides:
markSupportedin classInputStream- Returns:
true, mark/reset is always supported.
-