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