Class ChannelData

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

public abstract class ChannelData extends Object implements Markable
Properties common to ChannelDataInput and ChannelDataOutput. Common properties include a reference to a ByteBuffer supplied by the user and methods for querying or modifying the stream position. This class does not define any read or write operations.
Since:
0.3
Version:
1.3
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private static final class 
    A mark pushed by the mark() method and pooled by the reset() method.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static final int
    Number of bits needed for storing the bit offset in bitPosition.
    private long
    The current bit position within the stream.
    The buffer to use for transferring data between the channel to memory.
    (package private) long
    The channel position where is located the buffer value at index 0.
    final long
    The position of the channel when this ChannelData has been created.
    final String
    A short identifier (typically a filename without path) used for formatting error message.
    The most recent mark, or null if none.
  • Constructor Summary

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

    Modifier and Type
    Method
    Description
    (package private) final void
    Sets the bit offset to zero.
    (package private) void
    flushAndSetPosition(int position)
    Writes (if applicable) the buffer content up to the given position, then sets the buffer position to the given value.
    final void
    flushBefore(long position)
    Discards the initial portion of the stream prior to the indicated position.
    final int
    Returns the current bit offset, as an integer between 0 and 7 inclusive.
    final long
    Returns the earliest position in the stream to which seeking may be performed.
    long
    Returns the current byte position of the stream.
    final void
    Pushes the current stream position onto a stack of marked positions.
    protected void
    Invoked when an operation between the channel and the buffer transferred no byte.
    private long
    Returns the current byte position of the stream, ignoring overriding by subclasses.
    (package private) final int
    Implementation of ChannelDataInput.readBit() provided here for performance reasons.
    final void
    Resets the current stream byte and bit positions from the stack of marked positions.
    final void
    reset(long position)
    Moves to the given position in the stream and discards all marks at or after that position.
    abstract void
    seek(long position)
    Moves to the given position in the stream, relative to the stream position at construction time.
    final void
    setBitOffset(int bitOffset)
    Sets the bit offset to the given value.
    final void
    setStreamPosition(long position)
    Sets the current byte position of the stream.
    final void
    Moves the stream position to the next byte boundary.
    Returns a string representation of this object for debugging purpose.

    Methods inherited from class java.lang.Object

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

    • BIT_OFFSET_SIZE

      private static final int BIT_OFFSET_SIZE
      Number of bits needed for storing the bit offset in bitPosition. The following condition must hold:
      See Also:
    • filename

      public final String filename
      A short identifier (typically a filename without path) used for formatting error message. This is often the value given by StorageConnector.getStorageName().
    • buffer

      public final ByteBuffer buffer
      The buffer to use for transferring data between the channel to memory.
    • channelOffset

      public final long channelOffset
      The position of the channel when this ChannelData has been created. This is almost always 0, but we allow other values in case the data to read or write are part of a bigger file.

      This value is added to the argument given to the seek(long) method. Users can ignore this field, unless they want to invoke SeekableByteChannel.position(long) directly.

    • bufferOffset

      long bufferOffset
      The channel position where is located the buffer value at index 0. This is initially zero and shall be incremented as below:
    • bitPosition

      private long bitPosition
      The current bit position within the stream. The 3 lowest bits are the bit offset, and the remaining of the long value is the stream position where the bit offset is valid.
      See Also:
    • mark

      private ChannelData.Mark mark
      The most recent mark, or null if none. This is the tail of a chained list of marks.
  • Constructor Details

    • ChannelData

      ChannelData(String filename, Channel channel, ByteBuffer buffer) throws IOException
      Creates a new instance for the given channel and using the given buffer. The channel is not stored by this class - it shall be stored by the subclass.
      Parameters:
      filename - a short identifier (typically a filename without path) used for formatting error message.
      channel - the channel from where data are read or where to wrote.
      buffer - the buffer where to store the data.
      Throws:
      IOException - if an error occurred while reading the channel.
    • ChannelData

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

      ChannelData(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

    • readBitFromBuffer

      final int readBitFromBuffer()
      Implementation of ChannelDataInput.readBit() provided here for performance reasons. It is caller responsibility to ensure that the buffer contains at least one byte.
    • getBitOffset

      public final int getBitOffset()
      Returns the current bit offset, as an integer between 0 and 7 inclusive.

      According ImageInputStream contract, the bit offset shall be reset to 0 by every call to any read or write method except readBit(), readBits(int), writeBit(int) and writeBits(long, int).

      Returns:
      the bit offset of the stream.
    • setBitOffset

      public final void setBitOffset(int bitOffset)
      Sets the bit offset to the given value. The given value shall be between 0 inclusive to 8 exclusive.
      Parameters:
      bitOffset - the new bit offset of the stream.
      Throws:
      IllegalArgumentException - if the given offset is out of range.
    • skipRemainingBits

      public final void skipRemainingBits()
      Moves the stream position to the next byte boundary. If the bit offset is zero, this method does nothing. Otherwise it skips the remaining bits in current byte.
    • clearBitOffset

      final void clearBitOffset()
      Sets the bit offset to zero.
    • getStreamPosition

      public long getStreamPosition()
      Returns the current byte position of the stream. The returned value is relative to the position that the stream had at ChannelData construction time.
      Specified by:
      getStreamPosition in interface Markable
      Returns:
      the position of the stream.
    • position

      private long position()
      Returns the current byte position of the stream, ignoring overriding by subclasses. The returned value is relative to the position that the stream had at ChannelData construction time.
    • setStreamPosition

      public final void setStreamPosition(long position)
      Sets the current byte position of the stream. This method does not seeks the stream; this method only modifies the value to be returned by getStreamPosition(). This method can be invoked when some external code has performed some work with the channel and wants to inform this ChannelData about the new position resulting from this work. Notes:
      Parameters:
      position - the new position of the stream.
    • getFlushedPosition

      public final long getFlushedPosition()
      Returns the earliest position in the stream to which seeking may be performed.
      Returns:
      the earliest legal position for seeking.
    • flushBefore

      public final void flushBefore(long position) throws IOException
      Discards the initial portion of the stream prior to the indicated position. Attempting to seek to an offset within the flushed portion of the stream may result in an IndexOutOfBoundsException.

      If the buffer is read-only, then this method does nothing. Otherwise this method moves the data starting at the given position to the beginning of the buffer, thus making more room for new data before the data at the given position is discarded.

      Parameters:
      position - the length of the stream prefix that may be flushed.
      Throws:
      IOException - if an I/O error occurred.
    • flushAndSetPosition

      void flushAndSetPosition(int position) throws IOException
      Writes (if applicable) the buffer content up to the given position, then sets the buffer position to the given value. The buffer limit is unchanged, and the buffer offset is incremented by the given value.
      Throws:
      IOException
    • seek

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

      public final void mark()
      Pushes the current stream position onto a stack of marked positions. Note that ChannelData maintains its own marks - the buffer's mark is left unchanged.
      Specified by:
      mark in interface Markable
      See Also:
    • reset

      public final void reset() throws IOException
      Resets the current stream byte and bit positions from the stack of marked positions. An IOException may be be thrown if the previous marked position lies in the discarded portion of the stream.

      Departure from Image I/O specification

      The ImageInputStream.reset() contract specifies that if there is no matching mark, then this method shall do nothing. This method throws IOException instead; silently ignoring mismatch is considered too dangerous. This is a departure from ImageInputStream but is consistent with InputStream.reset() contract.
      Specified by:
      reset in interface Markable
      Throws:
      IOException - if this stream cannot move to the last mark position.
      See Also:
    • reset

      public final void reset(long position) throws IOException
      Moves to the given position in the stream and discards all marks at or after that position. If a mark exists at the given position, the bit offset is also restored.
      Specified by:
      reset in interface Markable
      Parameters:
      position - position where to seek.
      Throws:
      IOException - if this stream cannot move to the specified mark position.
    • onEmptyTransfer

      protected void onEmptyTransfer() throws IOException
      Invoked when an operation between the channel and the buffer transferred no byte. Note that this is unrelated to end-of-file, in which case ReadableByteChannel.read(ByteBuffer) returns -1. A return value of 0 happen for example if the channel is a socket in non-blocking mode and the socket buffer has not yet transferred new data.

      The current implementation sleeps an arbitrary number of time before to allow a new try. We do that in order to avoid high CPU consumption when data are expected to take more than a few nanoseconds to arrive.

      Throws:
      IOException - if the implementation chooses to stop the process.
    • toString

      public String toString()
      Returns a string representation of this object for debugging purpose.
      Overrides:
      toString in class Object
      Returns:
      a string representation of this object.