//============================================================================== // PassThruReader.java //============================================================================== package tribble.io; // System imports import java.io.InputStream; import java.io.IOException; import java.io.Reader; import java.lang.String; // Local imports // (None) /******************************************************************************* * Pass-through character reader stream. * *
* Reads bytes from an underlying {@link InputStream} object, returning each byte
* as a Unicode character code. This is effectively a character stream that
* reads ISO 8859-1 character codes as uninterpreted single-byte sequences,
* i.e., each character code is composed of a single 8-bit octet read from the
* input stream.
*
*
* @version $Revision: 1.1 $ $Date: 2005/04/06 04:17:06 $
* @since 2005-04-05
* @author
* David R. Tribble
* (david@tribble.com).
*
*
* Copyright ©2005 by David R. Tribble, all rights reserved.
*
* Permission is granted to freely use and distribute this source
* code provided that the original copyright and authorship notices
* remain intact.
*
* @see PassThruWriter
*/
public class PassThruReader
extends java.io.Reader
{
// Identification
/** Revision information. */
static final String REV =
"@(#)tribble/io/PassThruReader.java $Revision: 1.1 $ $Date: 2005/04/06 04:17:06 $\n";
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Protected variables
/** Underlying byte input stream. */
protected InputStream m_in;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Public constructors
/***************************************************************************
* Constructor.
*
* @param in
* Underlying input stream, which provides a source of input bytes.
*
* @since 1.1, 2005-04-05
*/
public PassThruReader(InputStream in)
{
// Initialize
super(in);
m_in = in;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Public methods
/***************************************************************************
* Close this input stream.
*
* @throws IOException
* Thrown if an I/O error occurs while closing the underlying input stream.
*
* @since 1.1, 2005-04-05
*/
public void close()
throws IOException
//overrides java.io.Reader
{
InputStream in;
// Close the underlying input stream
in = m_in;
m_in = null;
if (in != null)
{
synchronized (this.lock)
{
in.close();
}
}
}
/***************************************************************************
* Read a single character.
* This method will block until a character is available, an I/O error
* occurs, or the end of the stream is reached.
*
* @return
* A Unicode character code, always in the range [0x0000,0x00FF], or -1 if
* the end of the input stream has been reached.
*
* @throws IOException
* Thrown if an I/O error occurs while reading the underlying input stream.
*
* @since 1.1, 2005-04-05
*/
public int read()
throws IOException
//overrides java.io.Reader
{
int ch;
if (m_in == null)
throw new IOException("Stream is closed.");
synchronized (this.lock)
{
// Read a character as a single byte
ch = m_in.read();
}
// Check for end of input
if (ch < 0)
return (-1);
// Return the byte as a Unicode character
return (ch & 0x00FF);
}
/***************************************************************************
* Read a group of characters.
* This method will block until a character is available, an I/O error
* occurs, or the end of the stream is reached.
*
* @param buf
* An array of Unicode characters to be read.
* Each character is read as an 8-bit character code, always in the range
* [0x0000,0x00FF].
*
* @param off
* Index of the first character in buf to read.
*
* @param len
* Number of characters in buf to read.
*
* @return
* The number of characters actually read from the input stream, or -1 if the
* end of the stream has been reached.
*
* @throws IOException
* Thrown if an I/O error occurs while reading the underlying input stream.
*
* @since 1.1, 2005-04-05
*/
public int read(char[] buf, int off, int len)
throws IOException
//overrides java.io.Reader
{
int n;
if (m_in == null)
throw new IOException("Stream is closed.");
synchronized (this.lock)
{
// Read characters as single bytes from the input stream
len += off;
for (n = off; n < len; n++)
{
int ch;
// Read the next character as a single byte
ch = m_in.read();
if (ch < 0)
break;
buf[n] = (char) (ch & 0x00FF);
}
}
return (n - off);
}
/***************************************************************************
* Skip (discard) a number of characters from this input stream.
*
* @param n
* The number of input characters to skip.
*
* @return
* The number of characters skipped.
*
* @throws IOException
* Thrown if an I/O error occurs in the underlying input stream.
*
* @since 1.1, 2005-04-05
*/
public long skip(long n)
throws IOException
//overrides java.io.Reader
{
if (m_in == null)
throw new IOException("Stream is closed.");
return (m_in.skip(n));
}
/***************************************************************************
* Determine whether input is available in this input stream ro not.
*
* @return
* True if the next {@link #read() read()} is guaranteed not to block for
* input, otherwise false. (Note that returning false does not guarantee
* that the next read will block.)
*
* @throws IOException
* Thrown if an I/O error occurs in the underlying input stream.
*
* @since 1.1, 2005-04-05
*/
public boolean ready()
throws IOException
//overrides java.io.Reader
{
if (m_in == null)
throw new IOException("Stream is closed.");
return (m_in.available() > 0);
}
/***************************************************************************
* Determine whether this stream supports the "mark" operation.
*
* @return
* True if the {@link #mark mark()} method is supported, otherwise false.
*
* @since 1.1, 2005-04-05
*/
public boolean markSupported()
//overrides java.io.Reader
{
if (m_in == null)
return (false);
return (m_in.markSupported());
}
/***************************************************************************
* Mark the present position in this input stream.
* A subsequent call to {@link #reset reset()} will attempt to reposition the
* stream to the marked point.
*
* @param limit
* The minimum number of characters that can be read while still preserving
* the position mark. Reading more than this number of characters may cause
* the mark to become invalidated.
*
* @throws IOException
* Thrown if this operation is not supported, or if any other I/O error
* occurs in the underlying input stream.
*
* @since 1.1, 2005-04-05
*/
public void mark(int limit)
throws IOException
//overrides java.io.Reader
{
if (m_in == null)
throw new IOException("Stream is closed.");
m_in.mark(limit);
}
/***************************************************************************
* Reset the position of this input stream.
* If the stream has been marked by a previous call to {@link #mark mark()}
* and the mark is still valid, the position is reset to that mark; otherwise
* the stream is repostioned appropriately, e.g., the to beginning of the
* stream.
*
* @throws IOException
* Thrown if this operation is not supported, or if the mark has become
* invalidated, or if any other I/O error occurs in the underlying input
* stream.
*
* @since 1.1, 2005-04-05
*/
public void reset()
throws IOException
//overrides java.io.Reader
{
if (m_in == null)
throw new IOException("Stream is closed.");
m_in.reset();
}
}
// End PassThruReader.java