Class InputStreamAdapter

java.lang.Object
java.io.InputStream
org.apache.sis.internal.storage.io.InputStreamAdapter
All Implemented Interfaces:
Closeable, AutoCloseable, Markable

public final class InputStreamAdapter extends InputStream implements Markable
Wraps an ImageInputStream as a standard InputStream.

Thread-safety

This class is thread-safe only if the underlying ImageInputStream is itself thread-safe. For performance reasons, this class does not synchronize the frequently invoked read(…) methods since they do nothing else than delegating to ImageInputStream. This means that if the wrapped input is ChannelImageInputStream, then this class is not thread-safe. This is not necessarily a contradiction with Java API since input streams define no explicit synchronization lock (contrarily to Reader.
Since:
0.4
Version:
1.2
See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    The underlying data input stream.
    (package private) boolean
    Temporarily set to true if a call to close() should not be propagated to the input.
    private int
    Value of nestedMarks at the time when markPosition has been set, or -1 if none.
    private long
    Position of the last mark created by mark(int).
    private int
    Count of marks created by mark(), not counting the mark created by mark(int).
  • Constructor Summary

    Constructors
    Constructor
    Description
    Constructs a new input stream.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Closes this input stream.
    long
    Returns the current byte position of the stream.
    void
    Marks the current position in this input stream.
    void
    mark(int readlimit)
    Discards the previous mark created by mark(int) and marks the current stream position.
    boolean
    Returns always true, since marks support is mandatory in image input stream.
    int
    Reads the next byte of data from the input stream.
    int
    read(byte[] b)
    Reads some number of bytes from the input stream.
    int
    read(byte[] b, int off, int len)
    Reads up to len bytes of data from the input stream.
    void
    Repositions this stream to the position at the time the mark method was last called.
    void
    reset(long mark)
    Moves to the given position in the stream and discards all marks at or after that position.
    long
    skip(long n)
    Skips over and discards n bytes of data from this input stream.

    Methods inherited from class java.lang.Object

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

    • input

      public final ImageInputStream input
      The underlying data input stream. In principle, public access to this field breaks encapsulation. But since InputStreamAdapter does not hold any state and just forwards every method calls to that ImageInputStream, using on object or the other does not make a difference.
    • markPosition

      private long markPosition
      Position of the last mark created by mark(int). Undefined if markIndex is negative.
    • markIndex

      private int markIndex
      Value of nestedMarks at the time when markPosition has been set, or -1 if none. Used for differentiating the (single) mark created by mark(int) from the (possibly many) marks created by mark(). This complexity exists because reset() must comply with two inconsistent mark(…) method contracts.
    • nestedMarks

      private int nestedMarks
      Count of marks created by mark(), not counting the mark created by mark(int). We have to keep this count ourselves because ImageInputStream.reset() does nothing if there is no mark, and provides no API for letting us know if reset() worked.
    • keepOpen

      boolean keepOpen
      Temporarily set to true if a call to close() should not be propagated to the input.
      See Also:
  • Constructor Details

    • InputStreamAdapter

      public InputStreamAdapter(ImageInputStream input) throws IOException
      Constructs a new input stream.
      Parameters:
      input - the stream to wrap.
      Throws:
      IOException - if an error occurred while creating the adapter.
  • Method Details

    • read

      public int read() throws IOException
      Reads the next byte of data from the input stream.
      Specified by:
      read in class InputStream
      Returns:
      the next byte, or -1 if the end of the stream is reached.
      Throws:
      IOException - if an I/O error occurs.
    • read

      public int read(byte[] b) throws IOException
      Reads some number of bytes from the input stream.
      Overrides:
      read in class InputStream
      Returns:
      total number of bytes read, or -1 if the end of the stream has been reached.
      Throws:
      IOException - if an I/O error occurs.
    • read

      public int read(byte[] b, int off, int len) throws IOException
      Reads up to len bytes of data from the input stream.
      Overrides:
      read in class InputStream
      Returns:
      total number of bytes read, or -1 if the end of the stream has been reached.
      Throws:
      IOException - if an I/O error occurs.
    • skip

      public long skip(long n) throws IOException
      Skips over and discards n bytes of data from this input stream.
      Overrides:
      skip in class InputStream
      Returns:
      total number of bytes skipped.
      Throws:
      IOException - if an I/O error occurs.
    • markSupported

      public boolean markSupported()
      Returns always true, since marks support is mandatory in image input stream.
      Overrides:
      markSupported in class InputStream
      Returns:
      true.
    • mark

      public void mark(int readlimit)
      Discards the previous mark created by mark(int) and marks the current stream position. This method is part of InputStream API, where only one mark can be set and multiple calls to reset() move to the same position until mark(int) is invoked again.
      Overrides:
      mark in class InputStream
      Parameters:
      readlimit - ignored.
      Throws:
      UncheckedIOException - if the mark cannot be set.
    • mark

      public void mark()
      Marks the current position in this input stream. This method is part of Markable API, where marks can be nested.
      Specified by:
      mark in interface Markable
      See Also:
    • reset

      public void reset() throws IOException
      Repositions this stream to the position at the time the mark method was last called. This method has to comply with both InputStream.reset() and Markable.reset() contracts. It does that by pulling from most recent mark to oldest mark regardless if marks were created by mark() or mark(int), except that all marks created by mark(int) are ignored except the most recent one.

      Implementations of reset() in Java I/O package does not discard the mark. The implementation in this InputStreamAdapter class does not discard the mark neither if the mark done by a call to mark(int) is the only mark remaining. Some code depends on the ability to do many reset() for the same mark.

      Specified by:
      reset in interface Markable
      Overrides:
      reset in class InputStream
      Throws:
      IOException - if this stream cannot move to the last mark position.
      See Also:
    • reset

      public void reset(long mark) throws IOException
      Moves to the given position in the stream and discards all marks at or after that position. This convolved method exists because of the attempt to conciliate two different APIs in this class (see reset()). This method does not simply call ImageInputStream.seek(long) because we need to keep track of the marks.
      Specified by:
      reset in interface Markable
      Parameters:
      mark - position where to seek.
      Throws:
      IOException - if this stream cannot move to the specified mark position.
    • getStreamPosition

      public long getStreamPosition() throws IOException
      Returns the current byte position of the stream.
      Specified by:
      getStreamPosition in interface Markable
      Returns:
      the position of the stream.
      Throws:
      IOException - if the position cannot be obtained.
    • close

      public void close() throws IOException
      Closes this input stream.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Overrides:
      close in class InputStream
      Throws:
      IOException - if an I/O error occurs.