Sharkysoft home

lava.riff
Class RiffChunkReader

java.lang.Object
  |
  +--lava.riff.RiffChunkReader
Direct Known Subclasses:
RiffStreamReader

public class RiffChunkReader
extends java.lang.Object

Reads data from RIFF chunk.

Details: A RiffChunkReader reads and returns data from a single chunk in a RIFF file. Since a RIFF file can have many chunks, there may be multiple chunk readers attached to the same open RIFF file. However, because each chunk reader maintains its own file pointer, all chunk readers associated with a given RIFF stream can operate independently, and it is usually safe to process data from multiple instances at the same time (in the same thread). Each RiffChunkReader maintains information about the chunk's tag, size, and location.

Several methods are available for reading various data types within a chunk. Most of these methods simply return the unit of data that was requested. However, when a RiffChunkReader is called on to read one of its own inner chunks, it simply advances its read pointer past the entire inner chunk, while returning a new instance of RiffChunkReader bound to the inner chunk. This makes it possible to set aside the inner chunk for later processing while continuing on with the outer chunk. Or, inner chunks can be processed immediately, in a depth-first recursive fashion. It is up to the programmer.


Field Summary
 long size
          Chunk data length.
 int tag
          Chunk type identifier.
 
Method Summary
 void free(long from, int amount)
          Unbuffers data segment.
 void freeAll()
          Unbuffers entire chunk.
 void freeHeader()
          Unbuffers header.
 boolean hasMoreData()
          Determines if more data is available.
 byte readByte()
          Reads BYTE.
 byte[] readBytes(byte[] bytes, int offset, int amount)
          Reads BYTEs.
 RiffChunkReader readChunk()
          Begins reading inner chunk.
 int readDword()
          Reads DWORD.
 int[] readDwords(int[] dwords, int offset, int amount)
          Reads DWORDs.
 java.lang.String readString()
          Reads string.
 int readTag()
          Reads chunk type identifier.
 short readWord()
          Reads WORD.
 short[] readWords(short[] words, int offset, int amount)
          Reads WORDs.
 void reset()
          Resets read position.
 void seek(long i)
          Sets read position.
 void skipBytes(long count)
          Skips bytes.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

tag

public final int tag
Chunk type identifier.

Details: This member is the tag associated with this chunk. The most significant byte is the first character of the tag.


size

public final long size
Chunk data length.

Details: This member is the length of this chunk's data segment.

Method Detail

readChunk

public RiffChunkReader readChunk()
                          throws java.io.IOException
Begins reading inner chunk.

Details: readChunk does the following:

  1. Verfies that the data at the current read location has the characteristics of a valid inner chunk, given the outer chunks' context.
  2. Sets the current read location to just beyond the inner chunk's end, as if all the inner chunk data had been skipped.
  3. Returns a new RiffChunkReader capable of reading the inner chunk that was skipped.

Other than the inner chunk's header, no data from the inner chunk is actually processed

If this method is called at the wrong time, i.e., when the outer chunk's pointer is not actually pointing to the start of an inner chunk, strange results can occur. This is because there is no way to determine whether what follows is actually an inner chunk or not. The first four bytes read are interpreted as the inner chunk's tag, and the following four bytes are read to determine the inner chunk's data length (so that it can be skipped in the outer chunk). But if the inner chunk's length field indicates an inner chunk that is small enough to be properly nested within the outer chunk, no error can be detected. Otherwise, an EOFException will be thrown.

Returns:
a new chunk reader for the inner chunk
Throws:
java.io.IOException - if an I/O error occurs
java.io.EOFException - if there is no inner chunk, or the inner chunk read is too large to be properly nested in the outer chunk

readTag

public final int readTag()
                  throws java.io.IOException
Reads chunk type identifier.

Details: readTag reads a four character tag (chunk type identifier) from the current position in the chunk. The most significant byte of the returned value is the first character of the tag.

Returns:
the chunk type identifier read
Throws:
java.io.EOFException - if reading four bytes for the tag will extend the chunk reader beyond the chunk's end

readByte

public final byte readByte()
                    throws java.io.IOException
Reads BYTE.

Details: readByte reads a single BYTE from the current position in the chunk.

Returns:
the BYTE
Throws:
java.io.EOFException - if reading a BYTE extends the chunk reader beyond the chunk's end

readWord

public final short readWord()
                     throws java.io.IOException
Reads WORD.

Details: readWord reads a WORD from the current position in the chunk.

Returns:
the WORD
Throws:
java.io.EOFException - if reading a WORD extends the chunk reader beyond the chunk's end

readDword

public final int readDword()
                    throws java.io.IOException
Reads DWORD.

Details: readDword reads a DWORD from the current position in the chunk.

Returns:
the DWORD
Throws:
java.io.EOFException - if reading a DWORD extends the chunk reader beyond the chunk's end

readBytes

public final byte[] readBytes(byte[] bytes,
                              int offset,
                              int amount)
                       throws java.io.IOException
Reads BYTEs.

Details: readBytes reads a sequence of BYTEs and returns them in the given byte array (bytes), starting with bytes [offset]. amount BYTEs are read. If bytes is null, a new byte array is created whose length is just large enough to accomodate the request. In either case, the array into which the BYTEs were written is returned.

Parameters:
bytes - the array to copy bytes into
offset - offset into array where copying begins
amount - the number of BYTEs to read
Returns:
the array of BYTEs that was read
Throws:
java.io.IOException - if an I/O error occurs
java.io.EOFException - if reading the BYTEs extends the chunk reader beyond the chunk's end

readWords

public final short[] readWords(short[] words,
                               int offset,
                               int amount)
                        throws java.io.IOException
Reads WORDs.

Details: readWords reads a sequence of WORDs and returns them in the given short array (words), starting with words [offset]. amount WORDs are read. If words is null, a new short array is created whose length is just large enough to accomodate the request. In either case, the array into which the WORDs were written is returned.

Parameters:
words - the array to copy words into
offset - offset into array where copying begins
amount - the number of WORDs to read
Returns:
the array of WORDs that was read
Throws:
java.io.IOException - if an I/O error occurs
java.io.EOFException - if reading the WORDs extends the chunk reader beyond the chunk's end

readDwords

public final int[] readDwords(int[] dwords,
                              int offset,
                              int amount)
                       throws java.io.IOException
Reads DWORDs.

Details: readDwords reads a sequence of DWORDs and returns them in the given int array (dwords), starting with dwords [offset]. amount DWORDs are read. If dwords is null, a new int array is created whose length is just large enough to accomodate the request. In either case, the array into which the DWORDs were written is returned.

Parameters:
dwords - the array to copy dwords into
offset - offset into array where copying begins
amount - the number of DWORDs to read
Returns:
the array of DWORDs that was read
Throws:
java.io.IOException - if an I/O error occurs
java.io.EOFException - if reading the DWORDs extends the chunk reader beyond the chunk's end

readString

public final java.lang.String readString()
                                  throws java.io.IOException
Reads string.

Details: readString reads a zero-terminated character string and returns it.

Returns:
the string that was read
Throws:
java.io.EOFException - if the chunk's end is reached before the end of the string is reached

reset

public final void reset()
Resets read position.

Details: reset sets this chunk's read position to the beginning of the chunk's data segment.


seek

public void seek(long i)
          throws java.io.IOException
Sets read position.

Details: seek sets this chunk's read position to the given offset relative to the beginning of the chunk's data segment. (0 is the offset of the first data byte immediately following the tag and size DWORDs.)

Parameters:
i - the new chunk pointer value
Throws:
java.io.EOFException - if the new chunk pointer value is beyond the end of the chunk

skipBytes

public final void skipBytes(long count)
                     throws java.io.IOException
Skips bytes.

Details: skipBytes skips past bytes in this chunk by advancing the chunk pointer.

Parameters:
count - the number of bytes to skip
Throws:
java.io.EOFException - if skipping the indicated number of bytes will place the chunk pointer beyond the end of the chunk

hasMoreData

public boolean hasMoreData()
Determines if more data is available.

Details: hasMoreData determines if at least one more byte can be read from this chunk.

Returns:
true if one more byte can be read, false otherwise

free

public void free(long from,
                 int amount)
          throws java.io.IOException
Unbuffers data segment.

Details: Clients can call free to indicate that they are no longer interested in the named portion of the RIFF source. This call translates into an equivalent call to the underlying IRiffInput's free method. from indicates the offset in this chunk of the segment and amount indicates the total number of BYTEs to release.

Parameters:
from - start of segment
amount - length of segment
Throws:
java.io.IOException - if an I/O error occurs

freeHeader

public void freeHeader()
                throws java.io.IOException
Unbuffers header.

Details: freeHeader serves the same purpose as free but has an implied range: the 8-BYTE header for this chunk.

Throws:
java.io.IOException - if an I/O error occurs

freeAll

public void freeAll()
             throws java.io.IOException
Unbuffers entire chunk.

Details: freeAll serves the same purpose as free but has an implied range: the entire chunk, including the header and the entire data segment.

Throws:
java.io.IOException - if an I/O error occurs

Sharkysoft home