--- /home/tromey/gnu/Nightly/classpath/classpath/java/io/PrintStream.java 2004-11-17 02:24:08.000000000 -0700 +++ java/io/PrintStream.java 2004-11-17 02:16:27.000000000 -0700 @@ -1,5 +1,5 @@ /* PrintStream.java -- OutputStream for printing output - Copyright (C) 1998, 1999, 2001, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,8 @@ package java.io; +import gnu.gcj.convert.UnicodeToBytes; + /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 * "The Java Language Specification", ISBN 0-201-63451-1 * Status: Believed complete and correct to 1.3 @@ -58,6 +60,21 @@ */ public class PrintStream extends FilterOutputStream { + /* Notice the implementation is quite similar to OutputStreamWriter. + * This leads to some minor duplication, because neither inherits + * from the other, and we want to maximize performance. */ + + // Line separator string. + private static final char[] line_separator + = System.getProperty("line.separator").toCharArray(); + + UnicodeToBytes converter; + + // Work buffer of characters for converter. + char[] work = new char[100]; + // Work buffer of bytes where we temporarily keep converter output. + byte[] work_bytes = new byte[100]; + /** * This boolean indicates whether or not an error has ever occurred * on this stream. @@ -71,54 +88,6 @@ private boolean auto_flush; /** - * The PrintWriter instance this object writes to - */ - private PrintWriter pw; - - /** - * Lets us know if the stream is closed - */ - private boolean closed; - - /** - * This class exists to forward the write calls from the PrintWriter back - * to us. This is required to make subclassing of PrintStream work - * correctly. - */ - private class ForwardStream extends OutputStream - { - // This is package-private to avoid a trampoline constructor. - ForwardStream () - { - } - - public void close () throws IOException - { - out.close (); - } - - public void flush () throws IOException - { - out.flush (); - } - - public void write (byte[] b) throws IOException - { - PrintStream.this.write (b); - } - - public void write (byte[] b, int off, int len) throws IOException - { - PrintStream.this.write (b, off, len); - } - - public void write (int b) throws IOException - { - PrintStream.this.write (b); - } - } - - /** * This method intializes a new PrintStream object to write * to the specified output sink. * @@ -146,10 +115,7 @@ { super (out); - // FIXME Instead of using PrintWriter and ForwardStream we - // should inline the character conversion (see libgcj's version - // of this class) - pw = new PrintWriter (new ForwardStream (), auto_flush); + converter = UnicodeToBytes.getDefaultEncoder(); this.auto_flush = auto_flush; } @@ -173,12 +139,7 @@ { super (out); - // FIXME Instead of using PrintWriter and ForwardStream we - // should inline the character conversion (see libgcj's version - // of this class) - pw = new PrintWriter ( - new OutputStreamWriter ( - new ForwardStream (), encoding), auto_flush); + converter = UnicodeToBytes.getEncoder (encoding); this.auto_flush = auto_flush; } @@ -193,10 +154,8 @@ */ public boolean checkError () { - if (!closed) - flush (); - - return error_occurred | pw.checkError (); + flush (); + return error_occurred; } /** @@ -213,8 +172,19 @@ */ public void close () { - pw.close (); - closed = true; + try + { + flush(); + out.close(); + } + catch (InterruptedIOException iioe) + { + Thread.currentThread().interrupt(); + } + catch (IOException e) + { + setError (); + } } /** @@ -223,7 +193,85 @@ */ public void flush () { - pw.flush(); + try + { + out.flush(); + } + catch (InterruptedIOException iioe) + { + Thread.currentThread().interrupt(); + } + catch (IOException e) + { + setError (); + } + } + + private synchronized void print (String str, boolean println) + { + try + { + writeChars(str, 0, str.length()); + if (println) + writeChars(line_separator, 0, line_separator.length); + if (auto_flush) + flush(); + } + catch (InterruptedIOException iioe) + { + Thread.currentThread().interrupt(); + } + catch (IOException e) + { + setError (); + } + } + + private synchronized void print (char[] chars, int pos, int len, + boolean println) + { + try + { + writeChars(chars, pos, len); + if (println) + writeChars(line_separator, 0, line_separator.length); + if (auto_flush) + flush(); + } + catch (InterruptedIOException iioe) + { + Thread.currentThread().interrupt(); + } + catch (IOException e) + { + setError (); + } + } + + private void writeChars(char[] buf, int offset, int count) + throws IOException + { + while (count > 0 || converter.havePendingBytes()) + { + converter.setOutput(work_bytes, 0); + int converted = converter.write(buf, offset, count); + offset += converted; + count -= converted; + out.write(work_bytes, 0, converter.count); + } + } + + private void writeChars(String str, int offset, int count) + throws IOException + { + while (count > 0 || converter.havePendingBytes()) + { + converter.setOutput(work_bytes, 0); + int converted = converter.write(str, offset, count, work); + offset += converted; + count -= converted; + out.write(work_bytes, 0, converter.count); + } } /** @@ -235,7 +283,7 @@ */ public void print (boolean bool) { - print (String.valueOf (bool)); + print(String.valueOf(bool), false); } /** @@ -246,7 +294,7 @@ */ public void print (int inum) { - print (String.valueOf (inum)); + print(String.valueOf(inum), false); } /** @@ -257,7 +305,7 @@ */ public void print (long lnum) { - print (String.valueOf (lnum)); + print(String.valueOf(lnum), false); } /** @@ -268,7 +316,7 @@ */ public void print (float fnum) { - print (String.valueOf (fnum)); + print(String.valueOf(fnum), false); } /** @@ -279,7 +327,7 @@ */ public void print (double dnum) { - print (String.valueOf (dnum)); + print(String.valueOf(dnum), false); } /** @@ -291,9 +339,7 @@ */ public void print (Object obj) { - // Don't call pw directly. Convert to String so we scan for newline - // characters on auto-flush; - print (String.valueOf (obj)); + print(obj == null ? "null" : obj.toString(), false); } /** @@ -304,10 +350,7 @@ */ public void print (String str) { - pw.print (str); - - if (auto_flush) - flush (); + print(str == null ? "null" : str, false); } /** @@ -316,9 +359,10 @@ * * @param ch The char value to be printed */ - public void print (char ch) + public synchronized void print (char ch) { - print (String.valueOf (ch)); + work[0] = ch; + print(work, 0, 1, false); } /** @@ -329,7 +373,7 @@ */ public void print (char[] charArray) { - pw.print (charArray); + print(charArray, 0, charArray.length, false); } /** @@ -339,7 +383,7 @@ */ public void println () { - pw.println(); + print(line_separator, 0, line_separator.length, false); } /** @@ -353,7 +397,7 @@ */ public void println (boolean bool) { - println (String.valueOf (bool)); + print(String.valueOf(bool), true); } /** @@ -366,7 +410,7 @@ */ public void println (int inum) { - println (String.valueOf (inum)); + print(String.valueOf(inum), true); } /** @@ -379,7 +423,7 @@ */ public void println (long lnum) { - println (String.valueOf (lnum)); + print(String.valueOf(lnum), true); } /** @@ -392,7 +436,7 @@ */ public void println (float fnum) { - println (String.valueOf (fnum)); + print(String.valueOf(fnum), true); } /** @@ -405,7 +449,7 @@ */ public void println (double dnum) { - println (String.valueOf (dnum)); + print(String.valueOf(dnum), true); } /** @@ -419,7 +463,7 @@ */ public void println (Object obj) { - println (String.valueOf (obj)); + print(obj == null ? "null" : obj.toString(), true); } /** @@ -432,7 +476,7 @@ */ public void println (String str) { - pw.println (str); + print (str == null ? "null" : str, true); } /** @@ -443,9 +487,10 @@ * * @param ch The char value to be printed */ - public void println (char ch) + public synchronized void println (char ch) { - println (String.valueOf (ch)); + work[0] = ch; + print(work, 0, 1, true); } /** @@ -458,7 +503,7 @@ */ public void println (char[] charArray) { - pw.println (charArray); + print(charArray, 0, charArray.length, true); } /** @@ -470,10 +515,6 @@ */ public void write (int oneByte) { - // We actually have to implement this method. Flush first so that - // things get written in the right order. - flush(); - try { out.write (oneByte & 0xff); @@ -501,10 +542,6 @@ */ public void write (byte[] buffer, int offset, int len) { - // We actually have to implement this method too. Flush first so that - // things get written in the right order. - flush(); - try { out.write (buffer, offset, len); @@ -522,3 +559,4 @@ } } } // class PrintStream +