jj2000.j2k.util
Class ISRandomAccessIO

java.lang.Object
  |
  +--jj2000.j2k.util.ISRandomAccessIO
All Implemented Interfaces:
BinaryDataInput, BinaryDataOutput, RandomAccessIO

public class ISRandomAccessIO
extends java.lang.Object
implements RandomAccessIO

This class implements a wrapper to turn an InputStream into a RandomAccessIO. To provide random access, the input data from the InputStream is cached in an in-memory buffer. The in-memory buffer size can be limited to a specified size. The data is read into the cache on a as needed basis, blocking only when necessary.

The cache grows automatically as necessary. However, if the data length is known prior to the creation of a ISRandomAccessIO object, it is best to specify that as the initial in-memory buffer size. That will minimize data copying and multiple allocation.

Multi-byte data is read in big-endian order. The in-memory buffer storage is released when 'close()' is called. This class can only be used for data input, not output. The wrapped InputStream is closed when all the input data is cached or when 'close()' is called.

If an out of memory condition is encountered when growing the in-memory buffer an IOException is thrown instead of an OutOfMemoryError. The exception message is "Out of memory to cache input data".

This class is intended for use as a "quick and dirty" way to give network connectivity to RandomAccessIO based classes. It is not intended as an efficient means of implementing network connectivity. Doing such requires reimplementing the RandomAccessIO based classes to directly use network connections.

This class does not use temporary files as buffers, because that would preclude the use in unsigned applets.


Field Summary
private  byte[] buf
           
private  boolean complete
           
private  int inc
           
private  java.io.InputStream is
          The InputStream that is wrapped
private  int len
           
private  int maxsize
           
private  int pos
           
 
Constructor Summary
ISRandomAccessIO(java.io.InputStream is)
          Creates a new RandomAccessIO wrapper for the given InputStream 'is'.
ISRandomAccessIO(java.io.InputStream is, int size, int inc, int maxsize)
          Creates a new RandomAccessIO wrapper for the given InputStream 'is'.
 
Method Summary
 void close()
          Closes this object for reading as well as the wrapped InputStream, if not already closed.
 void flush()
          Does nothing since this class does not implement data output.
 int getByteOrdering()
          Returns the endianess (i.e., byte ordering) of multi-byte I/O operations.
 int getPos()
          Returns the current position in the stream, which is the position from where the next byte of data would be read.
private  void growBuffer()
          Grows the cache buffer by 'inc', upto a maximum of 'maxsize'.
 int length()
          Returns the length of the stream.
 int read()
          Reads a byte of data from the stream.
 byte readByte()
          Reads a signed byte (8 bit) from the input.
 double readDouble()
          Reads an IEEE double precision (i.e., 64 bit) floating-point number from the input.
 float readFloat()
          Reads an IEEE single precision (i.e., 32 bit) floating-point number from the input.
 void readFully(byte[] b, int off, int n)
          Reads 'len' bytes of data from this file into an array of bytes.
private  void readInput()
          Reads data from the wrapped InputStream and places it in the cache buffer.
 int readInt()
          Reads a signed int (32 bit) from the input.
 long readLong()
          Reads a signed long (64 bit) from the input.
 short readShort()
          Reads a signed short (16 bit) from the input.
 int readUnsignedByte()
          Reads an unsigned byte (8 bit) from the input.
 long readUnsignedInt()
          Reads a unsigned int (32 bit) from the input.
 int readUnsignedShort()
          Reads an unsigned short (16 bit) from the input.
 void seek(int off)
          Moves the current position for the next read operation to offset.
 int skipBytes(int n)
          Skips 'n' bytes from the input.
 void write(int b)
          Throws an IOException since this class does not implement data output.
 void writeByte(int v)
          Throws an IOException since this class does not implement data output.
 void writeDouble(double v)
          Throws an IOException since this class does not implement data output.
 void writeFloat(float v)
          Throws an IOException since this class does not implement data output.
 void writeInt(int v)
          Throws an IOException since this class does not implement data output.
 void writeLong(long v)
          Throws an IOException since this class does not implement data output.
 void writeShort(int v)
          Throws an IOException since this class does not implement data output.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

is

private java.io.InputStream is
The InputStream that is wrapped


maxsize

private int maxsize

inc

private int inc

buf

private byte[] buf

len

private int len

pos

private int pos

complete

private boolean complete
Constructor Detail

ISRandomAccessIO

public ISRandomAccessIO(java.io.InputStream is,
                        int size,
                        int inc,
                        int maxsize)
Creates a new RandomAccessIO wrapper for the given InputStream 'is'. The internal cache buffer will have size 'size' and will increment by 'inc' each time it is needed. The maximum buffer size is limited to 'maxsize'.

Parameters:
is - The input from where to get the data.
size - The initial size for the cache buffer, in bytes.
inc - The size increment for the cache buffer, in bytes.
maxsize - The maximum size for the cache buffer, in bytes.

ISRandomAccessIO

public ISRandomAccessIO(java.io.InputStream is)
Creates a new RandomAccessIO wrapper for the given InputStream 'is'. The internal cache buffer size and increment is to to 256 kB. The maximum buffer size is set to Integer.MAX_VALUE (2 GB).

Parameters:
is - The input from where to get the data.
Method Detail

growBuffer

private void growBuffer()
                 throws java.io.IOException
Grows the cache buffer by 'inc', upto a maximum of 'maxsize'. The buffer size will be increased by at least one byte, if no exception is thrown.

Throws:
java.io.IOException - If the maximum cache size is reached or if not enough memory is available to grow the buffer.

readInput

private void readInput()
                throws java.io.IOException
Reads data from the wrapped InputStream and places it in the cache buffer. Reads all input data that will not cause it to block, but at least on byte is read (even if it blocks), unless EOF is reached. This method can not be called if EOF has been already reached (i.e. 'complete' is true). The wrapped InputStream is closed if the EOF is reached.

Throws:
java.io.IOException - An I/O error occurred, out of meory to grow cache or maximum cache size reached.

close

public void close()
           throws java.io.IOException
Closes this object for reading as well as the wrapped InputStream, if not already closed. The memory used by the cache is released.

Specified by:
close in interface RandomAccessIO
Throws:
java.io.IOException - If an I/O error occurs while closing the underlying InputStream.

getPos

public int getPos()
           throws java.io.IOException
Returns the current position in the stream, which is the position from where the next byte of data would be read. The first byte in the stream is in position 0.

Specified by:
getPos in interface RandomAccessIO
Returns:
The offset of the current position, in bytes.
Throws:
java.io.IOException - If an I/O error occurred.

seek

public void seek(int off)
          throws java.io.IOException
Moves the current position for the next read operation to offset. The offset is measured from the beginning of the stream. If the offset is set beyond the currently cached data, the missing data will be read only when a read operation is performed. Setting the offset beyond the end of the data will cause an EOFException only if the data length is currently known, otherwise an IOException will occur when a read operation is attempted at that position.

Specified by:
seek in interface RandomAccessIO
Parameters:
off - The offset where to move to.
Throws:
java.io.EOFException - If seeking beyond EOF and the data length is known.
java.io.IOException - If an I/O error ocurred.

length

public int length()
           throws java.io.IOException
Returns the length of the stream. This will cause all the data to be read. This method will block until all the data is read, which can be lengthy across the network.

Specified by:
length in interface RandomAccessIO
Returns:
The length of the stream, in bytes.
Throws:
java.io.IOException - If an I/O error ocurred.

read

public int read()
         throws java.io.IOException
Reads a byte of data from the stream.

Specified by:
read in interface RandomAccessIO
Returns:
The byte read, as an int in the range [0-255].
Throws:
java.io.EOFException - If the end-of file was reached.
java.io.IOException - If an I/O error ocurred.

readFully

public void readFully(byte[] b,
                      int off,
                      int n)
               throws java.io.IOException
Reads 'len' bytes of data from this file into an array of bytes. This method reads repeatedly from the stream until all the bytes are read. This method blocks until all the bytes are read, the end of the stream is detected, or an exception is thrown.

Specified by:
readFully in interface RandomAccessIO
Parameters:
b - The buffer into which the data is to be read. It must be long enough.
off - The index in 'b' where to place the first byte read.
n - The number of bytes to read.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

getByteOrdering

public int getByteOrdering()
Returns the endianess (i.e., byte ordering) of multi-byte I/O operations. Always EndianType.BIG_ENDIAN since this class implements only big-endian.

Specified by:
getByteOrdering in interface BinaryDataInput
Returns:
Always EndianType.BIG_ENDIAN.
See Also:
EndianType

readByte

public byte readByte()
              throws java.io.IOException
Reads a signed byte (8 bit) from the input.

Specified by:
readByte in interface BinaryDataInput
Returns:
The next byte-aligned signed byte (8 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

readUnsignedByte

public int readUnsignedByte()
                     throws java.io.IOException
Reads an unsigned byte (8 bit) from the input.

Specified by:
readUnsignedByte in interface BinaryDataInput
Returns:
The next byte-aligned unsigned byte (8 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

readShort

public short readShort()
                throws java.io.IOException
Reads a signed short (16 bit) from the input.

Specified by:
readShort in interface BinaryDataInput
Returns:
The next byte-aligned signed short (16 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

readUnsignedShort

public int readUnsignedShort()
                      throws java.io.IOException
Reads an unsigned short (16 bit) from the input.

Specified by:
readUnsignedShort in interface BinaryDataInput
Returns:
The next byte-aligned unsigned short (16 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

readInt

public int readInt()
            throws java.io.IOException
Reads a signed int (32 bit) from the input.

Specified by:
readInt in interface BinaryDataInput
Returns:
The next byte-aligned signed int (32 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

readUnsignedInt

public long readUnsignedInt()
                     throws java.io.IOException
Reads a unsigned int (32 bit) from the input.

Specified by:
readUnsignedInt in interface BinaryDataInput
Returns:
The next byte-aligned unsigned int (32 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

readLong

public long readLong()
              throws java.io.IOException
Reads a signed long (64 bit) from the input.

Specified by:
readLong in interface BinaryDataInput
Returns:
The next byte-aligned signed long (64 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

readFloat

public float readFloat()
                throws java.io.IOException
Reads an IEEE single precision (i.e., 32 bit) floating-point number from the input.

Specified by:
readFloat in interface BinaryDataInput
Returns:
The next byte-aligned IEEE float (32 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

readDouble

public double readDouble()
                  throws java.io.IOException
Reads an IEEE double precision (i.e., 64 bit) floating-point number from the input.

Specified by:
readDouble in interface BinaryDataInput
Returns:
The next byte-aligned IEEE double (64 bit) from the input.
Throws:
java.io.EOFException - If the end-of file was reached before getting all the necessary data.
java.io.IOException - If an I/O error ocurred.

skipBytes

public int skipBytes(int n)
              throws java.io.IOException
Skips 'n' bytes from the input.

Specified by:
skipBytes in interface BinaryDataInput
Parameters:
n - The number of bytes to skip
Returns:
Always n.
Throws:
java.io.EOFException - If the end-of file was reached before all the bytes could be skipped.
java.io.IOException - If an I/O error ocurred.

flush

public void flush()
Does nothing since this class does not implement data output.

Specified by:
flush in interface BinaryDataOutput

write

public void write(int b)
           throws java.io.IOException
Throws an IOException since this class does not implement data output.

Specified by:
write in interface RandomAccessIO
Parameters:
b - The byte to write. The lower 8 bits of b are written.
Throws:
java.io.IOException - If an I/O error ocurred.

writeByte

public void writeByte(int v)
               throws java.io.IOException
Throws an IOException since this class does not implement data output.

Specified by:
writeByte in interface BinaryDataOutput
Parameters:
v - The value to write to the output
Throws:
java.io.IOException - If an I/O error ocurred.

writeShort

public void writeShort(int v)
                throws java.io.IOException
Throws an IOException since this class does not implement data output.

Specified by:
writeShort in interface BinaryDataOutput
Parameters:
v - The value to write to the output
Throws:
java.io.IOException - If an I/O error ocurred.

writeInt

public void writeInt(int v)
              throws java.io.IOException
Throws an IOException since this class does not implement data output.

Specified by:
writeInt in interface BinaryDataOutput
Parameters:
v - The value to write to the output
Throws:
java.io.IOException - If an I/O error ocurred.

writeLong

public void writeLong(long v)
               throws java.io.IOException
Throws an IOException since this class does not implement data output.

Specified by:
writeLong in interface BinaryDataOutput
Parameters:
v - The value to write to the output
Throws:
java.io.IOException - If an I/O error ocurred.

writeFloat

public void writeFloat(float v)
                throws java.io.IOException
Throws an IOException since this class does not implement data output.

Specified by:
writeFloat in interface BinaryDataOutput
Parameters:
v - The value to write to the output
Throws:
java.io.IOException - If an I/O error ocurred.

writeDouble

public void writeDouble(double v)
                 throws java.io.IOException
Throws an IOException since this class does not implement data output.

Specified by:
writeDouble in interface BinaryDataOutput
Parameters:
v - The value to write to the output
Throws:
java.io.IOException - If an I/O error ocurred.