Class ChannelDataInput

java.lang.Object
org.apache.sis.internal.storage.io.ChannelData
org.apache.sis.internal.storage.io.ChannelDataInput
All Implemented Interfaces:
Markable
Direct Known Subclasses:
ChannelImageInputStream

public class ChannelDataInput extends ChannelData
Provides convenience methods for working with a (ReadableByteChannel, ByteBuffer) pair. The channel and the buffer must be supplied by the caller. It is okay if they have already been used before ChannelDataInput creation.

Encapsulation

This class exposes publicly the channel and the buffer because this class is not expected to perform all possible data manipulations that we can do with the buffers. This class is only a helper tool, which often needs to be completed by specialized operations performed directly on the buffer. However, users are encouraged to transfer data from the channel to the buffer using only the methods provided in this class if they want to keep the seek(long) and ChannelData.getStreamPosition() values accurate.

Since this class is only a helper tool, it does not "own" the channel and consequently does not provide close() method. It is users responsibility to close the channel after usage.

Relationship with DataInput

This class API is compatibly with the DataInput interface, so subclasses can implement that interface if they wish. This class does not implement DataInput itself because it is not needed for SIS purposes, and because DataInput has undesirable methods (readLine() and readUTF()). However, the ChannelImageInputStream class implements the DataInput interface, together with the ImageInputStream one, mostly for situations when inter-operability with javax.imageio is needed.
Since:
0.3
Version:
1.3
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    (package private) class 
    Helper class for the readFully(…) methods, in order to avoid duplicating almost identical code many times.
    (package private) final class 
    Reads bytes from the enclosing stream and stores them into the given destination array.
    (package private) final class 
    Reads characters from the enclosing stream and stores them into the given destination array.
    (package private) final class 
    Reads double values from the enclosing stream and stores them into the given destination array.
    (package private) final class 
    Reads float values from the enclosing stream and stores them into the given destination array.
    (package private) final class 
    Reads integers from the enclosing stream and stores them into the given destination array.
    (package private) final class 
    Reads long integers from the enclosing stream and stores them into the given destination array.
    (package private) final class 
    Reads short integers from the enclosing stream and stores them into the given destination array.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    The channel from where data are read.
    private static final int
    Minimum number of bytes to skip in the seek(long) operation.

    Fields inherited from class org.apache.sis.internal.storage.io.ChannelData

    buffer, bufferOffset, channelOffset, filename
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates a new instance for a buffer filled with the bytes to use.
    ChannelDataInput(String filename, ReadableByteChannel channel, ByteBuffer buffer, boolean filled)
    Creates a new data input for the given channel and using the given buffer.
    Creates a new input stream from the given ChannelDataInput.
  • Method Summary

    Modifier and Type
    Method
    Description
    final void
    Makes sure that the buffer contains at least n remaining bytes.
    private void
    Makes sure that the buffer contains at least one remaining byte.
    private String
    eof()
    Returns the "end of file" error message, for EOFException creations.
    final boolean
    Returns true if the buffer or the channel has at least one byte remaining.
    final long
    Returns the length of the stream (in bytes), or -1 if unknown.
    final int
    Tries to read more bytes from the channel without changing the buffer position.
    (package private) final void
    Pushes back the last processed byte.
    final int
    Reads a single bit from the stream.
    final long
    readBits(int numBits)
    Reads many bits from the stream.
    final byte
    Reads the next byte value (8 bits) from the stream.
    final byte[]
    readBytes(int length)
    Reads the given amount of bytes from the stream and returns them in a newly allocated array.
    final char
    Reads the next character (16 bits) from the stream.
    final char[]
    readChars(int length)
    Reads the given amount of characters from the stream and returns them in a newly allocated array.
    final double
    Reads the next double value (64 bits) from the stream.
    final double[]
    readDoubles(int length)
    Reads the given amount of doubles from the stream and returns them in a newly allocated array.
    final float
    Reads the next float value (32 bits) from the stream.
    final float[]
    readFloats(int length)
    Reads the given amount of floats from the stream and returns them in a newly allocated array.
    final void
    readFully(byte[] dest)
    Reads dest.length bytes from the stream, and stores them into dest starting at index 0.
    final void
    readFully(byte[] dest, int offset, int length)
    Reads length bytes from the stream, and stores them into dest starting at index offset.
    final void
    readFully(char[] dest, int offset, int length)
    Reads length characters from the stream, and stores them into dest starting at index offset.
    final void
    readFully(double[] dest, int offset, int length)
    Reads length doubles from the stream, and stores them into dest starting at index offset.
    final void
    readFully(float[] dest, int offset, int length)
    Reads length floats from the stream, and stores them into dest starting at index offset.
    final void
    readFully(int[] dest, int offset, int length)
    Reads length integers from the stream, and stores them into dest starting at index offset.
    final void
    readFully(long[] dest, int offset, int length)
    Reads length long integers from the stream, and stores them into dest starting at index offset.
    final void
    readFully(short[] dest, int offset, int length)
    Reads length short integers from the stream, and stores them into dest starting at index offset.
    final int
    Reads the next integer value (32 bits) from the stream.
    final int[]
    readInts(int length)
    Reads the given amount of integers from the stream and returns them in a newly allocated array.
    final long
    Reads the next long value (64 bits) from the stream.
    final long[]
    readLongs(int length)
    Reads the given amount of longs from the stream and returns them in a newly allocated array.
    final short
    Reads the next short value (16 bits) from the stream.
    final short[]
    readShorts(int length)
    Reads the given amount of shorts from the stream and returns them in a newly allocated array.
    final String
    readString(int length, Charset encoding)
    Decodes a string from a sequence of bytes in the given encoding.
    final int
    Reads the next unsigned byte value (8 bits) from the stream.
    final long
    Reads the next unsigned integer value (32 bits) from the stream.
    final int
    Reads the next unsigned short value (16 bits) from the stream.
    final boolean
    Empties the buffer and reset the channel position at the beginning of the stream.
    final void
    seek(long position)
    Moves to the given position in the stream, relative to the stream position at construction time.

    Methods inherited from class java.lang.Object

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

    • SEEK_THRESHOLD

      private static final int SEEK_THRESHOLD
      Minimum number of bytes to skip in the seek(long) operation. If there is less bytes to skip, then it is not worth to do a seek and we will continue reading as normal instead.

      This threshold is used because some formats add padding to their data for aligning on 32 bits boundary. It may result in very small seeks before reading the next chunk of data. A common padding is 32 bits, but there is no harm in using a larger one here (64 bits).

      See Also:
    • channel

      public final ReadableByteChannel channel
      The channel from where data are read. This is supplied at construction time.
  • Constructor Details

    • ChannelDataInput

      public ChannelDataInput(String filename, ReadableByteChannel channel, ByteBuffer buffer, boolean filled) throws IOException
      Creates a new data input for the given channel and using the given buffer. If the buffer already contains some data, then the filled argument shall be true. Otherwise (e.g. if it is a newly created buffer), then filled shall be false.
      Parameters:
      filename - a short identifier (typically a filename without path) used for formatting error message.
      channel - the channel from where data are read.
      buffer - the buffer where to copy the data.
      filled - true if the buffer already contains data, or false if it needs to be initially filled with some content read from the channel.
      Throws:
      IOException - if an error occurred while reading the channel.
    • ChannelDataInput

      ChannelDataInput(ChannelDataInput input)
      Creates a new input stream from the given ChannelDataInput. This constructor is invoked when we need to change the implementation class. The old input should not be used anymore after this constructor has been invoked.
      Parameters:
      input - the existing instance from which to takes the channel and buffer.
    • ChannelDataInput

      public ChannelDataInput(String filename, ByteBuffer data)
      Creates a new instance for a buffer filled with the bytes to use. This constructor uses an independent, read-only view of the given buffer. No reference to the given buffer will be retained.
      Parameters:
      filename - a short identifier (typically a filename without path) used for formatting error message.
      data - the buffer filled with all bytes to read.
  • Method Details

    • length

      public final long length() throws IOException
      Returns the length of the stream (in bytes), or -1 if unknown. The length is relative to the channel position at construction time.
      Returns:
      the length of the stream (in bytes) relative to ChannelData.channelOffset, or -1 if unknown.
      Throws:
      IOException - if an error occurred while fetching the stream length.
    • prefetch

      public final int prefetch() throws IOException
      Tries to read more bytes from the channel without changing the buffer position. This method returns a negative number if the buffer is already full or if the channel reached the end of stream. Otherwise this method reads an arbitrary number of bytes not greater than the space available in the buffer, and returns the amount bytes actually read.
      Returns:
      the number of bytes read, or -2 if the buffer is full, or -1 on end of stream.
      Throws:
      IOException - if an error occurred while reading the bytes.
      Since:
      0.4
    • hasRemaining

      public final boolean hasRemaining() throws IOException
      Returns true if the buffer or the channel has at least one byte remaining. If the buffer has no remaining bytes, then this method will attempts to read at least one byte from the channel. If no bytes can be read because the channel has reached the end of stream, then this method returns false.
      Returns:
      true if the buffer contains at least one remaining byte.
      Throws:
      IOException - if it was necessary to read from the channel and this operation failed.
    • ensureBufferContains

      public final void ensureBufferContains(int n) throws EOFException, IOException
      Makes sure that the buffer contains at least n remaining bytes. It is caller's responsibility to ensure that the given number of bytes is not greater than the buffer capacity.
      Parameters:
      n - the minimal number of bytes needed in the buffer.
      Throws:
      EOFException - if the channel has reached the end of stream.
      IOException - if another kind of error occurred while reading.
    • ensureNonEmpty

      private void ensureNonEmpty() throws IOException
      Makes sure that the buffer contains at least one remaining byte.
      Throws:
      EOFException - if the channel has reached the end of stream.
      IOException - if another kind of error occurred while reading.
    • eof

      private String eof()
      Returns the "end of file" error message, for EOFException creations.
    • pushBack

      final void pushBack()
      Pushes back the last processed byte. This is used when a call to readBit() did not used every bits in a byte, or when readLine() checked for the Windows-style of EOL.
    • readBit

      public final int readBit() throws IOException
      Reads a single bit from the stream. The bit to be read depends on the current bit offset.
      Returns:
      the value of the next bit from the stream.
      Throws:
      IOException - if an error occurred while reading (including EOF).
    • readBits

      public final long readBits(int numBits) throws IOException
      Reads many bits from the stream. The first bit to be read depends on the current bit offset.
      Parameters:
      numBits - the number of bits to read.
      Returns:
      the value of the next bits from the stream.
      Throws:
      IOException - if an error occurred while reading (including EOF).
    • readByte

      public final byte readByte() throws IOException
      Reads the next byte value (8 bits) from the stream. This method ensures that there is at least 1 byte remaining in the buffer, reading new bytes from the channel if necessary, then delegates to ByteBuffer.get().
      Returns:
      the value of the next byte from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readUnsignedByte

      public final int readUnsignedByte() throws IOException
      Reads the next unsigned byte value (8 bits) from the stream. The implementation is as below:
      Returns:
      the value of the next unsigned byte from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readShort

      public final short readShort() throws IOException
      Reads the next short value (16 bits) from the stream. This method ensures that there is at least 2 bytes remaining in the buffer, reading new bytes from the channel if necessary, then delegates to ByteBuffer.getShort().
      Returns:
      the value of the next short from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readUnsignedShort

      public final int readUnsignedShort() throws IOException
      Reads the next unsigned short value (16 bits) from the stream. The implementation is as below:
      Returns:
      the value of the next unsigned short from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readChar

      public final char readChar() throws IOException
      Reads the next character (16 bits) from the stream. This method ensures that there is at least 2 bytes remaining in the buffer, reading new bytes from the channel if necessary, then delegates to ByteBuffer.getChar().
      Returns:
      the value of the next character from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readInt

      public final int readInt() throws IOException
      Reads the next integer value (32 bits) from the stream. This method ensures that there is at least 4 bytes remaining in the buffer, reading new bytes from the channel if necessary, then delegates to ByteBuffer.getInt().
      Returns:
      the value of the next integer from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readUnsignedInt

      public final long readUnsignedInt() throws IOException
      Reads the next unsigned integer value (32 bits) from the stream. The implementation is as below:
      Returns:
      the value of the next unsigned integer from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readLong

      public final long readLong() throws IOException
      Reads the next long value (64 bits) from the stream. This method ensures that there is at least 8 bytes remaining in the buffer, reading new bytes from the channel if necessary, then delegates to ByteBuffer.getLong().
      Returns:
      the value of the next integer from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFloat

      public final float readFloat() throws IOException
      Reads the next float value (32 bits) from the stream. This method ensures that there is at least 4 bytes remaining in the buffer, reading new bytes from the channel if necessary, then delegates to ByteBuffer.getFloat().
      Returns:
      the value of the next float from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readDouble

      public final double readDouble() throws IOException
      Reads the next double value (64 bits) from the stream. This method ensures that there is at least 8 bytes remaining in the buffer, reading new bytes from the channel if necessary, then delegates to ByteBuffer.getDouble().
      Returns:
      the value of the next double from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readBytes

      public final byte[] readBytes(int length) throws IOException
      Reads the given amount of bytes from the stream and returns them in a newly allocated array. This is a convenience method for readFully(byte[], int, int) with a new array.
      Parameters:
      length - The number of bytes to read.
      Returns:
      the next bytes in a newly allocated array of the given length.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readChars

      public final char[] readChars(int length) throws IOException
      Reads the given amount of characters from the stream and returns them in a newly allocated array. This is a convenience method for readFully(char[], int, int) with a new array.
      Parameters:
      length - The number of characters to read.
      Returns:
      the next characters in a newly allocated array of the given length.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readShorts

      public final short[] readShorts(int length) throws IOException
      Reads the given amount of shorts from the stream and returns them in a newly allocated array. This is a convenience method for readFully(short[], int, int) with a new array.
      Parameters:
      length - The number of shorts to read.
      Returns:
      the next shorts in a newly allocated array of the given length.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readInts

      public final int[] readInts(int length) throws IOException
      Reads the given amount of integers from the stream and returns them in a newly allocated array. This is a convenience method for readFully(int[], int, int) with a new array.
      Parameters:
      length - The number of integers to read.
      Returns:
      the next integers in a newly allocated array of the given length.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readLongs

      public final long[] readLongs(int length) throws IOException
      Reads the given amount of longs from the stream and returns them in a newly allocated array. This is a convenience method for readFully(long[], int, int) with a new array.
      Parameters:
      length - The number of longs to read.
      Returns:
      the next longs in a newly allocated array of the given length.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFloats

      public final float[] readFloats(int length) throws IOException
      Reads the given amount of floats from the stream and returns them in a newly allocated array. This is a convenience method for readFully(float[], int, int) with a new array.
      Parameters:
      length - The number of floats to read.
      Returns:
      the next floats in a newly allocated array of the given length.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readDoubles

      public final double[] readDoubles(int length) throws IOException
      Reads the given amount of doubles from the stream and returns them in a newly allocated array. This is a convenience method for readFully(double[], int, int) with a new array.
      Parameters:
      length - The number of doubles to read.
      Returns:
      the next doubles in a newly allocated array of the given length.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFully

      public final void readFully(byte[] dest) throws IOException
      Reads dest.length bytes from the stream, and stores them into dest starting at index 0. The implementation is as below:
      Parameters:
      dest - An array of bytes to be written to.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFully

      public final void readFully(byte[] dest, int offset, int length) throws IOException
      Reads length bytes from the stream, and stores them into dest starting at index offset.
      Parameters:
      dest - an array of bytes to be written to.
      offset - the starting position within dest to write.
      length - the number of bytes to read.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFully

      public final void readFully(char[] dest, int offset, int length) throws IOException
      Reads length characters from the stream, and stores them into dest starting at index offset.
      Parameters:
      dest - An array of characters to be written to.
      offset - The starting position within dest to write.
      length - The number of characters to read.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFully

      public final void readFully(short[] dest, int offset, int length) throws IOException
      Reads length short integers from the stream, and stores them into dest starting at index offset.
      Parameters:
      dest - An array of short integers to be written to.
      offset - The starting position within dest to write.
      length - The number of short integers to read.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFully

      public final void readFully(int[] dest, int offset, int length) throws IOException
      Reads length integers from the stream, and stores them into dest starting at index offset.
      Parameters:
      dest - an array of integers to be written to.
      offset - the starting position within dest to write.
      length - the number of integers to read.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFully

      public final void readFully(long[] dest, int offset, int length) throws IOException
      Reads length long integers from the stream, and stores them into dest starting at index offset.
      Parameters:
      dest - an array of long integers to be written to.
      offset - the starting position within dest to write.
      length - the number of long integers to read.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFully

      public final void readFully(float[] dest, int offset, int length) throws IOException
      Reads length floats from the stream, and stores them into dest starting at index offset.
      Parameters:
      dest - an array of floats to be written to.
      offset - the starting position within dest to write.
      length - the number of floats to read.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readFully

      public final void readFully(double[] dest, int offset, int length) throws IOException
      Reads length doubles from the stream, and stores them into dest starting at index offset.
      Parameters:
      dest - an array of doubles to be written to.
      offset - the starting position within dest to write.
      length - the number of doubles to read.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readString

      public final String readString(int length, Charset encoding) throws IOException
      Decodes a string from a sequence of bytes in the given encoding. This method tries to avoid the creation of a temporary byte[] array when possible.

      This convenience method shall be used only for relatively small amount of String instances to decode, for example attribute values in the file header. For large amount of data, consider using CharsetDecoder instead.

      Parameters:
      length - number of bytes to read.
      encoding - the character encoding.
      Returns:
      the string decoded from the length next bytes.
      Throws:
      IOException - if an error occurred while reading the bytes, or if the given encoding is invalid.
    • seek

      public final void seek(long position) throws IOException
      Moves to the given position in the stream, relative to the stream position at construction time.
      Specified by:
      seek in class ChannelData
      Parameters:
      position - the position where to move.
      Throws:
      IOException - if the stream cannot be moved to the given position.
    • rewind

      public final boolean rewind() throws IOException
      Empties the buffer and reset the channel position at the beginning of the stream. This method is similar to seek(0) except that the buffer content is discarded.
      Returns:
      true on success, or false if it is not possible to reset the position.
      Throws:
      IOException - if the stream cannot be moved to the original position.