//============================================================================== // tribble/io/SuspendablePrintWriter.java //------------------------------------------------------------------------------ package tribble.io; // System imports import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; import java.lang.String; import java.lang.System; import java.lang.Throwable; // Local imports import tribble.io.SuspendableWriterI; /******************************************************************************* * A character print output stream that can be suspended and resumed. * *

* This is a default implementation of a character output stream that can be * suspended and resumed (see {@link tribble.io.SuspendableWriterI}), based on * the standard {@link java.io.PrintWriter} class. It provides the capability * of suspending all output written to the stream, so that subsequent write * requests perform no output. It also has the capability of resuming all output * written to the stream. * *

* The member methods of this class never throw exceptions (such as * {@link java.io.IOException}). Instead, when errors occur, they set an * internal flag that can be examined by calling method {@link #checkError}. * Unlike the {@link PrintWriter} class, this class provides a * {@link #clearError} method for clearing the internal error flag. * * @version $Revision: 1.3 $ $Date: 2003/02/01 17:28:18 $ * @since 2001-06-30 * @author * David R. Tribble, * david@tribble.com. *
* Copyright ©2001 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 SuspendableWriter */ public class SuspendablePrintWriter extends PrintWriter implements SuspendableWriterI { // Identification /** Revision information. */ static final String REV = "@(#)tribble/io/SuspendablePrintWriter.java $Revision: 1.3 $ $Date: 2003/02/01 17:28:18 $\n"; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Protected variables /** Underlying output stream. */ protected Writer m_sus; /** Internal error flag. */ protected boolean m_err; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Public constructor methods /*************************************************************************** * Constructor. * Establishes a null (empty) underlying output stream for this stream. * * @since 1.1, 2001-06-30 * * @see #setOutput */ public SuspendablePrintWriter() { // Establish a null (empty) underlying output stream for this stream super(System.out); // Non-null dummy arg setOutput(null); } /*************************************************************************** * Constructor. * Establishes the underlying output stream to which all output for this * stream is written. * * @param os * The underlying output stream for this print stream. * * @since 1.1, 2001-06-30 */ public SuspendablePrintWriter(Writer os) { // Establish the underlying output stream for this stream super(System.out); // Non-null dummy arg setOutput(os); } /*************************************************************************** * Constructor. * Establishes the underlying output stream to which all output for this * stream is written. * * @param os * The underlying output stream for this print stream. * * @param autoFlush * If true, this flag specifies that pending (buffered) output should be * flushed to the underlying output stream whenever {@link #println()} is * called. * * @since 1.1, 2001-06-30 */ public SuspendablePrintWriter(Writer os, boolean autoFlush) { // Establish the underlying output stream for this stream super(System.out); // Non-null dummy arg setOutput(new PrintWriter(os, autoFlush)); } /*************************************************************************** * Constructor. * Establishes the underlying output stream to which all output for this * stream is written. * * @param os * The underlying output stream (which is a byte output stream) for this * print stream. * * @since 1.1, 2001-06-30 */ public SuspendablePrintWriter(OutputStream os) { // Establish the underlying output stream for this stream super(System.out); // Non-null dummy arg setOutput(new PrintWriter(os)); } /*************************************************************************** * Constructor. * Establishes the underlying output stream to which all output for this * stream is written. * * @param os * The underlying output stream (which is a byte output stream) for this * print stream. * * @param autoFlush * If true, this flag specifies that pending (buffered) output should be * flushed to the underlying output stream whenever {@link #println()} is * called. * * @since 1.1, 2001-06-30 */ public SuspendablePrintWriter(OutputStream os, boolean autoFlush) { // Establish the underlying output stream for this stream super(System.out); // Non-null dummy arg setOutput(new PrintWriter(os, autoFlush)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Public methods /*************************************************************************** * Suspends subsequent output written to this output stream. * *

* Subsequent calls to any of the write(), print(), or * println() methods will not write any output to the underlying * stream. * *

* Output to this stream can be resumed by calling {@link #resume}. * *

* This method may be called multiple times without any intervening call to * {@link #resume} without any ill effects. * * @since 1.1, 2001-06-30 * * @see #resume */ public void suspend() //implements tribble.io.SuspendableWriterI { // Suspend subsequent output to this stream out = null; } /*************************************************************************** * Resumes subsequent output written to this output stream. * *

* Subsequent calls to any of the write(), print(), or * println() methods will cause output to be written to the * underlying stream. * *

* Output to this stream can be suspended by calling {@link #suspend}. * *

* This method may be called multiple times without any previous or * intervening call to {@link #suspend} without any ill effects. * * @since 1.1, 2001-06-30 * * @see #suspend */ public void resume() //implements tribble.io.SuspendableWriterI { // Resume subsequent output to this stream out = m_sus; } /*************************************************************************** * Determines if this output stream is suspended or not. * * @return * True if this output stream is currently suspended, otherwise false. * * @since 1.1, 2001-09-11 * * @see #suspend */ public boolean isSuspended() //implements tribble.io.SuspendableWriterI { // Determine if this output stream is suspended return (out == null); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Public methods /*************************************************************************** * Closes this output stream. * *

* Note that this method is required to flush and close the underlying * output stream of this stream. It does this regardless of whether or not * this stream is suspended. * *

* Note that this method does not throw any unchecked exceptions * (in particular, java.io.IOException). * * @since 1.1, 2001-06-30 */ public synchronized void close() //overrides java.io.PrintWriter { if (m_sus != null) { out = m_sus; try { // Flush the underlying output stream out.flush(); // May throw } catch (IOException ex) { // Set the internal error flag m_err = true; } try { // Close the underlying output stream out.close(); // May throw } catch (IOException ex) { // Set the internal error flag m_err = true; } } // Disassociate the underlying output stream from this stream out = null; m_sus = null; } /*************************************************************************** * Flushes any pending output to the output stream. * *

* This does nothing if this output stream is suspended. * * @since 1.1, 2001-06-30 */ public synchronized void flush() //overrides java.io.PrintWriter { if (out != null) { try { // Flush the underlying output stream out.flush(); // May throw } catch (IOException ex) { // Set the internal error flag m_err = true; } } } /*************************************************************************** * Checks the internal error flag. * *

* Any pending output to the underlying output stream is flushed, and then * the setting of the internal error flag is is returned. The flag is set * any time an output (write) error occurs on the underlying output stream. * *

* The status of the underlying output stream is always checked, whether or * not this stream is suspended. * * @return * True if an output (write) error has occurred on this stream. * * @since 1.1, 2001-06-30 * * @see #clearError */ public boolean checkError() //overrides java.io.PrintWriter { if (m_sus != null) { // Flush the underlying output stream, // then retrieve the internal error flag from it if (super.checkError()) m_err = true; } // Examine the internal error flag return (m_err); } /*************************************************************************** * Writes the contents of a character array to this output stream. * No output is written if this stream is suspended. * * @param cbuf * A character buffer to write. * * @since 1.1, 2001-06-30 */ public synchronized void write(char[] cbuf) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.write(cbuf); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a portion of a character array to this output stream. * No output is written if this stream is suspended. * * @param cbuf * A character buffer, from which a subset of characters is written. * * @param off * The offset of the first character within character buffer cbuf * to write. * * @param len * The number of characters from character buffer cbuf to write. * * @since 1.1, 2001-06-30 */ public synchronized void write(char[] cbuf, int off, int len) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.write(cbuf, off, len); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes the contents of a string to this output stream. * No output is written if this stream is suspended. * * @param str * A string to write. * * @since 1.1, 2001-06-30 */ public synchronized void write(String str) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.write(str); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a subset of a string to this output stream. * No output is written if this stream is suspended. * * @param str * A string containing the substring to write. * * @param off * The offset of the first character within the string to write. * * @param len * The number of characters from the substring to write. * * @since 1.1, 2001-06-30 */ public synchronized void write(String str, int off, int len) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.write(str, off, len); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a single character to this output stream. * No output is written if this stream is suspended. * * @param c * A character code to write. * * @since 1.1, 2001-06-30 */ public synchronized void write(int c) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.write(c); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a boolean value, as its equivalent text string, to this output * stream. * No output is written if this stream is suspended. * * @param val * A boolean value to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(boolean val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes an integer value, as its equivalent text string, to this output * stream. * No output is written if this stream is suspended. * * @param val * An integer value to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(int val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a long integer value, as its equivalent text string, to this * output stream. * No output is written if this stream is suspended. * * @param val * A long integer value to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(long val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a float value, as its equivalent text string, to this output * stream. * No output is written if this stream is suspended. * * @param val * A float value to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(float val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a double float value, as its equivalent text string, to this * output stream. * No output is written if this stream is suspended. * * @param val * A double float value to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(double val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a character to this output stream. * No output is written if this stream is suspended. * * @param val * A character to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(char val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes the contents of a character array to this output stream. * No output is written if this stream is suspended. * * @param val * A character array to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(char[] val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes the contents of a text string to this output stream. * No output is written if this stream is suspended. * * @param val * A string to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(String val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes an object, as its equivalent text string, to this output stream. * No output is written if this stream is suspended. * * @param val * An object to write. * * @since 1.1, 2001-06-30 */ public synchronized void print(Object val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.print(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a newline to this output stream. * No output is written if this stream is suspended. * * @since 1.1, 2001-06-30 */ public synchronized void println() //overrides java.io.PrintWriter { // Write a newline to the underlying output stream if (out != null) { super.println(); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a boolean value, as its equivalent text string, and then a newline * to this output stream. * No output is written if this stream is suspended. * * @param val * A boolean value to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(boolean val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes an integer value, as its equivalent text string, and then a * newline to this output stream. * No output is written if this stream is suspended. * * @param val * An integer value to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(int val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a long integer value, as its equivalent text string, and then a * newline to this output stream. * No output is written if this stream is suspended. * * @param val * A long integer value to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(long val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a float value, as its equivalent text string, and then a newline * to this output stream. * No output is written if this stream is suspended. * * @param val * A float value to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(float val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a double float value, as its equivalent text string, and then a * newline to this output stream. * No output is written if this stream is suspended. * * @param val * A double float value to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(double val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes a character and then a newline to this output stream. * No output is written if this stream is suspended. * * @param val * A character to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(char val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes the contents of a character array and then a newline to this * output stream. * No output is written if this stream is suspended. * * @param val * A character array to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(char[] val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes the contents of a string and then a newline to this output stream. * No output is written if this stream is suspended. * * @param val * A string to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(String val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Writes an object, as its equivalent text string, and then a newline to * this output stream. * No output is written if this stream is suspended. * * @param val * An object to write. * * @since 1.1, 2001-06-30 */ public synchronized void println(Object val) //overrides java.io.PrintWriter { if (out != null) { // Write character output to the underlying output stream super.println(val); // Does not throw // Retrieve the internal error flag from the underlying stream if (super.checkError()) m_err = true; } } /*************************************************************************** * Establishes the underlying output stream to which all output for this * stream is written. * *

* Note that calling this method implicitly resumes output to this stream * and clears the internal error flag. * * @param os * The underlying output stream for this stream. * * @since 1.1, 2001-06-30 */ public synchronized void setOutput(Writer os) { // Establish the underlying output stream for this stream out = os; m_sus = os; m_err = false; } /*************************************************************************** * Retrieves the underlying output stream to which all output for this * stream is written. * * @return * The underlying output stream of this stream. * * @since 1.1, 2001-06-30 */ public Writer getOutput() { // Retrieve the underlying output stream for this stream return (m_sus); } /*************************************************************************** * Clears the internal error flag. * *

* Note that due to the deficiencies in the way that the {@link PrintWriter} * class is implemented, the effect of clearing the internal flag may be * undone after the next call to any of the write() or * print() methods. * * @since 1.1, 2001-06-30 * * @see #checkError */ public void clearError() { // Clear (reset) the internal error flag m_err = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Protected methods /*************************************************************************** * Finalization. * *

* Flushes, but does not close, the underlying output stream (if there is * one), and then disassociates it from this output stream. * * @throws Throwable * Thrown if an error occurs. * * @since 1.1, 2001-06-30 */ protected synchronized void finalize() throws Throwable { // Flush the underlying output stream for this stream out = m_sus; flush(); // Does not throw // Note: Do not close the underlying output stream for this stream // Disassociate the underlying output stream from this stream out = null; m_sus = null; super.finalize(); } } // End SuspendablePrintWriter.java