harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r350181 [100/198] - in /incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core: ./ depends/ depends/files/ depends/jars/ depends/libs/ depends/libs/linux.IA32/ depends/libs/win.IA32/ depends/oss/ depends/oss/linux.IA32/ depends/oss/win....
Date Thu, 01 Dec 2005 06:04:00 GMT
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PipedReader.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PipedReader.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PipedReader.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PipedReader.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,407 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.io;
+
+
+/**
+ * PipedReader is a class which receives information on a communications pipe.
+ * When two threads want to pass data back and forth, one creates a piped writer
+ * and the other creates a piped reader.
+ * 
+ */
+public class PipedReader extends Reader {
+	private Thread lastReader, lastWriter;
+
+	private boolean isClosed = false;
+
+	/**
+	 * The circular buffer through which data is passed.
+	 */
+	private char data[];
+
+	/**
+	 * The index in <code>buffer</code> where the next character will be
+	 * written.
+	 */
+	private int in = -1;
+
+	/**
+	 * The index in <code>buffer</code> where the next character will be read.
+	 */
+	private int out = 0;
+
+	/**
+	 * The size of the default pipe in characters
+	 */
+	private static final int PIPE_SIZE = 1024;
+
+	/**
+	 * Indicates if this pipe is connected
+	 */
+	private boolean isConnected = false;
+
+	/**
+	 * Constructs a new unconnected PipedReader. The resulting Reader must be
+	 * connected to a PipedWriter before data may be read from it.
+	 */
+	public PipedReader() {
+		data = new char[PIPE_SIZE];
+	}
+
+	/**
+	 * Constructs a new PipedReader connected to the PipedWriter
+	 * <code>out</code>. Any data written to the writer can be read from the
+	 * this reader.
+	 * 
+	 * @param out
+	 *            the PipedWriter to connect to.
+	 * 
+	 * @throws IOException
+	 *             if this or <code>out</code> are already connected.
+	 */
+	public PipedReader(PipedWriter out) throws IOException {
+		this();
+		connect(out);
+	}
+
+	/**
+	 * Close this PipedReader. This implementation releases the buffer used for
+	 * the pipe and notifies all threads waiting to read or write.
+	 * 
+	 * @throws IOException
+	 *             If an error occurs attempting to close this reader.
+	 */
+	public void close() throws IOException {
+		synchronized (lock) {
+			/* No exception thrown if already closed */
+			if (data != null) {
+				/* Release buffer to indicate closed. */
+				data = null;
+			}
+		}
+	}
+
+	/**
+	 * Connects this PipedReader to a PipedWriter. Any data written to the
+	 * Writer becomes available in this Reader.
+	 * 
+	 * @param src
+	 *            the source PipedWriter.
+	 * 
+	 * @throws IOException
+	 *             If either Writer or Reader is already connected.
+	 */
+	public void connect(PipedWriter src) throws IOException {
+		synchronized (lock) {
+			src.connect(this);
+		}
+	}
+
+	/**
+	 * Establish the connection to the PipedWriter.
+	 * 
+	 * @param src
+	 *            the source PipedWriter
+	 * 
+	 * @throws IOException
+	 *             If this Reader is already connected.
+	 */
+	void establishConnection(PipedWriter src) throws IOException {
+		synchronized (lock) {
+			if (data == null)
+				throw new IOException(com.ibm.oti.util.Msg.getString("K0078")); //$NON-NLS-1$
+			if (!isConnected) {
+				isConnected = true;
+			} else
+				throw new IOException(com.ibm.oti.util.Msg.getString("K007a")); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Reads the next character from this Reader. Answer the character actually
+	 * read or -1 if no character was read and end of reader was encountered.
+	 * Separate threads should be used for the reader of the PipedReader and the
+	 * PipedWriter. There may be undesirable results if more than one Thread
+	 * interacts a reader or writer pipe.
+	 * 
+	 * @return int the character read -1 if end of reader.
+	 * 
+	 * @throws IOException
+	 *             If the reader is already closed or another IOException
+	 *             occurs.
+	 */
+	public int read() throws IOException {
+		char[] carray = new char[1];
+		int result = read(carray, 0, 1);
+		return result != -1 ? carray[0] : result;
+	}
+
+	/**
+	 * Reads at most <code>count</code> character from this PipedReader and
+	 * stores them in char array <code>buffer</code> starting at
+	 * <code>offset</code>. Answer the number of characters actually read or
+	 * -1 if no characters were read and end of stream was encountered. Separate
+	 * threads should be used for the reader of the PipedReader and the
+	 * PipedWriter. There may be undesirable results if more than one Thread
+	 * interacts a reader or writer pipe.
+	 * 
+	 * @param buffer
+	 *            the charcter array in which to store the read characters.
+	 * @param offset
+	 *            the offset in <code>buffer</code> to store the read
+	 *            characters.
+	 * @param count
+	 *            the maximum number of characters to store in
+	 *            <code>buffer</code>.
+	 * @return int the number of characters actually read or -1 if end of
+	 *         reader.
+	 * 
+	 * @throws IOException
+	 *             If the reader is already closed or another IOException
+	 *             occurs.
+	 */
+	public int read(char[] buffer, int offset, int count) throws IOException {
+		// avoid int overflow
+		if (0 <= offset && offset <= buffer.length && 0 <= count
+				&& count <= buffer.length - offset) {
+			synchronized (lock) {
+				if (isConnected && data != null) {
+					if (count == 0)
+						return 0;
+					/**
+					 * Set the last thread to be reading on this PipedReader. If
+					 * lastReader dies while someone is waiting to write an
+					 * IOException of "Pipe broken" will be thrown in receive()
+					 */
+					lastReader = Thread.currentThread();
+					try {
+						boolean first = true;
+						while (in == -1) {
+							// Are we at end of stream?
+							if (isClosed)
+								return -1;
+							if (!first && lastWriter != null
+									&& !lastWriter.isAlive())
+								throw new IOException(com.ibm.oti.util.Msg
+										.getString("K0076")); //$NON-NLS-1$
+							first = false;
+							// Notify callers of receive()
+							notifyAll();
+							lock.wait(1000);
+						}
+					} catch (InterruptedException e) {
+						throw new InterruptedIOException();
+					}
+
+					int copyLength = 0;
+					/* Copy chars from out to end of buffer first */
+					if (out >= in) {
+						copyLength = count > data.length - out ? data.length
+								- out : count;
+						System.arraycopy(data, out, buffer, offset, copyLength);
+						out += copyLength;
+						if (out == data.length)
+							out = 0;
+						if (out == in) {
+							// empty buffer
+							in = -1;
+							out = 0;
+						}
+					}
+
+					/*
+					 * Did the read fully suceed in the previous copy or is the
+					 * buffer empty?
+					 */
+					if (copyLength == count || in == -1)
+						return copyLength;
+
+					int charsCopied = copyLength;
+					/* Copy bytes from 0 to the number of available bytes */
+					copyLength = in - out > count - copyLength ? count
+							- copyLength : in - out;
+					System.arraycopy(data, out, buffer, offset + charsCopied,
+							copyLength);
+					out += copyLength;
+					if (out == in) {
+						// empty buffer
+						in = -1;
+						out = 0;
+					}
+					return charsCopied + copyLength;
+				}
+				if (!isConnected) {
+					throw new IOException(com.ibm.oti.util.Msg
+							.getString("K007b")); //$NON-NLS-1$
+				}
+				throw new IOException(com.ibm.oti.util.Msg.getString("K0078")); //$NON-NLS-1$
+			}
+		}
+		throw new ArrayIndexOutOfBoundsException();
+	}
+
+	/**
+	 * Answer a boolean indicating whether or not this Reader is ready to be
+	 * read. Answers true if the buffer contains characters to be read.
+	 * 
+	 * @return boolean <code>true</code> if there are characters ready,
+	 *         <code>false<code> otherwise.
+	 *
+	 * @throws 		IOException If the reader is already closed or another IOException occurs.
+	 */
+	public boolean ready() throws IOException {
+		synchronized (lock) {
+			if (isConnected) {
+				if (data != null) {
+					return in != -1;
+				}
+				throw new IOException(com.ibm.oti.util.Msg.getString("K0078")); //$NON-NLS-1$
+			}
+			throw new IOException(com.ibm.oti.util.Msg.getString("K007b")); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Receives a char and stores it into the PipedReader. This called by
+	 * PipedWriter.write() when writes occur.
+	 * <P>
+	 * If the buffer is full and the thread sending #receive is interrupted, the
+	 * InterruptedIOException will be thrown.
+	 * 
+	 * @param oneChar
+	 *            the char to store into the pipe.
+	 * 
+	 * @throws IOException
+	 *             If the stream is already closed or another IOException
+	 *             occurs.
+	 */
+	void receive(char oneChar) throws IOException {
+		synchronized (lock) {
+			if (data != null) {
+				/**
+				 * Set the last thread to be writing on this PipedWriter. If
+				 * lastWriter dies while someone is waiting to read an
+				 * IOException of "Pipe broken" will be thrown in read()
+				 */
+				lastWriter = Thread.currentThread();
+				try {
+					while (data != null && out == in) {
+						notifyAll();
+						wait(1000);
+						if (lastReader != null && !lastReader.isAlive())
+							throw new IOException(com.ibm.oti.util.Msg
+									.getString("K0076")); //$NON-NLS-1$
+					}
+				} catch (InterruptedException e) {
+					throw new InterruptedIOException();
+				}
+				if (data != null) {
+					if (in == -1)
+						in = 0;
+					data[in++] = oneChar;
+					if (in == data.length)
+						in = 0;
+					return;
+				}
+			}
+			throw new IOException(com.ibm.oti.util.Msg.getString("K0078")); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Receives a char array and stores it into the PipedReader. This called by
+	 * PipedWriter.write() when writes occur.
+	 * <P>
+	 * If the buffer is full and the thread sending #receive is interrupted, the
+	 * InterruptedIOException will be thrown.
+	 * 
+	 * @param chars
+	 *            the char array to store into the pipe.
+	 * @param offset
+	 *            offset to start reading from
+	 * @param count
+	 *            total characters to read
+	 * 
+	 * @throws IOException
+	 *             If the stream is already closed or another IOException
+	 *             occurs.
+	 */
+	void receive(char[] chars, int offset, int count) throws IOException {
+		synchronized (lock) {
+			if (data != null) {
+				/**
+				 * Set the last thread to be writing on this PipedWriter. If
+				 * lastWriter dies while someone is waiting to read an
+				 * IOException of "Pipe broken" will be thrown in read()
+				 */
+				lastWriter = Thread.currentThread();
+				while (count > 0) {
+					try {
+						while (data != null && out == in) {
+							notifyAll();
+							wait(1000);
+							if (lastReader != null && !lastReader.isAlive())
+								throw new IOException(com.ibm.oti.util.Msg
+										.getString("K0076")); //$NON-NLS-1$
+						}
+					} catch (InterruptedException e) {
+						throw new InterruptedIOException();
+					}
+					if (data == null)
+						break;
+					if (in == -1)
+						in = 0;
+					if (in >= out) {
+						int length = data.length - in;
+						if (count < length)
+							length = count;
+						System.arraycopy(chars, offset, data, in, length);
+						offset += length;
+						count -= length;
+						in += length;
+						if (in == data.length)
+							in = 0;
+					}
+					if (count > 0 && in != out) {
+						int length = out - in;
+						if (count < length)
+							length = count;
+						System.arraycopy(chars, offset, data, in, length);
+						offset += length;
+						count -= length;
+						in += length;
+					}
+				}
+				if (count == 0)
+					return;
+			}
+			throw new IOException(com.ibm.oti.util.Msg.getString("K0078")); //$NON-NLS-1$
+		}
+	}
+
+	void done() {
+		synchronized (lock) {
+			isClosed = true;
+			notifyAll();
+		}
+	}
+
+	void flush() {
+		synchronized (lock) {
+			notifyAll();
+		}
+	}
+}

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PipedWriter.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PipedWriter.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PipedWriter.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PipedWriter.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,191 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.io;
+
+
+/**
+ * PipedWriter is a class which places information on a communications pipe.
+ * When two threads want to pass data back and forth, one creates a piped writer
+ * and the other creates a piped reader.
+ * 
+ * @see PipedReader
+ */
+public class PipedWriter extends Writer {
+	/**
+	 * The destination PipedReader
+	 */
+	private PipedReader dest;
+
+	private boolean closed = false;
+
+	/**
+	 * Constructs a new unconnected PipedWriter. The resulting Stream must be
+	 * connected to a PipedReader before data may be written to it.
+	 */
+	public PipedWriter() {
+		super();
+	}
+
+	/**
+	 * Constructs a new PipedWriter connected to the PipedReader
+	 * <code>dest</code>. Any data written to this Writer can be read from
+	 * the <code>dest</code>.
+	 * 
+	 * @param dest
+	 *            the PipedReader to connect to.
+	 * 
+	 * @throws java.io.IOException
+	 *             if <code>dest</code> is already connected.
+	 */
+	public PipedWriter(PipedReader dest) throws IOException {
+		super(dest);
+		connect(dest);
+	}
+
+	/**
+	 * Close this PipedWriter. Any data buffered in the corresponding
+	 * PipedReader can be read, then -1 will be returned to the reader. If this
+	 * Writer is not connected, this method does nothing.
+	 * 
+	 * @throws java.io.IOException
+	 *             If an error occurs attempting to close this PipedWriter.
+	 */
+	public void close() throws IOException {
+		synchronized (lock) {
+			/* Is the pipe connected? */
+			if (dest != null) {
+				dest.done();
+				dest = null;
+			}
+			closed = true;
+		}
+	}
+
+	/**
+	 * Connects this PipedWriter to a PipedReader. Any data written to this
+	 * Writer becomes readable in the Reader.
+	 * 
+	 * @param stream
+	 *            the destination PipedReader.
+	 * 
+	 * @throws java.io.IOException
+	 *             If this Writer or the dest is already connected.
+	 */
+	public void connect(PipedReader stream) throws IOException {
+		synchronized (lock) {
+			if (this.dest == null) {
+				if (!closed) {
+					stream.establishConnection(this);
+					this.dest = stream;
+				} else
+					throw new IOException(com.ibm.oti.util.Msg
+							.getString("K0078")); //$NON-NLS-1$
+			} else
+				throw new IOException(com.ibm.oti.util.Msg.getString("K0079")); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Notifies the readers on the PipedReader that characters can be read. This
+	 * method does nothing if this Writer is not connected.
+	 * 
+	 * @throws java.io.IOException
+	 *             If an IO error occurs during the flush.
+	 */
+	public void flush() throws IOException {
+		if (dest != null)
+			dest.flush();
+	}
+
+	/**
+	 * Writes <code>count</code> <code>chars</code> from the char array
+	 * <code>buffer</code> starting at offset <code>index</code> to this
+	 * PipedWriter. The written data can now be read from the destination
+	 * PipedReader. Separate threads should be used for the reader of the
+	 * PipedReader and the PipedWriter. There may be undesirable results if more
+	 * than one Thread interacts a input or output pipe.
+	 * 
+	 * @param buffer
+	 *            the buffer to be written
+	 * @param offset
+	 *            offset in buffer to get chars
+	 * @param count
+	 *            number of chars in buffer to write
+	 * 
+	 * @throws java.io.IOException
+	 *             If the receiving thread was terminated without closing the
+	 *             pipe. This case is not currently handled correctly.
+	 * @throws java.io.InterruptedIOException
+	 *             If the pipe is full and the current thread is interrupted
+	 *             waiting for space to write data. This case is not currently
+	 *             handled correctly.
+	 * @throws java.lang.NullPointerException
+	 *             If the receiver has not been connected yet.
+	 * @throws java.lang.IllegalArgumentException
+	 *             If any of the arguments are out of bounds.
+	 */
+	public void write(char buffer[], int offset, int count) throws IOException {
+		// avoid int overflow
+		if (0 <= offset && offset <= buffer.length && 0 <= count
+				&& count <= buffer.length - offset) {
+			synchronized (lock) {
+				if (!closed) {
+					if (dest != null)
+						dest.receive(buffer, offset, count);
+					else
+						throw new IOException(com.ibm.oti.util.Msg
+								.getString("K007b")); //$NON-NLS-1$
+				} else
+					throw new IOException(com.ibm.oti.util.Msg
+							.getString("K0078")); //$NON-NLS-1$
+			}
+		} else
+			throw new ArrayIndexOutOfBoundsException();
+	}
+
+	/**
+	 * Writes the character <code>c</code> to this PipedWriter. The written
+	 * data can now be read from the destination PipedReader. Separate threads
+	 * should be used for the reader of the PipedReader and the PipedWriter.
+	 * There may be undesirable results if more than one Thread interacts a
+	 * input or output pipe.
+	 * 
+	 * @param c
+	 *            the character to be written
+	 * 
+	 * @throws java.io.IOException
+	 *             If the receiving thread was terminated without closing the
+	 *             pipe. This case is not currently handled correctly.
+	 * @throws java.io.InterruptedIOException
+	 *             If the pipe is full and the current thread is interrupted
+	 *             waiting for space to write data. This case is not currently
+	 *             handled correctly.
+	 * @throws java.lang.NullPointerException
+	 *             If the receiver has not been connected yet.
+	 */
+	public void write(int c) throws IOException {
+		synchronized (lock) {
+			if (!closed) {
+				if (dest != null)
+					dest.receive((char) c);
+				else
+					throw new IOException(com.ibm.oti.util.Msg
+							.getString("K007b")); //$NON-NLS-1$
+			} else
+				throw new IOException(com.ibm.oti.util.Msg.getString("K0078")); //$NON-NLS-1$
+		}
+	}
+}

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PrintStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PrintStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PrintStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PrintStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,486 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.io;
+
+
+import java.nio.charset.Charset;
+import java.security.AccessController;
+
+import com.ibm.oti.util.PriviAction;
+
+/**
+ * PrintStream is a class which takes an OutputStream and provides convenience
+ * methods for printing common data types in a human readable format on the
+ * stream. This is not to be confused with DataOutputStream which is used for
+ * encoding common datatypes so that they can be read back in. No IOExceptions
+ * are thrown by this class. Instead, callers should call checkError() to see if
+ * a problem has been encountered in this Stream.
+ * 
+ */
+public class PrintStream extends FilterOutputStream {
+
+	/**
+	 * protect writes to the underlying stream.
+	 */
+	private Object lock = new Object();
+
+	/**
+	 * indicates whether or not this PrintStream has incurred an error.
+	 */
+	boolean ioError = false;
+
+	/**
+	 * indicates whether or not this PrintStream should flush its contents after
+	 * printing a new line.
+	 */
+	boolean autoflush = false;
+
+	private String encoding;
+
+	private final String lineSeparator = (String) AccessController
+			.doPrivileged(new PriviAction("line.separator")); //$NON-NLS-1$
+
+	/**
+	 * Constructs a new PrintStream on the OutputStream <code>out</code>. All
+	 * writes to the target can now take place through this PrintStream. By
+	 * default, the PrintStream is set to not autoflush when a newline is
+	 * encountered.
+	 * 
+	 * @param out
+	 *            the OutputStream to provide convenience methods on.
+	 */
+	public PrintStream(OutputStream out) {
+		super(out);
+		if (out == null)
+			throw new NullPointerException();
+	}
+
+	/**
+	 * Constructs a new PrintStream on the OutputStream <code>out</code>. All
+	 * writes to the target can now take place through this PrintStream. The
+	 * PrintStream is set to not autoflush if <code>autoflush</code> is
+	 * <code>true</code>.
+	 * 
+	 * @param out
+	 *            the OutputStream to provide convenience methods on.
+	 * @param autoflush
+	 *            indicates whether or not to flush contents upon encountering a
+	 *            newline sequence.
+	 */
+	public PrintStream(OutputStream out, boolean autoflush) {
+		super(out);
+		if (out == null)
+			throw new NullPointerException();
+		this.autoflush = autoflush;
+	}
+
+	/**
+	 * Constructs a new PrintStream on the OutputStream <code>out</code>. All
+	 * writes to the target can now take place through this PrintStream. The
+	 * PrintStream is set to not autoflush if <code>autoflush</code> is
+	 * <code>true</code>.
+	 * 
+	 * @param out
+	 *            the OutputStream to provide convenience methods on.
+	 * @param autoflush
+	 *            indicates whether or not to flush contents upon encountering a
+	 *            newline sequence.
+	 * @param enc
+	 *            the non-null String describing the desired character encoding.
+	 * 
+	 * @throws UnsupportedEncodingException
+	 *             If the chosen encoding is not supported
+	 */
+	public PrintStream(OutputStream out, boolean autoflush, String enc)
+			throws UnsupportedEncodingException {
+		super(out);
+		if (out == null)
+			throw new NullPointerException();
+		this.autoflush = autoflush;
+		if (!Charset.isSupported(enc))
+			throw new UnsupportedEncodingException(enc);
+		encoding = enc;
+	}
+
+	/**
+	 * Answers a boolean indicating whether or not this PrintStream has
+	 * encountered an error. If so, the receiver should probably be closed since
+	 * futher writes will not actually take place. A side effect of calling
+	 * checkError is that the target OutputStream is flushed.
+	 * 
+	 * @return <code>true</code> if an error occurred in this PrintStream,
+	 *         <code>false</code> otherwise.
+	 */
+	public boolean checkError() {
+		if (out != null)
+			flush();
+		return ioError;
+	}
+
+	/**
+	 * Close this PrintStream. This implementation flushes and then closes the
+	 * target stream. If an error occurs, set an error in this PrintStream to
+	 * <code>true</code>.
+	 * 
+	 */
+	public void close() {
+		synchronized (lock) {
+			flush();
+			if (out != null) {
+				try {
+					out.close();
+					out = null;
+				} catch (IOException e) {
+					setError();
+				}
+			}
+		}
+	}
+
+	/**
+	 * Flush this PrintStream to ensure all pending data is sent out to the
+	 * target OutputStream. This implementation flushes the target OutputStream.
+	 * If an error occurs, set an error in this PrintStream to <code>true</code>.
+	 * 
+	 */
+	public void flush() {
+		synchronized (lock) {
+			if (out != null) {
+				try {
+					out.flush();
+					return;
+				} catch (IOException e) {
+				}
+			}
+		}
+		setError();
+	}
+
+	private void newline() {
+		print(lineSeparator);
+	}
+
+	/**
+	 * Prints the String representation of the character array parameter
+	 * <code>charArray</code> to the target OutputStream.
+	 * 
+	 * @param charArray
+	 *            the character array to print on this PrintStream.
+	 */
+	public void print(char[] charArray) {
+		print(new String(charArray, 0, charArray.length));
+	}
+
+	/**
+	 * Prints the String representation of the character parameter
+	 * <code>ch</code> to the target OutputStream.
+	 * 
+	 * @param ch
+	 *            the character to print on this PrintStream.
+	 */
+	public void print(char ch) {
+		print(String.valueOf(ch));
+	}
+
+	/**
+	 * Prints the String representation of the <code>double</code> parameter
+	 * <code>dnum</code> to the target OutputStream.
+	 * 
+	 * @param dnum
+	 *            the <code>double</code> to print on this PrintStream.
+	 */
+	public void print(double dnum) {
+		print(String.valueOf(dnum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>float</code> parameter
+	 * <code>fnum</code> to the target OutputStream.
+	 * 
+	 * @param fnum
+	 *            the <code>float</code> to print on this PrintStream.
+	 */
+	public void print(float fnum) {
+		print(String.valueOf(fnum));
+	}
+
+	/**
+	 * Obtains the <code>int</code> argument as a <code>String</code> and
+	 * prints it to the target {@link OutputStream}.
+	 * 
+	 * @param inum
+	 *            the <code>int</code> to print on this PrintStream.
+	 */
+	public void print(int inum) {
+		print(String.valueOf(inum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>long</code> parameter
+	 * <code>lnum</code> to the target OutputStream.
+	 * 
+	 * @param lnum
+	 *            the <code>long</code> to print on this PrintStream.
+	 */
+	public void print(long lnum) {
+		print(String.valueOf(lnum));
+	}
+
+	/**
+	 * Prints the String representation of the Object parameter <code>obj</code>
+	 * to the target OutputStream.
+	 * 
+	 * @param obj
+	 *            the Object to print on this PrintStream.
+	 */
+	public void print(Object obj) {
+		print(String.valueOf(obj));
+	}
+
+	/**
+	 * Prints the String representation of the <code>String</code> parameter
+	 * <code>str</code> to the target OutputStream.
+	 * 
+	 * @param str
+	 *            the <code>String</code> to print on this PrintStream.
+	 */
+	public void print(String str) {
+		synchronized (lock) {
+			if (out == null) {
+				setError();
+				return;
+			}
+			if (str == null) {
+				print("null"); //$NON-NLS-1$
+				return;
+			}
+
+			try {
+				if (encoding == null)
+					write(str.getBytes());
+				else
+					write(str.getBytes(encoding));
+			} catch (IOException e) {
+				setError();
+			}
+		}
+	}
+
+	/**
+	 * Prints the String representation of the <code>boolean</code> parameter
+	 * <code>bool</code> to the target OutputStream.
+	 * 
+	 * @param bool
+	 *            the <code>boolean</code> to print on this PrintStream.
+	 */
+	public void print(boolean bool) {
+		print(String.valueOf(bool));
+	}
+
+	/**
+	 * Prints the String representation of the System property
+	 * <code>"line.separator"</code> to the target OutputStream.
+	 * 
+	 */
+	public void println() {
+		newline();
+	}
+
+	/**
+	 * Prints the String representation of the character array parameter
+	 * <code>charArray</code> to the target OutputStream followed by the
+	 * System property <code>"line.separator"</code>.
+	 * 
+	 * @param charArray
+	 *            the character array to print on this PrintStream.
+	 */
+	public void println(char[] charArray) {
+		println(new String(charArray, 0, charArray.length));
+	}
+
+	/**
+	 * Prints the String representation of the character parameter
+	 * <code>ch</code> to the target OutputStream followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param ch
+	 *            the character to print on this PrintStream.
+	 */
+	public void println(char ch) {
+		println(String.valueOf(ch));
+	}
+
+	/**
+	 * Prints the String representation of the <code>double</code> parameter
+	 * <code>dnum</code> to the target OutputStream followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param dnum
+	 *            the double to print on this PrintStream.
+	 */
+	public void println(double dnum) {
+		println(String.valueOf(dnum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>float</code> parameter
+	 * <code>fnum</code> to the target OutputStream followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param fnum
+	 *            the float to print on this PrintStream.
+	 */
+	public void println(float fnum) {
+		println(String.valueOf(fnum));
+	}
+
+	/**
+	 * Obtains the <code>int</code> argument as a <code>String</code> and
+	 * prints it to the target {@link OutputStream} followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param inum
+	 *            the int to print on this PrintStream.
+	 */
+	public void println(int inum) {
+		println(String.valueOf(inum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>long</code> parameter
+	 * <code>lnum</code> to the target OutputStream followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param lnum
+	 *            the long to print on this PrintStream.
+	 */
+	public void println(long lnum) {
+		println(String.valueOf(lnum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>Object</code> parameter
+	 * <code>obj</code> to the target OutputStream followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param obj
+	 *            the <code>Object</code> to print on this PrintStream.
+	 */
+	public void println(Object obj) {
+		println(String.valueOf(obj));
+	}
+
+	/**
+	 * Prints the String representation of the <code>String</code> parameter
+	 * <code>str</code> to the target OutputStream followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param str
+	 *            the <code>String</code> to print on this PrintStream.
+	 */
+	public void println(String str) {
+		synchronized (lock) {
+			print(str);
+			newline();
+		}
+	}
+
+	/**
+	 * Prints the String representation of the <code>boolean</code> parameter
+	 * <code>bool</code> to the target OutputStream followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param bool
+	 *            the boolean to print on this PrintStream.
+	 */
+	public void println(boolean bool) {
+		println(String.valueOf(bool));
+	}
+
+	protected void setError() {
+		ioError = true;
+	}
+
+	/**
+	 * Writes <code>count</code> <code>bytes</code> from the byte array
+	 * <code>buffer</code> starting at <code>offset</code> to this
+	 * PrintStream. This implementation writes the <code>buffer</code> to the
+	 * target OutputStream and if this PrintStream is set to autoflush, flushes
+	 * it. If an error occurs, set an error in this PrintStream to
+	 * <code>true</code>.
+	 * 
+	 * @param buffer
+	 *            the buffer to be written
+	 * @param offset
+	 *            offset in buffer to get bytes
+	 * @param count
+	 *            number of bytes in buffer to write
+	 * 
+	 * @throws IndexOutOfBoundsException
+	 *             If offset or count are outside of bounds.
+	 */
+	public void write(byte[] buffer, int offset, int count) {
+		if (buffer != null) {
+			// avoid int overflow
+			if (0 <= offset && offset <= buffer.length && 0 <= count
+					&& count <= buffer.length - offset) {
+				synchronized (lock) {
+					if (out == null) {
+						setError();
+						return;
+					}
+					try {
+						out.write(buffer, offset, count);
+						if (autoflush)
+							flush();
+					} catch (IOException e) {
+						setError();
+					}
+				}
+			} else
+				throw new ArrayIndexOutOfBoundsException(com.ibm.oti.util.Msg
+						.getString("K002f")); //$NON-NLS-1$
+		} else
+			throw new NullPointerException();
+	}
+
+	/**
+	 * Writes the specified byte <code>oneByte</code> to this PrintStream.
+	 * Only the low order byte of <code>oneByte</code> is written. This
+	 * implementation writes <code>oneByte</code> to the target OutputStream.
+	 * If <code>oneByte</code> is equal to the character <code>'\n'</code>
+	 * and this PrintSteam is set to autoflush, the target OutputStream is
+	 * flushed.
+	 * 
+	 * @param oneByte
+	 *            the byte to be written
+	 */
+	public void write(int oneByte) {
+		synchronized (lock) {
+			if (out == null) {
+				setError();
+				return;
+			}
+			try {
+				out.write(oneByte);
+				if (autoflush && (oneByte & 0xFF) == '\n')
+					flush();
+			} catch (IOException e) {
+				setError();
+			}
+		}
+	}
+}

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PrintWriter.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PrintWriter.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PrintWriter.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PrintWriter.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,477 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.io;
+
+
+import java.security.AccessController;
+
+import com.ibm.oti.util.PriviAction;
+
+/**
+ * PrintWriter is a class which takes either an OutputStream or Writer and
+ * provides convenience methods for printing common data types in a human
+ * readable format on the stream. No IOExceptions are thrown by this class.
+ * Instead, callers should call checkError() to see if a problem has been
+ * encountered in this Writer.
+ * 
+ */
+public class PrintWriter extends Writer {
+	/**
+	 * The writer to output data to.
+	 */
+	protected Writer out;
+
+	/**
+	 * indicates whether or not this PrintWriter has incurred an error.
+	 */
+	boolean ioError = false;
+
+	/**
+	 * indicates whether or not this PrintWriter should flush its contents after
+	 * printing a new line.
+	 */
+	boolean autoflush = false;
+
+	private final String lineSeparator = (String) AccessController
+			.doPrivileged(new PriviAction("line.separator")); //$NON-NLS-1$
+
+	/**
+	 * Constructs a new PrintWriter on the OutputStream <code>out</code>. All
+	 * writes to the target can now take place through this PrintWriter. By
+	 * default, the PrintWriter is set to not autoflush when println() is
+	 * called.
+	 * 
+	 * @param out
+	 *            the the OutputStream to provide convenience methods on.
+	 */
+	public PrintWriter(OutputStream out) {
+		this(new OutputStreamWriter(out), false);
+	}
+
+	/**
+	 * Constructs a new PrintWriter on the OutputStream <code>out</code>. All
+	 * writes to the target can now take place through this PrintWriter. By
+	 * default, the PrintWriter is set to not autoflush when println() is
+	 * called.
+	 * 
+	 * @param out
+	 *            the the OutputStream to provide convenience methods on.
+	 * @param autoflush
+	 *            whether to flush when println() is called.
+	 * 
+	 */
+	public PrintWriter(OutputStream out, boolean autoflush) {
+		this(new OutputStreamWriter(out), autoflush);
+	}
+
+	/**
+	 * Constructs a new PrintWriter on the Writer <code>wr</code>. All writes
+	 * to the target can now take place through this PrintWriter. By default,
+	 * the PrintWriter is set to not autoflush when println() is called.
+	 * 
+	 * @param wr
+	 *            the Writer to provide convenience methods on.
+	 * 
+	 */
+	public PrintWriter(Writer wr) {
+		this(wr, false);
+	}
+
+	/**
+	 * Constructs a new PrintWriter on the Writer <code>wr</code>. All writes
+	 * to the target can now take place through this PrintWriter. By default,
+	 * the PrintWriter is set to not autoflush when println() is called.
+	 * 
+	 * @param wr
+	 *            the Writer to provide convenience methods on.
+	 * @param autoflush
+	 *            whether to flush when println() is called.
+	 * 
+	 */
+	public PrintWriter(Writer wr, boolean autoflush) {
+		super(wr);
+		this.autoflush = autoflush;
+		out = wr;
+	}
+
+	/**
+	 * Answers a boolean indicating whether or not this PrintWriter has
+	 * encountered an error. If so, the receiver should probably be closed since
+	 * futher writes will not actually take place. A side effect of calling
+	 * checkError is that the target Writer is flushed.
+	 * 
+	 * @return boolean has an error occurred in this PrintWriter.
+	 */
+	public boolean checkError() {
+		if (out != null)
+			flush();
+		return ioError;
+	}
+
+	/**
+	 * Close this PrintWriter. This implementation flushes and then closes the
+	 * target writer. If an error occurs, set an error in this PrintWriter to
+	 * <code>true</code>.
+	 * 
+	 */
+	public void close() {
+		synchronized (lock) {
+			if (out != null) {
+				try {
+					out.close();
+				} catch (IOException e) {
+					setError();
+				}
+				out = null;
+			}
+		}
+	}
+
+	/**
+	 * Flush this PrintWriter to ensure all pending data is sent out to the
+	 * target Writer. This implementation flushes the target writer. If an error
+	 * occurs, set an error in this PrintWriter to <code>true</code>.
+	 */
+	public void flush() {
+		synchronized (lock) {
+			if (out != null) {
+				try {
+					out.flush();
+				} catch (IOException e) {
+					setError();
+				}
+			} else {
+				setError();
+			}
+		}
+	}
+
+	private void newline() {
+		print(lineSeparator);
+		if (autoflush)
+			flush();
+	}
+
+	/**
+	 * Prints the String representation of the character array parameter
+	 * <code>charArray</code> to the target Writer.
+	 * 
+	 * @param charArray
+	 *            the character array to print on this Writer.
+	 */
+	public void print(char[] charArray) {
+		print(new String(charArray, 0, charArray.length));
+	}
+
+	/**
+	 * Prints the String representation of the character parameter
+	 * <code>ch</code> to the target Writer.
+	 * 
+	 * @param ch
+	 *            the character to print on this Writer.
+	 */
+	public void print(char ch) {
+		print(String.valueOf(ch));
+	}
+
+	/**
+	 * Prints the String representation of the <code>double</code> parameter
+	 * <code>dnum</code> to the target Writer.
+	 * 
+	 * @param dnum
+	 *            the <code>double</code> to print on this Writer.
+	 */
+	public void print(double dnum) {
+		print(String.valueOf(dnum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>float</code> parameter
+	 * <code>fnum</code> to the target Writer.
+	 * 
+	 * @param fnum
+	 *            the <code>float</code> to print on this Writer.
+	 */
+	public void print(float fnum) {
+		print(String.valueOf(fnum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>int</code> parameter
+	 * <code>inum</code> to the target Writer.
+	 * 
+	 * @param inum
+	 *            the <code>int</code> to print on this Writer.
+	 */
+	public void print(int inum) {
+		print(String.valueOf(inum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>long</code> parameter
+	 * <code>lnum</code> to the target Writer.
+	 * 
+	 * @param lnum
+	 *            the <code>long</code> to print on this Writer.
+	 */
+	public void print(long lnum) {
+		print(String.valueOf(lnum));
+	}
+
+	/**
+	 * Prints the String representation of the Object parameter <code>obj</code>
+	 * to the target Writer.
+	 * 
+	 * @param obj
+	 *            the Object to print on this Writer.
+	 */
+	public void print(Object obj) {
+		print(String.valueOf(obj));
+	}
+
+	/**
+	 * Prints the String representation of the <code>String</code> parameter
+	 * <code>str</code> to the target Writer.
+	 * 
+	 * @param str
+	 *            the <code>String</code> to print on this Writer.
+	 */
+	public void print(String str) {
+		write(str != null ? str : String.valueOf((Object) null));
+	}
+
+	/**
+	 * Prints the String representation of the <code>boolean</code> parameter
+	 * <code>bool</code> to the target Writer.
+	 * 
+	 * @param bool
+	 *            the <code>boolean</code> to print on this Writer.
+	 */
+	public void print(boolean bool) {
+		print(String.valueOf(bool));
+	}
+
+	/**
+	 * Prints the String representation of the System property
+	 * <code>"line.separator"</code> to the target Writer.
+	 */
+	public void println() {
+		synchronized (lock) {
+			newline();
+		}
+	}
+
+	/**
+	 * Prints the String representation of the character array parameter
+	 * <code>charArray</code> to the target Writer followed by the System
+	 * property <code>"line.separator"</code>.
+	 * 
+	 * @param charArray
+	 *            the character array to print on this Writer.
+	 */
+	public void println(char[] charArray) {
+		println(new String(charArray, 0, charArray.length));
+	}
+
+	/**
+	 * Prints the String representation of the character parameter
+	 * <code>ch</code> to the target Writer followed by the System property
+	 * <code>"line.separator"</code>.
+	 * 
+	 * @param ch
+	 *            the character to print on this Writer.
+	 */
+	public void println(char ch) {
+		println(String.valueOf(ch));
+	}
+
+	/**
+	 * Prints the String representation of the <code>double</code> parameter
+	 * <code>dnum</code> to the target Writer followed by the System property
+	 * <code>"line.separator"</code>.
+	 * 
+	 * @param dnum
+	 *            the double to print on this Writer.
+	 */
+	public void println(double dnum) {
+		println(String.valueOf(dnum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>float</code> parameter
+	 * <code>fnum</code> to the target Writer followed by the System property
+	 * <code>"line.separator"</code>.
+	 * 
+	 * @param fnum
+	 *            the float to print on this Writer.
+	 */
+	public void println(float fnum) {
+		println(String.valueOf(fnum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>int</code> parameter
+	 * <code>inum</code> to the target Writer followed by the System property
+	 * <code>"line.separator"</code>.
+	 * 
+	 * @param inum
+	 *            the int to print on this Writer.
+	 */
+	public void println(int inum) {
+		println(String.valueOf(inum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>long</code> parameter
+	 * <code>lnum</code> to the target Writer followed by the System property
+	 * <code>"line.separator"</code>.
+	 * 
+	 * @param lnum
+	 *            the long to print on this Writer.
+	 */
+	public void println(long lnum) {
+		println(String.valueOf(lnum));
+	}
+
+	/**
+	 * Prints the String representation of the <code>Object</code> parameter
+	 * <code>obj</code> to the target Writer followed by the System property
+	 * <code>"line.separator"</code>.
+	 * 
+	 * @param obj
+	 *            the <code>Object</code> to print on this Writer.
+	 */
+	public void println(Object obj) {
+		println(String.valueOf(obj));
+	}
+
+	/**
+	 * Prints the String representation of the <code>String</code> parameter
+	 * <code>str</code> to the target Writer followed by the System property
+	 * <code>"line.separator"</code>.
+	 * 
+	 * @param str
+	 *            the <code>String</code> to print on this Writer.
+	 */
+	public void println(String str) {
+		synchronized (lock) {
+			print(str);
+			newline();
+		}
+	}
+
+	/**
+	 * Prints the String representation of the <code>boolean</code> parameter
+	 * <code>bool</code> to the target Writer followed by the System property
+	 * <code>"line.separator"</code>.
+	 * 
+	 * @param bool
+	 *            the boolean to print on this Writer.
+	 */
+	public void println(boolean bool) {
+		println(String.valueOf(bool));
+	}
+
+	/**
+	 * Set the flag indicating that this PrintWriter has encountered an IO
+	 * error.
+	 */
+	protected void setError() {
+		synchronized (lock) {
+			ioError = true;
+		}
+	}
+
+	/**
+	 * Writes the entire character buffer
+	 * 
+	 * @buf to this Writer.
+	 * 
+	 * @param buf
+	 *            the non-null array containing characters to write.
+	 */
+	public void write(char buf[]) {
+		write(buf, 0, buf.length);
+	}
+
+	/**
+	 * Writes <code>count</code> characters starting at <code>offset</code>
+	 * in <code>buf<code>
+	 * to this Writer.
+	 *
+	 * @param 		buf			the non-null array containing characters to write.
+	 * @param 		offset 		offset in buf to retrieve characters
+	 * @param 		count 		maximum number of characters to write
+	 *
+	 * @throws		ArrayIndexOutOfBoundsException 	If offset or count are outside of bounds.
+	 */
+	public void write(char buf[], int offset, int count) {
+		doWrite(buf, offset, count);
+	}
+
+	/**
+	 * Writes the specified character to this Writer. This implementation writes
+	 * the low order two bytes to the target writer.
+	 * 
+	 * @param oneChar
+	 *            The character to write
+	 */
+	public void write(int oneChar) {
+		doWrite(new char[] { (char) oneChar }, 0, 1);
+	}
+	
+	private final void doWrite(char buf[], int offset, int count) {
+		synchronized (lock) {
+			if (out != null) {
+				try {
+					out.write(buf, offset, count);
+				} catch (IOException e) {
+					setError();
+				}
+			} else {
+				setError();
+			}
+		}
+	}
+	
+	/**
+	 * Writes the characters from the String <code>str</code> to this Writer.
+	 * 
+	 * @param str
+	 *            the non-null String containing the characters to write.
+	 */
+	public void write(String str) {
+		write(str.toCharArray());
+	}
+
+	/**
+	 * Writes <code>count</code> characters from the String <code>str</code>
+	 * starting at <code>offset</code> to this Writer.
+	 * 
+	 * @param str
+	 *            the non-null String containing the characters to write.
+	 * @param offset
+	 *            where in <code>str</code> to get chars from.
+	 * @param count
+	 *            how many characters to write.
+	 * 
+	 * @throws ArrayIndexOutOfBoundsException
+	 *             If offset or count are outside of bounds.
+	 */
+	public void write(String str, int offset, int count) {
+		write(str.substring(offset, offset + count).toCharArray());
+	}
+}

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PushbackInputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PushbackInputStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PushbackInputStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PushbackInputStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,292 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.io;
+
+
+/**
+ * PushbackInputStream is a filter class which allows bytes read to be pushed
+ * back into the stream so that they can be reread. Parsers may find this
+ * useful. There is a progammable limit to the number of bytes which may be
+ * pushed back. If the buffer of pushed back bytes is empty, bytes are read from
+ * the source input stream.
+ * 
+ */
+public class PushbackInputStream extends FilterInputStream {
+	/**
+	 * The <code>byte</code> array containing the bytes to read.
+	 */
+	protected byte[] buf;
+
+	/**
+	 * The current position within the byte array <code>buf</code>. A value
+	 * equal to buf.length indicates no bytes available. A value of 0 indicates
+	 * the buffer is full.
+	 */
+	protected int pos;
+
+	/**
+	 * Constructs a new PushbackInputStream on the InputStream <code>in</code>.
+	 * The size of the pushback buffer is set to the default, or 1 byte.
+	 * 
+	 * @param in
+	 *            the InputStream to allow pushback operations on.
+	 * 
+	 */
+	public PushbackInputStream(InputStream in) {
+		super(in);
+		buf = new byte[1];
+		pos = 1;
+	}
+
+	/**
+	 * Constructs a new PushbackInputStream on the InputStream <code>in</code>.
+	 * The size of the pushback buffer is set to <code>size</code>.
+	 * 
+	 * @param in
+	 *            the InputStream to allow pushback operations on.
+	 * @param size
+	 *            the size of the pushback buffer (<code>size>=0</code>).
+	 */
+	public PushbackInputStream(InputStream in, int size) {
+		super(in);
+		if (size > 0) {
+			buf = new byte[size];
+			pos = size;
+		} else
+			throw new IllegalArgumentException(com.ibm.oti.util.Msg
+					.getString("K0058")); //$NON-NLS-1$
+	}
+
+	/**
+	 * Answers a int representing then number of bytes that are available before
+	 * this PushbackInputStream will block. This method returns the number of
+	 * bytes available in the pushback buffer plus those available in the target
+	 * stream.
+	 * 
+	 * @return int the number of bytes available before blocking.
+	 * 
+	 * @throws java.io.IOException
+	 *             If an error occurs in this stream.
+	 */
+	public int available() throws IOException {
+		if (buf != null)
+			return buf.length - pos + in.available();
+		throw new IOException();
+	}
+
+	/**
+	 * Close this PushbackInputStream. This implementation closes the target
+	 * stream.
+	 * 
+	 * @throws IOException
+	 *             If an error occurs attempting to close this stream.
+	 */
+	public void close() throws IOException {
+		if (in != null) {
+			in.close();
+			in = null;
+			buf = null;
+		}
+	}
+
+	/**
+	 * Answers a boolean indicating whether or not this PushbackInputStream
+	 * supports mark() and reset(). This implementation always answers false
+	 * since PushbackInputStreams do not support mark/reset.
+	 * 
+	 * @return boolean indicates whether or not mark() and reset() are
+	 *         supported.
+	 */
+	public boolean markSupported() {
+		return false;
+	}
+
+	/**
+	 * Reads a single byte from this PushbackInputStream and returns the result
+	 * as an int. The low-order byte is returned or -1 of the end of stream was
+	 * encountered. If the pushback buffer does not contain any available bytes
+	 * then a byte from the target input stream is returned.
+	 * 
+	 * @return int The byte read or -1 if end of stream.
+	 * 
+	 * @throws IOException
+	 *             If an IOException occurs.
+	 */
+	public int read() throws IOException {
+		if (buf != null) {
+			// Is there a pushback byte available?
+			if (pos < buf.length)
+				return (buf[pos++] & 0xFF);
+			// Assume read() in the InputStream will return low-order byte or -1
+			// if end of stream.
+			return in.read();
+		}
+		throw new IOException();
+	}
+
+	/**
+	 * Reads at most <code>length</code> bytes from this PushbackInputStream
+	 * and stores them in byte array <code>buffer</code> starting at
+	 * <code>offset</code>. Answer the number of bytes actually read or -1 if
+	 * no bytes were read and end of stream was encountered. This implementation
+	 * reads bytes from the pushback buffer first, then the target stream if
+	 * more bytes are required to satisfy <code>count</code>.
+	 * 
+	 * @param buffer
+	 *            the byte array in which to store the read bytes.
+	 * @param offset
+	 *            the offset in <code>buffer</code> to store the read bytes.
+	 * @param length
+	 *            the maximum number of bytes to store in <code>buffer</code>.
+	 * @return the number of bytes actually read or -1 if end of stream.
+	 * 
+	 * @throws IOException
+	 *             If an IOException occurs.
+	 */
+	public int read(byte[] buffer, int offset, int length) throws IOException {
+		if (buf != null && buffer != null) {
+			// avoid int overflow
+			if (0 <= offset && offset <= buffer.length && 0 <= length
+					&& length <= buffer.length - offset) {
+				int copiedBytes = 0, copyLength = 0, newOffset = offset;
+				// Are there pushback bytes available?
+				if (pos < buf.length) {
+					copyLength = (buf.length - pos >= length) ? length
+							: buf.length - pos;
+					System.arraycopy(buf, pos, buffer, newOffset, copyLength);
+					newOffset += copyLength;
+					copiedBytes += copyLength;
+					// Use up the bytes in the local buffer
+					pos += copyLength;
+				}
+				// Have we copied enough?
+				if (copyLength == length)
+					return length;
+				int inCopied = in.read(buffer, newOffset, length - copiedBytes);
+				if (inCopied > 0)
+					return inCopied + copiedBytes;
+				if (copiedBytes == 0)
+					return inCopied;
+				return copiedBytes;
+			}
+			throw new ArrayIndexOutOfBoundsException();
+		} else if (buf == null) {
+			throw new IOException();
+		}
+		throw new NullPointerException();
+	}
+
+	/**
+	 * Skips <code>count</code> number of bytes in this PushbackInputStream.
+	 * Subsequent <code>read()</code>'s will not return these bytes unless
+	 * <code>reset()</code> is used. This implementation skips
+	 * <code>count</code> number of bytes in the buffer and/or the target
+	 * stream.
+	 * 
+	 * @param count
+	 *            the number of bytes to skip.
+	 * @return the number of bytes actually skipped.
+	 * 
+	 * @throws IOException
+	 *             If the stream is already closed or another IOException
+	 *             occurs.
+	 */
+	public long skip(long count) throws IOException {
+		if (in != null) {
+			if (count <= 0) {
+				return 0;
+			}
+			int numSkipped = 0;
+			if (pos < buf.length) {
+				numSkipped += (count < buf.length - pos) ? count : buf.length
+						- pos;
+				pos += numSkipped;
+			}
+			if (numSkipped < count) {
+				numSkipped += in.skip(count - numSkipped);
+			}
+			return numSkipped;
+		}
+		throw new IOException(com.ibm.oti.util.Msg.getString("K0059")); //$NON-NLS-1$
+	}
+
+	/**
+	 * Push back all the bytes in <code>buffer</code>. The bytes are pushed
+	 * so that they would be read back buffer[0], buffer[1], etc. If the push
+	 * back buffer cannot handle the entire contents of <code>buffer</code>,
+	 * an IOException will be thrown. Some of the buffer may already be in the
+	 * buffer after the exception is thrown.
+	 * 
+	 * @param buffer
+	 *            the byte array containing bytes to push back into the stream.
+	 * 
+	 * @throws IOException
+	 *             If the pushback buffer becomes, or is, full.
+	 */
+	public void unread(byte[] buffer) throws IOException {
+		unread(buffer, 0, buffer.length);
+	}
+
+	/**
+	 * Push back <code>length</code> number of bytes in <code>buffer</code>
+	 * starting at <code>offset</code>. The bytes are pushed so that they
+	 * would be read back buffer[offset], buffer[offset+1], etc. If the push
+	 * back buffer cannot handle the bytes copied from <code>buffer</code>,
+	 * an IOException will be thrown. Some of the bytes may already be in the
+	 * buffer after the exception is thrown.
+	 * 
+	 * @param buffer
+	 *            the byte array containing bytes to push back into the stream.
+	 * @param offset
+	 *            the location to start taking bytes to push back.
+	 * @param length
+	 *            the number of bytes to push back.
+	 * 
+	 * @throws IOException
+	 *             If the pushback buffer becomes, or is, full.
+	 */
+	public void unread(byte[] buffer, int offset, int length)
+			throws IOException {
+		// avoid int overflow
+		if (0 <= offset && offset <= buffer.length && 0 <= length
+				&& length <= buffer.length - offset) {
+			for (int i = offset + length - 1; i >= offset; i--)
+				unread(buffer[i]);
+		} else
+			throw new ArrayIndexOutOfBoundsException();
+	}
+
+	/**
+	 * Push back one <code>byte</code>. Takes the byte <code>oneByte</code>
+	 * and puts in in the local buffer of bytes to read back before accessing
+	 * the target input stream.
+	 * 
+	 * @param oneByte
+	 *            the byte to push back into the stream.
+	 * 
+	 * @throws IOException
+	 *             If the pushback buffer is already full.
+	 */
+	public void unread(int oneByte) throws IOException {
+		if (buf != null) {
+			if (pos != 0)
+				buf[--pos] = (byte) oneByte;
+			else
+				throw new IOException(com.ibm.oti.util.Msg.getString("K007e")); //$NON-NLS-1$
+		} else
+			throw new IOException();
+	}
+}

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PushbackReader.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PushbackReader.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PushbackReader.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/io/PushbackReader.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,304 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.io;
+
+
+/**
+ * PushbackReader is a filter class which allows chars read to be pushed back
+ * into the stream so that they can be reread. Parsers may find this useful.
+ * There is a progammable limit to the number of chars which may be pushed back.
+ * If the buffer of pushed back chars is empty, chars are read from the source
+ * reader.
+ * 
+ */
+public class PushbackReader extends FilterReader {
+	/**
+	 * The <code>char</code> array containing the chars to read.
+	 */
+	char[] buf;
+
+	/**
+	 * The current position within the char array <code>buf</code>. A value
+	 * equal to buf.length indicates no chars available. A value of 0 indicates
+	 * the buffer is full.
+	 */
+	int pos;
+
+	/**
+	 * Constructs a new PushbackReader on the Reader <code>in</code>. The
+	 * size of the pushback buffer is set to the default, or 1 character.
+	 * 
+	 * @param in
+	 *            the Reader to allow pushback operations on.
+	 * 
+	 */
+	public PushbackReader(Reader in) {
+		super(in);
+		buf = new char[1];
+		pos = 1;
+	}
+
+	/**
+	 * Constructs a new PushbackReader on the Reader <code>in</code>. The
+	 * size of the pushback buffer is set to <code>size</code> characters.
+	 * 
+	 * @param in
+	 *            the Reader to allow pushback operations on.
+	 * @param size
+	 *            the size of the pushback buffer (<code>size>=0</code>) in
+	 *            characters.
+	 */
+	public PushbackReader(Reader in, int size) {
+		super(in);
+		if (size > 0) {
+			buf = new char[size];
+			pos = size;
+		} else
+			throw new IllegalArgumentException(com.ibm.oti.util.Msg
+					.getString("K0058")); //$NON-NLS-1$
+	}
+
+	/**
+	 * Close this PushbackReader. This implementation closes this reader,
+	 * releases the buffer used to pushback characters, and closes the target
+	 * reader.
+	 * 
+	 * @throws IOException
+	 *             If an error occurs attempting to close this Reader.
+	 */
+	public void close() throws IOException {
+		synchronized (lock) {
+			buf = null;
+			in.close();
+		}
+	}
+
+	/**
+	 * Mark this PushbackReader. Since mark is not supported, this method will
+	 * always throw IOException.
+	 * 
+	 * @param readAheadLimit
+	 *            ignored, this method always throws IOException.
+	 * 
+	 * @throws IOException
+	 *             Since mark is not supported byt PushbackReader.
+	 */
+	public void mark(int readAheadLimit) throws IOException {
+		throw new IOException(com.ibm.oti.util.Msg.getString("K007f")); //$NON-NLS-1$
+	}
+
+	/**
+	 * Answers a boolean indicating whether or not this PushbackReader supports
+	 * mark() and reset(). This implementation always answers false since
+	 * PushbackReaders do not support mark/reset.
+	 * 
+	 * @return boolean indicates whether or not mark() and reset() are
+	 *         supported.
+	 */
+	public boolean markSupported() {
+		return false;
+	}
+
+	/**
+	 * Reads a single character from this PushbackReader and returns the result
+	 * as an int. The 2 lowest-order bytes are returned or -1 of the end of
+	 * stream was encountered. If the pushback buffer does not contain any
+	 * available chars then a char from the target input reader is returned.
+	 * 
+	 * @return int The char read or -1 if end of stream.
+	 * 
+	 * @throws IOException
+	 *             If an IOException occurs.
+	 */
+	public int read() throws IOException {
+		synchronized (lock) {
+			if (buf != null) {
+				/* Is there a pushback character available? */
+				if (pos < buf.length) {
+					return buf[pos++];
+				}
+				/**
+				 * Assume read() in the InputStream will return 2 lowest-order
+				 * bytes or -1 if end of stream.
+				 */
+				return in.read();
+			}
+			throw new IOException();
+		}
+	}
+
+	/**
+	 * Reads at most <code>count</code> chars from this PushbackReader and
+	 * stores them in char array <code>buffer</code> starting at
+	 * <code>offset</code>. Answer the number of chars actually read or -1 if
+	 * no chars were read and end of stream was encountered. This implementation
+	 * reads chars from the pushback buffer first, then the target stream if
+	 * more chars are required to satisfy <code>count</code>.
+	 * 
+	 * @param buffer
+	 *            the char array in which to store the read chars.
+	 * @param offset
+	 *            the offset in <code>buffer</code> to store the read chars.
+	 * @param count
+	 *            the maximum number of chars to store in <code>buffer</code>.
+	 * @return the number of chars actually read or -1 if end of stream.
+	 * 
+	 * @throws IOException
+	 *             If an IOException occurs.
+	 */
+	public int read(char[] buffer, int offset, int count) throws IOException {
+		// avoid int overflow
+		if (0 <= offset && offset <= buffer.length && 0 <= count
+				&& count <= buffer.length - offset) {
+			synchronized (lock) {
+				if (buf != null) {
+					int copiedChars = 0, copyLength = 0, newOffset = offset;
+					/* Are there pushback chars available? */
+					if (pos < buf.length) {
+						copyLength = (buf.length - pos >= count) ? count
+								: buf.length - pos;
+						System.arraycopy(buf, pos, buffer, newOffset,
+								copyLength);
+						newOffset += copyLength;
+						copiedChars += copyLength;
+						/* Use up the chars in the local buffer */
+						pos += copyLength;
+					}
+					/* Have we copied enough? */
+					if (copyLength == count) {
+						return count;
+					}
+					int inCopied = in.read(buffer, newOffset, count
+							- copiedChars);
+					if (inCopied > 0) {
+						return inCopied + copiedChars;
+					}
+					if (copiedChars == 0) {
+						return inCopied;
+					}
+					return copiedChars;
+				}
+				throw new IOException();
+			}
+		}
+		throw new ArrayIndexOutOfBoundsException();
+	}
+
+	/**
+	 * Answers a <code>boolean</code> indicating whether or not this
+	 * PushbackReader is ready to be read without blocking. If the result is
+	 * <code>true</code>, the next <code>read()</code> will not block. If
+	 * the result is <code>false</code> this Reader may or may not block when
+	 * <code>read()</code> is sent.
+	 * 
+	 * @return boolean <code>true</code> if the receiver will not block when
+	 *         <code>read()</code> is called, <code>false</code> if unknown
+	 *         or blocking will occur.
+	 * 
+	 * @throws IOException
+	 *             If the Reader is already closed or some other IO error
+	 *             occurs.
+	 */
+	public boolean ready() throws IOException {
+		synchronized (lock) {
+			if (buf != null)
+				return (buf.length - pos > 0 || in.ready());
+			throw new IOException(com.ibm.oti.util.Msg.getString("K0080")); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Resets this PushbackReader. Since mark is not supported, always throw
+	 * IOException.
+	 * 
+	 * @throws IOException
+	 *             Since mark is not supported.
+	 */
+	public void reset() throws IOException {
+		throw new IOException(com.ibm.oti.util.Msg.getString("K007f")); //$NON-NLS-1$
+	}
+
+	/**
+	 * Push back all the chars in <code>buffer</code>. The chars are pushed
+	 * so that they would be read back buffer[0], buffer[1], etc. If the push
+	 * back buffer cannot handle the entire contents of <code>buffer</code>,
+	 * an IOException will be thrown. Some of the buffer may already be in the
+	 * buffer after the exception is thrown.
+	 * 
+	 * @param buffer
+	 *            the char array containing chars to push back into the reader.
+	 * 
+	 * @throws IOException
+	 *             If the pushback buffer becomes, or is, full.
+	 */
+	public void unread(char[] buffer) throws IOException {
+		unread(buffer, 0, buffer.length);
+	}
+
+	/**
+	 * Push back <code>count</code> number of chars in <code>buffer</code>
+	 * starting at <code>offset</code>. The chars are pushed so that they
+	 * would be read back buffer[offset], buffer[offset+1], etc. If the push
+	 * back buffer cannot handle the chars copied from <code>buffer</code>,
+	 * an IOException will be thrown. Some of the chars may already be in the
+	 * buffer after the exception is thrown.
+	 * 
+	 * @param buffer
+	 *            the char array containing chars to push back into the reader.
+	 * @param offset
+	 *            the location to start taking chars to push back.
+	 * @param count
+	 *            the number of chars to push back.
+	 * 
+	 * @throws IOException
+	 *             If the pushback buffer becomes, or is, full.
+	 */
+	public void unread(char[] buffer, int offset, int count) throws IOException {
+		// avoid int overflow
+		if (0 <= offset && offset <= buffer.length && 0 <= count
+				&& count <= buffer.length - offset) {
+			synchronized (lock) {
+				for (int i = offset + count - 1; i >= offset; i--)
+					unread(buffer[i]);
+			}
+		} else
+			throw new ArrayIndexOutOfBoundsException();
+	}
+
+	/**
+	 * Push back one <code>char</code>. Takes the char <code>oneChar</code>
+	 * and puts in in the local buffer of chars to read back before accessing
+	 * the target input stream.
+	 * 
+	 * @param oneChar
+	 *            the char to push back into the stream.
+	 * 
+	 * @throws IOException
+	 *             If the pushback buffer is already full.
+	 */
+	public void unread(int oneChar) throws IOException {
+		synchronized (lock) {
+			if (buf != null) {
+				if (pos != 0)
+					buf[--pos] = (char) oneChar;
+				else
+					throw new IOException(com.ibm.oti.util.Msg
+							.getString("K007e")); //$NON-NLS-1$
+			} else
+				throw new IOException();
+		}
+	}
+}



Mime
View raw message