diff -r 000000000000 -r 724f3e1ea53e emul/compact/src/main/java/java/io/BufferedWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/compact/src/main/java/java/io/BufferedWriter.java Sat Sep 07 13:51:24 2013 +0200 @@ -0,0 +1,272 @@ +/* + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + + +/** + * Writes text to a character-output stream, buffering characters so as to + * provide for the efficient writing of single characters, arrays, and strings. + * + *

The buffer size may be specified, or the default size may be accepted. + * The default is large enough for most purposes. + * + *

A newLine() method is provided, which uses the platform's own notion of + * line separator as defined by the system property line.separator. + * Not all platforms use the newline character ('\n') to terminate lines. + * Calling this method to terminate each output line is therefore preferred to + * writing a newline character directly. + * + *

In general, a Writer sends its output immediately to the underlying + * character or byte stream. Unless prompt output is required, it is advisable + * to wrap a BufferedWriter around any Writer whose write() operations may be + * costly, such as FileWriters and OutputStreamWriters. For example, + * + *

+ * PrintWriter out
+ *   = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
+ * 
+ * + * will buffer the PrintWriter's output to the file. Without buffering, each + * invocation of a print() method would cause characters to be converted into + * bytes that would then be written immediately to the file, which can be very + * inefficient. + * + * @see PrintWriter + * @see FileWriter + * @see OutputStreamWriter + * @see java.nio.file.Files#newBufferedWriter + * + * @author Mark Reinhold + * @since JDK1.1 + */ + +public class BufferedWriter extends Writer { + + private Writer out; + + private char cb[]; + private int nChars, nextChar; + + private static int defaultCharBufferSize = 8192; + + /** + * Line separator string. This is the value of the line.separator + * property at the moment that the stream was created. + */ + private String lineSeparator; + + /** + * Creates a buffered character-output stream that uses a default-sized + * output buffer. + * + * @param out A Writer + */ + public BufferedWriter(Writer out) { + this(out, defaultCharBufferSize); + } + + /** + * Creates a new buffered character-output stream that uses an output + * buffer of the given size. + * + * @param out A Writer + * @param sz Output-buffer size, a positive integer + * + * @exception IllegalArgumentException If sz is <= 0 + */ + public BufferedWriter(Writer out, int sz) { + super(out); + if (sz <= 0) + throw new IllegalArgumentException("Buffer size <= 0"); + this.out = out; + cb = new char[sz]; + nChars = sz; + nextChar = 0; + + lineSeparator = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("line.separator")); + } + + /** Checks to make sure that the stream has not been closed */ + private void ensureOpen() throws IOException { + if (out == null) + throw new IOException("Stream closed"); + } + + /** + * Flushes the output buffer to the underlying character stream, without + * flushing the stream itself. This method is non-private only so that it + * may be invoked by PrintStream. + */ + void flushBuffer() throws IOException { + synchronized (lock) { + ensureOpen(); + if (nextChar == 0) + return; + out.write(cb, 0, nextChar); + nextChar = 0; + } + } + + /** + * Writes a single character. + * + * @exception IOException If an I/O error occurs + */ + public void write(int c) throws IOException { + synchronized (lock) { + ensureOpen(); + if (nextChar >= nChars) + flushBuffer(); + cb[nextChar++] = (char) c; + } + } + + /** + * Our own little min method, to avoid loading java.lang.Math if we've run + * out of file descriptors and we're trying to print a stack trace. + */ + private int min(int a, int b) { + if (a < b) return a; + return b; + } + + /** + * Writes a portion of an array of characters. + * + *

Ordinarily this method stores characters from the given array into + * this stream's buffer, flushing the buffer to the underlying stream as + * needed. If the requested length is at least as large as the buffer, + * however, then this method will flush the buffer and write the characters + * directly to the underlying stream. Thus redundant + * BufferedWriters will not copy data unnecessarily. + * + * @param cbuf A character array + * @param off Offset from which to start reading characters + * @param len Number of characters to write + * + * @exception IOException If an I/O error occurs + */ + public void write(char cbuf[], int off, int len) throws IOException { + synchronized (lock) { + ensureOpen(); + if ((off < 0) || (off > cbuf.length) || (len < 0) || + ((off + len) > cbuf.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + + if (len >= nChars) { + /* If the request length exceeds the size of the output buffer, + flush the buffer and then write the data directly. In this + way buffered streams will cascade harmlessly. */ + flushBuffer(); + out.write(cbuf, off, len); + return; + } + + int b = off, t = off + len; + while (b < t) { + int d = min(nChars - nextChar, t - b); + System.arraycopy(cbuf, b, cb, nextChar, d); + b += d; + nextChar += d; + if (nextChar >= nChars) + flushBuffer(); + } + } + } + + /** + * Writes a portion of a String. + * + *

If the value of the len parameter is negative then no + * characters are written. This is contrary to the specification of this + * method in the {@linkplain java.io.Writer#write(java.lang.String,int,int) + * superclass}, which requires that an {@link IndexOutOfBoundsException} be + * thrown. + * + * @param s String to be written + * @param off Offset from which to start reading characters + * @param len Number of characters to be written + * + * @exception IOException If an I/O error occurs + */ + public void write(String s, int off, int len) throws IOException { + synchronized (lock) { + ensureOpen(); + + int b = off, t = off + len; + while (b < t) { + int d = min(nChars - nextChar, t - b); + s.getChars(b, b + d, cb, nextChar); + b += d; + nextChar += d; + if (nextChar >= nChars) + flushBuffer(); + } + } + } + + /** + * Writes a line separator. The line separator string is defined by the + * system property line.separator, and is not necessarily a single + * newline ('\n') character. + * + * @exception IOException If an I/O error occurs + */ + public void newLine() throws IOException { + write(lineSeparator); + } + + /** + * Flushes the stream. + * + * @exception IOException If an I/O error occurs + */ + public void flush() throws IOException { + synchronized (lock) { + flushBuffer(); + out.flush(); + } + } + + public void close() throws IOException { + synchronized (lock) { + if (out == null) { + return; + } + try { + flushBuffer(); + } finally { + out.close(); + out = null; + cb = null; + } + } + } +}