--- /home/tromey/gnu/Nightly/classpath/classpath/java/io/OutputStreamWriter.java 2004-11-23 02:24:09.000000000 -0700 +++ java/io/OutputStreamWriter.java 2004-11-17 02:16:27.000000000 -0700 @@ -38,8 +38,7 @@ package java.io; -import gnu.java.io.EncodingManager; -import gnu.java.io.encode.Encoder; +import gnu.gcj.convert.UnicodeToBytes; /** * This class writes characters to an output stream that is byte oriented @@ -76,13 +75,28 @@ */ public class OutputStreamWriter extends Writer { + BufferedOutputStream out; /** * This is the byte-character encoder class that does the writing and * translation of characters to bytes before writing to the underlying * class. */ - private Encoder out; + UnicodeToBytes converter; + + /* Temporary buffer. */ + private char[] work; + private int wcount; + + private OutputStreamWriter(OutputStream out, UnicodeToBytes encoder) + { + this.out = out instanceof BufferedOutputStream + ? (BufferedOutputStream) out + : new BufferedOutputStream(out, 250); + /* Don't need to call super(out) here as long as the lock gets set. */ + this.lock = out; + this.converter = encoder; + } /** * This method initializes a new instance of OutputStreamWriter @@ -100,7 +114,7 @@ public OutputStreamWriter (OutputStream out, String encoding_scheme) throws UnsupportedEncodingException { - this.out = EncodingManager.getEncoder (out, encoding_scheme); + this(out, UnicodeToBytes.getEncoder(encoding_scheme)); } /** @@ -111,7 +125,7 @@ */ public OutputStreamWriter (OutputStream out) { - this.out = EncodingManager.getEncoder (out); + this(out, UnicodeToBytes.getDefaultEncoder()); } /** @@ -122,7 +136,16 @@ */ public void close () throws IOException { - out.close (); + synchronized (lock) + { + if (out != null) + { + flush(); + out.close(); + out = null; + } + work = null; + } } /** @@ -134,7 +157,7 @@ */ public String getEncoding () { - return out != null ? out.getSchemeName () : null; + return out != null ? converter.getName() : null; } /** @@ -144,7 +167,18 @@ */ public void flush () throws IOException { - out.flush (); + synchronized (lock) + { + if (out == null) + throw new IOException("Stream closed"); + + if (wcount > 0) + { + writeChars(work, 0, wcount); + wcount = 0; + } + out.flush(); + } } /** @@ -160,7 +194,51 @@ */ public void write (char[] buf, int offset, int count) throws IOException { - out.write (buf, offset, count); + synchronized (lock) + { + if (out == null) + throw new IOException("Stream closed"); + + if (wcount > 0) + { + writeChars(work, 0, wcount); + wcount = 0; + } + writeChars(buf, offset, count); + } + } + + /* + * Writes characters through to the inferior BufferedOutputStream. + * Ignores wcount and the work buffer. + */ + private void writeChars(char[] buf, int offset, int count) + throws IOException + { + while (count > 0 || converter.havePendingBytes()) + { + // We must flush if out.count == out.buf.length. + // It is probably a good idea to flush if out.buf is almost full. + // This test is an approximation for "almost full". + if (out.count + count >= out.buf.length) + { + out.flush(); + if (out.count != 0) + throw new IOException("unable to flush output byte buffer"); + } + converter.setOutput(out.buf, out.count); + int converted = converter.write(buf, offset, count); + // Flush if we cannot make progress. + if (converted == 0 && out.count == converter.count) + { + out.flush(); + if (out.count != 0) + throw new IOException("unable to flush output byte buffer"); + } + offset += converted; + count -= converted; + out.count = converter.count; + } } /** @@ -177,7 +255,33 @@ */ public void write (String str, int offset, int count) throws IOException { - out.write (str, offset, count); + synchronized (lock) + { + if (out == null) + throw new IOException("Stream closed"); + + if (work == null) + work = new char[100]; + int wlength = work.length; + while (count > 0) + { + int size = count; + if (wcount + size > wlength) + { + if (2*wcount > wlength) + { + writeChars(work, 0, wcount); + wcount = 0; + } + if (wcount + size > wlength) + size = wlength - wcount; + } + str.getChars(offset, offset+size, work, wcount); + offset += size; + count -= size; + wcount += size; + } + } } /** @@ -189,7 +293,20 @@ */ public void write (int ch) throws IOException { - out.write (ch); + synchronized (lock) + { + if (out == null) + throw new IOException("Stream closed"); + + if (work == null) + work = new char[100]; + if (wcount >= work.length) + { + writeChars(work, 0, wcount); + wcount = 0; + } + work[wcount++] = (char) ch; + } } } // class OutputStreamWriter