//============================================================================== // ReaderInputStream.java //============================================================================== package tribble.io; // System imports import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.lang.String; import java.lang.StringBuffer; // Local imports // (None) /******************************************************************************* * Pass-through character reader stream. * *
* Reads characters from an underlying {@link Reader} object, returning them as * 8-bit character codes. Only the low-order 8 bits of each character is * returned; character codes greater than 0x00FF are truncated to 8 bits. * This is similar to 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. * *
* This class is essentially the inverse of class
* {@link java.io.InputStreamReader}.
*
*
* @version $Revision: 1.1 $ $Date: 2005/04/13 03:20:43 $
* @since 2005-04-10
* @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 WriterOutputStream
* @see PassThruReader
* @see java.io.InputStreamReader
*/
public class ReaderInputStream
extends java.io.InputStream
{
// Identification
/** Revision information. */
static final String REV =
"@(#)tribble/io/ReaderInputStream.java $Revision: 1.1 $ $Date: 2005/04/13 03:20:43 $\n";
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Protected variables
/** Underlying input stream reader. */
protected Reader m_in;
/** Pushed-back character. */
protected int m_ungetCh = -1;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Public constructors
/***************************************************************************
* Constructor.
*
* @param out
* Underlying input stream, which provides a destination for input bytes.
*
* @since 1.1, 2005-04-10
*/
public ReaderInputStream(Reader in)
{
// Initialize
m_in = in;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Public methods
/***************************************************************************
* Close this input stream.
*
* @throws IOException
* Thrown if an I/O error occurs while closing the underlying input reader.
*
* @since 1.1, 2005-04-10
*/
public void close()
throws IOException
//overrides java.io.InputStream
{
Reader in;
// Close the underlying input reader
in = m_in;
m_in = null;
if (in != null)
in.close();
}
/***************************************************************************
* Read a single character.
*
* @return
* A character code, or -1 if the end of the input stream has been reached.
* Only the lower 8 bits of the character are returned (yielding characters
* in the range [0x0000,0x00FF]).
*
* @throws IOException
* Thrown if an I/O error occurs while reading from the underlying input
* reader.
*
* @since 1.1, 2005-04-10
*/
public int read()
throws IOException
//overrides java.io.InputStream
{
int ch;
if (m_in == null)
throw new IOException("Stream is closed.");
// Read a character as a single byte
if (m_ungetCh >= 0)
{
// Pop the previously pushed-back character
ch = m_ungetCh;
m_ungetCh = -1;
}
else
ch = m_in.read();
if (ch < 0)
return (-1);
else
return (ch & 0x00FF);
}
/***************************************************************************
* Read a group of characters.
*
*
* This method has exactly the same effect as the call: * read(buf, 0, buf.length). * * * @param buf * An array of character bytes to be read. * Each byte represents a single 8-bit character code in the range * [0x0000,0x00FF]. * * @return * The actual number of characters (byte) read into buf, or -1 * if the end of the input stream has been reached. * * @throws IOException * Thrown if an I/O error occurs while reading from the underlying input * reader. * * @since 1.1, 2005-04-10 */ public int read(byte[] buf) throws IOException //overrides java.io.InputStream { return (read(buf, 0, buf.length)); } /*************************************************************************** * Read a group of characters. * * @param buf * An array of character bytes to be read. * Each byte represents a single 8-bit character code 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 actual number of characters (byte) read into buf, or -1 if * the end of the input stream has been reached. * * @throws IOException * Thrown if an I/O error occurs while reading from the underlying input * reader. * * @since 1.1, 2005-04-10 */ public int read(byte[] buf, int off, int len) throws IOException //overrides java.io.InputStream { int n; if (m_in == null) throw new IOException("Stream is closed."); // Read characters as bytes from the input reader len += off; n = off; if (m_ungetCh >= 0 && n < len) { // Pop the previously pushed-back character buf[n++] = (byte) (m_ungetCh & 0xFF); m_ungetCh = -1; } while (n < len) { int ch; // Read the next character into a single byte ch = m_in.read(); if (ch < 0) break; buf[n++] = (byte) (ch & 0xFF); } // Return the number of characters read if (n == off) return (-1); else return (n - off); } /*************************************************************************** * Read a line of text from this input stream. * *
* If the underlying stream is a {@link java.io.BufferedReader}, * its readLine() method is called. * Otherwise, characters are read until a terminating newline sequence is * encountered; a line is considered to be terminated by a line feed * (LF, U+000A, '\n'), a carriage return (CR, U+000D, '\r'), or * a carriage return followed immediately by a linefeed (CR LF). * *
* This method is not defined by the {@link java.io.InputStream} class, but * is provided as a convenient enhancement. * * * @throws IOException * Thrown if an I/O error occurs while reading from the underlying input * reader. * * @since 1.1, 2005-04-10 */ public String readLine() throws IOException { if (m_in == null) throw new IOException("Stream is closed."); // Read a text line from the input reader if (m_in instanceof BufferedReader) { return (((BufferedReader) m_in).readLine()); } else { StringBuffer line; // Read characters up to a newline sequence line = new StringBuffer(80); for (;;) { int ch; // Read the next input character ch = m_in.read(); if (ch == '\r') { // Check for a CR/LF sequence ch = m_in.read(); if (ch >= 0 && ch != '\n') m_ungetCh = ch; break; } else if (ch == '\n') break; else if (ch < 0) break; else line.append((char) ch); } // Return the text line return (line.toString()); } } } // End ReaderInputStream.java