You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/12/01 07:04:00 UTC
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....
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();
+ }
+ }
+}