//============================================================================== // 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