8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Utility methods for packing/unpacking primitive values in/out of byte arrays
* using big-endian byte ordering.
*/
class Bits {
/*
* Methods for unpacking primitive values from byte arrays starting at
* given offsets.
*/
static boolean getBoolean(byte[] b, int off) {
return b[off] != 0;
}
static char getChar(byte[] b, int off) {
return (char) ((b[off + 1] & 0xFF) +
(b[off] << 8));
}
static short getShort(byte[] b, int off) {
return (short) ((b[off + 1] & 0xFF) +
(b[off] << 8));
}
static int getInt(byte[] b, int off) {
return ((b[off + 3] & 0xFF) ) +
((b[off + 2] & 0xFF) << 8) +
((b[off + 1] & 0xFF) << 16) +
((b[off ] ) << 24);
}
static float getFloat(byte[] b, int off) {
return Float.intBitsToFloat(getInt(b, off));
}
static long getLong(byte[] b, int off) {
return ((b[off + 7] & 0xFFL) ) +
((b[off + 6] & 0xFFL) << 8) +
((b[off + 5] & 0xFFL) << 16) +
((b[off + 4] & 0xFFL) << 24) +
((b[off + 3] & 0xFFL) << 32) +
((b[off + 2] & 0xFFL) << 40) +
((b[off + 1] & 0xFFL) << 48) +
(((long) b[off]) << 56);
}
static double getDouble(byte[] b, int off) {
return Double.longBitsToDouble(getLong(b, off));
}
/*
* Methods for packing primitive values into byte arrays starting at given
* offsets.
*/
static void putBoolean(byte[] b, int off, boolean val) {
b[off] = (byte) (val ? 1 : 0);
}
static void putChar(byte[] b, int off, char val) {
b[off + 1] = (byte) (val );
b[off ] = (byte) (val >>> 8);
}
static void putShort(byte[] b, int off, short val) {
b[off + 1] = (byte) (val );
b[off ] = (byte) (val >>> 8);
}
static void putInt(byte[] b, int off, int val) {
b[off + 3] = (byte) (val );
b[off + 2] = (byte) (val >>> 8);
b[off + 1] = (byte) (val >>> 16);
b[off ] = (byte) (val >>> 24);
}
static void putFloat(byte[] b, int off, float val) {
putInt(b, off, Float.floatToIntBits(val));
}
static void putLong(byte[] b, int off, long val) {
b[off + 7] = (byte) (val );
b[off + 6] = (byte) (val >>> 8);
b[off + 5] = (byte) (val >>> 16);
b[off + 4] = (byte) (val >>> 24);
b[off + 3] = (byte) (val >>> 32);
b[off + 2] = (byte) (val >>> 40);
b[off + 1] = (byte) (val >>> 48);
b[off ] = (byte) (val >>> 56);
}
static void putDouble(byte[] b, int off, double val) {
putLong(b, off, Double.doubleToLongBits(val));
}
}

View file

@ -0,0 +1,495 @@
/*
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import jdk.internal.misc.Unsafe;
/**
* A <code>BufferedInputStream</code> adds
* functionality to another input stream-namely,
* the ability to buffer the input and to
* support the <code>mark</code> and <code>reset</code>
* methods. When the <code>BufferedInputStream</code>
* is created, an internal buffer array is
* created. As bytes from the stream are read
* or skipped, the internal buffer is refilled
* as necessary from the contained input stream,
* many bytes at a time. The <code>mark</code>
* operation remembers a point in the input
* stream and the <code>reset</code> operation
* causes all the bytes read since the most
* recent <code>mark</code> operation to be
* reread before new bytes are taken from
* the contained input stream.
*
* @author Arthur van Hoff
* @since 1.0
*/
public
class BufferedInputStream extends FilterInputStream {
private static int DEFAULT_BUFFER_SIZE = 8192;
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
/**
* As this class is used early during bootstrap, it's motivated to use
* Unsafe.compareAndSetObject instead of AtomicReferenceFieldUpdater
* (or VarHandles) to reduce dependencies and improve startup time.
*/
private static final Unsafe U = Unsafe.getUnsafe();
private static final long BUF_OFFSET
= U.objectFieldOffset(BufferedInputStream.class, "buf");
/**
* The internal buffer array where the data is stored. When necessary,
* it may be replaced by another array of
* a different size.
*/
/*
* We null this out with a CAS on close(), which is necessary since
* closes can be asynchronous. We use nullness of buf[] as primary
* indicator that this stream is closed. (The "in" field is also
* nulled out on close.)
*/
protected volatile byte[] buf;
/**
* The index one greater than the index of the last valid byte in
* the buffer.
* This value is always
* in the range <code>0</code> through <code>buf.length</code>;
* elements <code>buf[0]</code> through <code>buf[count-1]
* </code>contain buffered input data obtained
* from the underlying input stream.
*/
protected int count;
/**
* The current position in the buffer. This is the index of the next
* character to be read from the <code>buf</code> array.
* <p>
* This value is always in the range <code>0</code>
* through <code>count</code>. If it is less
* than <code>count</code>, then <code>buf[pos]</code>
* is the next byte to be supplied as input;
* if it is equal to <code>count</code>, then
* the next <code>read</code> or <code>skip</code>
* operation will require more bytes to be
* read from the contained input stream.
*
* @see java.io.BufferedInputStream#buf
*/
protected int pos;
/**
* The value of the <code>pos</code> field at the time the last
* <code>mark</code> method was called.
* <p>
* This value is always
* in the range <code>-1</code> through <code>pos</code>.
* If there is no marked position in the input
* stream, this field is <code>-1</code>. If
* there is a marked position in the input
* stream, then <code>buf[markpos]</code>
* is the first byte to be supplied as input
* after a <code>reset</code> operation. If
* <code>markpos</code> is not <code>-1</code>,
* then all bytes from positions <code>buf[markpos]</code>
* through <code>buf[pos-1]</code> must remain
* in the buffer array (though they may be
* moved to another place in the buffer array,
* with suitable adjustments to the values
* of <code>count</code>, <code>pos</code>,
* and <code>markpos</code>); they may not
* be discarded unless and until the difference
* between <code>pos</code> and <code>markpos</code>
* exceeds <code>marklimit</code>.
*
* @see java.io.BufferedInputStream#mark(int)
* @see java.io.BufferedInputStream#pos
*/
protected int markpos = -1;
/**
* The maximum read ahead allowed after a call to the
* <code>mark</code> method before subsequent calls to the
* <code>reset</code> method fail.
* Whenever the difference between <code>pos</code>
* and <code>markpos</code> exceeds <code>marklimit</code>,
* then the mark may be dropped by setting
* <code>markpos</code> to <code>-1</code>.
*
* @see java.io.BufferedInputStream#mark(int)
* @see java.io.BufferedInputStream#reset()
*/
protected int marklimit;
/**
* Check to make sure that underlying input stream has not been
* nulled out due to close; if not return it;
*/
private InputStream getInIfOpen() throws IOException {
InputStream input = in;
if (input == null)
throw new IOException("Stream closed");
return input;
}
/**
* Check to make sure that buffer has not been nulled out due to
* close; if not return it;
*/
private byte[] getBufIfOpen() throws IOException {
byte[] buffer = buf;
if (buffer == null)
throw new IOException("Stream closed");
return buffer;
}
/**
* Creates a <code>BufferedInputStream</code>
* and saves its argument, the input stream
* <code>in</code>, for later use. An internal
* buffer array is created and stored in <code>buf</code>.
*
* @param in the underlying input stream.
*/
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
/**
* Creates a <code>BufferedInputStream</code>
* with the specified buffer size,
* and saves its argument, the input stream
* <code>in</code>, for later use. An internal
* buffer array of length <code>size</code>
* is created and stored in <code>buf</code>.
*
* @param in the underlying input stream.
* @param size the buffer size.
* @exception IllegalArgumentException if {@code size <= 0}.
*/
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
/**
* Fills the buffer with more data, taking into account
* shuffling and other tricks for dealing with marks.
* Assumes that it is being called by a synchronized method.
* This method also assumes that all data has already been read in,
* hence pos > count.
*/
private void fill() throws IOException {
byte[] buffer = getBufIfOpen();
if (markpos < 0)
pos = 0; /* no mark: throw away the buffer */
else if (pos >= buffer.length) /* no room left in buffer */
if (markpos > 0) { /* can throw away early part of the buffer */
int sz = pos - markpos;
System.arraycopy(buffer, markpos, buffer, 0, sz);
pos = sz;
markpos = 0;
} else if (buffer.length >= marklimit) {
markpos = -1; /* buffer got too big, invalidate mark */
pos = 0; /* drop buffer contents */
} else if (buffer.length >= MAX_BUFFER_SIZE) {
throw new OutOfMemoryError("Required array size too large");
} else { /* grow buffer */
int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
pos * 2 : MAX_BUFFER_SIZE;
if (nsz > marklimit)
nsz = marklimit;
byte[] nbuf = new byte[nsz];
System.arraycopy(buffer, 0, nbuf, 0, pos);
if (!U.compareAndSetObject(this, BUF_OFFSET, buffer, nbuf)) {
// Can't replace buf if there was an async close.
// Note: This would need to be changed if fill()
// is ever made accessible to multiple threads.
// But for now, the only way CAS can fail is via close.
// assert buf == null;
throw new IOException("Stream closed");
}
buffer = nbuf;
}
count = pos;
int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
if (n > 0)
count = n + pos;
}
/**
* See
* the general contract of the <code>read</code>
* method of <code>InputStream</code>.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if this input stream has been closed by
* invoking its {@link #close()} method,
* or an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
/**
* Read characters into a portion of an array, reading from the underlying
* stream at most once if necessary.
*/
private int read1(byte[] b, int off, int len) throws IOException {
int avail = count - pos;
if (avail <= 0) {
/* If the requested length is at least as large as the buffer, and
if there is no mark/reset activity, do not bother to copy the
bytes into the local buffer. In this way buffered streams will
cascade harmlessly. */
if (len >= getBufIfOpen().length && markpos < 0) {
return getInIfOpen().read(b, off, len);
}
fill();
avail = count - pos;
if (avail <= 0) return -1;
}
int cnt = (avail < len) ? avail : len;
System.arraycopy(getBufIfOpen(), pos, b, off, cnt);
pos += cnt;
return cnt;
}
/**
* Reads bytes from this byte-input stream into the specified byte array,
* starting at the given offset.
*
* <p> This method implements the general contract of the corresponding
* <code>{@link InputStream#read(byte[], int, int) read}</code> method of
* the <code>{@link InputStream}</code> class. As an additional
* convenience, it attempts to read as many bytes as possible by repeatedly
* invoking the <code>read</code> method of the underlying stream. This
* iterated <code>read</code> continues until one of the following
* conditions becomes true: <ul>
*
* <li> The specified number of bytes have been read,
*
* <li> The <code>read</code> method of the underlying stream returns
* <code>-1</code>, indicating end-of-file, or
*
* <li> The <code>available</code> method of the underlying stream
* returns zero, indicating that further input requests would block.
*
* </ul> If the first <code>read</code> on the underlying stream returns
* <code>-1</code> to indicate end-of-file then this method returns
* <code>-1</code>. Otherwise this method returns the number of bytes
* actually read.
*
* <p> Subclasses of this class are encouraged, but not required, to
* attempt to read as many bytes as possible in the same fashion.
*
* @param b destination buffer.
* @param off offset at which to start storing bytes.
* @param len maximum number of bytes to read.
* @return the number of bytes read, or <code>-1</code> if the end of
* the stream has been reached.
* @exception IOException if this input stream has been closed by
* invoking its {@link #close()} method,
* or an I/O error occurs.
*/
public synchronized int read(byte b[], int off, int len)
throws IOException
{
getBufIfOpen(); // Check for closed stream
if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int n = 0;
for (;;) {
int nread = read1(b, off + n, len - n);
if (nread <= 0)
return (n == 0) ? nread : n;
n += nread;
if (n >= len)
return n;
// if not closed but no bytes available, return
InputStream input = in;
if (input != null && input.available() <= 0)
return n;
}
}
/**
* See the general contract of the <code>skip</code>
* method of <code>InputStream</code>.
*
* @throws IOException if this input stream has been closed by
* invoking its {@link #close()} method,
* {@code in.skip(n)} throws an IOException,
* or an I/O error occurs.
*/
public synchronized long skip(long n) throws IOException {
getBufIfOpen(); // Check for closed stream
if (n <= 0) {
return 0;
}
long avail = count - pos;
if (avail <= 0) {
// If no mark position set then don't keep in buffer
if (markpos <0)
return getInIfOpen().skip(n);
// Fill in buffer to save bytes for reset
fill();
avail = count - pos;
if (avail <= 0)
return 0;
}
long skipped = (avail < n) ? avail : n;
pos += skipped;
return skipped;
}
/**
* Returns an estimate of the number of bytes that can be read (or
* skipped over) from this input stream without blocking by the next
* invocation of a method for this input stream. The next invocation might be
* the same thread or another thread. A single read or skip of this
* many bytes will not block, but may read or skip fewer bytes.
* <p>
* This method returns the sum of the number of bytes remaining to be read in
* the buffer (<code>count&nbsp;- pos</code>) and the result of calling the
* {@link java.io.FilterInputStream#in in}.available().
*
* @return an estimate of the number of bytes that can be read (or skipped
* over) from this input stream without blocking.
* @exception IOException if this input stream has been closed by
* invoking its {@link #close()} method,
* or an I/O error occurs.
*/
public synchronized int available() throws IOException {
int n = count - pos;
int avail = getInIfOpen().available();
return n > (Integer.MAX_VALUE - avail)
? Integer.MAX_VALUE
: n + avail;
}
/**
* See the general contract of the <code>mark</code>
* method of <code>InputStream</code>.
*
* @param readlimit the maximum limit of bytes that can be read before
* the mark position becomes invalid.
* @see java.io.BufferedInputStream#reset()
*/
public synchronized void mark(int readlimit) {
marklimit = readlimit;
markpos = pos;
}
/**
* See the general contract of the <code>reset</code>
* method of <code>InputStream</code>.
* <p>
* If <code>markpos</code> is <code>-1</code>
* (no mark has been set or the mark has been
* invalidated), an <code>IOException</code>
* is thrown. Otherwise, <code>pos</code> is
* set equal to <code>markpos</code>.
*
* @exception IOException if this stream has not been marked or,
* if the mark has been invalidated, or the stream
* has been closed by invoking its {@link #close()}
* method, or an I/O error occurs.
* @see java.io.BufferedInputStream#mark(int)
*/
public synchronized void reset() throws IOException {
getBufIfOpen(); // Cause exception if closed
if (markpos < 0)
throw new IOException("Resetting to invalid mark");
pos = markpos;
}
/**
* Tests if this input stream supports the <code>mark</code>
* and <code>reset</code> methods. The <code>markSupported</code>
* method of <code>BufferedInputStream</code> returns
* <code>true</code>.
*
* @return a <code>boolean</code> indicating if this stream type supports
* the <code>mark</code> and <code>reset</code> methods.
* @see java.io.InputStream#mark(int)
* @see java.io.InputStream#reset()
*/
public boolean markSupported() {
return true;
}
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* Once the stream has been closed, further read(), available(), reset(),
* or skip() invocations will throw an IOException.
* Closing a previously closed stream has no effect.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
byte[] buffer;
while ( (buffer = buf) != null) {
if (U.compareAndSetObject(this, BUF_OFFSET, buffer, null)) {
InputStream input = in;
in = null;
if (input != null)
input.close();
return;
}
// Else retry in case a new buf was CASed in fill()
}
}
}

View file

@ -0,0 +1,145 @@
/*
* Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* The class implements a buffered output stream. By setting up such
* an output stream, an application can write bytes to the underlying
* output stream without necessarily causing a call to the underlying
* system for each byte written.
*
* @author Arthur van Hoff
* @since 1.0
*/
public class BufferedOutputStream extends FilterOutputStream {
/**
* The internal buffer where data is stored.
*/
protected byte buf[];
/**
* The number of valid bytes in the buffer. This value is always
* in the range {@code 0} through {@code buf.length}; elements
* {@code buf[0]} through {@code buf[count-1]} contain valid
* byte data.
*/
protected int count;
/**
* Creates a new buffered output stream to write data to the
* specified underlying output stream.
*
* @param out the underlying output stream.
*/
public BufferedOutputStream(OutputStream out) {
this(out, 8192);
}
/**
* Creates a new buffered output stream to write data to the
* specified underlying output stream with the specified buffer
* size.
*
* @param out the underlying output stream.
* @param size the buffer size.
* @exception IllegalArgumentException if size &lt;= 0.
*/
public BufferedOutputStream(OutputStream out, int size) {
super(out);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
/** Flush the internal buffer */
private void flushBuffer() throws IOException {
if (count > 0) {
out.write(buf, 0, count);
count = 0;
}
}
/**
* Writes the specified byte to this buffered output stream.
*
* @param b the byte to be written.
* @exception IOException if an I/O error occurs.
*/
@Override
public synchronized void write(int b) throws IOException {
if (count >= buf.length) {
flushBuffer();
}
buf[count++] = (byte)b;
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this buffered output stream.
*
* <p> Ordinarily this method stores bytes from the given array into this
* stream's buffer, flushing the buffer to the underlying output stream as
* needed. If the requested length is at least as large as this stream's
* buffer, however, then this method will flush the buffer and write the
* bytes directly to the underlying output stream. Thus redundant
* <code>BufferedOutputStream</code>s will not copy data unnecessarily.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs.
*/
@Override
public synchronized void write(byte b[], int off, int len) throws IOException {
if (len >= buf.length) {
/* If the request length exceeds the size of the output buffer,
flush the output buffer and then write the data directly.
In this way buffered streams will cascade harmlessly. */
flushBuffer();
out.write(b, off, len);
return;
}
if (len > buf.length - count) {
flushBuffer();
}
System.arraycopy(b, off, buf, count, len);
count += len;
}
/**
* Flushes this buffered output stream. This forces any buffered
* output bytes to be written out to the underlying output stream.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
@Override
public synchronized void flush() throws IOException {
flushBuffer();
out.flush();
}
}

View file

@ -0,0 +1,596 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* Reads text from a character-input stream, buffering characters so as to
* provide for the efficient reading of characters, arrays, and lines.
*
* <p> The buffer size may be specified, or the default size may be used. The
* default is large enough for most purposes.
*
* <p> In general, each read request made of a Reader causes a corresponding
* read request to be made of the underlying character or byte stream. It is
* therefore advisable to wrap a BufferedReader around any Reader whose read()
* operations may be costly, such as FileReaders and InputStreamReaders. For
* example,
*
* <pre>
* BufferedReader in
* = new BufferedReader(new FileReader("foo.in"));
* </pre>
*
* will buffer the input from the specified file. Without buffering, each
* invocation of read() or readLine() could cause bytes to be read from the
* file, converted into characters, and then returned, which can be very
* inefficient.
*
* <p> Programs that use DataInputStreams for textual input can be localized by
* replacing each DataInputStream with an appropriate BufferedReader.
*
* @see FileReader
* @see InputStreamReader
* @see java.nio.file.Files#newBufferedReader
*
* @author Mark Reinhold
* @since 1.1
*/
public class BufferedReader extends Reader {
private Reader in;
private char cb[];
private int nChars, nextChar;
private static final int INVALIDATED = -2;
private static final int UNMARKED = -1;
private int markedChar = UNMARKED;
private int readAheadLimit = 0; /* Valid only when markedChar > 0 */
/** If the next character is a line feed, skip it */
private boolean skipLF = false;
/** The skipLF flag when the mark was set */
private boolean markedSkipLF = false;
private static int defaultCharBufferSize = 8192;
private static int defaultExpectedLineLength = 80;
/**
* Creates a buffering character-input stream that uses an input buffer of
* the specified size.
*
* @param in A Reader
* @param sz Input-buffer size
*
* @exception IllegalArgumentException If {@code sz <= 0}
*/
public BufferedReader(Reader in, int sz) {
super(in);
if (sz <= 0)
throw new IllegalArgumentException("Buffer size <= 0");
this.in = in;
cb = new char[sz];
nextChar = nChars = 0;
}
/**
* Creates a buffering character-input stream that uses a default-sized
* input buffer.
*
* @param in A Reader
*/
public BufferedReader(Reader in) {
this(in, defaultCharBufferSize);
}
/** Checks to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
if (in == null)
throw new IOException("Stream closed");
}
/**
* Fills the input buffer, taking the mark into account if it is valid.
*/
private void fill() throws IOException {
int dst;
if (markedChar <= UNMARKED) {
/* No mark */
dst = 0;
} else {
/* Marked */
int delta = nextChar - markedChar;
if (delta >= readAheadLimit) {
/* Gone past read-ahead limit: Invalidate mark */
markedChar = INVALIDATED;
readAheadLimit = 0;
dst = 0;
} else {
if (readAheadLimit <= cb.length) {
/* Shuffle in the current buffer */
System.arraycopy(cb, markedChar, cb, 0, delta);
markedChar = 0;
dst = delta;
} else {
/* Reallocate buffer to accommodate read-ahead limit */
char ncb[] = new char[readAheadLimit];
System.arraycopy(cb, markedChar, ncb, 0, delta);
cb = ncb;
markedChar = 0;
dst = delta;
}
nextChar = nChars = delta;
}
}
int n;
do {
n = in.read(cb, dst, cb.length - dst);
} while (n == 0);
if (n > 0) {
nChars = dst + n;
nextChar = dst;
}
}
/**
* Reads a single character.
*
* @return The character read, as an integer in the range
* 0 to 65535 ({@code 0x00-0xffff}), or -1 if the
* end of the stream has been reached
* @exception IOException If an I/O error occurs
*/
public int read() throws IOException {
synchronized (lock) {
ensureOpen();
for (;;) {
if (nextChar >= nChars) {
fill();
if (nextChar >= nChars)
return -1;
}
if (skipLF) {
skipLF = false;
if (cb[nextChar] == '\n') {
nextChar++;
continue;
}
}
return cb[nextChar++];
}
}
}
/**
* Reads characters into a portion of an array, reading from the underlying
* stream if necessary.
*/
private int read1(char[] cbuf, int off, int len) throws IOException {
if (nextChar >= nChars) {
/* If the requested length is at least as large as the buffer, and
if there is no mark/reset activity, and if line feeds are not
being skipped, do not bother to copy the characters into the
local buffer. In this way buffered streams will cascade
harmlessly. */
if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
return in.read(cbuf, off, len);
}
fill();
}
if (nextChar >= nChars) return -1;
if (skipLF) {
skipLF = false;
if (cb[nextChar] == '\n') {
nextChar++;
if (nextChar >= nChars)
fill();
if (nextChar >= nChars)
return -1;
}
}
int n = Math.min(len, nChars - nextChar);
System.arraycopy(cb, nextChar, cbuf, off, n);
nextChar += n;
return n;
}
/**
* Reads characters into a portion of an array.
*
* <p> This method implements the general contract of the corresponding
* <code>{@link Reader#read(char[], int, int) read}</code> method of the
* <code>{@link Reader}</code> class. As an additional convenience, it
* attempts to read as many characters as possible by repeatedly invoking
* the <code>read</code> method of the underlying stream. This iterated
* <code>read</code> continues until one of the following conditions becomes
* true: <ul>
*
* <li> The specified number of characters have been read,
*
* <li> The <code>read</code> method of the underlying stream returns
* <code>-1</code>, indicating end-of-file, or
*
* <li> The <code>ready</code> method of the underlying stream
* returns <code>false</code>, indicating that further input requests
* would block.
*
* </ul> If the first <code>read</code> on the underlying stream returns
* <code>-1</code> to indicate end-of-file then this method returns
* <code>-1</code>. Otherwise this method returns the number of characters
* actually read.
*
* <p> Subclasses of this class are encouraged, but not required, to
* attempt to read as many characters as possible in the same fashion.
*
* <p> Ordinarily this method takes characters from this stream's character
* buffer, filling it from the underlying stream as necessary. If,
* however, the buffer is empty, the mark is not valid, and the requested
* length is at least as large as the buffer, then this method will read
* characters directly from the underlying stream into the given array.
* Thus redundant <code>BufferedReader</code>s will not copy data
* unnecessarily.
*
* @param cbuf Destination buffer
* @param off Offset at which to start storing characters
* @param len Maximum number of characters to read
*
* @return The number of characters read, or -1 if the end of the
* stream has been reached
*
* @exception IOException If an I/O error occurs
* @exception IndexOutOfBoundsException {@inheritDoc}
*/
public int read(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int n = read1(cbuf, off, len);
if (n <= 0) return n;
while ((n < len) && in.ready()) {
int n1 = read1(cbuf, off + n, len - n);
if (n1 <= 0) break;
n += n1;
}
return n;
}
}
/**
* Reads a line of text. A line is considered to be terminated by any one
* of a line feed ('\n'), a carriage return ('\r'), a carriage return
* followed immediately by a line feed, or by reaching the end-of-file
* (EOF).
*
* @param ignoreLF If true, the next '\n' will be skipped
*
* @return A String containing the contents of the line, not including
* any line-termination characters, or null if the end of the
* stream has been reached without reading any characters
*
* @see java.io.LineNumberReader#readLine()
*
* @exception IOException If an I/O error occurs
*/
String readLine(boolean ignoreLF) throws IOException {
StringBuffer s = null;
int startChar;
synchronized (lock) {
ensureOpen();
boolean omitLF = ignoreLF || skipLF;
bufferLoop:
for (;;) {
if (nextChar >= nChars)
fill();
if (nextChar >= nChars) { /* EOF */
if (s != null && s.length() > 0)
return s.toString();
else
return null;
}
boolean eol = false;
char c = 0;
int i;
/* Skip a leftover '\n', if necessary */
if (omitLF && (cb[nextChar] == '\n'))
nextChar++;
skipLF = false;
omitLF = false;
charLoop:
for (i = nextChar; i < nChars; i++) {
c = cb[i];
if ((c == '\n') || (c == '\r')) {
eol = true;
break charLoop;
}
}
startChar = nextChar;
nextChar = i;
if (eol) {
String str;
if (s == null) {
str = new String(cb, startChar, i - startChar);
} else {
s.append(cb, startChar, i - startChar);
str = s.toString();
}
nextChar++;
if (c == '\r') {
skipLF = true;
}
return str;
}
if (s == null)
s = new StringBuffer(defaultExpectedLineLength);
s.append(cb, startChar, i - startChar);
}
}
}
/**
* Reads a line of text. A line is considered to be terminated by any one
* of a line feed ('\n'), a carriage return ('\r'), a carriage return
* followed immediately by a line feed, or by reaching the end-of-file
* (EOF).
*
* @return A String containing the contents of the line, not including
* any line-termination characters, or null if the end of the
* stream has been reached without reading any characters
*
* @exception IOException If an I/O error occurs
*
* @see java.nio.file.Files#readAllLines
*/
public String readLine() throws IOException {
return readLine(false);
}
/**
* Skips characters.
*
* @param n The number of characters to skip
*
* @return The number of characters actually skipped
*
* @exception IllegalArgumentException If <code>n</code> is negative.
* @exception IOException If an I/O error occurs
*/
public long skip(long n) throws IOException {
if (n < 0L) {
throw new IllegalArgumentException("skip value is negative");
}
synchronized (lock) {
ensureOpen();
long r = n;
while (r > 0) {
if (nextChar >= nChars)
fill();
if (nextChar >= nChars) /* EOF */
break;
if (skipLF) {
skipLF = false;
if (cb[nextChar] == '\n') {
nextChar++;
}
}
long d = nChars - nextChar;
if (r <= d) {
nextChar += r;
r = 0;
break;
}
else {
r -= d;
nextChar = nChars;
}
}
return n - r;
}
}
/**
* Tells whether this stream is ready to be read. A buffered character
* stream is ready if the buffer is not empty, or if the underlying
* character stream is ready.
*
* @exception IOException If an I/O error occurs
*/
public boolean ready() throws IOException {
synchronized (lock) {
ensureOpen();
/*
* If newline needs to be skipped and the next char to be read
* is a newline character, then just skip it right away.
*/
if (skipLF) {
/* Note that in.ready() will return true if and only if the next
* read on the stream will not block.
*/
if (nextChar >= nChars && in.ready()) {
fill();
}
if (nextChar < nChars) {
if (cb[nextChar] == '\n')
nextChar++;
skipLF = false;
}
}
return (nextChar < nChars) || in.ready();
}
}
/**
* Tells whether this stream supports the mark() operation, which it does.
*/
public boolean markSupported() {
return true;
}
/**
* Marks the present position in the stream. Subsequent calls to reset()
* will attempt to reposition the stream to this point.
*
* @param readAheadLimit Limit on the number of characters that may be
* read while still preserving the mark. An attempt
* to reset the stream after reading characters
* up to this limit or beyond may fail.
* A limit value larger than the size of the input
* buffer will cause a new buffer to be allocated
* whose size is no smaller than limit.
* Therefore large values should be used with care.
*
* @exception IllegalArgumentException If {@code readAheadLimit < 0}
* @exception IOException If an I/O error occurs
*/
public void mark(int readAheadLimit) throws IOException {
if (readAheadLimit < 0) {
throw new IllegalArgumentException("Read-ahead limit < 0");
}
synchronized (lock) {
ensureOpen();
this.readAheadLimit = readAheadLimit;
markedChar = nextChar;
markedSkipLF = skipLF;
}
}
/**
* Resets the stream to the most recent mark.
*
* @exception IOException If the stream has never been marked,
* or if the mark has been invalidated
*/
public void reset() throws IOException {
synchronized (lock) {
ensureOpen();
if (markedChar < 0)
throw new IOException((markedChar == INVALIDATED)
? "Mark invalid"
: "Stream not marked");
nextChar = markedChar;
skipLF = markedSkipLF;
}
}
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
try {
in.close();
} finally {
in = null;
cb = null;
}
}
}
/**
* Returns a {@code Stream}, the elements of which are lines read from
* this {@code BufferedReader}. The {@link Stream} is lazily populated,
* i.e., read only occurs during the
* <a href="../util/stream/package-summary.html#StreamOps">terminal
* stream operation</a>.
*
* <p> The reader must not be operated on during the execution of the
* terminal stream operation. Otherwise, the result of the terminal stream
* operation is undefined.
*
* <p> After execution of the terminal stream operation there are no
* guarantees that the reader will be at a specific position from which to
* read the next character or line.
*
* <p> If an {@link IOException} is thrown when accessing the underlying
* {@code BufferedReader}, it is wrapped in an {@link
* UncheckedIOException} which will be thrown from the {@code Stream}
* method that caused the read to take place. This method will return a
* Stream if invoked on a BufferedReader that is closed. Any operation on
* that stream that requires reading from the BufferedReader after it is
* closed, will cause an UncheckedIOException to be thrown.
*
* @return a {@code Stream<String>} providing the lines of text
* described by this {@code BufferedReader}
*
* @since 1.8
*/
public Stream<String> lines() {
Iterator<String> iter = new Iterator<>() {
String nextLine = null;
@Override
public boolean hasNext() {
if (nextLine != null) {
return true;
} else {
try {
nextLine = readLine();
return (nextLine != null);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
@Override
public String next() {
if (nextLine != null || hasNext()) {
String line = nextLine;
nextLine = null;
return line;
} else {
throw new NoSuchElementException();
}
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iter, Spliterator.ORDERED | Spliterator.NONNULL), false);
}
}

View file

@ -0,0 +1,275 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Writes text to a character-output stream, buffering characters so as to
* provide for the efficient writing of single characters, arrays, and strings.
*
* <p> The buffer size may be specified, or the default size may be accepted.
* The default is large enough for most purposes.
*
* <p> A newLine() method is provided, which uses the platform's own notion of
* line separator as defined by the system property {@code line.separator}.
* Not all platforms use the newline character ('\n') to terminate lines.
* Calling this method to terminate each output line is therefore preferred to
* writing a newline character directly.
*
* <p> In general, a Writer sends its output immediately to the underlying
* character or byte stream. Unless prompt output is required, it is advisable
* to wrap a BufferedWriter around any Writer whose write() operations may be
* costly, such as FileWriters and OutputStreamWriters. For example,
*
* <pre>
* PrintWriter out
* = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
* </pre>
*
* will buffer the PrintWriter's output to the file. Without buffering, each
* invocation of a print() method would cause characters to be converted into
* bytes that would then be written immediately to the file, which can be very
* inefficient.
*
* @see PrintWriter
* @see FileWriter
* @see OutputStreamWriter
* @see java.nio.file.Files#newBufferedWriter
*
* @author Mark Reinhold
* @since 1.1
*/
public class BufferedWriter extends Writer {
private Writer out;
private char cb[];
private int nChars, nextChar;
private static int defaultCharBufferSize = 8192;
/**
* Creates a buffered character-output stream that uses a default-sized
* output buffer.
*
* @param out A Writer
*/
public BufferedWriter(Writer out) {
this(out, defaultCharBufferSize);
}
/**
* Creates a new buffered character-output stream that uses an output
* buffer of the given size.
*
* @param out A Writer
* @param sz Output-buffer size, a positive integer
*
* @exception IllegalArgumentException If {@code sz <= 0}
*/
public BufferedWriter(Writer out, int sz) {
super(out);
if (sz <= 0)
throw new IllegalArgumentException("Buffer size <= 0");
this.out = out;
cb = new char[sz];
nChars = sz;
nextChar = 0;
}
/** Checks to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
if (out == null)
throw new IOException("Stream closed");
}
/**
* Flushes the output buffer to the underlying character stream, without
* flushing the stream itself. This method is non-private only so that it
* may be invoked by PrintStream.
*/
void flushBuffer() throws IOException {
synchronized (lock) {
ensureOpen();
if (nextChar == 0)
return;
out.write(cb, 0, nextChar);
nextChar = 0;
}
}
/**
* Writes a single character.
*
* @exception IOException If an I/O error occurs
*/
public void write(int c) throws IOException {
synchronized (lock) {
ensureOpen();
if (nextChar >= nChars)
flushBuffer();
cb[nextChar++] = (char) c;
}
}
/**
* Our own little min method, to avoid loading java.lang.Math if we've run
* out of file descriptors and we're trying to print a stack trace.
*/
private int min(int a, int b) {
if (a < b) return a;
return b;
}
/**
* Writes a portion of an array of characters.
*
* <p> Ordinarily this method stores characters from the given array into
* this stream's buffer, flushing the buffer to the underlying stream as
* needed. If the requested length is at least as large as the buffer,
* however, then this method will flush the buffer and write the characters
* directly to the underlying stream. Thus redundant
* {@code BufferedWriter}s will not copy data unnecessarily.
*
* @param cbuf A character array
* @param off Offset from which to start reading characters
* @param len Number of characters to write
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given array
*
* @throws IOException If an I/O error occurs
*/
public void write(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
if (len >= nChars) {
/* If the request length exceeds the size of the output buffer,
flush the buffer and then write the data directly. In this
way buffered streams will cascade harmlessly. */
flushBuffer();
out.write(cbuf, off, len);
return;
}
int b = off, t = off + len;
while (b < t) {
int d = min(nChars - nextChar, t - b);
System.arraycopy(cbuf, b, cb, nextChar, d);
b += d;
nextChar += d;
if (nextChar >= nChars)
flushBuffer();
}
}
}
/**
* Writes a portion of a String.
*
* @implSpec
* While the specification of this method in the
* {@linkplain java.io.Writer#write(java.lang.String,int,int) superclass}
* recommends that an {@link IndexOutOfBoundsException} be thrown
* if {@code len} is negative or {@code off + len} is negative,
* the implementation in this class does not throw such an exception in
* these cases but instead simply writes no characters.
*
* @param s String to be written
* @param off Offset from which to start reading characters
* @param len Number of characters to be written
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative,
* or {@code off + len} is greater than the length
* of the given string
*
* @throws IOException If an I/O error occurs
*/
public void write(String s, int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
int b = off, t = off + len;
while (b < t) {
int d = min(nChars - nextChar, t - b);
s.getChars(b, b + d, cb, nextChar);
b += d;
nextChar += d;
if (nextChar >= nChars)
flushBuffer();
}
}
}
/**
* Writes a line separator. The line separator string is defined by the
* system property {@code line.separator}, and is not necessarily a single
* newline ('\n') character.
*
* @exception IOException If an I/O error occurs
*/
public void newLine() throws IOException {
write(System.lineSeparator());
}
/**
* Flushes the stream.
*
* @exception IOException If an I/O error occurs
*/
public void flush() throws IOException {
synchronized (lock) {
flushBuffer();
out.flush();
}
}
@SuppressWarnings("try")
public void close() throws IOException {
synchronized (lock) {
if (out == null) {
return;
}
try (Writer w = out) {
flushBuffer();
} finally {
out = null;
cb = null;
}
}
}
}

View file

@ -0,0 +1,282 @@
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A <code>ByteArrayInputStream</code> contains
* an internal buffer that contains bytes that
* may be read from the stream. An internal
* counter keeps track of the next byte to
* be supplied by the <code>read</code> method.
* <p>
* Closing a {@code ByteArrayInputStream} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@code IOException}.
*
* @author Arthur van Hoff
* @see java.io.StringBufferInputStream
* @since 1.0
*/
public
class ByteArrayInputStream extends InputStream {
/**
* An array of bytes that was provided
* by the creator of the stream. Elements <code>buf[0]</code>
* through <code>buf[count-1]</code> are the
* only bytes that can ever be read from the
* stream; element <code>buf[pos]</code> is
* the next byte to be read.
*/
protected byte buf[];
/**
* The index of the next character to read from the input stream buffer.
* This value should always be nonnegative
* and not larger than the value of <code>count</code>.
* The next byte to be read from the input stream buffer
* will be <code>buf[pos]</code>.
*/
protected int pos;
/**
* The currently marked position in the stream.
* ByteArrayInputStream objects are marked at position zero by
* default when constructed. They may be marked at another
* position within the buffer by the <code>mark()</code> method.
* The current buffer position is set to this point by the
* <code>reset()</code> method.
* <p>
* If no mark has been set, then the value of mark is the offset
* passed to the constructor (or 0 if the offset was not supplied).
*
* @since 1.1
*/
protected int mark = 0;
/**
* The index one greater than the last valid character in the input
* stream buffer.
* This value should always be nonnegative
* and not larger than the length of <code>buf</code>.
* It is one greater than the position of
* the last byte within <code>buf</code> that
* can ever be read from the input stream buffer.
*/
protected int count;
/**
* Creates a <code>ByteArrayInputStream</code>
* so that it uses <code>buf</code> as its
* buffer array.
* The buffer array is not copied.
* The initial value of <code>pos</code>
* is <code>0</code> and the initial value
* of <code>count</code> is the length of
* <code>buf</code>.
*
* @param buf the input buffer.
*/
public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
/**
* Creates <code>ByteArrayInputStream</code>
* that uses <code>buf</code> as its
* buffer array. The initial value of <code>pos</code>
* is <code>offset</code> and the initial value
* of <code>count</code> is the minimum of <code>offset+length</code>
* and <code>buf.length</code>.
* The buffer array is not copied. The buffer's mark is
* set to the specified offset.
*
* @param buf the input buffer.
* @param offset the offset in the buffer of the first byte to read.
* @param length the maximum number of bytes to read from the buffer.
*/
public ByteArrayInputStream(byte buf[], int offset, int length) {
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.mark = offset;
}
/**
* Reads the next byte of data from this input stream. The value
* byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>. If no byte is available
* because the end of the stream has been reached, the value
* <code>-1</code> is returned.
* <p>
* This <code>read</code> method
* cannot block.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream has been reached.
*/
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
/**
* Reads up to <code>len</code> bytes of data into an array of bytes
* from this input stream.
* If <code>pos</code> equals <code>count</code>,
* then <code>-1</code> is returned to indicate
* end of file. Otherwise, the number <code>k</code>
* of bytes read is equal to the smaller of
* <code>len</code> and <code>count-pos</code>.
* If <code>k</code> is positive, then bytes
* <code>buf[pos]</code> through <code>buf[pos+k-1]</code>
* are copied into <code>b[off]</code> through
* <code>b[off+k-1]</code> in the manner performed
* by <code>System.arraycopy</code>. The
* value <code>k</code> is added into <code>pos</code>
* and <code>k</code> is returned.
* <p>
* This <code>read</code> method cannot block.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
*/
public synchronized int read(byte b[], int off, int len) {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
}
if (pos >= count) {
return -1;
}
int avail = count - pos;
if (len > avail) {
len = avail;
}
if (len <= 0) {
return 0;
}
System.arraycopy(buf, pos, b, off, len);
pos += len;
return len;
}
/**
* Skips <code>n</code> bytes of input from this input stream. Fewer
* bytes might be skipped if the end of the input stream is reached.
* The actual number <code>k</code>
* of bytes to be skipped is equal to the smaller
* of <code>n</code> and <code>count-pos</code>.
* The value <code>k</code> is added into <code>pos</code>
* and <code>k</code> is returned.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
*/
public synchronized long skip(long n) {
long k = count - pos;
if (n < k) {
k = n < 0 ? 0 : n;
}
pos += k;
return k;
}
/**
* Returns the number of remaining bytes that can be read (or skipped over)
* from this input stream.
* <p>
* The value returned is <code>count&nbsp;- pos</code>,
* which is the number of bytes remaining to be read from the input buffer.
*
* @return the number of remaining bytes that can be read (or skipped
* over) from this input stream without blocking.
*/
public synchronized int available() {
return count - pos;
}
/**
* Tests if this <code>InputStream</code> supports mark/reset. The
* <code>markSupported</code> method of <code>ByteArrayInputStream</code>
* always returns <code>true</code>.
*
* @since 1.1
*/
public boolean markSupported() {
return true;
}
/**
* Set the current marked position in the stream.
* ByteArrayInputStream objects are marked at position zero by
* default when constructed. They may be marked at another
* position within the buffer by this method.
* <p>
* If no mark has been set, then the value of the mark is the
* offset passed to the constructor (or 0 if the offset was not
* supplied).
*
* <p> Note: The <code>readAheadLimit</code> for this class
* has no meaning.
*
* @since 1.1
*/
public void mark(int readAheadLimit) {
mark = pos;
}
/**
* Resets the buffer to the marked position. The marked position
* is 0 unless another position was marked or an offset was specified
* in the constructor.
*/
public synchronized void reset() {
pos = mark;
}
/**
* Closing a {@code ByteArrayInputStream} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@code IOException}.
*/
public void close() throws IOException {
}
}

View file

@ -0,0 +1,283 @@
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.Arrays;
/**
* This class implements an output stream in which the data is
* written into a byte array. The buffer automatically grows as data
* is written to it.
* The data can be retrieved using {@code toByteArray()} and
* {@code toString()}.
* <p>
* Closing a {@code ByteArrayOutputStream} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@code IOException}.
*
* @author Arthur van Hoff
* @since 1.0
*/
public class ByteArrayOutputStream extends OutputStream {
/**
* The buffer where data is stored.
*/
protected byte buf[];
/**
* The number of valid bytes in the buffer.
*/
protected int count;
/**
* Creates a new byte array output stream. The buffer capacity is
* initially 32 bytes, though its size increases if necessary.
*/
public ByteArrayOutputStream() {
this(32);
}
/**
* Creates a new byte array output stream, with a buffer capacity of
* the specified size, in bytes.
*
* @param size the initial size.
* @exception IllegalArgumentException if size is negative.
*/
public ByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
}
/**
* Increases the capacity if necessary to ensure that it can hold
* at least the number of elements specified by the minimum
* capacity argument.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if {@code minCapacity < 0}. This is
* interpreted as a request for the unsatisfiably large capacity
* {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
*/
private void ensureCapacity(int minCapacity) {
// overflow-conscious code
if (minCapacity - buf.length > 0)
grow(minCapacity);
}
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = buf.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
buf = Arrays.copyOf(buf, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/**
* Writes the specified byte to this byte array output stream.
*
* @param b the byte to be written.
*/
public synchronized void write(int b) {
ensureCapacity(count + 1);
buf[count] = (byte) b;
count += 1;
}
/**
* Writes {@code len} bytes from the specified byte array
* starting at offset {@code off} to this byte array output stream.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
*/
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
}
ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
count += len;
}
/**
* Writes the complete contents of this byte array output stream to
* the specified output stream argument, as if by calling the output
* stream's write method using {@code out.write(buf, 0, count)}.
*
* @param out the output stream to which to write the data.
* @exception IOException if an I/O error occurs.
*/
public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
}
/**
* Resets the {@code count} field of this byte array output
* stream to zero, so that all currently accumulated output in the
* output stream is discarded. The output stream can be used again,
* reusing the already allocated buffer space.
*
* @see java.io.ByteArrayInputStream#count
*/
public synchronized void reset() {
count = 0;
}
/**
* Creates a newly allocated byte array. Its size is the current
* size of this output stream and the valid contents of the buffer
* have been copied into it.
*
* @return the current contents of this output stream, as a byte array.
* @see java.io.ByteArrayOutputStream#size()
*/
public synchronized byte[] toByteArray() {
return Arrays.copyOf(buf, count);
}
/**
* Returns the current size of the buffer.
*
* @return the value of the {@code count} field, which is the number
* of valid bytes in this output stream.
* @see java.io.ByteArrayOutputStream#count
*/
public synchronized int size() {
return count;
}
/**
* Converts the buffer's contents into a string decoding bytes using the
* platform's default character set. The length of the new {@code String}
* is a function of the character set, and hence may not be equal to the
* size of the buffer.
*
* <p> This method always replaces malformed-input and unmappable-character
* sequences with the default replacement string for the platform's
* default character set. The {@linkplain java.nio.charset.CharsetDecoder}
* class should be used when more control over the decoding process is
* required.
*
* @return String decoded from the buffer's contents.
* @since 1.1
*/
public synchronized String toString() {
return new String(buf, 0, count);
}
/**
* Converts the buffer's contents into a string by decoding the bytes using
* the named {@link java.nio.charset.Charset charset}. The length of the new
* {@code String} is a function of the charset, and hence may not be equal
* to the length of the byte array.
*
* <p> This method always replaces malformed-input and unmappable-character
* sequences with this charset's default replacement string. The {@link
* java.nio.charset.CharsetDecoder} class should be used when more control
* over the decoding process is required.
*
* @param charsetName the name of a supported
* {@link java.nio.charset.Charset charset}
* @return String decoded from the buffer's contents.
* @exception UnsupportedEncodingException
* If the named charset is not supported
* @since 1.1
*/
public synchronized String toString(String charsetName)
throws UnsupportedEncodingException
{
return new String(buf, 0, count, charsetName);
}
/**
* Creates a newly allocated string. Its size is the current size of
* the output stream and the valid contents of the buffer have been
* copied into it. Each character <i>c</i> in the resulting string is
* constructed from the corresponding element <i>b</i> in the byte
* array such that:
* <blockquote><pre>{@code
* c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))
* }</pre></blockquote>
*
* @deprecated This method does not properly convert bytes into characters.
* As of JDK&nbsp;1.1, the preferred way to do this is via the
* {@code toString(String enc)} method, which takes an encoding-name
* argument, or the {@code toString()} method, which uses the
* platform's default character encoding.
*
* @param hibyte the high byte of each resulting Unicode character.
* @return the current contents of the output stream, as a string.
* @see java.io.ByteArrayOutputStream#size()
* @see java.io.ByteArrayOutputStream#toString(String)
* @see java.io.ByteArrayOutputStream#toString()
*/
@Deprecated
public synchronized String toString(int hibyte) {
return new String(buf, hibyte, 0, count);
}
/**
* Closing a {@code ByteArrayOutputStream} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@code IOException}.
*/
public void close() throws IOException {
}
}

View file

@ -0,0 +1,240 @@
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* This class implements a character buffer that can be used as a
* character-input stream.
*
* @author Herb Jellinek
* @since 1.1
*/
public class CharArrayReader extends Reader {
/** The character buffer. */
protected char buf[];
/** The current buffer position. */
protected int pos;
/** The position of mark in buffer. */
protected int markedPos = 0;
/**
* The index of the end of this buffer. There is not valid
* data at or beyond this index.
*/
protected int count;
/**
* Creates a CharArrayReader from the specified array of chars.
* @param buf Input buffer (not copied)
*/
public CharArrayReader(char buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
/**
* Creates a CharArrayReader from the specified array of chars.
*
* <p> The resulting reader will start reading at the given
* {@code offset}. The total number of {@code char} values that can be
* read from this reader will be either {@code length} or
* {@code buf.length-offset}, whichever is smaller.
*
* @throws IllegalArgumentException
* If {@code offset} is negative or greater than
* {@code buf.length}, or if {@code length} is negative, or if
* the sum of these two values is negative.
*
* @param buf Input buffer (not copied)
* @param offset Offset of the first char to read
* @param length Number of chars to read
*/
public CharArrayReader(char buf[], int offset, int length) {
if ((offset < 0) || (offset > buf.length) || (length < 0) ||
((offset + length) < 0)) {
throw new IllegalArgumentException();
}
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.markedPos = offset;
}
/** Checks to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
if (buf == null)
throw new IOException("Stream closed");
}
/**
* Reads a single character.
*
* @exception IOException If an I/O error occurs
*/
public int read() throws IOException {
synchronized (lock) {
ensureOpen();
if (pos >= count)
return -1;
else
return buf[pos++];
}
}
/**
* Reads characters into a portion of an array.
* @param b Destination buffer
* @param off Offset at which to start storing characters
* @param len Maximum number of characters to read
* @return The actual number of characters read, or -1 if
* the end of the stream has been reached
*
* @exception IOException If an I/O error occurs
* @exception IndexOutOfBoundsException {@inheritDoc}
*/
public int read(char b[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
if (pos >= count) {
return -1;
}
int avail = count - pos;
if (len > avail) {
len = avail;
}
if (len <= 0) {
return 0;
}
System.arraycopy(buf, pos, b, off, len);
pos += len;
return len;
}
}
/**
* Skips characters. Returns the number of characters that were skipped.
*
* <p>The <code>n</code> parameter may be negative, even though the
* <code>skip</code> method of the {@link Reader} superclass throws
* an exception in this case. If <code>n</code> is negative, then
* this method does nothing and returns <code>0</code>.
*
* @param n The number of characters to skip
* @return The number of characters actually skipped
* @exception IOException If the stream is closed, or an I/O error occurs
*/
public long skip(long n) throws IOException {
synchronized (lock) {
ensureOpen();
long avail = count - pos;
if (n > avail) {
n = avail;
}
if (n < 0) {
return 0;
}
pos += n;
return n;
}
}
/**
* Tells whether this stream is ready to be read. Character-array readers
* are always ready to be read.
*
* @exception IOException If an I/O error occurs
*/
public boolean ready() throws IOException {
synchronized (lock) {
ensureOpen();
return (count - pos) > 0;
}
}
/**
* Tells whether this stream supports the mark() operation, which it does.
*/
public boolean markSupported() {
return true;
}
/**
* Marks the present position in the stream. Subsequent calls to reset()
* will reposition the stream to this point.
*
* @param readAheadLimit Limit on the number of characters that may be
* read while still preserving the mark. Because
* the stream's input comes from a character array,
* there is no actual limit; hence this argument is
* ignored.
*
* @exception IOException If an I/O error occurs
*/
public void mark(int readAheadLimit) throws IOException {
synchronized (lock) {
ensureOpen();
markedPos = pos;
}
}
/**
* Resets the stream to the most recent mark, or to the beginning if it has
* never been marked.
*
* @exception IOException If an I/O error occurs
*/
public void reset() throws IOException {
synchronized (lock) {
ensureOpen();
pos = markedPos;
}
}
/**
* Closes the stream and releases any system resources associated with
* it. Once the stream has been closed, further read(), ready(),
* mark(), reset(), or skip() invocations will throw an IOException.
* Closing a previously closed stream has no effect. This method will block
* while there is another thread blocking on the reader.
*/
public void close() {
synchronized (lock) {
buf = null;
}
}
}

View file

@ -0,0 +1,290 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.Arrays;
/**
* This class implements a character buffer that can be used as an Writer.
* The buffer automatically grows when data is written to the stream. The data
* can be retrieved using toCharArray() and toString().
* <P>
* Note: Invoking close() on this class has no effect, and methods
* of this class can be called after the stream has closed
* without generating an IOException.
*
* @author Herb Jellinek
* @since 1.1
*/
public
class CharArrayWriter extends Writer {
/**
* The buffer where data is stored.
*/
protected char buf[];
/**
* The number of chars in the buffer.
*/
protected int count;
/**
* Creates a new CharArrayWriter.
*/
public CharArrayWriter() {
this(32);
}
/**
* Creates a new CharArrayWriter with the specified initial size.
*
* @param initialSize an int specifying the initial buffer size.
* @exception IllegalArgumentException if initialSize is negative
*/
public CharArrayWriter(int initialSize) {
if (initialSize < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ initialSize);
}
buf = new char[initialSize];
}
/**
* Writes a character to the buffer.
*/
public void write(int c) {
synchronized (lock) {
int newcount = count + 1;
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
buf[count] = (char)c;
count = newcount;
}
}
/**
* Writes characters to the buffer.
* @param c the data to be written
* @param off the start offset in the data
* @param len the number of chars that are written
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given array
*/
public void write(char c[], int off, int len) {
if ((off < 0) || (off > c.length) || (len < 0) ||
((off + len) > c.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
synchronized (lock) {
int newcount = count + len;
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
System.arraycopy(c, off, buf, count, len);
count = newcount;
}
}
/**
* Write a portion of a string to the buffer.
* @param str String to be written from
* @param off Offset from which to start reading characters
* @param len Number of characters to be written
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given string
*/
public void write(String str, int off, int len) {
synchronized (lock) {
int newcount = count + len;
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
str.getChars(off, off + len, buf, count);
count = newcount;
}
}
/**
* Writes the contents of the buffer to another character stream.
*
* @param out the output stream to write to
* @throws IOException If an I/O error occurs.
*/
public void writeTo(Writer out) throws IOException {
synchronized (lock) {
out.write(buf, 0, count);
}
}
/**
* Appends the specified character sequence to this writer.
*
* <p> An invocation of this method of the form {@code out.append(csq)}
* behaves in exactly the same way as the invocation
*
* <pre>
* out.write(csq.toString()) </pre>
*
* <p> Depending on the specification of {@code toString} for the
* character sequence {@code csq}, the entire sequence may not be
* appended. For instance, invoking the {@code toString} method of a
* character buffer will return a subsequence whose content depends upon
* the buffer's position and limit.
*
* @param csq
* The character sequence to append. If {@code csq} is
* {@code null}, then the four characters {@code "null"} are
* appended to this writer.
*
* @return This writer
*
* @since 1.5
*/
public CharArrayWriter append(CharSequence csq) {
String s = String.valueOf(csq);
write(s, 0, s.length());
return this;
}
/**
* Appends a subsequence of the specified character sequence to this writer.
*
* <p> An invocation of this method of the form
* {@code out.append(csq, start, end)} when
* {@code csq} is not {@code null}, behaves in
* exactly the same way as the invocation
*
* <pre>
* out.write(csq.subSequence(start, end).toString()) </pre>
*
* @param csq
* The character sequence from which a subsequence will be
* appended. If {@code csq} is {@code null}, then characters
* will be appended as if {@code csq} contained the four
* characters {@code "null"}.
*
* @param start
* The index of the first character in the subsequence
*
* @param end
* The index of the character following the last character in the
* subsequence
*
* @return This writer
*
* @throws IndexOutOfBoundsException
* If {@code start} or {@code end} are negative, {@code start}
* is greater than {@code end}, or {@code end} is greater than
* {@code csq.length()}
*
* @since 1.5
*/
public CharArrayWriter append(CharSequence csq, int start, int end) {
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
/**
* Appends the specified character to this writer.
*
* <p> An invocation of this method of the form {@code out.append(c)}
* behaves in exactly the same way as the invocation
*
* <pre>
* out.write(c) </pre>
*
* @param c
* The 16-bit character to append
*
* @return This writer
*
* @since 1.5
*/
public CharArrayWriter append(char c) {
write(c);
return this;
}
/**
* Resets the buffer so that you can use it again without
* throwing away the already allocated buffer.
*/
public void reset() {
count = 0;
}
/**
* Returns a copy of the input data.
*
* @return an array of chars copied from the input data.
*/
public char[] toCharArray() {
synchronized (lock) {
return Arrays.copyOf(buf, count);
}
}
/**
* Returns the current size of the buffer.
*
* @return an int representing the current size of the buffer.
*/
public int size() {
return count;
}
/**
* Converts input data to a string.
* @return the string.
*/
public String toString() {
synchronized (lock) {
return new String(buf, 0, count);
}
}
/**
* Flush the stream.
*/
public void flush() { }
/**
* Close the stream. This method does not release the buffer, since its
* contents might still be required. Note: Invoking this method in this class
* will have no effect.
*/
public void close() { }
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Base class for character conversion exceptions.
*
* @author Asmus Freytag
* @since 1.1
*/
public class CharConversionException
extends java.io.IOException
{
private static final long serialVersionUID = -8680016352018427031L;
/**
* This provides no detailed message.
*/
public CharConversionException() {
}
/**
* This provides a detailed message.
*
* @param s the detailed message associated with the exception.
*/
public CharConversionException(String s) {
super(s);
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.io.IOException;
/**
* A {@code Closeable} is a source or destination of data that can be closed.
* The close method is invoked to release resources that the object is
* holding (such as open files).
*
* @since 1.5
*/
public interface Closeable extends AutoCloseable {
/**
* Closes this stream and releases any system resources associated
* with it. If the stream is already closed then invoking this
* method has no effect.
*
* <p> As noted in {@link AutoCloseable#close()}, cases where the
* close may fail require careful attention. It is strongly advised
* to relinquish the underlying resources and to internally
* <em>mark</em> the {@code Closeable} as closed, prior to throwing
* the {@code IOException}.
*
* @throws IOException if an I/O error occurs
*/
public void close() throws IOException;
}

View file

@ -0,0 +1,583 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.*;
import java.nio.charset.Charset;
import jdk.internal.misc.JavaIOAccess;
import jdk.internal.misc.SharedSecrets;
import sun.nio.cs.StreamDecoder;
import sun.nio.cs.StreamEncoder;
/**
* Methods to access the character-based console device, if any, associated
* with the current Java virtual machine.
*
* <p> Whether a virtual machine has a console is dependent upon the
* underlying platform and also upon the manner in which the virtual
* machine is invoked. If the virtual machine is started from an
* interactive command line without redirecting the standard input and
* output streams then its console will exist and will typically be
* connected to the keyboard and display from which the virtual machine
* was launched. If the virtual machine is started automatically, for
* example by a background job scheduler, then it will typically not
* have a console.
* <p>
* If this virtual machine has a console then it is represented by a
* unique instance of this class which can be obtained by invoking the
* {@link java.lang.System#console()} method. If no console device is
* available then an invocation of that method will return {@code null}.
* <p>
* Read and write operations are synchronized to guarantee the atomic
* completion of critical operations; therefore invoking methods
* {@link #readLine()}, {@link #readPassword()}, {@link #format format()},
* {@link #printf printf()} as well as the read, format and write operations
* on the objects returned by {@link #reader()} and {@link #writer()} may
* block in multithreaded scenarios.
* <p>
* Invoking {@code close()} on the objects returned by the {@link #reader()}
* and the {@link #writer()} will not close the underlying stream of those
* objects.
* <p>
* The console-read methods return {@code null} when the end of the
* console input stream is reached, for example by typing control-D on
* Unix or control-Z on Windows. Subsequent read operations will succeed
* if additional characters are later entered on the console's input
* device.
* <p>
* Unless otherwise specified, passing a {@code null} argument to any method
* in this class will cause a {@link NullPointerException} to be thrown.
* <p>
* <b>Security note:</b>
* If an application needs to read a password or other secure data, it should
* use {@link #readPassword()} or {@link #readPassword(String, Object...)} and
* manually zero the returned character array after processing to minimize the
* lifetime of sensitive data in memory.
*
* <blockquote><pre>{@code
* Console cons;
* char[] passwd;
* if ((cons = System.console()) != null &&
* (passwd = cons.readPassword("[%s]", "Password:")) != null) {
* ...
* java.util.Arrays.fill(passwd, ' ');
* }
* }</pre></blockquote>
*
* @author Xueming Shen
* @since 1.6
*/
public final class Console implements Flushable
{
/**
* Retrieves the unique {@link java.io.PrintWriter PrintWriter} object
* associated with this console.
*
* @return The printwriter associated with this console
*/
public PrintWriter writer() {
return pw;
}
/**
* Retrieves the unique {@link java.io.Reader Reader} object associated
* with this console.
* <p>
* This method is intended to be used by sophisticated applications, for
* example, a {@link java.util.Scanner} object which utilizes the rich
* parsing/scanning functionality provided by the {@code Scanner}:
* <blockquote><pre>
* Console con = System.console();
* if (con != null) {
* Scanner sc = new Scanner(con.reader());
* ...
* }
* </pre></blockquote>
* <p>
* For simple applications requiring only line-oriented reading, use
* {@link #readLine}.
* <p>
* The bulk read operations {@link java.io.Reader#read(char[]) read(char[]) },
* {@link java.io.Reader#read(char[], int, int) read(char[], int, int) } and
* {@link java.io.Reader#read(java.nio.CharBuffer) read(java.nio.CharBuffer)}
* on the returned object will not read in characters beyond the line
* bound for each invocation, even if the destination buffer has space for
* more characters. The {@code Reader}'s {@code read} methods may block if a
* line bound has not been entered or reached on the console's input device.
* A line bound is considered to be any one of a line feed ({@code '\n'}),
* a carriage return ({@code '\r'}), a carriage return followed immediately
* by a linefeed, or an end of stream.
*
* @return The reader associated with this console
*/
public Reader reader() {
return reader;
}
/**
* Writes a formatted string to this console's output stream using
* the specified format string and arguments.
*
* @param fmt
* A format string as described in <a
* href="../util/Formatter.html#syntax">Format string syntax</a>
*
* @param args
* Arguments referenced by the format specifiers in the format
* string. If there are more arguments than format specifiers, the
* extra arguments are ignored. The number of arguments is
* variable and may be zero. The maximum number of arguments is
* limited by the maximum dimension of a Java array as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>.
* The behaviour on a
* {@code null} argument depends on the <a
* href="../util/Formatter.html#syntax">conversion</a>.
*
* @throws IllegalFormatException
* If a format string contains an illegal syntax, a format
* specifier that is incompatible with the given arguments,
* insufficient arguments given the format string, or other
* illegal conditions. For specification of all possible
* formatting errors, see the <a
* href="../util/Formatter.html#detail">Details</a> section
* of the formatter class specification.
*
* @return This console
*/
public Console format(String fmt, Object ...args) {
formatter.format(fmt, args).flush();
return this;
}
/**
* A convenience method to write a formatted string to this console's
* output stream using the specified format string and arguments.
*
* <p> An invocation of this method of the form
* {@code con.printf(format, args)} behaves in exactly the same way
* as the invocation of
* <pre>con.format(format, args)</pre>.
*
* @param format
* A format string as described in <a
* href="../util/Formatter.html#syntax">Format string syntax</a>.
*
* @param args
* Arguments referenced by the format specifiers in the format
* string. If there are more arguments than format specifiers, the
* extra arguments are ignored. The number of arguments is
* variable and may be zero. The maximum number of arguments is
* limited by the maximum dimension of a Java array as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>.
* The behaviour on a
* {@code null} argument depends on the <a
* href="../util/Formatter.html#syntax">conversion</a>.
*
* @throws IllegalFormatException
* If a format string contains an illegal syntax, a format
* specifier that is incompatible with the given arguments,
* insufficient arguments given the format string, or other
* illegal conditions. For specification of all possible
* formatting errors, see the <a
* href="../util/Formatter.html#detail">Details</a> section of the
* formatter class specification.
*
* @return This console
*/
public Console printf(String format, Object ... args) {
return format(format, args);
}
/**
* Provides a formatted prompt, then reads a single line of text from the
* console.
*
* @param fmt
* A format string as described in <a
* href="../util/Formatter.html#syntax">Format string syntax</a>.
*
* @param args
* Arguments referenced by the format specifiers in the format
* string. If there are more arguments than format specifiers, the
* extra arguments are ignored. The maximum number of arguments is
* limited by the maximum dimension of a Java array as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>.
*
* @throws IllegalFormatException
* If a format string contains an illegal syntax, a format
* specifier that is incompatible with the given arguments,
* insufficient arguments given the format string, or other
* illegal conditions. For specification of all possible
* formatting errors, see the <a
* href="../util/Formatter.html#detail">Details</a> section
* of the formatter class specification.
*
* @throws IOError
* If an I/O error occurs.
*
* @return A string containing the line read from the console, not
* including any line-termination characters, or {@code null}
* if an end of stream has been reached.
*/
public String readLine(String fmt, Object ... args) {
String line = null;
synchronized (writeLock) {
synchronized(readLock) {
if (fmt.length() != 0)
pw.format(fmt, args);
try {
char[] ca = readline(false);
if (ca != null)
line = new String(ca);
} catch (IOException x) {
throw new IOError(x);
}
}
}
return line;
}
/**
* Reads a single line of text from the console.
*
* @throws IOError
* If an I/O error occurs.
*
* @return A string containing the line read from the console, not
* including any line-termination characters, or {@code null}
* if an end of stream has been reached.
*/
public String readLine() {
return readLine("");
}
/**
* Provides a formatted prompt, then reads a password or passphrase from
* the console with echoing disabled.
*
* @param fmt
* A format string as described in <a
* href="../util/Formatter.html#syntax">Format string syntax</a>
* for the prompt text.
*
* @param args
* Arguments referenced by the format specifiers in the format
* string. If there are more arguments than format specifiers, the
* extra arguments are ignored. The maximum number of arguments is
* limited by the maximum dimension of a Java array as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>.
*
* @throws IllegalFormatException
* If a format string contains an illegal syntax, a format
* specifier that is incompatible with the given arguments,
* insufficient arguments given the format string, or other
* illegal conditions. For specification of all possible
* formatting errors, see the <a
* href="../util/Formatter.html#detail">Details</a>
* section of the formatter class specification.
*
* @throws IOError
* If an I/O error occurs.
*
* @return A character array containing the password or passphrase read
* from the console, not including any line-termination characters,
* or {@code null} if an end of stream has been reached.
*/
public char[] readPassword(String fmt, Object ... args) {
char[] passwd = null;
synchronized (writeLock) {
synchronized(readLock) {
try {
echoOff = echo(false);
} catch (IOException x) {
throw new IOError(x);
}
IOError ioe = null;
try {
if (fmt.length() != 0)
pw.format(fmt, args);
passwd = readline(true);
} catch (IOException x) {
ioe = new IOError(x);
} finally {
try {
echoOff = echo(true);
} catch (IOException x) {
if (ioe == null)
ioe = new IOError(x);
else
ioe.addSuppressed(x);
}
if (ioe != null)
throw ioe;
}
pw.println();
}
}
return passwd;
}
/**
* Reads a password or passphrase from the console with echoing disabled
*
* @throws IOError
* If an I/O error occurs.
*
* @return A character array containing the password or passphrase read
* from the console, not including any line-termination characters,
* or {@code null} if an end of stream has been reached.
*/
public char[] readPassword() {
return readPassword("");
}
/**
* Flushes the console and forces any buffered output to be written
* immediately .
*/
public void flush() {
pw.flush();
}
private Object readLock;
private Object writeLock;
private Reader reader;
private Writer out;
private PrintWriter pw;
private Formatter formatter;
private Charset cs;
private char[] rcb;
private static native String encoding();
private static native boolean echo(boolean on) throws IOException;
private static boolean echoOff;
private char[] readline(boolean zeroOut) throws IOException {
int len = reader.read(rcb, 0, rcb.length);
if (len < 0)
return null; //EOL
if (rcb[len-1] == '\r')
len--; //remove CR at end;
else if (rcb[len-1] == '\n') {
len--; //remove LF at end;
if (len > 0 && rcb[len-1] == '\r')
len--; //remove the CR, if there is one
}
char[] b = new char[len];
if (len > 0) {
System.arraycopy(rcb, 0, b, 0, len);
if (zeroOut) {
Arrays.fill(rcb, 0, len, ' ');
}
}
return b;
}
private char[] grow() {
assert Thread.holdsLock(readLock);
char[] t = new char[rcb.length * 2];
System.arraycopy(rcb, 0, t, 0, rcb.length);
rcb = t;
return rcb;
}
class LineReader extends Reader {
private Reader in;
private char[] cb;
private int nChars, nextChar;
boolean leftoverLF;
LineReader(Reader in) {
this.in = in;
cb = new char[1024];
nextChar = nChars = 0;
leftoverLF = false;
}
public void close () {}
public boolean ready() throws IOException {
//in.ready synchronizes on readLock already
return in.ready();
}
public int read(char cbuf[], int offset, int length)
throws IOException
{
int off = offset;
int end = offset + length;
if (offset < 0 || offset > cbuf.length || length < 0 ||
end < 0 || end > cbuf.length) {
throw new IndexOutOfBoundsException();
}
synchronized(readLock) {
boolean eof = false;
char c = 0;
for (;;) {
if (nextChar >= nChars) { //fill
int n = 0;
do {
n = in.read(cb, 0, cb.length);
} while (n == 0);
if (n > 0) {
nChars = n;
nextChar = 0;
if (n < cb.length &&
cb[n-1] != '\n' && cb[n-1] != '\r') {
/*
* we're in canonical mode so each "fill" should
* come back with an eol. if there no lf or nl at
* the end of returned bytes we reached an eof.
*/
eof = true;
}
} else { /*EOF*/
if (off - offset == 0)
return -1;
return off - offset;
}
}
if (leftoverLF && cbuf == rcb && cb[nextChar] == '\n') {
/*
* if invoked by our readline, skip the leftover, otherwise
* return the LF.
*/
nextChar++;
}
leftoverLF = false;
while (nextChar < nChars) {
c = cbuf[off++] = cb[nextChar];
cb[nextChar++] = 0;
if (c == '\n') {
return off - offset;
} else if (c == '\r') {
if (off == end) {
/* no space left even the next is LF, so return
* whatever we have if the invoker is not our
* readLine()
*/
if (cbuf == rcb) {
cbuf = grow();
end = cbuf.length;
} else {
leftoverLF = true;
return off - offset;
}
}
if (nextChar == nChars && in.ready()) {
/*
* we have a CR and we reached the end of
* the read in buffer, fill to make sure we
* don't miss a LF, if there is one, it's possible
* that it got cut off during last round reading
* simply because the read in buffer was full.
*/
nChars = in.read(cb, 0, cb.length);
nextChar = 0;
}
if (nextChar < nChars && cb[nextChar] == '\n') {
cbuf[off++] = '\n';
nextChar++;
}
return off - offset;
} else if (off == end) {
if (cbuf == rcb) {
cbuf = grow();
end = cbuf.length;
} else {
return off - offset;
}
}
}
if (eof)
return off - offset;
}
}
}
}
// Set up JavaIOAccess in SharedSecrets
static {
try {
// Add a shutdown hook to restore console's echo state should
// it be necessary.
SharedSecrets.getJavaLangAccess()
.registerShutdownHook(0 /* shutdown hook invocation order */,
false /* only register if shutdown is not in progress */,
new Runnable() {
public void run() {
try {
if (echoOff) {
echo(true);
}
} catch (IOException x) { }
}
});
} catch (IllegalStateException e) {
// shutdown is already in progress and console is first used
// by a shutdown hook
}
SharedSecrets.setJavaIOAccess(new JavaIOAccess() {
public Console console() {
if (istty()) {
if (cons == null)
cons = new Console();
return cons;
}
return null;
}
public Charset charset() {
// This method is called in sun.security.util.Password,
// cons already exists when this method is called
return cons.cs;
}
});
}
private static Console cons;
private static native boolean istty();
private Console() {
readLock = new Object();
writeLock = new Object();
String csname = encoding();
if (csname != null) {
try {
cs = Charset.forName(csname);
} catch (Exception x) {}
}
if (cs == null)
cs = Charset.defaultCharset();
out = StreamEncoder.forOutputStreamWriter(
new FileOutputStream(FileDescriptor.out),
writeLock,
cs);
pw = new PrintWriter(out, true) { public void close() {} };
formatter = new Formatter(out);
reader = new LineReader(StreamDecoder.forInputStreamReader(
new FileInputStream(FileDescriptor.in),
readLock,
cs));
rcb = new char[1024];
}
}

View file

@ -0,0 +1,603 @@
/*
* Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* The {@code DataInput} interface provides
* for reading bytes from a binary stream and
* reconstructing from them data in any of
* the Java primitive types. There is also
* a
* facility for reconstructing a {@code String}
* from data in
* <a href="#modified-utf-8">modified UTF-8</a>
* format.
* <p>
* It is generally true of all the reading
* routines in this interface that if end of
* file is reached before the desired number
* of bytes has been read, an {@code EOFException}
* (which is a kind of {@code IOException})
* is thrown. If any byte cannot be read for
* any reason other than end of file, an {@code IOException}
* other than {@code EOFException} is
* thrown. In particular, an {@code IOException}
* may be thrown if the input stream has been
* closed.
*
* <h3><a id="modified-utf-8">Modified UTF-8</a></h3>
* <p>
* Implementations of the DataInput and DataOutput interfaces represent
* Unicode strings in a format that is a slight modification of UTF-8.
* (For information regarding the standard UTF-8 format, see section
* <i>3.9 Unicode Encoding Forms</i> of <i>The Unicode Standard, Version
* 4.0</i>)
*
* <ul>
* <li>Characters in the range {@code '\u005Cu0001'} to
* {@code '\u005Cu007F'} are represented by a single byte.
* <li>The null character {@code '\u005Cu0000'} and characters
* in the range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are
* represented by a pair of bytes.
* <li>Characters in the range {@code '\u005Cu0800'}
* to {@code '\u005CuFFFF'} are represented by three bytes.
* </ul>
*
* <table class="plain" style="margin-left:2em;">
* <caption>Encoding of UTF-8 values</caption>
* <thead>
* <tr>
* <th scope="col" rowspan="2">Value</th>
* <th scope="col" rowspan="2">Byte</th>
* <th scope="col" colspan="8" id="bit_a">Bit Values</th>
* </tr>
* <tr>
* <!-- Value -->
* <!-- Byte -->
* <th scope="col" style="width:3em"> 7 </th>
* <th scope="col" style="width:3em"> 6 </th>
* <th scope="col" style="width:3em"> 5 </th>
* <th scope="col" style="width:3em"> 4 </th>
* <th scope="col" style="width:3em"> 3 </th>
* <th scope="col" style="width:3em"> 2 </th>
* <th scope="col" style="width:3em"> 1 </th>
* <th scope="col" style="width:3em"> 0 </th>
* </thead>
* <tbody>
* <tr>
* <th scope="row" style="text-align:left; font-weight:normal">
* {@code \u005Cu0001} to {@code \u005Cu007F} </th>
* <th scope="row" style="font-weight:normal; text-align:center"> 1 </th>
* <td style="text-align:center">0
* <td colspan="7" style="text-align:right; padding-right:6em">bits 6-0
* </tr>
* <tr>
* <th scope="row" rowspan="2" style="text-align:left; font-weight:normal">
* {@code \u005Cu0000},<br>
* {@code \u005Cu0080} to {@code \u005Cu07FF} </th>
* <th scope="row" style="font-weight:normal; text-align:center"> 1 </th>
* <td style="text-align:center">1
* <td style="text-align:center">1
* <td style="text-align:center">0
* <td colspan="5" style="text-align:right; padding-right:6em">bits 10-6
* </tr>
* <tr>
* <!-- (value) -->
* <th scope="row" style="font-weight:normal; text-align:center"> 2 </th>
* <td style="text-align:center">1
* <td style="text-align:center">0
* <td colspan="6" style="text-align:right; padding-right:6em">bits 5-0
* </tr>
* <tr>
* <th scope="row" rowspan="3" style="text-align:left; font-weight:normal">
* {@code \u005Cu0800} to {@code \u005CuFFFF} </th>
* <th scope="row" style="font-weight:normal; text-align:center"> 1 </th>
* <td style="text-align:center">1
* <td style="text-align:center">1
* <td style="text-align:center">1
* <td style="text-align:center">0
* <td colspan="4" style="text-align:right; padding-right:6em">bits 15-12
* </tr>
* <tr>
* <!-- (value) -->
* <th scope="row" style="font-weight:normal; text-align:center"> 2 </th>
* <td style="text-align:center">1
* <td style="text-align:center">0
* <td colspan="6" style="text-align:right; padding-right:6em">bits 11-6
* </tr>
* <tr>
* <!-- (value) -->
* <th scope="row" style="font-weight:normal; text-align:center"> 3 </th>
* <td style="text-align:center">1
* <td style="text-align:center">0
* <td colspan="6" style="text-align:right; padding-right:6em">bits 5-0
* </tr>
* </tbody>
* </table>
*
* <p>
* The differences between this format and the
* standard UTF-8 format are the following:
* <ul>
* <li>The null byte {@code '\u005Cu0000'} is encoded in 2-byte format
* rather than 1-byte, so that the encoded strings never have
* embedded nulls.
* <li>Only the 1-byte, 2-byte, and 3-byte formats are used.
* <li><a href="../lang/Character.html#unicode">Supplementary characters</a>
* are represented in the form of surrogate pairs.
* </ul>
* @author Frank Yellin
* @see java.io.DataInputStream
* @see java.io.DataOutput
* @since 1.0
*/
public
interface DataInput {
/**
* Reads some bytes from an input
* stream and stores them into the buffer
* array {@code b}. The number of bytes
* read is equal
* to the length of {@code b}.
* <p>
* This method blocks until one of the
* following conditions occurs:
* <ul>
* <li>{@code b.length}
* bytes of input data are available, in which
* case a normal return is made.
*
* <li>End of
* file is detected, in which case an {@code EOFException}
* is thrown.
*
* <li>An I/O error occurs, in
* which case an {@code IOException} other
* than {@code EOFException} is thrown.
* </ul>
* <p>
* If {@code b} is {@code null},
* a {@code NullPointerException} is thrown.
* If {@code b.length} is zero, then
* no bytes are read. Otherwise, the first
* byte read is stored into element {@code b[0]},
* the next one into {@code b[1]}, and
* so on.
* If an exception is thrown from
* this method, then it may be that some but
* not all bytes of {@code b} have been
* updated with data from the input stream.
*
* @param b the buffer into which the data is read.
* @throws NullPointerException if {@code b} is {@code null}.
* @throws EOFException if this stream reaches the end before reading
* all the bytes.
* @throws IOException if an I/O error occurs.
*/
void readFully(byte b[]) throws IOException;
/**
*
* Reads {@code len}
* bytes from
* an input stream.
* <p>
* This method
* blocks until one of the following conditions
* occurs:
* <ul>
* <li>{@code len} bytes
* of input data are available, in which case
* a normal return is made.
*
* <li>End of file
* is detected, in which case an {@code EOFException}
* is thrown.
*
* <li>An I/O error occurs, in
* which case an {@code IOException} other
* than {@code EOFException} is thrown.
* </ul>
* <p>
* If {@code b} is {@code null},
* a {@code NullPointerException} is thrown.
* If {@code off} is negative, or {@code len}
* is negative, or {@code off+len} is
* greater than the length of the array {@code b},
* then an {@code IndexOutOfBoundsException}
* is thrown.
* If {@code len} is zero,
* then no bytes are read. Otherwise, the first
* byte read is stored into element {@code b[off]},
* the next one into {@code b[off+1]},
* and so on. The number of bytes read is,
* at most, equal to {@code len}.
*
* @param b the buffer into which the data is read.
* @param off an int specifying the offset in the data array {@code b}.
* @param len an int specifying the number of bytes to read.
* @throws NullPointerException if {@code b} is {@code null}.
* @throws IndexOutOfBoundsException if {@code off} is negative,
* {@code len} is negative, or {@code len} is greater than
* {@code b.length - off}.
* @throws EOFException if this stream reaches the end before reading
* all the bytes.
* @throws IOException if an I/O error occurs.
*/
void readFully(byte b[], int off, int len) throws IOException;
/**
* Makes an attempt to skip over
* {@code n} bytes
* of data from the input
* stream, discarding the skipped bytes. However,
* it may skip
* over some smaller number of
* bytes, possibly zero. This may result from
* any of a
* number of conditions; reaching
* end of file before {@code n} bytes
* have been skipped is
* only one possibility.
* This method never throws an {@code EOFException}.
* The actual
* number of bytes skipped is returned.
*
* @param n the number of bytes to be skipped.
* @return the number of bytes actually skipped.
* @exception IOException if an I/O error occurs.
*/
int skipBytes(int n) throws IOException;
/**
* Reads one input byte and returns
* {@code true} if that byte is nonzero,
* {@code false} if that byte is zero.
* This method is suitable for reading
* the byte written by the {@code writeBoolean}
* method of interface {@code DataOutput}.
*
* @return the {@code boolean} value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
boolean readBoolean() throws IOException;
/**
* Reads and returns one input byte.
* The byte is treated as a signed value in
* the range {@code -128} through {@code 127},
* inclusive.
* This method is suitable for
* reading the byte written by the {@code writeByte}
* method of interface {@code DataOutput}.
*
* @return the 8-bit value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
byte readByte() throws IOException;
/**
* Reads one input byte, zero-extends
* it to type {@code int}, and returns
* the result, which is therefore in the range
* {@code 0}
* through {@code 255}.
* This method is suitable for reading
* the byte written by the {@code writeByte}
* method of interface {@code DataOutput}
* if the argument to {@code writeByte}
* was intended to be a value in the range
* {@code 0} through {@code 255}.
*
* @return the unsigned 8-bit value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
int readUnsignedByte() throws IOException;
/**
* Reads two input bytes and returns
* a {@code short} value. Let {@code a}
* be the first byte read and {@code b}
* be the second byte. The value
* returned
* is:
* <pre>{@code (short)((a << 8) | (b & 0xff))
* }</pre>
* This method
* is suitable for reading the bytes written
* by the {@code writeShort} method of
* interface {@code DataOutput}.
*
* @return the 16-bit value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
short readShort() throws IOException;
/**
* Reads two input bytes and returns
* an {@code int} value in the range {@code 0}
* through {@code 65535}. Let {@code a}
* be the first byte read and
* {@code b}
* be the second byte. The value returned is:
* <pre>{@code (((a & 0xff) << 8) | (b & 0xff))
* }</pre>
* This method is suitable for reading the bytes
* written by the {@code writeShort} method
* of interface {@code DataOutput} if
* the argument to {@code writeShort}
* was intended to be a value in the range
* {@code 0} through {@code 65535}.
*
* @return the unsigned 16-bit value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
int readUnsignedShort() throws IOException;
/**
* Reads two input bytes and returns a {@code char} value.
* Let {@code a}
* be the first byte read and {@code b}
* be the second byte. The value
* returned is:
* <pre>{@code (char)((a << 8) | (b & 0xff))
* }</pre>
* This method
* is suitable for reading bytes written by
* the {@code writeChar} method of interface
* {@code DataOutput}.
*
* @return the {@code char} value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
char readChar() throws IOException;
/**
* Reads four input bytes and returns an
* {@code int} value. Let {@code a-d}
* be the first through fourth bytes read. The value returned is:
* <pre>{@code
* (((a & 0xff) << 24) | ((b & 0xff) << 16) |
* ((c & 0xff) << 8) | (d & 0xff))
* }</pre>
* This method is suitable
* for reading bytes written by the {@code writeInt}
* method of interface {@code DataOutput}.
*
* @return the {@code int} value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
int readInt() throws IOException;
/**
* Reads eight input bytes and returns
* a {@code long} value. Let {@code a-h}
* be the first through eighth bytes read.
* The value returned is:
* <pre>{@code
* (((long)(a & 0xff) << 56) |
* ((long)(b & 0xff) << 48) |
* ((long)(c & 0xff) << 40) |
* ((long)(d & 0xff) << 32) |
* ((long)(e & 0xff) << 24) |
* ((long)(f & 0xff) << 16) |
* ((long)(g & 0xff) << 8) |
* ((long)(h & 0xff)))
* }</pre>
* <p>
* This method is suitable
* for reading bytes written by the {@code writeLong}
* method of interface {@code DataOutput}.
*
* @return the {@code long} value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
long readLong() throws IOException;
/**
* Reads four input bytes and returns
* a {@code float} value. It does this
* by first constructing an {@code int}
* value in exactly the manner
* of the {@code readInt}
* method, then converting this {@code int}
* value to a {@code float} in
* exactly the manner of the method {@code Float.intBitsToFloat}.
* This method is suitable for reading
* bytes written by the {@code writeFloat}
* method of interface {@code DataOutput}.
*
* @return the {@code float} value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
float readFloat() throws IOException;
/**
* Reads eight input bytes and returns
* a {@code double} value. It does this
* by first constructing a {@code long}
* value in exactly the manner
* of the {@code readLong}
* method, then converting this {@code long}
* value to a {@code double} in exactly
* the manner of the method {@code Double.longBitsToDouble}.
* This method is suitable for reading
* bytes written by the {@code writeDouble}
* method of interface {@code DataOutput}.
*
* @return the {@code double} value read.
* @exception EOFException if this stream reaches the end before reading
* all the bytes.
* @exception IOException if an I/O error occurs.
*/
double readDouble() throws IOException;
/**
* Reads the next line of text from the input stream.
* It reads successive bytes, converting
* each byte separately into a character,
* until it encounters a line terminator or
* end of
* file; the characters read are then
* returned as a {@code String}. Note
* that because this
* method processes bytes,
* it does not support input of the full Unicode
* character set.
* <p>
* If end of file is encountered
* before even one byte can be read, then {@code null}
* is returned. Otherwise, each byte that is
* read is converted to type {@code char}
* by zero-extension. If the character {@code '\n'}
* is encountered, it is discarded and reading
* ceases. If the character {@code '\r'}
* is encountered, it is discarded and, if
* the following byte converts &#32;to the
* character {@code '\n'}, then that is
* discarded also; reading then ceases. If
* end of file is encountered before either
* of the characters {@code '\n'} and
* {@code '\r'} is encountered, reading
* ceases. Once reading has ceased, a {@code String}
* is returned that contains all the characters
* read and not discarded, taken in order.
* Note that every character in this string
* will have a value less than {@code \u005Cu0100},
* that is, {@code (char)256}.
*
* @return the next line of text from the input stream,
* or {@code null} if the end of file is
* encountered before a byte can be read.
* @exception IOException if an I/O error occurs.
*/
String readLine() throws IOException;
/**
* Reads in a string that has been encoded using a
* <a href="#modified-utf-8">modified UTF-8</a>
* format.
* The general contract of {@code readUTF}
* is that it reads a representation of a Unicode
* character string encoded in modified
* UTF-8 format; this string of characters
* is then returned as a {@code String}.
* <p>
* First, two bytes are read and used to
* construct an unsigned 16-bit integer in
* exactly the manner of the {@code readUnsignedShort}
* method . This integer value is called the
* <i>UTF length</i> and specifies the number
* of additional bytes to be read. These bytes
* are then converted to characters by considering
* them in groups. The length of each group
* is computed from the value of the first
* byte of the group. The byte following a
* group, if any, is the first byte of the
* next group.
* <p>
* If the first byte of a group
* matches the bit pattern {@code 0xxxxxxx}
* (where {@code x} means "may be {@code 0}
* or {@code 1}"), then the group consists
* of just that byte. The byte is zero-extended
* to form a character.
* <p>
* If the first byte
* of a group matches the bit pattern {@code 110xxxxx},
* then the group consists of that byte {@code a}
* and a second byte {@code b}. If there
* is no byte {@code b} (because byte
* {@code a} was the last of the bytes
* to be read), or if byte {@code b} does
* not match the bit pattern {@code 10xxxxxx},
* then a {@code UTFDataFormatException}
* is thrown. Otherwise, the group is converted
* to the character:
* <pre>{@code (char)(((a & 0x1F) << 6) | (b & 0x3F))
* }</pre>
* If the first byte of a group
* matches the bit pattern {@code 1110xxxx},
* then the group consists of that byte {@code a}
* and two more bytes {@code b} and {@code c}.
* If there is no byte {@code c} (because
* byte {@code a} was one of the last
* two of the bytes to be read), or either
* byte {@code b} or byte {@code c}
* does not match the bit pattern {@code 10xxxxxx},
* then a {@code UTFDataFormatException}
* is thrown. Otherwise, the group is converted
* to the character:
* <pre>{@code
* (char)(((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F))
* }</pre>
* If the first byte of a group matches the
* pattern {@code 1111xxxx} or the pattern
* {@code 10xxxxxx}, then a {@code UTFDataFormatException}
* is thrown.
* <p>
* If end of file is encountered
* at any time during this entire process,
* then an {@code EOFException} is thrown.
* <p>
* After every group has been converted to
* a character by this process, the characters
* are gathered, in the same order in which
* their corresponding groups were read from
* the input stream, to form a {@code String},
* which is returned.
* <p>
* The {@code writeUTF}
* method of interface {@code DataOutput}
* may be used to write data that is suitable
* for reading by this method.
* @return a Unicode string.
* @exception EOFException if this stream reaches the end
* before reading all the bytes.
* @exception IOException if an I/O error occurs.
* @exception UTFDataFormatException if the bytes do not represent a
* valid modified UTF-8 encoding of a string.
*/
String readUTF() throws IOException;
}

View file

@ -0,0 +1,668 @@
/*
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A data input stream lets an application read primitive Java data
* types from an underlying input stream in a machine-independent
* way. An application uses a data output stream to write data that
* can later be read by a data input stream.
* <p>
* DataInputStream is not necessarily safe for multithreaded access.
* Thread safety is optional and is the responsibility of users of
* methods in this class.
*
* @author Arthur van Hoff
* @see java.io.DataOutputStream
* @since 1.0
*/
public
class DataInputStream extends FilterInputStream implements DataInput {
/**
* Creates a DataInputStream that uses the specified
* underlying InputStream.
*
* @param in the specified input stream
*/
public DataInputStream(InputStream in) {
super(in);
}
/**
* working arrays initialized on demand by readUTF
*/
private byte bytearr[] = new byte[80];
private char chararr[] = new char[80];
/**
* Reads some number of bytes from the contained input stream and
* stores them into the buffer array <code>b</code>. The number of
* bytes actually read is returned as an integer. This method blocks
* until input data is available, end of file is detected, or an
* exception is thrown.
*
* <p>If <code>b</code> is null, a <code>NullPointerException</code> is
* thrown. If the length of <code>b</code> is zero, then no bytes are
* read and <code>0</code> is returned; otherwise, there is an attempt
* to read at least one byte. If no byte is available because the
* stream is at end of file, the value <code>-1</code> is returned;
* otherwise, at least one byte is read and stored into <code>b</code>.
*
* <p>The first byte read is stored into element <code>b[0]</code>, the
* next one into <code>b[1]</code>, and so on. The number of bytes read
* is, at most, equal to the length of <code>b</code>. Let <code>k</code>
* be the number of bytes actually read; these bytes will be stored in
* elements <code>b[0]</code> through <code>b[k-1]</code>, leaving
* elements <code>b[k]</code> through <code>b[b.length-1]</code>
* unaffected.
*
* <p>The <code>read(b)</code> method has the same effect as:
* <blockquote><pre>
* read(b, 0, b.length)
* </pre></blockquote>
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end
* of the stream has been reached.
* @exception IOException if the first byte cannot be read for any reason
* other than end of file, the stream has been closed and the underlying
* input stream does not support reading after close, or another I/O
* error occurs.
* @see java.io.FilterInputStream#in
* @see java.io.InputStream#read(byte[], int, int)
*/
public final int read(byte b[]) throws IOException {
return in.read(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from the contained
* input stream into an array of bytes. An attempt is made to read
* as many as <code>len</code> bytes, but a smaller number may be read,
* possibly zero. The number of bytes actually read is returned as an
* integer.
*
* <p> This method blocks until input data is available, end of file is
* detected, or an exception is thrown.
*
* <p> If <code>len</code> is zero, then no bytes are read and
* <code>0</code> is returned; otherwise, there is an attempt to read at
* least one byte. If no byte is available because the stream is at end of
* file, the value <code>-1</code> is returned; otherwise, at least one
* byte is read and stored into <code>b</code>.
*
* <p> The first byte read is stored into element <code>b[off]</code>, the
* next one into <code>b[off+1]</code>, and so on. The number of bytes read
* is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
* bytes actually read; these bytes will be stored in elements
* <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
* leaving elements <code>b[off+</code><i>k</i><code>]</code> through
* <code>b[off+len-1]</code> unaffected.
*
* <p> In every case, elements <code>b[0]</code> through
* <code>b[off]</code> and elements <code>b[off+len]</code> through
* <code>b[b.length-1]</code> are unaffected.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end
* of the stream has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if the first byte cannot be read for any reason
* other than end of file, the stream has been closed and the underlying
* input stream does not support reading after close, or another I/O
* error occurs.
* @see java.io.FilterInputStream#in
* @see java.io.InputStream#read(byte[], int, int)
*/
public final int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);
}
/**
* See the general contract of the {@code readFully}
* method of {@code DataInput}.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @param b the buffer into which the data is read.
* @throws NullPointerException if {@code b} is {@code null}.
* @throws EOFException if this input stream reaches the end before
* reading all the bytes.
* @throws IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final void readFully(byte b[]) throws IOException {
readFully(b, 0, b.length);
}
/**
* See the general contract of the {@code readFully}
* method of {@code DataInput}.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the data array {@code b}.
* @param len the number of bytes to read.
* @exception NullPointerException if {@code b} is {@code null}.
* @exception IndexOutOfBoundsException if {@code off} is negative,
* {@code len} is negative, or {@code len} is greater than
* {@code b.length - off}.
* @exception EOFException if this input stream reaches the end before
* reading all the bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final void readFully(byte b[], int off, int len) throws IOException {
if (len < 0)
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int count = in.read(b, off + n, len - n);
if (count < 0)
throw new EOFException();
n += count;
}
}
/**
* See the general contract of the <code>skipBytes</code>
* method of <code>DataInput</code>.
* <p>
* Bytes for this operation are read from the contained
* input stream.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @exception IOException if the contained input stream does not support
* seek, or the stream has been closed and
* the contained input stream does not support
* reading after close, or another I/O error occurs.
*/
public final int skipBytes(int n) throws IOException {
int total = 0;
int cur = 0;
while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
total += cur;
}
return total;
}
/**
* See the general contract of the <code>readBoolean</code>
* method of <code>DataInput</code>.
* <p>
* Bytes for this operation are read from the contained
* input stream.
*
* @return the <code>boolean</code> value read.
* @exception EOFException if this input stream has reached the end.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final boolean readBoolean() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return (ch != 0);
}
/**
* See the general contract of the <code>readByte</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next byte of this input stream as a signed 8-bit
* <code>byte</code>.
* @exception EOFException if this input stream has reached the end.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final byte readByte() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return (byte)(ch);
}
/**
* See the general contract of the <code>readUnsignedByte</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next byte of this input stream, interpreted as an
* unsigned 8-bit number.
* @exception EOFException if this input stream has reached the end.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final int readUnsignedByte() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return ch;
}
/**
* See the general contract of the <code>readShort</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next two bytes of this input stream, interpreted as a
* signed 16-bit number.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final short readShort() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (short)((ch1 << 8) + (ch2 << 0));
}
/**
* See the general contract of the <code>readUnsignedShort</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next two bytes of this input stream, interpreted as an
* unsigned 16-bit integer.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final int readUnsignedShort() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
/**
* See the general contract of the <code>readChar</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next two bytes of this input stream, interpreted as a
* <code>char</code>.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final char readChar() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (char)((ch1 << 8) + (ch2 << 0));
}
/**
* See the general contract of the <code>readInt</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next four bytes of this input stream, interpreted as an
* <code>int</code>.
* @exception EOFException if this input stream reaches the end before
* reading four bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final int readInt() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
private byte readBuffer[] = new byte[8];
/**
* See the general contract of the <code>readLong</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next eight bytes of this input stream, interpreted as a
* <code>long</code>.
* @exception EOFException if this input stream reaches the end before
* reading eight bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final long readLong() throws IOException {
readFully(readBuffer, 0, 8);
return (((long)readBuffer[0] << 56) +
((long)(readBuffer[1] & 255) << 48) +
((long)(readBuffer[2] & 255) << 40) +
((long)(readBuffer[3] & 255) << 32) +
((long)(readBuffer[4] & 255) << 24) +
((readBuffer[5] & 255) << 16) +
((readBuffer[6] & 255) << 8) +
((readBuffer[7] & 255) << 0));
}
/**
* See the general contract of the <code>readFloat</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next four bytes of this input stream, interpreted as a
* <code>float</code>.
* @exception EOFException if this input stream reaches the end before
* reading four bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.DataInputStream#readInt()
* @see java.lang.Float#intBitsToFloat(int)
*/
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
/**
* See the general contract of the <code>readDouble</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next eight bytes of this input stream, interpreted as a
* <code>double</code>.
* @exception EOFException if this input stream reaches the end before
* reading eight bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @see java.io.DataInputStream#readLong()
* @see java.lang.Double#longBitsToDouble(long)
*/
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
private char lineBuffer[];
/**
* See the general contract of the <code>readLine</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @deprecated This method does not properly convert bytes to characters.
* As of JDK&nbsp;1.1, the preferred way to read lines of text is via the
* <code>BufferedReader.readLine()</code> method. Programs that use the
* <code>DataInputStream</code> class to read lines can be converted to use
* the <code>BufferedReader</code> class by replacing code of the form:
* <blockquote><pre>
* DataInputStream d =&nbsp;new&nbsp;DataInputStream(in);
* </pre></blockquote>
* with:
* <blockquote><pre>
* BufferedReader d
* =&nbsp;new&nbsp;BufferedReader(new&nbsp;InputStreamReader(in));
* </pre></blockquote>
*
* @return the next line of text from this input stream.
* @exception IOException if an I/O error occurs.
* @see java.io.BufferedReader#readLine()
* @see java.io.FilterInputStream#in
*/
@Deprecated
public final String readLine() throws IOException {
char buf[] = lineBuffer;
if (buf == null) {
buf = lineBuffer = new char[128];
}
int room = buf.length;
int offset = 0;
int c;
loop: while (true) {
switch (c = in.read()) {
case -1:
case '\n':
break loop;
case '\r':
int c2 = in.read();
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
this.in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
}
break loop;
default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
if ((c == -1) && (offset == 0)) {
return null;
}
return String.copyValueOf(buf, 0, offset);
}
/**
* See the general contract of the <code>readUTF</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return a Unicode string.
* @exception EOFException if this input stream reaches the end before
* reading all the bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @exception UTFDataFormatException if the bytes do not represent a valid
* modified UTF-8 encoding of a string.
* @see java.io.DataInputStream#readUTF(java.io.DataInput)
*/
public final String readUTF() throws IOException {
return readUTF(this);
}
/**
* Reads from the
* stream <code>in</code> a representation
* of a Unicode character string encoded in
* <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
* this string of characters is then returned as a <code>String</code>.
* The details of the modified UTF-8 representation
* are exactly the same as for the <code>readUTF</code>
* method of <code>DataInput</code>.
*
* @param in a data input stream.
* @return a Unicode string.
* @exception EOFException if the input stream reaches the end
* before all the bytes.
* @exception IOException the stream has been closed and the contained
* input stream does not support reading after close, or
* another I/O error occurs.
* @exception UTFDataFormatException if the bytes do not represent a
* valid modified UTF-8 encoding of a Unicode string.
* @see java.io.DataInputStream#readUnsignedShort()
*/
public static final String readUTF(DataInput in) throws IOException {
int utflen = in.readUnsignedShort();
byte[] bytearr = null;
char[] chararr = null;
if (in instanceof DataInputStream) {
DataInputStream dis = (DataInputStream)in;
if (dis.bytearr.length < utflen){
dis.bytearr = new byte[utflen*2];
dis.chararr = new char[utflen*2];
}
chararr = dis.chararr;
bytearr = dis.bytearr;
} else {
bytearr = new byte[utflen];
chararr = new char[utflen];
}
int c, char2, char3;
int count = 0;
int chararr_count=0;
in.readFully(bytearr, 0, utflen);
while (count < utflen) {
c = (int) bytearr[count] & 0xff;
if (c > 127) break;
count++;
chararr[chararr_count++]=(char)c;
}
while (count < utflen) {
c = (int) bytearr[count] & 0xff;
switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
/* 0xxxxxxx*/
count++;
chararr[chararr_count++]=(char)c;
break;
case 12: case 13:
/* 110x xxxx 10xx xxxx*/
count += 2;
if (count > utflen)
throw new UTFDataFormatException(
"malformed input: partial character at end");
char2 = (int) bytearr[count-1];
if ((char2 & 0xC0) != 0x80)
throw new UTFDataFormatException(
"malformed input around byte " + count);
chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
(char2 & 0x3F));
break;
case 14:
/* 1110 xxxx 10xx xxxx 10xx xxxx */
count += 3;
if (count > utflen)
throw new UTFDataFormatException(
"malformed input: partial character at end");
char2 = (int) bytearr[count-2];
char3 = (int) bytearr[count-1];
if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
throw new UTFDataFormatException(
"malformed input around byte " + (count-1));
chararr[chararr_count++]=(char)(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
default:
/* 10xx xxxx, 1111 xxxx */
throw new UTFDataFormatException(
"malformed input around byte " + count);
}
}
// The number of chars produced may be less than utflen
return new String(chararr, 0, chararr_count);
}
}

View file

@ -0,0 +1,354 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* The <code>DataOutput</code> interface provides
* for converting data from any of the Java
* primitive types to a series of bytes and
* writing these bytes to a binary stream.
* There is also a facility for converting
* a <code>String</code> into
* <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
* format and writing the resulting series
* of bytes.
* <p>
* For all the methods in this interface that
* write bytes, it is generally true that if
* a byte cannot be written for any reason,
* an <code>IOException</code> is thrown.
*
* @author Frank Yellin
* @see java.io.DataInput
* @see java.io.DataOutputStream
* @since 1.0
*/
public
interface DataOutput {
/**
* Writes to the output stream the eight
* low-order bits of the argument <code>b</code>.
* The 24 high-order bits of <code>b</code>
* are ignored.
*
* @param b the byte to be written.
* @throws IOException if an I/O error occurs.
*/
void write(int b) throws IOException;
/**
* Writes to the output stream all the bytes in array <code>b</code>.
* If <code>b</code> is <code>null</code>,
* a <code>NullPointerException</code> is thrown.
* If <code>b.length</code> is zero, then
* no bytes are written. Otherwise, the byte
* <code>b[0]</code> is written first, then
* <code>b[1]</code>, and so on; the last byte
* written is <code>b[b.length-1]</code>.
*
* @param b the data.
* @throws IOException if an I/O error occurs.
*/
void write(byte b[]) throws IOException;
/**
* Writes <code>len</code> bytes from array
* <code>b</code>, in order, to
* the output stream. If <code>b</code>
* is <code>null</code>, a <code>NullPointerException</code>
* is thrown. If <code>off</code> is negative,
* or <code>len</code> is negative, or <code>off+len</code>
* is greater than the length of the array
* <code>b</code>, then an <code>IndexOutOfBoundsException</code>
* is thrown. If <code>len</code> is zero,
* then no bytes are written. Otherwise, the
* byte <code>b[off]</code> is written first,
* then <code>b[off+1]</code>, and so on; the
* last byte written is <code>b[off+len-1]</code>.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @throws IOException if an I/O error occurs.
*/
void write(byte b[], int off, int len) throws IOException;
/**
* Writes a <code>boolean</code> value to this output stream.
* If the argument <code>v</code>
* is <code>true</code>, the value <code>(byte)1</code>
* is written; if <code>v</code> is <code>false</code>,
* the value <code>(byte)0</code> is written.
* The byte written by this method may
* be read by the <code>readBoolean</code>
* method of interface <code>DataInput</code>,
* which will then return a <code>boolean</code>
* equal to <code>v</code>.
*
* @param v the boolean to be written.
* @throws IOException if an I/O error occurs.
*/
void writeBoolean(boolean v) throws IOException;
/**
* Writes to the output stream the eight low-
* order bits of the argument <code>v</code>.
* The 24 high-order bits of <code>v</code>
* are ignored. (This means that <code>writeByte</code>
* does exactly the same thing as <code>write</code>
* for an integer argument.) The byte written
* by this method may be read by the <code>readByte</code>
* method of interface <code>DataInput</code>,
* which will then return a <code>byte</code>
* equal to <code>(byte)v</code>.
*
* @param v the byte value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeByte(int v) throws IOException;
/**
* Writes two bytes to the output
* stream to represent the value of the argument.
* The byte values to be written, in the order
* shown, are:
* <pre>{@code
* (byte)(0xff & (v >> 8))
* (byte)(0xff & v)
* }</pre> <p>
* The bytes written by this method may be
* read by the <code>readShort</code> method
* of interface <code>DataInput</code> , which
* will then return a <code>short</code> equal
* to <code>(short)v</code>.
*
* @param v the <code>short</code> value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeShort(int v) throws IOException;
/**
* Writes a <code>char</code> value, which
* is comprised of two bytes, to the
* output stream.
* The byte values to be written, in the order
* shown, are:
* <pre>{@code
* (byte)(0xff & (v >> 8))
* (byte)(0xff & v)
* }</pre><p>
* The bytes written by this method may be
* read by the <code>readChar</code> method
* of interface <code>DataInput</code> , which
* will then return a <code>char</code> equal
* to <code>(char)v</code>.
*
* @param v the <code>char</code> value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeChar(int v) throws IOException;
/**
* Writes an <code>int</code> value, which is
* comprised of four bytes, to the output stream.
* The byte values to be written, in the order
* shown, are:
* <pre>{@code
* (byte)(0xff & (v >> 24))
* (byte)(0xff & (v >> 16))
* (byte)(0xff & (v >> 8))
* (byte)(0xff & v)
* }</pre><p>
* The bytes written by this method may be read
* by the <code>readInt</code> method of interface
* <code>DataInput</code> , which will then
* return an <code>int</code> equal to <code>v</code>.
*
* @param v the <code>int</code> value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeInt(int v) throws IOException;
/**
* Writes a <code>long</code> value, which is
* comprised of eight bytes, to the output stream.
* The byte values to be written, in the order
* shown, are:
* <pre>{@code
* (byte)(0xff & (v >> 56))
* (byte)(0xff & (v >> 48))
* (byte)(0xff & (v >> 40))
* (byte)(0xff & (v >> 32))
* (byte)(0xff & (v >> 24))
* (byte)(0xff & (v >> 16))
* (byte)(0xff & (v >> 8))
* (byte)(0xff & v)
* }</pre><p>
* The bytes written by this method may be
* read by the <code>readLong</code> method
* of interface <code>DataInput</code> , which
* will then return a <code>long</code> equal
* to <code>v</code>.
*
* @param v the <code>long</code> value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeLong(long v) throws IOException;
/**
* Writes a <code>float</code> value,
* which is comprised of four bytes, to the output stream.
* It does this as if it first converts this
* <code>float</code> value to an <code>int</code>
* in exactly the manner of the <code>Float.floatToIntBits</code>
* method and then writes the <code>int</code>
* value in exactly the manner of the <code>writeInt</code>
* method. The bytes written by this method
* may be read by the <code>readFloat</code>
* method of interface <code>DataInput</code>,
* which will then return a <code>float</code>
* equal to <code>v</code>.
*
* @param v the <code>float</code> value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeFloat(float v) throws IOException;
/**
* Writes a <code>double</code> value,
* which is comprised of eight bytes, to the output stream.
* It does this as if it first converts this
* <code>double</code> value to a <code>long</code>
* in exactly the manner of the <code>Double.doubleToLongBits</code>
* method and then writes the <code>long</code>
* value in exactly the manner of the <code>writeLong</code>
* method. The bytes written by this method
* may be read by the <code>readDouble</code>
* method of interface <code>DataInput</code>,
* which will then return a <code>double</code>
* equal to <code>v</code>.
*
* @param v the <code>double</code> value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeDouble(double v) throws IOException;
/**
* Writes a string to the output stream.
* For every character in the string
* <code>s</code>, taken in order, one byte
* is written to the output stream. If
* <code>s</code> is <code>null</code>, a <code>NullPointerException</code>
* is thrown.<p> If <code>s.length</code>
* is zero, then no bytes are written. Otherwise,
* the character <code>s[0]</code> is written
* first, then <code>s[1]</code>, and so on;
* the last character written is <code>s[s.length-1]</code>.
* For each character, one byte is written,
* the low-order byte, in exactly the manner
* of the <code>writeByte</code> method . The
* high-order eight bits of each character
* in the string are ignored.
*
* @param s the string of bytes to be written.
* @throws IOException if an I/O error occurs.
*/
void writeBytes(String s) throws IOException;
/**
* Writes every character in the string <code>s</code>,
* to the output stream, in order,
* two bytes per character. If <code>s</code>
* is <code>null</code>, a <code>NullPointerException</code>
* is thrown. If <code>s.length</code>
* is zero, then no characters are written.
* Otherwise, the character <code>s[0]</code>
* is written first, then <code>s[1]</code>,
* and so on; the last character written is
* <code>s[s.length-1]</code>. For each character,
* two bytes are actually written, high-order
* byte first, in exactly the manner of the
* <code>writeChar</code> method.
*
* @param s the string value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeChars(String s) throws IOException;
/**
* Writes two bytes of length information
* to the output stream, followed
* by the
* <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
* representation
* of every character in the string <code>s</code>.
* If <code>s</code> is <code>null</code>,
* a <code>NullPointerException</code> is thrown.
* Each character in the string <code>s</code>
* is converted to a group of one, two, or
* three bytes, depending on the value of the
* character.<p>
* If a character <code>c</code>
* is in the range <code>&#92;u0001</code> through
* <code>&#92;u007f</code>, it is represented
* by one byte:
* <pre>(byte)c </pre> <p>
* If a character <code>c</code> is <code>&#92;u0000</code>
* or is in the range <code>&#92;u0080</code>
* through <code>&#92;u07ff</code>, then it is
* represented by two bytes, to be written
* in the order shown: <pre>{@code
* (byte)(0xc0 | (0x1f & (c >> 6)))
* (byte)(0x80 | (0x3f & c))
* }</pre> <p> If a character
* <code>c</code> is in the range <code>&#92;u0800</code>
* through <code>uffff</code>, then it is
* represented by three bytes, to be written
* in the order shown: <pre>{@code
* (byte)(0xe0 | (0x0f & (c >> 12)))
* (byte)(0x80 | (0x3f & (c >> 6)))
* (byte)(0x80 | (0x3f & c))
* }</pre> <p> First,
* the total number of bytes needed to represent
* all the characters of <code>s</code> is
* calculated. If this number is larger than
* <code>65535</code>, then a <code>UTFDataFormatException</code>
* is thrown. Otherwise, this length is written
* to the output stream in exactly the manner
* of the <code>writeShort</code> method;
* after this, the one-, two-, or three-byte
* representation of each character in the
* string <code>s</code> is written.<p> The
* bytes written by this method may be read
* by the <code>readUTF</code> method of interface
* <code>DataInput</code> , which will then
* return a <code>String</code> equal to <code>s</code>.
*
* @param s the string value to be written.
* @throws IOException if an I/O error occurs.
*/
void writeUTF(String s) throws IOException;
}

View file

@ -0,0 +1,416 @@
/*
* Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A data output stream lets an application write primitive Java data
* types to an output stream in a portable way. An application can
* then use a data input stream to read the data back in.
*
* @author unascribed
* @see java.io.DataInputStream
* @since 1.0
*/
public
class DataOutputStream extends FilterOutputStream implements DataOutput {
/**
* The number of bytes written to the data output stream so far.
* If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
*/
protected int written;
/**
* bytearr is initialized on demand by writeUTF
*/
private byte[] bytearr = null;
/**
* Creates a new data output stream to write data to the specified
* underlying output stream. The counter <code>written</code> is
* set to zero.
*
* @param out the underlying output stream, to be saved for later
* use.
* @see java.io.FilterOutputStream#out
*/
public DataOutputStream(OutputStream out) {
super(out);
}
/**
* Increases the written counter by the specified value
* until it reaches Integer.MAX_VALUE.
*/
private void incCount(int value) {
int temp = written + value;
if (temp < 0) {
temp = Integer.MAX_VALUE;
}
written = temp;
}
/**
* Writes the specified byte (the low eight bits of the argument
* <code>b</code>) to the underlying output stream. If no exception
* is thrown, the counter <code>written</code> is incremented by
* <code>1</code>.
* <p>
* Implements the <code>write</code> method of <code>OutputStream</code>.
*
* @param b the <code>byte</code> to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public synchronized void write(int b) throws IOException {
out.write(b);
incCount(1);
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to the underlying output stream.
* If no exception is thrown, the counter <code>written</code> is
* incremented by <code>len</code>.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public synchronized void write(byte b[], int off, int len)
throws IOException
{
out.write(b, off, len);
incCount(len);
}
/**
* Flushes this data output stream. This forces any buffered output
* bytes to be written out to the stream.
* <p>
* The <code>flush</code> method of <code>DataOutputStream</code>
* calls the <code>flush</code> method of its underlying output stream.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException {
out.flush();
}
/**
* Writes a <code>boolean</code> to the underlying output stream as
* a 1-byte value. The value <code>true</code> is written out as the
* value <code>(byte)1</code>; the value <code>false</code> is
* written out as the value <code>(byte)0</code>. If no exception is
* thrown, the counter <code>written</code> is incremented by
* <code>1</code>.
*
* @param v a <code>boolean</code> value to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeBoolean(boolean v) throws IOException {
out.write(v ? 1 : 0);
incCount(1);
}
/**
* Writes out a <code>byte</code> to the underlying output stream as
* a 1-byte value. If no exception is thrown, the counter
* <code>written</code> is incremented by <code>1</code>.
*
* @param v a <code>byte</code> value to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeByte(int v) throws IOException {
out.write(v);
incCount(1);
}
/**
* Writes a <code>short</code> to the underlying output stream as two
* bytes, high byte first. If no exception is thrown, the counter
* <code>written</code> is incremented by <code>2</code>.
*
* @param v a <code>short</code> to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeShort(int v) throws IOException {
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
incCount(2);
}
/**
* Writes a <code>char</code> to the underlying output stream as a
* 2-byte value, high byte first. If no exception is thrown, the
* counter <code>written</code> is incremented by <code>2</code>.
*
* @param v a <code>char</code> value to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeChar(int v) throws IOException {
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
incCount(2);
}
/**
* Writes an <code>int</code> to the underlying output stream as four
* bytes, high byte first. If no exception is thrown, the counter
* <code>written</code> is incremented by <code>4</code>.
*
* @param v an <code>int</code> to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeInt(int v) throws IOException {
out.write((v >>> 24) & 0xFF);
out.write((v >>> 16) & 0xFF);
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
incCount(4);
}
private byte writeBuffer[] = new byte[8];
/**
* Writes a <code>long</code> to the underlying output stream as eight
* bytes, high byte first. In no exception is thrown, the counter
* <code>written</code> is incremented by <code>8</code>.
*
* @param v a <code>long</code> to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeLong(long v) throws IOException {
writeBuffer[0] = (byte)(v >>> 56);
writeBuffer[1] = (byte)(v >>> 48);
writeBuffer[2] = (byte)(v >>> 40);
writeBuffer[3] = (byte)(v >>> 32);
writeBuffer[4] = (byte)(v >>> 24);
writeBuffer[5] = (byte)(v >>> 16);
writeBuffer[6] = (byte)(v >>> 8);
writeBuffer[7] = (byte)(v >>> 0);
out.write(writeBuffer, 0, 8);
incCount(8);
}
/**
* Converts the float argument to an <code>int</code> using the
* <code>floatToIntBits</code> method in class <code>Float</code>,
* and then writes that <code>int</code> value to the underlying
* output stream as a 4-byte quantity, high byte first. If no
* exception is thrown, the counter <code>written</code> is
* incremented by <code>4</code>.
*
* @param v a <code>float</code> value to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
* @see java.lang.Float#floatToIntBits(float)
*/
public final void writeFloat(float v) throws IOException {
writeInt(Float.floatToIntBits(v));
}
/**
* Converts the double argument to a <code>long</code> using the
* <code>doubleToLongBits</code> method in class <code>Double</code>,
* and then writes that <code>long</code> value to the underlying
* output stream as an 8-byte quantity, high byte first. If no
* exception is thrown, the counter <code>written</code> is
* incremented by <code>8</code>.
*
* @param v a <code>double</code> value to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
* @see java.lang.Double#doubleToLongBits(double)
*/
public final void writeDouble(double v) throws IOException {
writeLong(Double.doubleToLongBits(v));
}
/**
* Writes out the string to the underlying output stream as a
* sequence of bytes. Each character in the string is written out, in
* sequence, by discarding its high eight bits. If no exception is
* thrown, the counter <code>written</code> is incremented by the
* length of <code>s</code>.
*
* @param s a string of bytes to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeBytes(String s) throws IOException {
int len = s.length();
for (int i = 0 ; i < len ; i++) {
out.write((byte)s.charAt(i));
}
incCount(len);
}
/**
* Writes a string to the underlying output stream as a sequence of
* characters. Each character is written to the data output stream as
* if by the <code>writeChar</code> method. If no exception is
* thrown, the counter <code>written</code> is incremented by twice
* the length of <code>s</code>.
*
* @param s a <code>String</code> value to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.DataOutputStream#writeChar(int)
* @see java.io.FilterOutputStream#out
*/
public final void writeChars(String s) throws IOException {
int len = s.length();
for (int i = 0 ; i < len ; i++) {
int v = s.charAt(i);
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
}
incCount(len * 2);
}
/**
* Writes a string to the underlying output stream using
* <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
* encoding in a machine-independent manner.
* <p>
* First, two bytes are written to the output stream as if by the
* <code>writeShort</code> method giving the number of bytes to
* follow. This value is the number of bytes actually written out,
* not the length of the string. Following the length, each character
* of the string is output, in sequence, using the modified UTF-8 encoding
* for the character. If no exception is thrown, the counter
* <code>written</code> is incremented by the total number of
* bytes written to the output stream. This will be at least two
* plus the length of <code>str</code>, and at most two plus
* thrice the length of <code>str</code>.
*
* @param str a string to be written.
* @exception IOException if an I/O error occurs.
*/
public final void writeUTF(String str) throws IOException {
writeUTF(str, this);
}
/**
* Writes a string to the specified DataOutput using
* <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
* encoding in a machine-independent manner.
* <p>
* First, two bytes are written to out as if by the <code>writeShort</code>
* method giving the number of bytes to follow. This value is the number of
* bytes actually written out, not the length of the string. Following the
* length, each character of the string is output, in sequence, using the
* modified UTF-8 encoding for the character. If no exception is thrown, the
* counter <code>written</code> is incremented by the total number of
* bytes written to the output stream. This will be at least two
* plus the length of <code>str</code>, and at most two plus
* thrice the length of <code>str</code>.
*
* @param str a string to be written.
* @param out destination to write to
* @return The number of bytes written out.
* @exception IOException if an I/O error occurs.
*/
static int writeUTF(String str, DataOutput out) throws IOException {
int strlen = str.length();
int utflen = 0;
int c, count = 0;
/* use charAt instead of copying String to char array */
for (int i = 0; i < strlen; i++) {
c = str.charAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
utflen++;
} else if (c > 0x07FF) {
utflen += 3;
} else {
utflen += 2;
}
}
if (utflen > 65535)
throw new UTFDataFormatException(
"encoded string too long: " + utflen + " bytes");
byte[] bytearr = null;
if (out instanceof DataOutputStream) {
DataOutputStream dos = (DataOutputStream)out;
if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
dos.bytearr = new byte[(utflen*2) + 2];
bytearr = dos.bytearr;
} else {
bytearr = new byte[utflen+2];
}
bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
int i=0;
for (i=0; i<strlen; i++) {
c = str.charAt(i);
if (!((c >= 0x0001) && (c <= 0x007F))) break;
bytearr[count++] = (byte) c;
}
for (;i < strlen; i++){
c = str.charAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
bytearr[count++] = (byte) c;
} else if (c > 0x07FF) {
bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
} else {
bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
}
}
out.write(bytearr, 0, utflen+2);
return utflen + 2;
}
/**
* Returns the current value of the counter <code>written</code>,
* the number of bytes written to this data output stream so far.
* If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
*
* @return the value of the <code>written</code> field.
* @see java.io.DataOutputStream#written
*/
public final int size() {
return written;
}
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.*;
import java.io.File;
import jdk.internal.misc.SharedSecrets;
/**
* This class holds a set of filenames to be deleted on VM exit through a shutdown hook.
* A set is used both to prevent double-insertion of the same file as well as offer
* quick removal.
*/
class DeleteOnExitHook {
private static LinkedHashSet<String> files = new LinkedHashSet<>();
static {
// DeleteOnExitHook must be the last shutdown hook to be invoked.
// Application shutdown hooks may add the first file to the
// delete on exit list and cause the DeleteOnExitHook to be
// registered during shutdown in progress. So set the
// registerShutdownInProgress parameter to true.
SharedSecrets.getJavaLangAccess()
.registerShutdownHook(2 /* Shutdown hook invocation order */,
true /* register even if shutdown in progress */,
new Runnable() {
public void run() {
runHooks();
}
}
);
}
private DeleteOnExitHook() {}
static synchronized void add(String file) {
if(files == null) {
// DeleteOnExitHook is running. Too late to add a file
throw new IllegalStateException("Shutdown in progress");
}
files.add(file);
}
static void runHooks() {
LinkedHashSet<String> theFiles;
synchronized (DeleteOnExitHook.class) {
theFiles = files;
files = null;
}
ArrayList<String> toBeDeleted = new ArrayList<>(theFiles);
// reverse the list to maintain previous jdk deletion order.
// Last in first deleted.
Collections.reverse(toBeDeleted);
for (String filename : toBeDeleted) {
(new File(filename)).delete();
}
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Signals that an end of file or end of stream has been reached
* unexpectedly during input.
* <p>
* This exception is mainly used by data input streams to signal end of
* stream. Note that many other input operations return a special value on
* end of stream rather than throwing an exception.
*
* @author Frank Yellin
* @see java.io.DataInputStream
* @see java.io.IOException
* @since 1.0
*/
public
class EOFException extends IOException {
private static final long serialVersionUID = 6433858223774886977L;
/**
* Constructs an <code>EOFException</code> with <code>null</code>
* as its error detail message.
*/
public EOFException() {
super();
}
/**
* Constructs an <code>EOFException</code> with the specified detail
* message. The string <code>s</code> may later be retrieved by the
* <code>{@link java.lang.Throwable#getMessage}</code> method of class
* <code>java.lang.Throwable</code>.
*
* @param s the detail message.
*/
public EOFException(String s) {
super(s);
}
}

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
package java.io;
import java.util.Iterator;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Set;
class ExpiringCache {
private long millisUntilExpiration;
private Map<String,Entry> map;
// Clear out old entries every few queries
private int queryCount;
private int queryOverflow = 300;
private int MAX_ENTRIES = 200;
static class Entry {
private long timestamp;
private String val;
Entry(long timestamp, String val) {
this.timestamp = timestamp;
this.val = val;
}
long timestamp() { return timestamp; }
void setTimestamp(long timestamp) { this.timestamp = timestamp; }
String val() { return val; }
void setVal(String val) { this.val = val; }
}
ExpiringCache() {
this(30000);
}
@SuppressWarnings("serial")
ExpiringCache(long millisUntilExpiration) {
this.millisUntilExpiration = millisUntilExpiration;
map = new LinkedHashMap<>() {
protected boolean removeEldestEntry(Map.Entry<String,Entry> eldest) {
return size() > MAX_ENTRIES;
}
};
}
synchronized String get(String key) {
if (++queryCount >= queryOverflow) {
cleanup();
}
Entry entry = entryFor(key);
if (entry != null) {
return entry.val();
}
return null;
}
synchronized void put(String key, String val) {
if (++queryCount >= queryOverflow) {
cleanup();
}
Entry entry = entryFor(key);
if (entry != null) {
entry.setTimestamp(System.currentTimeMillis());
entry.setVal(val);
} else {
map.put(key, new Entry(System.currentTimeMillis(), val));
}
}
synchronized void clear() {
map.clear();
}
private Entry entryFor(String key) {
Entry entry = map.get(key);
if (entry != null) {
long delta = System.currentTimeMillis() - entry.timestamp();
if (delta < 0 || delta >= millisUntilExpiration) {
map.remove(key);
entry = null;
}
}
return entry;
}
private void cleanup() {
Set<String> keySet = map.keySet();
// Avoid ConcurrentModificationExceptions
String[] keys = new String[keySet.size()];
int i = 0;
for (String key: keySet) {
keys[i++] = key;
}
for (int j = 0; j < keys.length; j++) {
entryFor(keys[j]);
}
queryCount = 0;
}
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.io.ObjectOutput;
import java.io.ObjectInput;
/**
* Only the identity of the class of an Externalizable instance is
* written in the serialization stream and it is the responsibility
* of the class to save and restore the contents of its instances.
*
* The writeExternal and readExternal methods of the Externalizable
* interface are implemented by a class to give the class complete
* control over the format and contents of the stream for an object
* and its supertypes. These methods must explicitly
* coordinate with the supertype to save its state. These methods supersede
* customized implementations of writeObject and readObject methods.<br>
*
* Object Serialization uses the Serializable and Externalizable
* interfaces. Object persistence mechanisms can use them as well. Each
* object to be stored is tested for the Externalizable interface. If
* the object supports Externalizable, the writeExternal method is called. If the
* object does not support Externalizable and does implement
* Serializable, the object is saved using
* ObjectOutputStream. <br> When an Externalizable object is
* reconstructed, an instance is created using the public no-arg
* constructor, then the readExternal method called. Serializable
* objects are restored by reading them from an ObjectInputStream.<br>
*
* An Externalizable instance can designate a substitution object via
* the writeReplace and readResolve methods documented in the Serializable
* interface.<br>
*
* @author unascribed
* @see java.io.ObjectOutputStream
* @see java.io.ObjectInputStream
* @see java.io.ObjectOutput
* @see java.io.ObjectInput
* @see java.io.Serializable
* @since 1.1
*/
public interface Externalizable extends java.io.Serializable {
/**
* The object implements the writeExternal method to save its contents
* by calling the methods of DataOutput for its primitive values or
* calling the writeObject method of ObjectOutput for objects, strings,
* and arrays.
*
* @serialData Overriding methods should use this tag to describe
* the data layout of this Externalizable object.
* List the sequence of element types and, if possible,
* relate the element to a public/protected field and/or
* method of this Externalizable class.
*
* @param out the stream to write the object to
* @exception IOException Includes any I/O exceptions that may occur
*/
void writeExternal(ObjectOutput out) throws IOException;
/**
* The object implements the readExternal method to restore its
* contents by calling the methods of DataInput for primitive
* types and readObject for objects, strings and arrays. The
* readExternal method must read the values in the same sequence
* and with the same types as were written by writeExternal.
*
* @param in the stream to read data from in order to restore the object
* @exception IOException if I/O errors occur
* @exception ClassNotFoundException If the class for an object being
* restored cannot be found.
*/
void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A filter for abstract pathnames.
*
* <p> Instances of this interface may be passed to the <code>{@link
* File#listFiles(java.io.FileFilter) listFiles(FileFilter)}</code> method
* of the <code>{@link java.io.File}</code> class.
*
* @since 1.2
*/
@FunctionalInterface
public interface FileFilter {
/**
* Tests whether or not the specified abstract pathname should be
* included in a pathname list.
*
* @param pathname The abstract pathname to be tested
* @return <code>true</code> if and only if <code>pathname</code>
* should be included
*/
boolean accept(File pathname);
}

View file

@ -0,0 +1,439 @@
/*
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.nio.channels.FileChannel;
import sun.nio.ch.FileChannelImpl;
/**
* A <code>FileInputStream</code> obtains input bytes
* from a file in a file system. What files
* are available depends on the host environment.
*
* <p><code>FileInputStream</code> is meant for reading streams of raw bytes
* such as image data. For reading streams of characters, consider using
* <code>FileReader</code>.
*
* @author Arthur van Hoff
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileOutputStream
* @see java.nio.file.Files#newInputStream
* @since 1.0
*/
public
class FileInputStream extends InputStream
{
/* File Descriptor - handle to the open file */
private final FileDescriptor fd;
/**
* The path of the referenced file
* (null if the stream is created with a file descriptor)
*/
private final String path;
private volatile FileChannel channel;
private final Object closeLock = new Object();
private volatile boolean closed;
/**
* Creates a <code>FileInputStream</code> by
* opening a connection to an actual file,
* the file named by the path name <code>name</code>
* in the file system. A new <code>FileDescriptor</code>
* object is created to represent this file
* connection.
* <p>
* First, if there is a security
* manager, its <code>checkRead</code> method
* is called with the <code>name</code> argument
* as its argument.
* <p>
* If the named file does not exist, is a directory rather than a regular
* file, or for some other reason cannot be opened for reading then a
* <code>FileNotFoundException</code> is thrown.
*
* @param name the system-dependent file name.
* @exception FileNotFoundException if the file does not exist,
* is a directory rather than a regular file,
* or for some other reason cannot be opened for
* reading.
* @exception SecurityException if a security manager exists and its
* <code>checkRead</code> method denies read access
* to the file.
* @see java.lang.SecurityManager#checkRead(java.lang.String)
*/
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
/**
* Creates a <code>FileInputStream</code> by
* opening a connection to an actual file,
* the file named by the <code>File</code>
* object <code>file</code> in the file system.
* A new <code>FileDescriptor</code> object
* is created to represent this file connection.
* <p>
* First, if there is a security manager,
* its <code>checkRead</code> method is called
* with the path represented by the <code>file</code>
* argument as its argument.
* <p>
* If the named file does not exist, is a directory rather than a regular
* file, or for some other reason cannot be opened for reading then a
* <code>FileNotFoundException</code> is thrown.
*
* @param file the file to be opened for reading.
* @exception FileNotFoundException if the file does not exist,
* is a directory rather than a regular file,
* or for some other reason cannot be opened for
* reading.
* @exception SecurityException if a security manager exists and its
* <code>checkRead</code> method denies read access to the file.
* @see java.io.File#getPath()
* @see java.lang.SecurityManager#checkRead(java.lang.String)
*/
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name);
}
/**
* Creates a <code>FileInputStream</code> by using the file descriptor
* <code>fdObj</code>, which represents an existing connection to an
* actual file in the file system.
* <p>
* If there is a security manager, its <code>checkRead</code> method is
* called with the file descriptor <code>fdObj</code> as its argument to
* see if it's ok to read the file descriptor. If read access is denied
* to the file descriptor a <code>SecurityException</code> is thrown.
* <p>
* If <code>fdObj</code> is null then a <code>NullPointerException</code>
* is thrown.
* <p>
* This constructor does not throw an exception if <code>fdObj</code>
* is {@link java.io.FileDescriptor#valid() invalid}.
* However, if the methods are invoked on the resulting stream to attempt
* I/O on the stream, an <code>IOException</code> is thrown.
*
* @param fdObj the file descriptor to be opened for reading.
* @throws SecurityException if a security manager exists and its
* <code>checkRead</code> method denies read access to the
* file descriptor.
* @see SecurityManager#checkRead(java.io.FileDescriptor)
*/
public FileInputStream(FileDescriptor fdObj) {
SecurityManager security = System.getSecurityManager();
if (fdObj == null) {
throw new NullPointerException();
}
if (security != null) {
security.checkRead(fdObj);
}
fd = fdObj;
path = null;
/*
* FileDescriptor is being shared by streams.
* Register this stream with FileDescriptor tracker.
*/
fd.attach(this);
}
/**
* Opens the specified file for reading.
* @param name the name of the file
*/
private native void open0(String name) throws FileNotFoundException;
// wrap native call to allow instrumentation
/**
* Opens the specified file for reading.
* @param name the name of the file
*/
private void open(String name) throws FileNotFoundException {
open0(name);
}
/**
* Reads a byte of data from this input stream. This method blocks
* if no input is yet available.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* file is reached.
* @exception IOException if an I/O error occurs.
*/
public int read() throws IOException {
return read0();
}
private native int read0() throws IOException;
/**
* Reads a subarray as a sequence of bytes.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
private native int readBytes(byte b[], int off, int len) throws IOException;
/**
* Reads up to <code>b.length</code> bytes of data from this input
* stream into an array of bytes. This method blocks until some input
* is available.
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[]) throws IOException {
return readBytes(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. If <code>len</code> is not zero, the method
* blocks until some input is available; otherwise, no
* bytes are read and <code>0</code> is returned.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[], int off, int len) throws IOException {
return readBytes(b, off, len);
}
/**
* Skips over and discards <code>n</code> bytes of data from the
* input stream.
*
* <p>The <code>skip</code> method may, for a variety of
* reasons, end up skipping over some smaller number of bytes,
* possibly <code>0</code>. If <code>n</code> is negative, the method
* will try to skip backwards. In case the backing file does not support
* backward skip at its current position, an <code>IOException</code> is
* thrown. The actual number of bytes skipped is returned. If it skips
* forwards, it returns a positive value. If it skips backwards, it
* returns a negative value.
*
* <p>This method may skip more bytes than what are remaining in the
* backing file. This produces no exception and the number of bytes skipped
* may include some number of bytes that were beyond the EOF of the
* backing file. Attempting to read from the stream after skipping past
* the end will result in -1 indicating the end of the file.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @exception IOException if n is negative, if the stream does not
* support seek, or if an I/O error occurs.
*/
public long skip(long n) throws IOException {
return skip0(n);
}
private native long skip0(long n) throws IOException;
/**
* Returns an estimate of the number of remaining bytes that can be read (or
* skipped over) from this input stream without blocking by the next
* invocation of a method for this input stream. Returns 0 when the file
* position is beyond EOF. The next invocation might be the same thread
* or another thread. A single read or skip of this many bytes will not
* block, but may read or skip fewer bytes.
*
* <p> In some cases, a non-blocking read (or skip) may appear to be
* blocked when it is merely slow, for example when reading large
* files over slow networks.
*
* @return an estimate of the number of remaining bytes that can be read
* (or skipped over) from this input stream without blocking.
* @exception IOException if this file input stream has been closed by calling
* {@code close} or an I/O error occurs.
*/
public int available() throws IOException {
return available0();
}
private native int available0() throws IOException;
/**
* Closes this file input stream and releases any system resources
* associated with the stream.
*
* <p> If this stream has an associated channel then the channel is closed
* as well.
*
* @exception IOException if an I/O error occurs.
*
* @revised 1.4
* @spec JSR-51
*/
public void close() throws IOException {
if (closed) {
return;
}
synchronized (closeLock) {
if (closed) {
return;
}
closed = true;
}
FileChannel fc = channel;
if (fc != null) {
// possible race with getChannel(), benign since
// FileChannel.close is final and idempotent
fc.close();
}
fd.closeAll(new Closeable() {
public void close() throws IOException {
close0();
}
});
}
/**
* Returns the <code>FileDescriptor</code>
* object that represents the connection to
* the actual file in the file system being
* used by this <code>FileInputStream</code>.
*
* @return the file descriptor object associated with this stream.
* @exception IOException if an I/O error occurs.
* @see java.io.FileDescriptor
*/
public final FileDescriptor getFD() throws IOException {
if (fd != null) {
return fd;
}
throw new IOException();
}
/**
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
* object associated with this file input stream.
*
* <p> The initial {@link java.nio.channels.FileChannel#position()
* position} of the returned channel will be equal to the
* number of bytes read from the file so far. Reading bytes from this
* stream will increment the channel's position. Changing the channel's
* position, either explicitly or by reading, will change this stream's
* file position.
*
* @return the file channel associated with this file input stream
*
* @since 1.4
* @spec JSR-51
*/
public FileChannel getChannel() {
FileChannel fc = this.channel;
if (fc == null) {
synchronized (this) {
fc = this.channel;
if (fc == null) {
this.channel = fc = FileChannelImpl.open(fd, path, true, false, this);
if (closed) {
try {
// possible race with close(), benign since
// FileChannel.close is final and idempotent
fc.close();
} catch (IOException ioe) {
throw new InternalError(ioe); // should not happen
}
}
}
}
}
return fc;
}
private static native void initIDs();
private native void close0() throws IOException;
static {
initIDs();
}
/**
* Ensures that the <code>close</code> method of this file input stream is
* called when there are no more references to it.
*
* @deprecated The {@code finalize} method has been deprecated.
* Subclasses that override {@code finalize} in order to perform cleanup
* should be modified to use alternative cleanup mechanisms and
* to remove the overriding {@code finalize} method.
* When overriding the {@code finalize} method, its implementation must explicitly
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
* See the specification for {@link Object#finalize()} for further
* information about migration options.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
@Deprecated(since="9")
protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Signals that an attempt to open the file denoted by a specified pathname
* has failed.
*
* <p> This exception will be thrown by the {@link FileInputStream}, {@link
* FileOutputStream}, and {@link RandomAccessFile} constructors when a file
* with the specified pathname does not exist. It will also be thrown by these
* constructors if the file does exist but for some reason is inaccessible, for
* example when an attempt is made to open a read-only file for writing.
*
* @author unascribed
* @since 1.0
*/
public class FileNotFoundException extends IOException {
private static final long serialVersionUID = -897856973823710492L;
/**
* Constructs a <code>FileNotFoundException</code> with
* <code>null</code> as its error detail message.
*/
public FileNotFoundException() {
super();
}
/**
* Constructs a <code>FileNotFoundException</code> with the
* specified detail message. The string <code>s</code> can be
* retrieved later by the
* <code>{@link java.lang.Throwable#getMessage}</code>
* method of class <code>java.lang.Throwable</code>.
*
* @param s the detail message.
*/
public FileNotFoundException(String s) {
super(s);
}
/**
* Constructs a <code>FileNotFoundException</code> with a detail message
* consisting of the given pathname string followed by the given reason
* string. If the <code>reason</code> argument is <code>null</code> then
* it will be omitted. This private constructor is invoked only by native
* I/O methods.
*
* @since 1.2
*/
private FileNotFoundException(String path, String reason) {
super(path + ((reason == null)
? ""
: " (" + reason + ")"));
}
}

View file

@ -0,0 +1,469 @@
/*
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.nio.channels.FileChannel;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
import sun.nio.ch.FileChannelImpl;
/**
* A file output stream is an output stream for writing data to a
* <code>File</code> or to a <code>FileDescriptor</code>. Whether or not
* a file is available or may be created depends upon the underlying
* platform. Some platforms, in particular, allow a file to be opened
* for writing by only one {@code FileOutputStream} (or other
* file-writing object) at a time. In such situations the constructors in
* this class will fail if the file involved is already open.
*
* <p><code>FileOutputStream</code> is meant for writing streams of raw bytes
* such as image data. For writing streams of characters, consider using
* <code>FileWriter</code>.
*
* @author Arthur van Hoff
* @see java.io.File
* @see java.io.FileDescriptor
* @see java.io.FileInputStream
* @see java.nio.file.Files#newOutputStream
* @since 1.0
*/
public
class FileOutputStream extends OutputStream
{
/**
* Access to FileDescriptor internals.
*/
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
/**
* The system dependent file descriptor.
*/
private final FileDescriptor fd;
/**
* The associated channel, initialized lazily.
*/
private volatile FileChannel channel;
/**
* The path of the referenced file
* (null if the stream is created with a file descriptor)
*/
private final String path;
private final Object closeLock = new Object();
private volatile boolean closed;
/**
* Creates a file output stream to write to the file with the
* specified name. A new <code>FileDescriptor</code> object is
* created to represent this file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with <code>name</code> as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @implSpec Invoking this constructor with the parameter {@code name} is
* equivalent to invoking {@link #FileOutputStream(String,boolean)
* new FileOutputStream(name, false)}.
*
* @param name the system-dependent filename
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null, false);
}
/**
* Creates a file output stream to write to the file with the specified
* name. If the second argument is <code>true</code>, then
* bytes will be written to the end of the file rather than the beginning.
* A new <code>FileDescriptor</code> object is created to represent this
* file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with <code>name</code> as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @param name the system-dependent file name
* @param append if <code>true</code>, then bytes will be written
* to the end of the file rather than the beginning
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason.
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
* @since 1.1
*/
public FileOutputStream(String name, boolean append)
throws FileNotFoundException
{
this(name != null ? new File(name) : null, append);
}
/**
* Creates a file output stream to write to the file represented by
* the specified <code>File</code> object. A new
* <code>FileDescriptor</code> object is created to represent this
* file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with the path represented by the <code>file</code>
* argument as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @param file the file to be opened for writing.
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.io.File#getPath()
* @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(File file) throws FileNotFoundException {
this(file, false);
}
/**
* Creates a file output stream to write to the file represented by
* the specified <code>File</code> object. If the second argument is
* <code>true</code>, then bytes will be written to the end of the file
* rather than the beginning. A new <code>FileDescriptor</code> object is
* created to represent this file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with the path represented by the <code>file</code>
* argument as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @param file the file to be opened for writing.
* @param append if <code>true</code>, then bytes will be written
* to the end of the file rather than the beginning
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.io.File#getPath()
* @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
* @since 1.4
*/
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
this.fd = new FileDescriptor();
fd.attach(this);
this.path = name;
open(name, append);
}
/**
* Creates a file output stream to write to the specified file
* descriptor, which represents an existing connection to an actual
* file in the file system.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with the file descriptor <code>fdObj</code>
* argument as its argument.
* <p>
* If <code>fdObj</code> is null then a <code>NullPointerException</code>
* is thrown.
* <p>
* This constructor does not throw an exception if <code>fdObj</code>
* is {@link java.io.FileDescriptor#valid() invalid}.
* However, if the methods are invoked on the resulting stream to attempt
* I/O on the stream, an <code>IOException</code> is thrown.
*
* @param fdObj the file descriptor to be opened for writing
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies
* write access to the file descriptor
* @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)
*/
public FileOutputStream(FileDescriptor fdObj) {
SecurityManager security = System.getSecurityManager();
if (fdObj == null) {
throw new NullPointerException();
}
if (security != null) {
security.checkWrite(fdObj);
}
this.fd = fdObj;
this.path = null;
fd.attach(this);
}
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private native void open0(String name, boolean append)
throws FileNotFoundException;
// wrap native call to allow instrumentation
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private void open(String name, boolean append)
throws FileNotFoundException {
open0(name, append);
}
/**
* Writes the specified byte to this file output stream.
*
* @param b the byte to be written.
* @param append {@code true} if the write operation first
* advances the position to the end of file
*/
private native void write(int b, boolean append) throws IOException;
/**
* Writes the specified byte to this file output stream. Implements
* the <code>write</code> method of <code>OutputStream</code>.
*
* @param b the byte to be written.
* @exception IOException if an I/O error occurs.
*/
public void write(int b) throws IOException {
write(b, fdAccess.getAppend(fd));
}
/**
* Writes a sub array as a sequence of bytes.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @param append {@code true} to first advance the position to the
* end of file
* @exception IOException If an I/O error has occurred.
*/
private native void writeBytes(byte b[], int off, int len, boolean append)
throws IOException;
/**
* Writes <code>b.length</code> bytes from the specified byte array
* to this file output stream.
*
* @param b the data.
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[]) throws IOException {
writeBytes(b, 0, b.length, fdAccess.getAppend(fd));
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this file output stream.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
writeBytes(b, off, len, fdAccess.getAppend(fd));
}
/**
* Closes this file output stream and releases any system resources
* associated with this stream. This file output stream may no longer
* be used for writing bytes.
*
* <p> If this stream has an associated channel then the channel is closed
* as well.
*
* @exception IOException if an I/O error occurs.
*
* @revised 1.4
* @spec JSR-51
*/
public void close() throws IOException {
if (closed) {
return;
}
synchronized (closeLock) {
if (closed) {
return;
}
closed = true;
}
FileChannel fc = channel;
if (fc != null) {
// possible race with getChannel(), benign since
// FileChannel.close is final and idempotent
fc.close();
}
fd.closeAll(new Closeable() {
public void close() throws IOException {
close0();
}
});
}
/**
* Returns the file descriptor associated with this stream.
*
* @return the <code>FileDescriptor</code> object that represents
* the connection to the file in the file system being used
* by this <code>FileOutputStream</code> object.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileDescriptor
*/
public final FileDescriptor getFD() throws IOException {
if (fd != null) {
return fd;
}
throw new IOException();
}
/**
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
* object associated with this file output stream.
*
* <p> The initial {@link java.nio.channels.FileChannel#position()
* position} of the returned channel will be equal to the
* number of bytes written to the file so far unless this stream is in
* append mode, in which case it will be equal to the size of the file.
* Writing bytes to this stream will increment the channel's position
* accordingly. Changing the channel's position, either explicitly or by
* writing, will change this stream's file position.
*
* @return the file channel associated with this file output stream
*
* @since 1.4
* @spec JSR-51
*/
public FileChannel getChannel() {
FileChannel fc = this.channel;
if (fc == null) {
synchronized (this) {
fc = this.channel;
if (fc == null) {
this.channel = fc = FileChannelImpl.open(fd, path, false, true, this);
if (closed) {
try {
// possible race with close(), benign since
// FileChannel.close is final and idempotent
fc.close();
} catch (IOException ioe) {
throw new InternalError(ioe); // should not happen
}
}
}
}
}
return fc;
}
/**
* Cleans up the connection to the file, and ensures that the
* <code>close</code> method of this file output stream is
* called when there are no more references to this stream.
*
* @deprecated The {@code finalize} method has been deprecated.
* Subclasses that override {@code finalize} in order to perform cleanup
* should be modified to use alternative cleanup mechanisms and
* to remove the overriding {@code finalize} method.
* When overriding the {@code finalize} method, its implementation must explicitly
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
* See the specification for {@link Object#finalize()} for further
* information about migration options.
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
@Deprecated(since="9")
protected void finalize() throws IOException {
if (fd != null) {
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush();
} else {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
}
private native void close0() throws IOException;
private static native void initIDs();
static {
initIDs();
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Convenience class for reading character files. The constructors of this
* class assume that the default character encoding and the default byte-buffer
* size are appropriate. To specify these values yourself, construct an
* InputStreamReader on a FileInputStream.
*
* <p>{@code FileReader} is meant for reading streams of characters.
* For reading streams of raw bytes, consider using a
* {@code FileInputStream}.
*
* @see InputStreamReader
* @see FileInputStream
*
* @author Mark Reinhold
* @since 1.1
*/
public class FileReader extends InputStreamReader {
/**
* Creates a new {@code FileReader}, given the name of the
* file to read from.
*
* @param fileName the name of the file to read from
* @exception FileNotFoundException if the named file does not exist,
* is a directory rather than a regular file,
* or for some other reason cannot be opened for
* reading.
*/
public FileReader(String fileName) throws FileNotFoundException {
super(new FileInputStream(fileName));
}
/**
* Creates a new {@code FileReader}, given the {@code File}
* to read from.
*
* @param file the {@code File} to read from
* @exception FileNotFoundException if the file does not exist,
* is a directory rather than a regular file,
* or for some other reason cannot be opened for
* reading.
*/
public FileReader(File file) throws FileNotFoundException {
super(new FileInputStream(file));
}
/**
* Creates a new {@code FileReader}, given the
* {@code FileDescriptor} to read from.
*
* @param fd the FileDescriptor to read from
*/
public FileReader(FileDescriptor fd) {
super(new FileInputStream(fd));
}
}

View file

@ -0,0 +1,248 @@
/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.lang.annotation.Native;
/**
* Package-private abstract class for the local filesystem abstraction.
*/
abstract class FileSystem {
/* -- Normalization and construction -- */
/**
* Return the local filesystem's name-separator character.
*/
public abstract char getSeparator();
/**
* Return the local filesystem's path-separator character.
*/
public abstract char getPathSeparator();
/**
* Convert the given pathname string to normal form. If the string is
* already in normal form then it is simply returned.
*/
public abstract String normalize(String path);
/**
* Compute the length of this pathname string's prefix. The pathname
* string must be in normal form.
*/
public abstract int prefixLength(String path);
/**
* Resolve the child pathname string against the parent.
* Both strings must be in normal form, and the result
* will be in normal form.
*/
public abstract String resolve(String parent, String child);
/**
* Return the parent pathname string to be used when the parent-directory
* argument in one of the two-argument File constructors is the empty
* pathname.
*/
public abstract String getDefaultParent();
/**
* Post-process the given URI path string if necessary. This is used on
* win32, e.g., to transform "/c:/foo" into "c:/foo". The path string
* still has slash separators; code in the File class will translate them
* after this method returns.
*/
public abstract String fromURIPath(String path);
/* -- Path operations -- */
/**
* Tell whether or not the given abstract pathname is absolute.
*/
public abstract boolean isAbsolute(File f);
/**
* Resolve the given abstract pathname into absolute form. Invoked by the
* getAbsolutePath and getCanonicalPath methods in the File class.
*/
public abstract String resolve(File f);
public abstract String canonicalize(String path) throws IOException;
/* -- Attribute accessors -- */
/* Constants for simple boolean attributes */
@Native public static final int BA_EXISTS = 0x01;
@Native public static final int BA_REGULAR = 0x02;
@Native public static final int BA_DIRECTORY = 0x04;
@Native public static final int BA_HIDDEN = 0x08;
/**
* Return the simple boolean attributes for the file or directory denoted
* by the given abstract pathname, or zero if it does not exist or some
* other I/O error occurs.
*/
public abstract int getBooleanAttributes(File f);
@Native public static final int ACCESS_READ = 0x04;
@Native public static final int ACCESS_WRITE = 0x02;
@Native public static final int ACCESS_EXECUTE = 0x01;
/**
* Check whether the file or directory denoted by the given abstract
* pathname may be accessed by this process. The second argument specifies
* which access, ACCESS_READ, ACCESS_WRITE or ACCESS_EXECUTE, to check.
* Return false if access is denied or an I/O error occurs
*/
public abstract boolean checkAccess(File f, int access);
/**
* Set on or off the access permission (to owner only or to all) to the file
* or directory denoted by the given abstract pathname, based on the parameters
* enable, access and oweronly.
*/
public abstract boolean setPermission(File f, int access, boolean enable, boolean owneronly);
/**
* Return the time at which the file or directory denoted by the given
* abstract pathname was last modified, or zero if it does not exist or
* some other I/O error occurs.
*/
public abstract long getLastModifiedTime(File f);
/**
* Return the length in bytes of the file denoted by the given abstract
* pathname, or zero if it does not exist, is a directory, or some other
* I/O error occurs.
*/
public abstract long getLength(File f);
/* -- File operations -- */
/**
* Create a new empty file with the given pathname. Return
* <code>true</code> if the file was created and <code>false</code> if a
* file or directory with the given pathname already exists. Throw an
* IOException if an I/O error occurs.
*/
public abstract boolean createFileExclusively(String pathname)
throws IOException;
/**
* Delete the file or directory denoted by the given abstract pathname,
* returning <code>true</code> if and only if the operation succeeds.
*/
public abstract boolean delete(File f);
/**
* List the elements of the directory denoted by the given abstract
* pathname. Return an array of strings naming the elements of the
* directory if successful; otherwise, return <code>null</code>.
*/
public abstract String[] list(File f);
/**
* Create a new directory denoted by the given abstract pathname,
* returning <code>true</code> if and only if the operation succeeds.
*/
public abstract boolean createDirectory(File f);
/**
* Rename the file or directory denoted by the first abstract pathname to
* the second abstract pathname, returning <code>true</code> if and only if
* the operation succeeds.
*/
public abstract boolean rename(File f1, File f2);
/**
* Set the last-modified time of the file or directory denoted by the
* given abstract pathname, returning <code>true</code> if and only if the
* operation succeeds.
*/
public abstract boolean setLastModifiedTime(File f, long time);
/**
* Mark the file or directory denoted by the given abstract pathname as
* read-only, returning <code>true</code> if and only if the operation
* succeeds.
*/
public abstract boolean setReadOnly(File f);
/* -- Filesystem interface -- */
/**
* List the available filesystem roots.
*/
public abstract File[] listRoots();
/* -- Disk usage -- */
@Native public static final int SPACE_TOTAL = 0;
@Native public static final int SPACE_FREE = 1;
@Native public static final int SPACE_USABLE = 2;
public abstract long getSpace(File f, int t);
/* -- Basic infrastructure -- */
/**
* Retrieve the maximum length of a component of a file path.
*
* @return The maximum length of a file path component.
*/
public abstract int getNameMax(String path);
/**
* Compare two abstract pathnames lexicographically.
*/
public abstract int compare(File f1, File f2);
/**
* Compute the hash code of an abstract pathname.
*/
public abstract int hashCode(File f);
// Flags for enabling/disabling performance optimizations for file
// name canonicalization
static boolean useCanonCaches = true;
static boolean useCanonPrefixCache = true;
private static boolean getBooleanProperty(String prop, boolean defaultVal) {
return Boolean.parseBoolean(System.getProperty(prop,
String.valueOf(defaultVal)));
}
static {
useCanonCaches = getBooleanProperty("sun.io.useCanonCaches",
useCanonCaches);
useCanonPrefixCache = getBooleanProperty("sun.io.useCanonPrefixCache",
useCanonPrefixCache);
}
}

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Convenience class for writing character files. The constructors of this
* class assume that the default character encoding and the default byte-buffer
* size are acceptable. To specify these values yourself, construct an
* OutputStreamWriter on a FileOutputStream.
*
* <p>Whether or not a file is available or may be created depends upon the
* underlying platform. Some platforms, in particular, allow a file to be
* opened for writing by only one {@code FileWriter} (or other file-writing
* object) at a time. In such situations the constructors in this class
* will fail if the file involved is already open.
*
* <p>{@code FileWriter} is meant for writing streams of characters.
* For writing streams of raw bytes, consider using a
* {@code FileOutputStream}.
*
* @see OutputStreamWriter
* @see FileOutputStream
*
* @author Mark Reinhold
* @since 1.1
*/
public class FileWriter extends OutputStreamWriter {
/**
* Constructs a FileWriter object given a file name.
*
* @param fileName String The system-dependent filename.
* @throws IOException if the named file exists but is a directory rather
* than a regular file, does not exist but cannot be
* created, or cannot be opened for any other reason
*/
public FileWriter(String fileName) throws IOException {
super(new FileOutputStream(fileName));
}
/**
* Constructs a FileWriter object given a file name with a boolean
* indicating whether or not to append the data written.
*
* @param fileName String The system-dependent filename.
* @param append boolean if {@code true}, then data will be written
* to the end of the file rather than the beginning.
* @throws IOException if the named file exists but is a directory rather
* than a regular file, does not exist but cannot be
* created, or cannot be opened for any other reason
*/
public FileWriter(String fileName, boolean append) throws IOException {
super(new FileOutputStream(fileName, append));
}
/**
* Constructs a FileWriter object given a File object.
*
* @param file a File object to write to.
* @throws IOException if the file exists but is a directory rather than
* a regular file, does not exist but cannot be created,
* or cannot be opened for any other reason
*/
public FileWriter(File file) throws IOException {
super(new FileOutputStream(file));
}
/**
* Constructs a FileWriter object given a File object. If the second
* argument is {@code true}, then bytes will be written to the end
* of the file rather than the beginning.
*
* @param file a File object to write to
* @param append if {@code true}, then bytes will be written
* to the end of the file rather than the beginning
* @throws IOException if the file exists but is a directory rather than
* a regular file, does not exist but cannot be created,
* or cannot be opened for any other reason
* @since 1.4
*/
public FileWriter(File file, boolean append) throws IOException {
super(new FileOutputStream(file, append));
}
/**
* Constructs a FileWriter object associated with a file descriptor.
*
* @param fd FileDescriptor object to write to.
*/
public FileWriter(FileDescriptor fd) {
super(new FileOutputStream(fd));
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Instances of classes that implement this interface are used to
* filter filenames. These instances are used to filter directory
* listings in the <code>list</code> method of class
* <code>File</code>, and by the Abstract Window Toolkit's file
* dialog component.
*
* @author Arthur van Hoff
* @author Jonathan Payne
* @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
* @see java.io.File
* @see java.io.File#list(java.io.FilenameFilter)
* @since 1.0
*/
@FunctionalInterface
public interface FilenameFilter {
/**
* Tests if a specified file should be included in a file list.
*
* @param dir the directory in which the file was found.
* @param name the name of the file.
* @return <code>true</code> if and only if the name should be
* included in the file list; <code>false</code> otherwise.
*/
boolean accept(File dir, String name);
}

View file

@ -0,0 +1,244 @@
/*
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A <code>FilterInputStream</code> contains
* some other input stream, which it uses as
* its basic source of data, possibly transforming
* the data along the way or providing additional
* functionality. The class <code>FilterInputStream</code>
* itself simply overrides all methods of
* <code>InputStream</code> with versions that
* pass all requests to the contained input
* stream. Subclasses of <code>FilterInputStream</code>
* may further override some of these methods
* and may also provide additional methods
* and fields.
*
* @author Jonathan Payne
* @since 1.0
*/
public
class FilterInputStream extends InputStream {
/**
* The input stream to be filtered.
*/
protected volatile InputStream in;
/**
* Creates a <code>FilterInputStream</code>
* by assigning the argument <code>in</code>
* to the field <code>this.in</code> so as
* to remember it for later use.
*
* @param in the underlying input stream, or <code>null</code> if
* this instance is to be created without an underlying stream.
*/
protected FilterInputStream(InputStream in) {
this.in = in;
}
/**
* Reads the next byte of data from this input stream. The value
* byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>. If no byte is available
* because the end of the stream has been reached, the value
* <code>-1</code> is returned. This method blocks until input data
* is available, the end of the stream is detected, or an exception
* is thrown.
* <p>
* This method
* simply performs <code>in.read()</code> and returns the result.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public int read() throws IOException {
return in.read();
}
/**
* Reads up to <code>b.length</code> bytes of data from this
* input stream into an array of bytes. This method blocks until some
* input is available.
* <p>
* This method simply performs the call
* <code>read(b, 0, b.length)</code> and returns
* the result. It is important that it does
* <i>not</i> do <code>in.read(b)</code> instead;
* certain subclasses of <code>FilterInputStream</code>
* depend on the implementation strategy actually
* used.
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#read(byte[], int, int)
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. If <code>len</code> is not zero, the method
* blocks until some input is available; otherwise, no
* bytes are read and <code>0</code> is returned.
* <p>
* This method simply performs <code>in.read(b, off, len)</code>
* and returns the result.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);
}
/**
* Skips over and discards <code>n</code> bytes of data from the
* input stream. The <code>skip</code> method may, for a variety of
* reasons, end up skipping over some smaller number of bytes,
* possibly <code>0</code>. The actual number of bytes skipped is
* returned.
* <p>
* This method simply performs <code>in.skip(n)</code>.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @throws IOException if {@code in.skip(n)} throws an IOException.
*/
public long skip(long n) throws IOException {
return in.skip(n);
}
/**
* Returns an estimate of the number of bytes that can be read (or
* skipped over) from this input stream without blocking by the next
* caller of a method for this input stream. The next caller might be
* the same thread or another thread. A single read or skip of this
* many bytes will not block, but may read or skip fewer bytes.
* <p>
* This method returns the result of {@link #in in}.available().
*
* @return an estimate of the number of bytes that can be read (or skipped
* over) from this input stream without blocking.
* @exception IOException if an I/O error occurs.
*/
public int available() throws IOException {
return in.available();
}
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* This
* method simply performs <code>in.close()</code>.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public void close() throws IOException {
in.close();
}
/**
* Marks the current position in this input stream. A subsequent
* call to the <code>reset</code> method repositions this stream at
* the last marked position so that subsequent reads re-read the same bytes.
* <p>
* The <code>readlimit</code> argument tells this input stream to
* allow that many bytes to be read before the mark position gets
* invalidated.
* <p>
* This method simply performs <code>in.mark(readlimit)</code>.
*
* @param readlimit the maximum limit of bytes that can be read before
* the mark position becomes invalid.
* @see java.io.FilterInputStream#in
* @see java.io.FilterInputStream#reset()
*/
public synchronized void mark(int readlimit) {
in.mark(readlimit);
}
/**
* Repositions this stream to the position at the time the
* <code>mark</code> method was last called on this input stream.
* <p>
* This method
* simply performs <code>in.reset()</code>.
* <p>
* Stream marks are intended to be used in
* situations where you need to read ahead a little to see what's in
* the stream. Often this is most easily done by invoking some
* general parser. If the stream is of the type handled by the
* parse, it just chugs along happily. If the stream is not of
* that type, the parser should toss an exception when it fails.
* If this happens within readlimit bytes, it allows the outer
* code to reset the stream and try another parser.
*
* @exception IOException if the stream has not been marked or if the
* mark has been invalidated.
* @see java.io.FilterInputStream#in
* @see java.io.FilterInputStream#mark(int)
*/
public synchronized void reset() throws IOException {
in.reset();
}
/**
* Tests if this input stream supports the <code>mark</code>
* and <code>reset</code> methods.
* This method
* simply performs <code>in.markSupported()</code>.
*
* @return <code>true</code> if this stream type supports the
* <code>mark</code> and <code>reset</code> method;
* <code>false</code> otherwise.
* @see java.io.FilterInputStream#in
* @see java.io.InputStream#mark(int)
* @see java.io.InputStream#reset()
*/
public boolean markSupported() {
return in.markSupported();
}
}

View file

@ -0,0 +1,209 @@
/*
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* This class is the superclass of all classes that filter output
* streams. These streams sit on top of an already existing output
* stream (the <i>underlying</i> output stream) which it uses as its
* basic sink of data, but possibly transforming the data along the
* way or providing additional functionality.
* <p>
* The class <code>FilterOutputStream</code> itself simply overrides
* all methods of <code>OutputStream</code> with versions that pass
* all requests to the underlying output stream. Subclasses of
* <code>FilterOutputStream</code> may further override some of these
* methods as well as provide additional methods and fields.
*
* @author Jonathan Payne
* @since 1.0
*/
public class FilterOutputStream extends OutputStream {
/**
* The underlying output stream to be filtered.
*/
protected OutputStream out;
/**
* Whether the stream is closed; implicitly initialized to false.
*/
private volatile boolean closed;
/**
* Object used to prevent a race on the 'closed' instance variable.
*/
private final Object closeLock = new Object();
/**
* Creates an output stream filter built on top of the specified
* underlying output stream.
*
* @param out the underlying output stream to be assigned to
* the field {@code this.out} for later use, or
* <code>null</code> if this instance is to be
* created without an underlying stream.
*/
public FilterOutputStream(OutputStream out) {
this.out = out;
}
/**
* Writes the specified <code>byte</code> to this output stream.
* <p>
* The <code>write</code> method of <code>FilterOutputStream</code>
* calls the <code>write</code> method of its underlying output stream,
* that is, it performs {@code out.write(b)}.
* <p>
* Implements the abstract {@code write} method of {@code OutputStream}.
*
* @param b the <code>byte</code>.
* @exception IOException if an I/O error occurs.
*/
@Override
public void write(int b) throws IOException {
out.write(b);
}
/**
* Writes <code>b.length</code> bytes to this output stream.
* <p>
* The <code>write</code> method of <code>FilterOutputStream</code>
* calls its <code>write</code> method of three arguments with the
* arguments <code>b</code>, <code>0</code>, and
* <code>b.length</code>.
* <p>
* Note that this method does not call the one-argument
* <code>write</code> method of its underlying output stream with
* the single argument <code>b</code>.
*
* @param b the data to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#write(byte[], int, int)
*/
@Override
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
/**
* Writes <code>len</code> bytes from the specified
* <code>byte</code> array starting at offset <code>off</code> to
* this output stream.
* <p>
* The <code>write</code> method of <code>FilterOutputStream</code>
* calls the <code>write</code> method of one argument on each
* <code>byte</code> to output.
* <p>
* Note that this method does not call the <code>write</code> method
* of its underlying output stream with the same arguments. Subclasses
* of <code>FilterOutputStream</code> should provide a more efficient
* implementation of this method.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#write(int)
*/
@Override
public void write(byte b[], int off, int len) throws IOException {
if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
throw new IndexOutOfBoundsException();
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
/**
* Flushes this output stream and forces any buffered output bytes
* to be written out to the stream.
* <p>
* The <code>flush</code> method of <code>FilterOutputStream</code>
* calls the <code>flush</code> method of its underlying output stream.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
@Override
public void flush() throws IOException {
out.flush();
}
/**
* Closes this output stream and releases any system resources
* associated with the stream.
* <p>
* When not already closed, the {@code close} method of {@code
* FilterOutputStream} calls its {@code flush} method, and then
* calls the {@code close} method of its underlying output stream.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#flush()
* @see java.io.FilterOutputStream#out
*/
@Override
public void close() throws IOException {
if (closed) {
return;
}
synchronized (closeLock) {
if (closed) {
return;
}
closed = true;
}
Throwable flushException = null;
try {
flush();
} catch (Throwable e) {
flushException = e;
throw e;
} finally {
if (flushException == null) {
out.close();
} else {
try {
out.close();
} catch (Throwable closeException) {
// evaluate possible precedence of flushException over closeException
if ((flushException instanceof ThreadDeath) &&
!(closeException instanceof ThreadDeath)) {
flushException.addSuppressed(closeException);
throw (ThreadDeath) flushException;
}
if (flushException != closeException) {
closeException.addSuppressed(flushException);
}
throw closeException;
}
}
}
}
}

View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Abstract class for reading filtered character streams.
* The abstract class <code>FilterReader</code> itself
* provides default methods that pass all requests to
* the contained stream. Subclasses of <code>FilterReader</code>
* should override some of these methods and may also provide
* additional methods and fields.
*
* @author Mark Reinhold
* @since 1.1
*/
public abstract class FilterReader extends Reader {
/**
* The underlying character-input stream.
*/
protected Reader in;
/**
* Creates a new filtered reader.
*
* @param in a Reader object providing the underlying stream.
* @throws NullPointerException if <code>in</code> is <code>null</code>
*/
protected FilterReader(Reader in) {
super(in);
this.in = in;
}
/**
* Reads a single character.
*
* @exception IOException If an I/O error occurs
*/
public int read() throws IOException {
return in.read();
}
/**
* Reads characters into a portion of an array.
*
* @exception IOException If an I/O error occurs
* @exception IndexOutOfBoundsException {@inheritDoc}
*/
public int read(char cbuf[], int off, int len) throws IOException {
return in.read(cbuf, off, len);
}
/**
* Skips characters.
*
* @exception IOException If an I/O error occurs
*/
public long skip(long n) throws IOException {
return in.skip(n);
}
/**
* Tells whether this stream is ready to be read.
*
* @exception IOException If an I/O error occurs
*/
public boolean ready() throws IOException {
return in.ready();
}
/**
* Tells whether this stream supports the mark() operation.
*/
public boolean markSupported() {
return in.markSupported();
}
/**
* Marks the present position in the stream.
*
* @exception IOException If an I/O error occurs
*/
public void mark(int readAheadLimit) throws IOException {
in.mark(readAheadLimit);
}
/**
* Resets the stream.
*
* @exception IOException If an I/O error occurs
*/
public void reset() throws IOException {
in.reset();
}
public void close() throws IOException {
in.close();
}
}

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Abstract class for writing filtered character streams.
* The abstract class <code>FilterWriter</code> itself
* provides default methods that pass all requests to the
* contained stream. Subclasses of <code>FilterWriter</code>
* should override some of these methods and may also
* provide additional methods and fields.
*
* @author Mark Reinhold
* @since 1.1
*/
public abstract class FilterWriter extends Writer {
/**
* The underlying character-output stream.
*/
protected Writer out;
/**
* Create a new filtered writer.
*
* @param out a Writer object to provide the underlying stream.
* @throws NullPointerException if <code>out</code> is <code>null</code>
*/
protected FilterWriter(Writer out) {
super(out);
this.out = out;
}
/**
* Writes a single character.
*
* @exception IOException If an I/O error occurs
*/
public void write(int c) throws IOException {
out.write(c);
}
/**
* Writes a portion of an array of characters.
*
* @param cbuf Buffer of characters to be written
* @param off Offset from which to start reading characters
* @param len Number of characters to be written
*
* @throws IndexOutOfBoundsException
* If the values of the {@code off} and {@code len} parameters
* cause the corresponding method of the underlying {@code Writer}
* to throw an {@code IndexOutOfBoundsException}
*
* @throws IOException If an I/O error occurs
*/
public void write(char cbuf[], int off, int len) throws IOException {
out.write(cbuf, off, len);
}
/**
* Writes a portion of a string.
*
* @param str String to be written
* @param off Offset from which to start reading characters
* @param len Number of characters to be written
*
* @throws IndexOutOfBoundsException
* If the values of the {@code off} and {@code len} parameters
* cause the corresponding method of the underlying {@code Writer}
* to throw an {@code IndexOutOfBoundsException}
*
* @throws IOException If an I/O error occurs
*/
public void write(String str, int off, int len) throws IOException {
out.write(str, off, len);
}
/**
* Flushes the stream.
*
* @exception IOException If an I/O error occurs
*/
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
out.close();
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.io.IOException;
/**
* A {@code Flushable} is a destination of data that can be flushed. The
* flush method is invoked to write any buffered output to the underlying
* stream.
*
* @since 1.5
*/
public interface Flushable {
/**
* Flushes this stream by writing any buffered output to the underlying
* stream.
*
* @throws IOException If an I/O error occurs
*/
void flush() throws IOException;
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Thrown when a serious I/O error has occurred.
*
* @author Xueming Shen
* @since 1.6
*/
public class IOError extends Error {
/**
* Constructs a new instance of IOError with the specified cause. The
* IOError is created with the detail message of
* {@code (cause==null ? null : cause.toString())} (which typically
* contains the class and detail message of cause).
*
* @param cause
* The cause of this error, or {@code null} if the cause
* is not known
*/
public IOError(Throwable cause) {
super(cause);
}
private static final long serialVersionUID = 67100927991680413L;
}

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Signals that an I/O exception of some sort has occurred. This
* class is the general class of exceptions produced by failed or
* interrupted I/O operations.
*
* @author unascribed
* @see java.io.InputStream
* @see java.io.OutputStream
* @since 1.0
*/
public
class IOException extends Exception {
static final long serialVersionUID = 7818375828146090155L;
/**
* Constructs an {@code IOException} with {@code null}
* as its error detail message.
*/
public IOException() {
super();
}
/**
* Constructs an {@code IOException} with the specified detail message.
*
* @param message
* The detail message (which is saved for later retrieval
* by the {@link #getMessage()} method)
*/
public IOException(String message) {
super(message);
}
/**
* Constructs an {@code IOException} with the specified detail message
* and cause.
*
* <p> Note that the detail message associated with {@code cause} is
* <i>not</i> automatically incorporated into this exception's detail
* message.
*
* @param message
* The detail message (which is saved for later retrieval
* by the {@link #getMessage()} method)
*
* @param cause
* The cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A null value is permitted,
* and indicates that the cause is nonexistent or unknown.)
*
* @since 1.6
*/
public IOException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs an {@code IOException} with the specified cause and a
* detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of {@code cause}).
* This constructor is useful for IO exceptions that are little more
* than wrappers for other throwables.
*
* @param cause
* The cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A null value is permitted,
* and indicates that the cause is nonexistent or unknown.)
*
* @since 1.6
*/
public IOException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,529 @@
/*
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.Arrays;
import java.util.Objects;
/**
* This abstract class is the superclass of all classes representing
* an input stream of bytes.
*
* <p> Applications that need to define a subclass of <code>InputStream</code>
* must always provide a method that returns the next byte of input.
*
* @author Arthur van Hoff
* @see java.io.BufferedInputStream
* @see java.io.ByteArrayInputStream
* @see java.io.DataInputStream
* @see java.io.FilterInputStream
* @see java.io.InputStream#read()
* @see java.io.OutputStream
* @see java.io.PushbackInputStream
* @since 1.0
*/
public abstract class InputStream implements Closeable {
// MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
// use when skipping.
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
private static final int DEFAULT_BUFFER_SIZE = 8192;
/**
* Reads the next byte of data from the input stream. The value byte is
* returned as an <code>int</code> in the range <code>0</code> to
* <code>255</code>. If no byte is available because the end of the stream
* has been reached, the value <code>-1</code> is returned. This method
* blocks until input data is available, the end of the stream is detected,
* or an exception is thrown.
*
* <p> A subclass must provide an implementation of this method.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if an I/O error occurs.
*/
public abstract int read() throws IOException;
/**
* Reads some number of bytes from the input stream and stores them into
* the buffer array <code>b</code>. The number of bytes actually read is
* returned as an integer. This method blocks until input data is
* available, end of file is detected, or an exception is thrown.
*
* <p> If the length of <code>b</code> is zero, then no bytes are read and
* <code>0</code> is returned; otherwise, there is an attempt to read at
* least one byte. If no byte is available because the stream is at the
* end of the file, the value <code>-1</code> is returned; otherwise, at
* least one byte is read and stored into <code>b</code>.
*
* <p> The first byte read is stored into element <code>b[0]</code>, the
* next one into <code>b[1]</code>, and so on. The number of bytes read is,
* at most, equal to the length of <code>b</code>. Let <i>k</i> be the
* number of bytes actually read; these bytes will be stored in elements
* <code>b[0]</code> through <code>b[</code><i>k</i><code>-1]</code>,
* leaving elements <code>b[</code><i>k</i><code>]</code> through
* <code>b[b.length-1]</code> unaffected.
*
* <p> The <code>read(b)</code> method for class <code>InputStream</code>
* has the same effect as: <pre><code> read(b, 0, b.length) </code></pre>
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception IOException If the first byte cannot be read for any reason
* other than the end of the file, if the input stream has been closed, or
* if some other I/O error occurs.
* @exception NullPointerException if <code>b</code> is <code>null</code>.
* @see java.io.InputStream#read(byte[], int, int)
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from the input stream into
* an array of bytes. An attempt is made to read as many as
* <code>len</code> bytes, but a smaller number may be read.
* The number of bytes actually read is returned as an integer.
*
* <p> This method blocks until input data is available, end of file is
* detected, or an exception is thrown.
*
* <p> If <code>len</code> is zero, then no bytes are read and
* <code>0</code> is returned; otherwise, there is an attempt to read at
* least one byte. If no byte is available because the stream is at end of
* file, the value <code>-1</code> is returned; otherwise, at least one
* byte is read and stored into <code>b</code>.
*
* <p> The first byte read is stored into element <code>b[off]</code>, the
* next one into <code>b[off+1]</code>, and so on. The number of bytes read
* is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
* bytes actually read; these bytes will be stored in elements
* <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
* leaving elements <code>b[off+</code><i>k</i><code>]</code> through
* <code>b[off+len-1]</code> unaffected.
*
* <p> In every case, elements <code>b[0]</code> through
* <code>b[off]</code> and elements <code>b[off+len]</code> through
* <code>b[b.length-1]</code> are unaffected.
*
* <p> The <code>read(b,</code> <code>off,</code> <code>len)</code> method
* for class <code>InputStream</code> simply calls the method
* <code>read()</code> repeatedly. If the first such call results in an
* <code>IOException</code>, that exception is returned from the call to
* the <code>read(b,</code> <code>off,</code> <code>len)</code> method. If
* any subsequent call to <code>read()</code> results in a
* <code>IOException</code>, the exception is caught and treated as if it
* were end of file; the bytes read up to that point are stored into
* <code>b</code> and the number of bytes read before the exception
* occurred is returned. The default implementation of this method blocks
* until the requested amount of input data <code>len</code> has been read,
* end of file is detected, or an exception is thrown. Subclasses are encouraged
* to provide a more efficient implementation of this method.
*
* @param b the buffer into which the data is read.
* @param off the start offset in array <code>b</code>
* at which the data is written.
* @param len the maximum number of bytes to read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception IOException If the first byte cannot be read for any reason
* other than end of file, or if the input stream has been closed, or if
* some other I/O error occurs.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @see java.io.InputStream#read()
*/
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
/**
* Reads all remaining bytes from the input stream. This method blocks until
* all remaining bytes have been read and end of stream is detected, or an
* exception is thrown. This method does not close the input stream.
*
* <p> When this stream reaches end of stream, further invocations of this
* method will return an empty byte array.
*
* <p> Note that this method is intended for simple cases where it is
* convenient to read all bytes into a byte array. It is not intended for
* reading input streams with large amounts of data.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes have been read. Consequently the input
* stream may not be at end of stream and may be in an inconsistent state.
* It is strongly recommended that the stream be promptly closed if an I/O
* error occurs.
*
* @return a byte array containing the bytes read from this input stream
* @throws IOException if an I/O error occurs
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated. For example, if an array larger than {@code 2GB} would
* be required to store the bytes.
*
* @since 9
*/
public byte[] readAllBytes() throws IOException {
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
int capacity = buf.length;
int nread = 0;
int n;
for (;;) {
// read to EOF which may read more or less than initial buffer size
while ((n = read(buf, nread, capacity - nread)) > 0)
nread += n;
// if the last call to read returned -1, then we're done
if (n < 0)
break;
// need to allocate a larger buffer
if (capacity <= MAX_BUFFER_SIZE - capacity) {
capacity = capacity << 1;
} else {
if (capacity == MAX_BUFFER_SIZE)
throw new OutOfMemoryError("Required array size too large");
capacity = MAX_BUFFER_SIZE;
}
buf = Arrays.copyOf(buf, capacity);
}
return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
}
/**
* Reads the requested number of bytes from the input stream into the given
* byte array. This method blocks until {@code len} bytes of input data have
* been read, end of stream is detected, or an exception is thrown. The
* number of bytes actually read, possibly zero, is returned. This method
* does not close the input stream.
*
* <p> In the case where end of stream is reached before {@code len} bytes
* have been read, then the actual number of bytes read will be returned.
* When this stream reaches end of stream, further invocations of this
* method will return zero.
*
* <p> If {@code len} is zero, then no bytes are read and {@code 0} is
* returned; otherwise, there is an attempt to read up to {@code len} bytes.
*
* <p> The first byte read is stored into element {@code b[off]}, the next
* one in to {@code b[off+1]}, and so on. The number of bytes read is, at
* most, equal to {@code len}. Let <i>k</i> be the number of bytes actually
* read; these bytes will be stored in elements {@code b[off]} through
* {@code b[off+}<i>k</i>{@code -1]}, leaving elements {@code b[off+}<i>k</i>
* {@code ]} through {@code b[off+len-1]} unaffected.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes of {@code b} have been updated with
* data from the input stream. Consequently the input stream and {@code b}
* may be in an inconsistent state. It is strongly recommended that the
* stream be promptly closed if an I/O error occurs.
*
* @param b the byte array into which the data is read
* @param off the start offset in {@code b} at which the data is written
* @param len the maximum number of bytes to read
* @return the actual number of bytes read into the buffer
* @throws IOException if an I/O error occurs
* @throws NullPointerException if {@code b} is {@code null}
* @throws IndexOutOfBoundsException If {@code off} is negative, {@code len}
* is negative, or {@code len} is greater than {@code b.length - off}
*
* @since 9
*/
public int readNBytes(byte[] b, int off, int len) throws IOException {
Objects.requireNonNull(b);
if (off < 0 || len < 0 || len > b.length - off)
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int count = read(b, off + n, len - n);
if (count < 0)
break;
n += count;
}
return n;
}
/**
* Skips over and discards <code>n</code> bytes of data from this input
* stream. The <code>skip</code> method may, for a variety of reasons, end
* up skipping over some smaller number of bytes, possibly <code>0</code>.
* This may result from any of a number of conditions; reaching end of file
* before <code>n</code> bytes have been skipped is only one possibility.
* The actual number of bytes skipped is returned. If {@code n} is
* negative, the {@code skip} method for class {@code InputStream} always
* returns 0, and no bytes are skipped. Subclasses may handle the negative
* value differently.
*
* <p> The <code>skip</code> method implementation of this class creates a
* byte array and then repeatedly reads into it until <code>n</code> bytes
* have been read or the end of the stream has been reached. Subclasses are
* encouraged to provide a more efficient implementation of this method.
* For instance, the implementation may depend on the ability to seek.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @throws IOException if an I/O error occurs.
*/
public long skip(long n) throws IOException {
long remaining = n;
int nr;
if (n <= 0) {
return 0;
}
int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
byte[] skipBuffer = new byte[size];
while (remaining > 0) {
nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
if (nr < 0) {
break;
}
remaining -= nr;
}
return n - remaining;
}
/**
* Returns an estimate of the number of bytes that can be read (or
* skipped over) from this input stream without blocking by the next
* invocation of a method for this input stream. The next invocation
* might be the same thread or another thread. A single read or skip of this
* many bytes will not block, but may read or skip fewer bytes.
*
* <p> Note that while some implementations of {@code InputStream} will return
* the total number of bytes in the stream, many will not. It is
* never correct to use the return value of this method to allocate
* a buffer intended to hold all data in this stream.
*
* <p> A subclass' implementation of this method may choose to throw an
* {@link IOException} if this input stream has been closed by
* invoking the {@link #close()} method.
*
* <p> The {@code available} method for class {@code InputStream} always
* returns {@code 0}.
*
* <p> This method should be overridden by subclasses.
*
* @return an estimate of the number of bytes that can be read (or skipped
* over) from this input stream without blocking or {@code 0} when
* it reaches the end of the input stream.
* @exception IOException if an I/O error occurs.
*/
public int available() throws IOException {
return 0;
}
/**
* Closes this input stream and releases any system resources associated
* with the stream.
*
* <p> The <code>close</code> method of <code>InputStream</code> does
* nothing.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {}
/**
* Marks the current position in this input stream. A subsequent call to
* the <code>reset</code> method repositions this stream at the last marked
* position so that subsequent reads re-read the same bytes.
*
* <p> The <code>readlimit</code> arguments tells this input stream to
* allow that many bytes to be read before the mark position gets
* invalidated.
*
* <p> The general contract of <code>mark</code> is that, if the method
* <code>markSupported</code> returns <code>true</code>, the stream somehow
* remembers all the bytes read after the call to <code>mark</code> and
* stands ready to supply those same bytes again if and whenever the method
* <code>reset</code> is called. However, the stream is not required to
* remember any data at all if more than <code>readlimit</code> bytes are
* read from the stream before <code>reset</code> is called.
*
* <p> Marking a closed stream should not have any effect on the stream.
*
* <p> The <code>mark</code> method of <code>InputStream</code> does
* nothing.
*
* @param readlimit the maximum limit of bytes that can be read before
* the mark position becomes invalid.
* @see java.io.InputStream#reset()
*/
public synchronized void mark(int readlimit) {}
/**
* Repositions this stream to the position at the time the
* <code>mark</code> method was last called on this input stream.
*
* <p> The general contract of <code>reset</code> is:
*
* <ul>
* <li> If the method <code>markSupported</code> returns
* <code>true</code>, then:
*
* <ul><li> If the method <code>mark</code> has not been called since
* the stream was created, or the number of bytes read from the stream
* since <code>mark</code> was last called is larger than the argument
* to <code>mark</code> at that last call, then an
* <code>IOException</code> might be thrown.
*
* <li> If such an <code>IOException</code> is not thrown, then the
* stream is reset to a state such that all the bytes read since the
* most recent call to <code>mark</code> (or since the start of the
* file, if <code>mark</code> has not been called) will be resupplied
* to subsequent callers of the <code>read</code> method, followed by
* any bytes that otherwise would have been the next input data as of
* the time of the call to <code>reset</code>. </ul>
*
* <li> If the method <code>markSupported</code> returns
* <code>false</code>, then:
*
* <ul><li> The call to <code>reset</code> may throw an
* <code>IOException</code>.
*
* <li> If an <code>IOException</code> is not thrown, then the stream
* is reset to a fixed state that depends on the particular type of the
* input stream and how it was created. The bytes that will be supplied
* to subsequent callers of the <code>read</code> method depend on the
* particular type of the input stream. </ul></ul>
*
* <p>The method <code>reset</code> for class <code>InputStream</code>
* does nothing except throw an <code>IOException</code>.
*
* @exception IOException if this stream has not been marked or if the
* mark has been invalidated.
* @see java.io.InputStream#mark(int)
* @see java.io.IOException
*/
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
}
/**
* Tests if this input stream supports the <code>mark</code> and
* <code>reset</code> methods. Whether or not <code>mark</code> and
* <code>reset</code> are supported is an invariant property of a
* particular input stream instance. The <code>markSupported</code> method
* of <code>InputStream</code> returns <code>false</code>.
*
* @return <code>true</code> if this stream instance supports the mark
* and reset methods; <code>false</code> otherwise.
* @see java.io.InputStream#mark(int)
* @see java.io.InputStream#reset()
*/
public boolean markSupported() {
return false;
}
/**
* Reads all bytes from this input stream and writes the bytes to the
* given output stream in the order that they are read. On return, this
* input stream will be at end of stream. This method does not close either
* stream.
* <p>
* This method may block indefinitely reading from the input stream, or
* writing to the output stream. The behavior for the case where the input
* and/or output stream is <i>asynchronously closed</i>, or the thread
* interrupted during the transfer, is highly input and output stream
* specific, and therefore not specified.
* <p>
* If an I/O error occurs reading from the input stream or writing to the
* output stream, then it may do so after some bytes have been read or
* written. Consequently the input stream may not be at end of stream and
* one, or both, streams may be in an inconsistent state. It is strongly
* recommended that both streams be promptly closed if an I/O error occurs.
*
* @param out the output stream, non-null
* @return the number of bytes transferred
* @throws IOException if an I/O error occurs when reading or writing
* @throws NullPointerException if {@code out} is {@code null}
*
* @since 9
*/
public long transferTo(OutputStream out) throws IOException {
Objects.requireNonNull(out, "out");
long transferred = 0;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int read;
while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
out.write(buffer, 0, read);
transferred += read;
}
return transferred;
}
}

View file

@ -0,0 +1,202 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.StreamDecoder;
/**
* An InputStreamReader is a bridge from byte streams to character streams: It
* reads bytes and decodes them into characters using a specified {@link
* java.nio.charset.Charset charset}. The charset that it uses
* may be specified by name or may be given explicitly, or the platform's
* default charset may be accepted.
*
* <p> Each invocation of one of an InputStreamReader's read() methods may
* cause one or more bytes to be read from the underlying byte-input stream.
* To enable the efficient conversion of bytes to characters, more bytes may
* be read ahead from the underlying stream than are necessary to satisfy the
* current read operation.
*
* <p> For top efficiency, consider wrapping an InputStreamReader within a
* BufferedReader. For example:
*
* <pre>
* BufferedReader in
* = new BufferedReader(new InputStreamReader(System.in));
* </pre>
*
* @see BufferedReader
* @see InputStream
* @see java.nio.charset.Charset
*
* @author Mark Reinhold
* @since 1.1
*/
public class InputStreamReader extends Reader {
private final StreamDecoder sd;
/**
* Creates an InputStreamReader that uses the default charset.
*
* @param in An InputStream
*/
public InputStreamReader(InputStream in) {
super(in);
try {
sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
} catch (UnsupportedEncodingException e) {
// The default encoding should always be available
throw new Error(e);
}
}
/**
* Creates an InputStreamReader that uses the named charset.
*
* @param in
* An InputStream
*
* @param charsetName
* The name of a supported
* {@link java.nio.charset.Charset charset}
*
* @exception UnsupportedEncodingException
* If the named charset is not supported
*/
public InputStreamReader(InputStream in, String charsetName)
throws UnsupportedEncodingException
{
super(in);
if (charsetName == null)
throw new NullPointerException("charsetName");
sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
}
/**
* Creates an InputStreamReader that uses the given charset.
*
* @param in An InputStream
* @param cs A charset
*
* @since 1.4
* @spec JSR-51
*/
public InputStreamReader(InputStream in, Charset cs) {
super(in);
if (cs == null)
throw new NullPointerException("charset");
sd = StreamDecoder.forInputStreamReader(in, this, cs);
}
/**
* Creates an InputStreamReader that uses the given charset decoder.
*
* @param in An InputStream
* @param dec A charset decoder
*
* @since 1.4
* @spec JSR-51
*/
public InputStreamReader(InputStream in, CharsetDecoder dec) {
super(in);
if (dec == null)
throw new NullPointerException("charset decoder");
sd = StreamDecoder.forInputStreamReader(in, this, dec);
}
/**
* Returns the name of the character encoding being used by this stream.
*
* <p> If the encoding has an historical name then that name is returned;
* otherwise the encoding's canonical name is returned.
*
* <p> If this instance was created with the {@link
* #InputStreamReader(InputStream, String)} constructor then the returned
* name, being unique for the encoding, may differ from the name passed to
* the constructor. This method will return <code>null</code> if the
* stream has been closed.
* </p>
* @return The historical name of this encoding, or
* <code>null</code> if the stream has been closed
*
* @see java.nio.charset.Charset
*
* @revised 1.4
* @spec JSR-51
*/
public String getEncoding() {
return sd.getEncoding();
}
/**
* Reads a single character.
*
* @return The character read, or -1 if the end of the stream has been
* reached
*
* @exception IOException If an I/O error occurs
*/
public int read() throws IOException {
return sd.read();
}
/**
* Reads characters into a portion of an array.
*
* @param cbuf Destination buffer
* @param offset Offset at which to start storing characters
* @param length Maximum number of characters to read
*
* @return The number of characters read, or -1 if the end of the
* stream has been reached
*
* @exception IOException If an I/O error occurs
* @exception IndexOutOfBoundsException {@inheritDoc}
*/
public int read(char cbuf[], int offset, int length) throws IOException {
return sd.read(cbuf, offset, length);
}
/**
* Tells whether this stream is ready to be read. An InputStreamReader is
* ready if its input buffer is not empty, or if bytes are available to be
* read from the underlying byte stream.
*
* @exception IOException If an I/O error occurs
*/
public boolean ready() throws IOException {
return sd.ready();
}
public void close() throws IOException {
sd.close();
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Signals that an I/O operation has been interrupted. An
* <code>InterruptedIOException</code> is thrown to indicate that an
* input or output transfer has been terminated because the thread
* performing it was interrupted. The field {@link #bytesTransferred}
* indicates how many bytes were successfully transferred before
* the interruption occurred.
*
* @author unascribed
* @see java.io.InputStream
* @see java.io.OutputStream
* @see java.lang.Thread#interrupt()
* @since 1.0
*/
public
class InterruptedIOException extends IOException {
private static final long serialVersionUID = 4020568460727500567L;
/**
* Constructs an <code>InterruptedIOException</code> with
* <code>null</code> as its error detail message.
*/
public InterruptedIOException() {
super();
}
/**
* Constructs an <code>InterruptedIOException</code> with the
* specified detail message. The string <code>s</code> can be
* retrieved later by the
* <code>{@link java.lang.Throwable#getMessage}</code>
* method of class <code>java.lang.Throwable</code>.
*
* @param s the detail message.
*/
public InterruptedIOException(String s) {
super(s);
}
/**
* Reports how many bytes had been transferred as part of the I/O
* operation before it was interrupted.
*
* @serial
*/
public int bytesTransferred = 0;
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Thrown when the Serialization runtime detects one of the following
* problems with a Class.
* <UL>
* <LI> The serial version of the class does not match that of the class
* descriptor read from the stream
* <LI> The class contains unknown datatypes
* <LI> The class does not have an accessible no-arg constructor
* </UL>
*
* @author unascribed
* @since 1.1
*/
public class InvalidClassException extends ObjectStreamException {
private static final long serialVersionUID = -4333316296251054416L;
/**
* Name of the invalid class.
*
* @serial Name of the invalid class.
*/
public String classname;
/**
* Report an InvalidClassException for the reason specified.
*
* @param reason String describing the reason for the exception.
*/
public InvalidClassException(String reason) {
super(reason);
}
/**
* Constructs an InvalidClassException object.
*
* @param cname a String naming the invalid class.
* @param reason a String describing the reason for the exception.
*/
public InvalidClassException(String cname, String reason) {
super(reason);
classname = cname;
}
/**
* Produce the message and include the classname, if present.
*/
public String getMessage() {
if (classname == null)
return super.getMessage();
else
return classname + "; " + super.getMessage();
}
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Indicates that one or more deserialized objects failed validation
* tests. The argument should provide the reason for the failure.
*
* @see ObjectInputValidation
* @since 1.1
*
* @author unascribed
* @since 1.1
*/
public class InvalidObjectException extends ObjectStreamException {
private static final long serialVersionUID = 3233174318281839583L;
/**
* Constructs an <code>InvalidObjectException</code>.
* @param reason Detailed message explaining the reason for the failure.
*
* @see ObjectInputValidation
*/
public InvalidObjectException(String reason) {
super(reason);
}
}

View file

@ -0,0 +1,293 @@
/*
* Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* This class is an input stream filter that provides the added
* functionality of keeping track of the current line number.
* <p>
* A line is a sequence of bytes ending with a carriage return
* character ({@code '\u005Cr'}), a newline character
* ({@code '\u005Cn'}), or a carriage return character followed
* immediately by a linefeed character. In all three cases, the line
* terminating character(s) are returned as a single newline character.
* <p>
* The line number begins at {@code 0}, and is incremented by
* {@code 1} when a {@code read} returns a newline character.
*
* @author Arthur van Hoff
* @see java.io.LineNumberReader
* @since 1.0
* @deprecated This class incorrectly assumes that bytes adequately represent
* characters. As of JDK&nbsp;1.1, the preferred way to operate on
* character streams is via the new character-stream classes, which
* include a class for counting line numbers.
*/
@Deprecated
public
class LineNumberInputStream extends FilterInputStream {
int pushBack = -1;
int lineNumber;
int markLineNumber;
int markPushBack = -1;
/**
* Constructs a newline number input stream that reads its input
* from the specified input stream.
*
* @param in the underlying input stream.
*/
public LineNumberInputStream(InputStream in) {
super(in);
}
/**
* Reads the next byte of data from this input stream. The value
* byte is returned as an {@code int} in the range
* {@code 0} to {@code 255}. If no byte is available
* because the end of the stream has been reached, the value
* {@code -1} is returned. This method blocks until input data
* is available, the end of the stream is detected, or an exception
* is thrown.
* <p>
* The {@code read} method of
* {@code LineNumberInputStream} calls the {@code read}
* method of the underlying input stream. It checks for carriage
* returns and newline characters in the input, and modifies the
* current line number as appropriate. A carriage-return character or
* a carriage return followed by a newline character are both
* converted into a single newline character.
*
* @return the next byte of data, or {@code -1} if the end of this
* stream is reached.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
* @see java.io.LineNumberInputStream#getLineNumber()
*/
@SuppressWarnings("fallthrough")
public int read() throws IOException {
int c = pushBack;
if (c != -1) {
pushBack = -1;
} else {
c = in.read();
}
switch (c) {
case '\r':
pushBack = in.read();
if (pushBack == '\n') {
pushBack = -1;
}
case '\n':
lineNumber++;
return '\n';
}
return c;
}
/**
* Reads up to {@code len} bytes of data from this input stream
* into an array of bytes. This method blocks until some input is available.
* <p>
* The {@code read} method of
* {@code LineNumberInputStream} repeatedly calls the
* {@code read} method of zero arguments to fill in the byte array.
*
* @param b the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* {@code -1} if there is no more data because the end of
* this stream has been reached.
* @exception IOException if an I/O error occurs.
* @see java.io.LineNumberInputStream#read()
*/
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
if (b != null) {
b[off + i] = (byte)c;
}
}
} catch (IOException ee) {
}
return i;
}
/**
* Skips over and discards {@code n} bytes of data from this
* input stream. The {@code skip} method may, for a variety of
* reasons, end up skipping over some smaller number of bytes,
* possibly {@code 0}. The actual number of bytes skipped is
* returned. If {@code n} is negative, no bytes are skipped.
* <p>
* The {@code skip} method of {@code LineNumberInputStream} creates
* a byte array and then repeatedly reads into it until
* {@code n} bytes have been read or the end of the stream has
* been reached.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public long skip(long n) throws IOException {
int chunk = 2048;
long remaining = n;
byte data[];
int nr;
if (n <= 0) {
return 0;
}
data = new byte[chunk];
while (remaining > 0) {
nr = read(data, 0, (int) Math.min(chunk, remaining));
if (nr < 0) {
break;
}
remaining -= nr;
}
return n - remaining;
}
/**
* Sets the line number to the specified argument.
*
* @param lineNumber the new line number.
* @see #getLineNumber
*/
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
/**
* Returns the current line number.
*
* @return the current line number.
* @see #setLineNumber
*/
public int getLineNumber() {
return lineNumber;
}
/**
* Returns the number of bytes that can be read from this input
* stream without blocking.
* <p>
* Note that if the underlying input stream is able to supply
* <i>k</i> input characters without blocking, the
* {@code LineNumberInputStream} can guarantee only to provide
* <i>k</i>/2 characters without blocking, because the
* <i>k</i> characters from the underlying input stream might
* consist of <i>k</i>/2 pairs of {@code '\u005Cr'} and
* {@code '\u005Cn'}, which are converted to just
* <i>k</i>/2 {@code '\u005Cn'} characters.
*
* @return the number of bytes that can be read from this input stream
* without blocking.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public int available() throws IOException {
return (pushBack == -1) ? super.available()/2 : super.available()/2 + 1;
}
/**
* Marks the current position in this input stream. A subsequent
* call to the {@code reset} method repositions this stream at
* the last marked position so that subsequent reads re-read the same bytes.
* <p>
* The {@code mark} method of
* {@code LineNumberInputStream} remembers the current line
* number in a private variable, and then calls the {@code mark}
* method of the underlying input stream.
*
* @param readlimit the maximum limit of bytes that can be read before
* the mark position becomes invalid.
* @see java.io.FilterInputStream#in
* @see java.io.LineNumberInputStream#reset()
*/
public void mark(int readlimit) {
markLineNumber = lineNumber;
markPushBack = pushBack;
in.mark(readlimit);
}
/**
* Repositions this stream to the position at the time the
* {@code mark} method was last called on this input stream.
* <p>
* The {@code reset} method of
* {@code LineNumberInputStream} resets the line number to be
* the line number at the time the {@code mark} method was
* called, and then calls the {@code reset} method of the
* underlying input stream.
* <p>
* Stream marks are intended to be used in
* situations where you need to read ahead a little to see what's in
* the stream. Often this is most easily done by invoking some
* general parser. If the stream is of the type handled by the
* parser, it just chugs along happily. If the stream is not of
* that type, the parser should toss an exception when it fails,
* which, if it happens within readlimit bytes, allows the outer
* code to reset the stream and try another parser.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
* @see java.io.LineNumberInputStream#mark(int)
*/
public void reset() throws IOException {
lineNumber = markLineNumber;
pushBack = markPushBack;
in.reset();
}
}

View file

@ -0,0 +1,285 @@
/*
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A buffered character-input stream that keeps track of line numbers. This
* class defines methods {@link #setLineNumber(int)} and {@link
* #getLineNumber()} for setting and getting the current line number
* respectively.
*
* <p> By default, line numbering begins at 0. This number increments at every
* <a href="#lt">line terminator</a> as the data is read, and can be changed
* with a call to {@code setLineNumber(int)}. Note however, that
* {@code setLineNumber(int)} does not actually change the current position in
* the stream; it only changes the value that will be returned by
* {@code getLineNumber()}.
*
* <p> A line is considered to be <a id="lt">terminated</a> by any one of a
* line feed ('\n'), a carriage return ('\r'), or a carriage return followed
* immediately by a linefeed.
*
* @author Mark Reinhold
* @since 1.1
*/
public class LineNumberReader extends BufferedReader {
/** The current line number */
private int lineNumber = 0;
/** The line number of the mark, if any */
private int markedLineNumber; // Defaults to 0
/** If the next character is a line feed, skip it */
private boolean skipLF;
/** The skipLF flag when the mark was set */
private boolean markedSkipLF;
/**
* Create a new line-numbering reader, using the default input-buffer
* size.
*
* @param in
* A Reader object to provide the underlying stream
*/
public LineNumberReader(Reader in) {
super(in);
}
/**
* Create a new line-numbering reader, reading characters into a buffer of
* the given size.
*
* @param in
* A Reader object to provide the underlying stream
*
* @param sz
* An int specifying the size of the buffer
*/
public LineNumberReader(Reader in, int sz) {
super(in, sz);
}
/**
* Set the current line number.
*
* @param lineNumber
* An int specifying the line number
*
* @see #getLineNumber
*/
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
/**
* Get the current line number.
*
* @return The current line number
*
* @see #setLineNumber
*/
public int getLineNumber() {
return lineNumber;
}
/**
* Read a single character. <a href="#lt">Line terminators</a> are
* compressed into single newline ('\n') characters. Whenever a line
* terminator is read the current line number is incremented.
*
* @return The character read, or -1 if the end of the stream has been
* reached
*
* @throws IOException
* If an I/O error occurs
*/
@SuppressWarnings("fallthrough")
public int read() throws IOException {
synchronized (lock) {
int c = super.read();
if (skipLF) {
if (c == '\n')
c = super.read();
skipLF = false;
}
switch (c) {
case '\r':
skipLF = true;
case '\n': /* Fall through */
lineNumber++;
return '\n';
}
return c;
}
}
/**
* Read characters into a portion of an array. Whenever a <a
* href="#lt">line terminator</a> is read the current line number is
* incremented.
*
* @param cbuf
* Destination buffer
*
* @param off
* Offset at which to start storing characters
*
* @param len
* Maximum number of characters to read
*
* @return The number of bytes read, or -1 if the end of the stream has
* already been reached
*
* @throws IOException
* If an I/O error occurs
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
@SuppressWarnings("fallthrough")
public int read(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
int n = super.read(cbuf, off, len);
for (int i = off; i < off + n; i++) {
int c = cbuf[i];
if (skipLF) {
skipLF = false;
if (c == '\n')
continue;
}
switch (c) {
case '\r':
skipLF = true;
case '\n': /* Fall through */
lineNumber++;
break;
}
}
return n;
}
}
/**
* Read a line of text. Whenever a <a href="#lt">line terminator</a> is
* read the current line number is incremented.
*
* @return A String containing the contents of the line, not including
* any <a href="#lt">line termination characters</a>, or
* {@code null} if the end of the stream has been reached
*
* @throws IOException
* If an I/O error occurs
*/
public String readLine() throws IOException {
synchronized (lock) {
String l = super.readLine(skipLF);
skipLF = false;
if (l != null)
lineNumber++;
return l;
}
}
/** Maximum skip-buffer size */
private static final int maxSkipBufferSize = 8192;
/** Skip buffer, null until allocated */
private char skipBuffer[] = null;
/**
* Skip characters.
*
* @param n
* The number of characters to skip
*
* @return The number of characters actually skipped
*
* @throws IOException
* If an I/O error occurs
*
* @throws IllegalArgumentException
* If {@code n} is negative
*/
public long skip(long n) throws IOException {
if (n < 0)
throw new IllegalArgumentException("skip() value is negative");
int nn = (int) Math.min(n, maxSkipBufferSize);
synchronized (lock) {
if ((skipBuffer == null) || (skipBuffer.length < nn))
skipBuffer = new char[nn];
long r = n;
while (r > 0) {
int nc = read(skipBuffer, 0, (int) Math.min(r, nn));
if (nc == -1)
break;
r -= nc;
}
return n - r;
}
}
/**
* Mark the present position in the stream. Subsequent calls to reset()
* will attempt to reposition the stream to this point, and will also reset
* the line number appropriately.
*
* @param readAheadLimit
* Limit on the number of characters that may be read while still
* preserving the mark. After reading this many characters,
* attempting to reset the stream may fail.
*
* @throws IOException
* If an I/O error occurs
*/
public void mark(int readAheadLimit) throws IOException {
synchronized (lock) {
super.mark(readAheadLimit);
markedLineNumber = lineNumber;
markedSkipLF = skipLF;
}
}
/**
* Reset the stream to the most recent mark.
*
* @throws IOException
* If the stream has not been marked, or if the mark has been
* invalidated
*/
public void reset() throws IOException {
synchronized (lock) {
super.reset();
lineNumber = markedLineNumber;
skipLF = markedSkipLF;
}
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Thrown when serialization or deserialization is not active.
*
* @author unascribed
* @since 1.1
*/
public class NotActiveException extends ObjectStreamException {
private static final long serialVersionUID = -3893467273049808895L;
/**
* Constructor to create a new NotActiveException with the reason given.
*
* @param reason a String describing the reason for the exception.
*/
public NotActiveException(String reason) {
super(reason);
}
/**
* Constructor to create a new NotActiveException without a reason.
*/
public NotActiveException() {
super();
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Thrown when an instance is required to have a Serializable interface.
* The serialization runtime or the class of the instance can throw
* this exception. The argument should be the name of the class.
*
* @author unascribed
* @since 1.1
*/
public class NotSerializableException extends ObjectStreamException {
private static final long serialVersionUID = 2906642554793891381L;
/**
* Constructs a NotSerializableException object with message string.
*
* @param classname Class of the instance being serialized/deserialized.
*/
public NotSerializableException(String classname) {
super(classname);
}
/**
* Constructs a NotSerializableException object.
*/
public NotSerializableException() {
super();
}
}

View file

@ -0,0 +1,107 @@
/*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* ObjectInput extends the DataInput interface to include the reading of
* objects. DataInput includes methods for the input of primitive types,
* ObjectInput extends that interface to include objects, arrays, and Strings.
*
* @author unascribed
* @see java.io.InputStream
* @see java.io.ObjectOutputStream
* @see java.io.ObjectInputStream
* @since 1.1
*/
public interface ObjectInput extends DataInput, AutoCloseable {
/**
* Read and return an object. The class that implements this interface
* defines where the object is "read" from.
*
* @return the object read from the stream
* @exception java.lang.ClassNotFoundException If the class of a serialized
* object cannot be found.
* @exception IOException If any of the usual Input/Output
* related exceptions occur.
*/
public Object readObject()
throws ClassNotFoundException, IOException;
/**
* Reads a byte of data. This method will block if no input is
* available.
* @return the byte read, or -1 if the end of the
* stream is reached.
* @exception IOException If an I/O error has occurred.
*/
public int read() throws IOException;
/**
* Reads into an array of bytes. This method will
* block until some input is available.
* @param b the buffer into which the data is read
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @exception IOException If an I/O error has occurred.
*/
public int read(byte b[]) throws IOException;
/**
* Reads into an array of bytes. This method will
* block until some input is available.
* @param b the buffer into which the data is read
* @param off the start offset of the data
* @param len the maximum number of bytes read
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @exception IOException If an I/O error has occurred.
*/
public int read(byte b[], int off, int len) throws IOException;
/**
* Skips n bytes of input.
* @param n the number of bytes to be skipped
* @return the actual number of bytes skipped.
* @exception IOException If an I/O error has occurred.
*/
public long skip(long n) throws IOException;
/**
* Returns the number of bytes that can be read
* without blocking.
* @return the number of available bytes.
* @exception IOException If an I/O error has occurred.
*/
public int available() throws IOException;
/**
* Closes the input stream. Must be called
* to release any resources associated with
* the stream.
* @exception IOException If an I/O error has occurred.
*/
public void close() throws IOException;
}

View file

@ -0,0 +1,673 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import jdk.internal.misc.SharedSecrets;
/**
* Filter classes, array lengths, and graph metrics during deserialization.
* If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)}
* method is called to validate classes, the length of each array,
* the number of objects being read from the stream, the depth of the graph,
* and the total number of bytes read from the stream.
* <p>
* A filter can be set via {@link ObjectInputStream#setObjectInputFilter setObjectInputFilter}
* for an individual ObjectInputStream.
* A filter can be set via {@link Config#setSerialFilter(ObjectInputFilter) Config.setSerialFilter}
* to affect every {@code ObjectInputStream} that does not otherwise set a filter.
* <p>
* A filter determines whether the arguments are {@link Status#ALLOWED ALLOWED}
* or {@link Status#REJECTED REJECTED} and should return the appropriate status.
* If the filter cannot determine the status it should return
* {@link Status#UNDECIDED UNDECIDED}.
* Filters should be designed for the specific use case and expected types.
* A filter designed for a particular use may be passed a class that is outside
* of the scope of the filter. If the purpose of the filter is to black-list classes
* then it can reject a candidate class that matches and report UNDECIDED for others.
* A filter may be called with class equals {@code null}, {@code arrayLength} equal -1,
* the depth, number of references, and stream size and return a status
* that reflects only one or only some of the values.
* This allows a filter to specific about the choice it is reporting and
* to use other filters without forcing either allowed or rejected status.
*
* <p>
* Typically, a custom filter should check if a process-wide filter
* is configured and defer to it if so. For example,
* <pre>{@code
* ObjectInputFilter.Status checkInput(FilterInfo info) {
* ObjectInputFilter serialFilter = ObjectInputFilter.Config.getSerialFilter();
* if (serialFilter != null) {
* ObjectInputFilter.Status status = serialFilter.checkInput(info);
* if (status != ObjectInputFilter.Status.UNDECIDED) {
* // The process-wide filter overrides this filter
* return status;
* }
* }
* if (info.serialClass() != null &&
* Remote.class.isAssignableFrom(info.serialClass())) {
* return Status.REJECTED; // Do not allow Remote objects
* }
* return Status.UNDECIDED;
* }
*}</pre>
* <p>
* Unless otherwise noted, passing a {@code null} argument to a
* method in this interface and its nested classes will cause a
* {@link NullPointerException} to be thrown.
*
* @see ObjectInputStream#setObjectInputFilter(ObjectInputFilter)
* @since 9
*/
@FunctionalInterface
public interface ObjectInputFilter {
/**
* Check the class, array length, number of object references, depth,
* stream size, and other available filtering information.
* Implementations of this method check the contents of the object graph being created
* during deserialization. The filter returns {@link Status#ALLOWED Status.ALLOWED},
* {@link Status#REJECTED Status.REJECTED}, or {@link Status#UNDECIDED Status.UNDECIDED}.
*
* @param filterInfo provides information about the current object being deserialized,
* if any, and the status of the {@link ObjectInputStream}
* @return {@link Status#ALLOWED Status.ALLOWED} if accepted,
* {@link Status#REJECTED Status.REJECTED} if rejected,
* {@link Status#UNDECIDED Status.UNDECIDED} if undecided.
*/
Status checkInput(FilterInfo filterInfo);
/**
* FilterInfo provides access to information about the current object
* being deserialized and the status of the {@link ObjectInputStream}.
* @since 9
*/
interface FilterInfo {
/**
* The class of an object being deserialized.
* For arrays, it is the array type.
* For example, the array class name of a 2 dimensional array of strings is
* "{@code [[Ljava.lang.String;}".
* To check the array's element type, iteratively use
* {@link Class#getComponentType() Class.getComponentType} while the result
* is an array and then check the class.
* The {@code serialClass is null} in the case where a new object is not being
* created and to give the filter a chance to check the depth, number of
* references to existing objects, and the stream size.
*
* @return class of an object being deserialized; may be null
*/
Class<?> serialClass();
/**
* The number of array elements when deserializing an array of the class.
*
* @return the non-negative number of array elements when deserializing
* an array of the class, otherwise -1
*/
long arrayLength();
/**
* The current depth.
* The depth starts at {@code 1} and increases for each nested object and
* decrements when each nested object returns.
*
* @return the current depth
*/
long depth();
/**
* The current number of object references.
*
* @return the non-negative current number of object references
*/
long references();
/**
* The current number of bytes consumed.
* @implSpec {@code streamBytes} is implementation specific
* and may not be directly related to the object in the stream
* that caused the callback.
*
* @return the non-negative current number of bytes consumed
*/
long streamBytes();
}
/**
* The status of a check on the class, array length, number of references,
* depth, and stream size.
*
* @since 9
*/
enum Status {
/**
* The status is undecided, not allowed and not rejected.
*/
UNDECIDED,
/**
* The status is allowed.
*/
ALLOWED,
/**
* The status is rejected.
*/
REJECTED;
}
/**
* A utility class to set and get the process-wide filter or create a filter
* from a pattern string. If a process-wide filter is set, it will be
* used for each {@link ObjectInputStream} that does not set its own filter.
* <p>
* When setting the filter, it should be stateless and idempotent,
* reporting the same result when passed the same arguments.
* <p>
* The filter is configured during the initialization of the {@code ObjectInputFilter.Config}
* class. For example, by calling {@link #getSerialFilter() Config.getSerialFilter}.
* If the system property {@code jdk.serialFilter} is defined, it is used
* to configure the filter.
* If the system property is not defined, and the {@link java.security.Security}
* property {@code jdk.serialFilter} is defined then it is used to configure the filter.
* Otherwise, the filter is not configured during initialization.
* The syntax for each property is the same as for the
* {@link #createFilter(String) createFilter} method.
* If a filter is not configured, it can be set with
* {@link #setSerialFilter(ObjectInputFilter) Config.setSerialFilter}.
*
* @since 9
*/
final class Config {
/* No instances. */
private Config() {}
/**
* Lock object for process-wide filter.
*/
private final static Object serialFilterLock = new Object();
/**
* Debug: Logger
*/
private final static System.Logger configLog;
/**
* Logger for debugging.
*/
static void filterLog(System.Logger.Level level, String msg, Object... args) {
if (configLog != null) {
configLog.log(level, msg, args);
}
}
/**
* The name for the process-wide deserialization filter.
* Used as a system property and a java.security.Security property.
*/
private final static String SERIAL_FILTER_PROPNAME = "jdk.serialFilter";
/**
* The process-wide filter; may be null.
* Lookup the filter in java.security.Security or
* the system property.
*/
private final static ObjectInputFilter configuredFilter;
static {
configuredFilter = AccessController
.doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
String props = System.getProperty(SERIAL_FILTER_PROPNAME);
if (props == null) {
props = Security.getProperty(SERIAL_FILTER_PROPNAME);
}
if (props != null) {
System.Logger log =
System.getLogger("java.io.serialization");
log.log(System.Logger.Level.INFO,
"Creating serialization filter from {0}", props);
try {
return createFilter(props);
} catch (RuntimeException re) {
log.log(System.Logger.Level.ERROR,
"Error configuring filter: {0}", re);
}
}
return null;
});
configLog = (configuredFilter != null) ? System.getLogger("java.io.serialization") : null;
// Setup shared secrets for RegistryImpl to use.
SharedSecrets.setJavaObjectInputFilterAccess(Config::createFilter2);
}
/**
* Current configured filter.
*/
private static ObjectInputFilter serialFilter = configuredFilter;
/**
* Returns the process-wide serialization filter or {@code null} if not configured.
*
* @return the process-wide serialization filter or {@code null} if not configured
*/
public static ObjectInputFilter getSerialFilter() {
synchronized (serialFilterLock) {
return serialFilter;
}
}
/**
* Set the process-wide filter if it has not already been configured or set.
*
* @param filter the serialization filter to set as the process-wide filter; not null
* @throws SecurityException if there is security manager and the
* {@code SerializablePermission("serialFilter")} is not granted
* @throws IllegalStateException if the filter has already been set {@code non-null}
*/
public static void setSerialFilter(ObjectInputFilter filter) {
Objects.requireNonNull(filter, "filter");
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION);
}
synchronized (serialFilterLock) {
if (serialFilter != null) {
throw new IllegalStateException("Serial filter can only be set once");
}
serialFilter = filter;
}
}
/**
* Returns an ObjectInputFilter from a string of patterns.
* <p>
* Patterns are separated by ";" (semicolon). Whitespace is significant and
* is considered part of the pattern.
* If a pattern includes an equals assignment, "{@code =}" it sets a limit.
* If a limit appears more than once the last value is used.
* <ul>
* <li>maxdepth={@code value} - the maximum depth of a graph</li>
* <li>maxrefs={@code value} - the maximum number of internal references</li>
* <li>maxbytes={@code value} - the maximum number of bytes in the input stream</li>
* <li>maxarray={@code value} - the maximum array length allowed</li>
* </ul>
* <p>
* Other patterns match or reject class or package name
* as returned from {@link Class#getName() Class.getName()} and
* if an optional module name is present
* {@link Module#getName() class.getModule().getName()}.
* Note that for arrays the element type is used in the pattern,
* not the array type.
* <ul>
* <li>If the pattern starts with "!", the class is rejected if the remaining pattern is matched;
* otherwise the class is allowed if the pattern matches.
* <li>If the pattern contains "/", the non-empty prefix up to the "/" is the module name;
* if the module name matches the module name of the class then
* the remaining pattern is matched with the class name.
* If there is no "/", the module name is not compared.
* <li>If the pattern ends with ".**" it matches any class in the package and all subpackages.
* <li>If the pattern ends with ".*" it matches any class in the package.
* <li>If the pattern ends with "*", it matches any class with the pattern as a prefix.
* <li>If the pattern is equal to the class name, it matches.
* <li>Otherwise, the pattern is not matched.
* </ul>
* <p>
* The resulting filter performs the limit checks and then
* tries to match the class, if any. If any of the limits are exceeded,
* the filter returns {@link Status#REJECTED Status.REJECTED}.
* If the class is an array type, the class to be matched is the element type.
* Arrays of any number of dimensions are treated the same as the element type.
* For example, a pattern of "{@code !example.Foo}",
* rejects creation of any instance or array of {@code example.Foo}.
* The first pattern that matches, working from left to right, determines
* the {@link Status#ALLOWED Status.ALLOWED}
* or {@link Status#REJECTED Status.REJECTED} result.
* If the limits are not exceeded and no pattern matches the class,
* the result is {@link Status#UNDECIDED Status.UNDECIDED}.
*
* @param pattern the pattern string to parse; not null
* @return a filter to check a class being deserialized;
* {@code null} if no patterns
* @throws IllegalArgumentException if the pattern string is illegal or
* malformed and cannot be parsed.
* In particular, if any of the following is true:
* <ul>
* <li> if a limit is missing the name or the name is not one of
* "maxdepth", "maxrefs", "maxbytes", or "maxarray"
* <li> if the value of the limit can not be parsed by
* {@link Long#parseLong Long.parseLong} or is negative
* <li> if the pattern contains "/" and the module name is missing
* or the remaining pattern is empty
* <li> if the package is missing for ".*" and ".**"
* </ul>
*/
public static ObjectInputFilter createFilter(String pattern) {
Objects.requireNonNull(pattern, "pattern");
return Global.createFilter(pattern, true);
}
/**
* Returns an ObjectInputFilter from a string of patterns that
* checks only the length for arrays, not the component type.
*
* @param pattern the pattern string to parse; not null
* @return a filter to check a class being deserialized;
* {@code null} if no patterns
*/
static ObjectInputFilter createFilter2(String pattern) {
Objects.requireNonNull(pattern, "pattern");
return Global.createFilter(pattern, false);
}
/**
* Implementation of ObjectInputFilter that performs the checks of
* the process-wide serialization filter. If configured, it will be
* used for all ObjectInputStreams that do not set their own filters.
*
*/
final static class Global implements ObjectInputFilter {
/**
* The pattern used to create the filter.
*/
private final String pattern;
/**
* The list of class filters.
*/
private final List<Function<Class<?>, Status>> filters;
/**
* Maximum allowed bytes in the stream.
*/
private long maxStreamBytes;
/**
* Maximum depth of the graph allowed.
*/
private long maxDepth;
/**
* Maximum number of references in a graph.
*/
private long maxReferences;
/**
* Maximum length of any array.
*/
private long maxArrayLength;
/**
* True to check the component type for arrays.
*/
private final boolean checkComponentType;
/**
* Returns an ObjectInputFilter from a string of patterns.
*
* @param pattern the pattern string to parse
* @param checkComponentType true if the filter should check
* the component type of arrays
* @return a filter to check a class being deserialized;
* {@code null} if no patterns
* @throws IllegalArgumentException if the parameter is malformed
* if the pattern is missing the name, the long value
* is not a number or is negative.
*/
static ObjectInputFilter createFilter(String pattern, boolean checkComponentType) {
try {
return new Global(pattern, checkComponentType);
} catch (UnsupportedOperationException uoe) {
// no non-empty patterns
return null;
}
}
/**
* Construct a new filter from the pattern String.
*
* @param pattern a pattern string of filters
* @param checkComponentType true if the filter should check
* the component type of arrays
* @throws IllegalArgumentException if the pattern is malformed
* @throws UnsupportedOperationException if there are no non-empty patterns
*/
private Global(String pattern, boolean checkComponentType) {
boolean hasLimits = false;
this.pattern = pattern;
this.checkComponentType = checkComponentType;
maxArrayLength = Long.MAX_VALUE; // Default values are unlimited
maxDepth = Long.MAX_VALUE;
maxReferences = Long.MAX_VALUE;
maxStreamBytes = Long.MAX_VALUE;
String[] patterns = pattern.split(";");
filters = new ArrayList<>(patterns.length);
for (int i = 0; i < patterns.length; i++) {
String p = patterns[i];
int nameLen = p.length();
if (nameLen == 0) {
continue;
}
if (parseLimit(p)) {
// If the pattern contained a limit setting, i.e. type=value
hasLimits = true;
continue;
}
boolean negate = p.charAt(0) == '!';
int poffset = negate ? 1 : 0;
// isolate module name, if any
int slash = p.indexOf('/', poffset);
if (slash == poffset) {
throw new IllegalArgumentException("module name is missing in: \"" + pattern + "\"");
}
final String moduleName = (slash >= 0) ? p.substring(poffset, slash) : null;
poffset = (slash >= 0) ? slash + 1 : poffset;
final Function<Class<?>, Status> patternFilter;
if (p.endsWith("*")) {
// Wildcard cases
if (p.endsWith(".*")) {
// Pattern is a package name with a wildcard
final String pkg = p.substring(poffset, nameLen - 1);
if (pkg.length() < 2) {
throw new IllegalArgumentException("package missing in: \"" + pattern + "\"");
}
if (negate) {
// A Function that fails if the class starts with the pattern, otherwise don't care
patternFilter = c -> matchesPackage(c, pkg) ? Status.REJECTED : Status.UNDECIDED;
} else {
// A Function that succeeds if the class starts with the pattern, otherwise don't care
patternFilter = c -> matchesPackage(c, pkg) ? Status.ALLOWED : Status.UNDECIDED;
}
} else if (p.endsWith(".**")) {
// Pattern is a package prefix with a double wildcard
final String pkgs = p.substring(poffset, nameLen - 2);
if (pkgs.length() < 2) {
throw new IllegalArgumentException("package missing in: \"" + pattern + "\"");
}
if (negate) {
// A Function that fails if the class starts with the pattern, otherwise don't care
patternFilter = c -> c.getName().startsWith(pkgs) ? Status.REJECTED : Status.UNDECIDED;
} else {
// A Function that succeeds if the class starts with the pattern, otherwise don't care
patternFilter = c -> c.getName().startsWith(pkgs) ? Status.ALLOWED : Status.UNDECIDED;
}
} else {
// Pattern is a classname (possibly empty) with a trailing wildcard
final String className = p.substring(poffset, nameLen - 1);
if (negate) {
// A Function that fails if the class starts with the pattern, otherwise don't care
patternFilter = c -> c.getName().startsWith(className) ? Status.REJECTED : Status.UNDECIDED;
} else {
// A Function that succeeds if the class starts with the pattern, otherwise don't care
patternFilter = c -> c.getName().startsWith(className) ? Status.ALLOWED : Status.UNDECIDED;
}
}
} else {
final String name = p.substring(poffset);
if (name.isEmpty()) {
throw new IllegalArgumentException("class or package missing in: \"" + pattern + "\"");
}
// Pattern is a class name
if (negate) {
// A Function that fails if the class equals the pattern, otherwise don't care
patternFilter = c -> c.getName().equals(name) ? Status.REJECTED : Status.UNDECIDED;
} else {
// A Function that succeeds if the class equals the pattern, otherwise don't care
patternFilter = c -> c.getName().equals(name) ? Status.ALLOWED : Status.UNDECIDED;
}
}
// If there is a moduleName, combine the module name check with the package/class check
if (moduleName == null) {
filters.add(patternFilter);
} else {
filters.add(c -> moduleName.equals(c.getModule().getName()) ? patternFilter.apply(c) : Status.UNDECIDED);
}
}
if (filters.isEmpty() && !hasLimits) {
throw new UnsupportedOperationException("no non-empty patterns");
}
}
/**
* Parse out a limit for one of maxarray, maxdepth, maxbytes, maxreferences.
*
* @param pattern a string with a type name, '=' and a value
* @return {@code true} if a limit was parsed, else {@code false}
* @throws IllegalArgumentException if the pattern is missing
* the name, the Long value is not a number or is negative.
*/
private boolean parseLimit(String pattern) {
int eqNdx = pattern.indexOf('=');
if (eqNdx < 0) {
// not a limit pattern
return false;
}
String valueString = pattern.substring(eqNdx + 1);
if (pattern.startsWith("maxdepth=")) {
maxDepth = parseValue(valueString);
} else if (pattern.startsWith("maxarray=")) {
maxArrayLength = parseValue(valueString);
} else if (pattern.startsWith("maxrefs=")) {
maxReferences = parseValue(valueString);
} else if (pattern.startsWith("maxbytes=")) {
maxStreamBytes = parseValue(valueString);
} else {
throw new IllegalArgumentException("unknown limit: " + pattern.substring(0, eqNdx));
}
return true;
}
/**
* Parse the value of a limit and check that it is non-negative.
* @param string inputstring
* @return the parsed value
* @throws IllegalArgumentException if parsing the value fails or the value is negative
*/
private static long parseValue(String string) throws IllegalArgumentException {
// Parse a Long from after the '=' to the end
long value = Long.parseLong(string);
if (value < 0) {
throw new IllegalArgumentException("negative limit: " + string);
}
return value;
}
/**
* {@inheritDoc}
*/
@Override
public Status checkInput(FilterInfo filterInfo) {
if (filterInfo.references() < 0
|| filterInfo.depth() < 0
|| filterInfo.streamBytes() < 0
|| filterInfo.references() > maxReferences
|| filterInfo.depth() > maxDepth
|| filterInfo.streamBytes() > maxStreamBytes) {
return Status.REJECTED;
}
Class<?> clazz = filterInfo.serialClass();
if (clazz != null) {
if (clazz.isArray()) {
if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > maxArrayLength) {
// array length is too big
return Status.REJECTED;
}
if (!checkComponentType) {
// As revised; do not check the component type for arrays
return Status.UNDECIDED;
}
do {
// Arrays are decided based on the component type
clazz = clazz.getComponentType();
} while (clazz.isArray());
}
if (clazz.isPrimitive()) {
// Primitive types are undecided; let someone else decide
return Status.UNDECIDED;
} else {
// Find any filter that allowed or rejected the class
final Class<?> cl = clazz;
Optional<Status> status = filters.stream()
.map(f -> f.apply(cl))
.filter(p -> p != Status.UNDECIDED)
.findFirst();
return status.orElse(Status.UNDECIDED);
}
}
return Status.UNDECIDED;
}
/**
* Returns {@code true} if the class is in the package.
*
* @param c a class
* @param pkg a package name (including the trailing ".")
* @return {@code true} if the class is in the package,
* otherwise {@code false}
*/
private static boolean matchesPackage(Class<?> c, String pkg) {
String n = c.getName();
return n.startsWith(pkg) && n.lastIndexOf('.') == pkg.length() - 1;
}
/**
* Returns the pattern used to create this filter.
* @return the pattern used to create this filter
*/
@Override
public String toString() {
return pattern;
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Callback interface to allow validation of objects within a graph.
* Allows an object to be called when a complete graph of objects has
* been deserialized.
*
* @author unascribed
* @see ObjectInputStream
* @see ObjectInputStream#registerValidation(java.io.ObjectInputValidation, int)
* @since 1.1
*/
public interface ObjectInputValidation {
/**
* Validates the object.
*
* @exception InvalidObjectException If the object cannot validate itself.
*/
public void validateObject() throws InvalidObjectException;
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* ObjectOutput extends the DataOutput interface to include writing of objects.
* DataOutput includes methods for output of primitive types, ObjectOutput
* extends that interface to include objects, arrays, and Strings.
*
* @author unascribed
* @see java.io.InputStream
* @see java.io.ObjectOutputStream
* @see java.io.ObjectInputStream
* @since 1.1
*/
public interface ObjectOutput extends DataOutput, AutoCloseable {
/**
* Write an object to the underlying storage or stream. The
* class that implements this interface defines how the object is
* written.
*
* @param obj the object to be written
* @exception IOException Any of the usual Input/Output related exceptions.
*/
public void writeObject(Object obj)
throws IOException;
/**
* Writes a byte. This method will block until the byte is actually
* written.
* @param b the byte
* @exception IOException If an I/O error has occurred.
*/
public void write(int b) throws IOException;
/**
* Writes an array of bytes. This method will block until the bytes
* are actually written.
* @param b the data to be written
* @exception IOException If an I/O error has occurred.
*/
public void write(byte b[]) throws IOException;
/**
* Writes a sub array of bytes.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
public void write(byte b[], int off, int len) throws IOException;
/**
* Flushes the stream. This will write any buffered
* output bytes.
* @exception IOException If an I/O error has occurred.
*/
public void flush() throws IOException;
/**
* Closes the stream. This method must be called
* to release any resources associated with the
* stream.
* @exception IOException If an I/O error has occurred.
*/
public void close() throws IOException;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,245 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Constants written into the Object Serialization Stream.
*
* @author unascribed
* @since 1.1
*/
public interface ObjectStreamConstants {
/**
* Magic number that is written to the stream header.
*/
static final short STREAM_MAGIC = (short)0xaced;
/**
* Version number that is written to the stream header.
*/
static final short STREAM_VERSION = 5;
/* Each item in the stream is preceded by a tag
*/
/**
* First tag value.
*/
static final byte TC_BASE = 0x70;
/**
* Null object reference.
*/
static final byte TC_NULL = (byte)0x70;
/**
* Reference to an object already written into the stream.
*/
static final byte TC_REFERENCE = (byte)0x71;
/**
* new Class Descriptor.
*/
static final byte TC_CLASSDESC = (byte)0x72;
/**
* new Object.
*/
static final byte TC_OBJECT = (byte)0x73;
/**
* new String.
*/
static final byte TC_STRING = (byte)0x74;
/**
* new Array.
*/
static final byte TC_ARRAY = (byte)0x75;
/**
* Reference to Class.
*/
static final byte TC_CLASS = (byte)0x76;
/**
* Block of optional data. Byte following tag indicates number
* of bytes in this block data.
*/
static final byte TC_BLOCKDATA = (byte)0x77;
/**
* End of optional block data blocks for an object.
*/
static final byte TC_ENDBLOCKDATA = (byte)0x78;
/**
* Reset stream context. All handles written into stream are reset.
*/
static final byte TC_RESET = (byte)0x79;
/**
* long Block data. The long following the tag indicates the
* number of bytes in this block data.
*/
static final byte TC_BLOCKDATALONG= (byte)0x7A;
/**
* Exception during write.
*/
static final byte TC_EXCEPTION = (byte)0x7B;
/**
* Long string.
*/
static final byte TC_LONGSTRING = (byte)0x7C;
/**
* new Proxy Class Descriptor.
*/
static final byte TC_PROXYCLASSDESC = (byte)0x7D;
/**
* new Enum constant.
* @since 1.5
*/
static final byte TC_ENUM = (byte)0x7E;
/**
* Last tag value.
*/
static final byte TC_MAX = (byte)0x7E;
/**
* First wire handle to be assigned.
*/
static final int baseWireHandle = 0x7e0000;
/******************************************************/
/* Bit masks for ObjectStreamClass flag.*/
/**
* Bit mask for ObjectStreamClass flag. Indicates a Serializable class
* defines its own writeObject method.
*/
static final byte SC_WRITE_METHOD = 0x01;
/**
* Bit mask for ObjectStreamClass flag. Indicates Externalizable data
* written in Block Data mode.
* Added for PROTOCOL_VERSION_2.
*
* @see #PROTOCOL_VERSION_2
* @since 1.2
*/
static final byte SC_BLOCK_DATA = 0x08;
/**
* Bit mask for ObjectStreamClass flag. Indicates class is Serializable.
*/
static final byte SC_SERIALIZABLE = 0x02;
/**
* Bit mask for ObjectStreamClass flag. Indicates class is Externalizable.
*/
static final byte SC_EXTERNALIZABLE = 0x04;
/**
* Bit mask for ObjectStreamClass flag. Indicates class is an enum type.
* @since 1.5
*/
static final byte SC_ENUM = 0x10;
/* *******************************************************************/
/* Security permissions */
/**
* Enable substitution of one object for another during
* serialization/deserialization.
*
* @see java.io.ObjectOutputStream#enableReplaceObject(boolean)
* @see java.io.ObjectInputStream#enableResolveObject(boolean)
* @since 1.2
*/
static final SerializablePermission SUBSTITUTION_PERMISSION =
new SerializablePermission("enableSubstitution");
/**
* Enable overriding of readObject and writeObject.
*
* @see java.io.ObjectOutputStream#writeObjectOverride(Object)
* @see java.io.ObjectInputStream#readObjectOverride()
* @since 1.2
*/
static final SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
new SerializablePermission("enableSubclassImplementation");
/**
* Enable setting the process-wide serial filter.
*
* @see java.io.ObjectInputFilter.Config#setSerialFilter(ObjectInputFilter)
* @since 9
*/
static final SerializablePermission SERIAL_FILTER_PERMISSION =
new SerializablePermission("serialFilter");
/**
* A Stream Protocol Version. <p>
*
* All externalizable data is written in JDK 1.1 external data
* format after calling this method. This version is needed to write
* streams containing Externalizable data that can be read by
* pre-JDK 1.1.6 JVMs.
*
* @see java.io.ObjectOutputStream#useProtocolVersion(int)
* @since 1.2
*/
public static final int PROTOCOL_VERSION_1 = 1;
/**
* A Stream Protocol Version. <p>
*
* This protocol is written by JVM 1.2.
*
* Externalizable data is written in block data mode and is
* terminated with TC_ENDBLOCKDATA. Externalizable class descriptor
* flags has SC_BLOCK_DATA enabled. JVM 1.1.6 and greater can
* read this format change.
*
* Enables writing a nonSerializable class descriptor into the
* stream. The serialVersionUID of a nonSerializable class is
* set to 0L.
*
* @see java.io.ObjectOutputStream#useProtocolVersion(int)
* @see #SC_BLOCK_DATA
* @since 1.2
*/
public static final int PROTOCOL_VERSION_2 = 2;
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Superclass of all exceptions specific to Object Stream classes.
*
* @author unascribed
* @since 1.1
*/
public abstract class ObjectStreamException extends IOException {
private static final long serialVersionUID = 7260898174833392607L;
/**
* Create an ObjectStreamException with the specified argument.
*
* @param message the detailed message for the exception
*/
protected ObjectStreamException(String message) {
super(message);
}
/**
* Create an ObjectStreamException.
*/
protected ObjectStreamException() {
super();
}
}

View file

@ -0,0 +1,354 @@
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.lang.reflect.Field;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
/**
* A description of a Serializable field from a Serializable class. An array
* of ObjectStreamFields is used to declare the Serializable fields of a class.
*
* @author Mike Warres
* @author Roger Riggs
* @see ObjectStreamClass
* @since 1.2
*/
public class ObjectStreamField
implements Comparable<Object>
{
/** field name */
private final String name;
/** canonical JVM signature of field type, if given */
private final String signature;
/** field type (Object.class if unknown non-primitive type) */
private final Class<?> type;
/** lazily constructed signature for the type, if no explicit signature */
private String typeSignature;
/** whether or not to (de)serialize field values as unshared */
private final boolean unshared;
/** corresponding reflective field object, if any */
private final Field field;
/** offset of field value in enclosing field group */
private int offset;
/**
* Create a Serializable field with the specified type. This field should
* be documented with a <code>serialField</code> tag.
*
* @param name the name of the serializable field
* @param type the <code>Class</code> object of the serializable field
*/
public ObjectStreamField(String name, Class<?> type) {
this(name, type, false);
}
/**
* Creates an ObjectStreamField representing a serializable field with the
* given name and type. If unshared is false, values of the represented
* field are serialized and deserialized in the default manner--if the
* field is non-primitive, object values are serialized and deserialized as
* if they had been written and read by calls to writeObject and
* readObject. If unshared is true, values of the represented field are
* serialized and deserialized as if they had been written and read by
* calls to writeUnshared and readUnshared.
*
* @param name field name
* @param type field type
* @param unshared if false, write/read field values in the same manner
* as writeObject/readObject; if true, write/read in the same
* manner as writeUnshared/readUnshared
* @since 1.4
*/
public ObjectStreamField(String name, Class<?> type, boolean unshared) {
if (name == null) {
throw new NullPointerException();
}
this.name = name;
this.type = type;
this.unshared = unshared;
this.field = null;
this.signature = null;
}
/**
* Creates an ObjectStreamField representing a field with the given name,
* signature and unshared setting.
*/
ObjectStreamField(String name, String signature, boolean unshared) {
if (name == null) {
throw new NullPointerException();
}
this.name = name;
this.signature = signature.intern();
this.unshared = unshared;
this.field = null;
switch (signature.charAt(0)) {
case 'Z': type = Boolean.TYPE; break;
case 'B': type = Byte.TYPE; break;
case 'C': type = Character.TYPE; break;
case 'S': type = Short.TYPE; break;
case 'I': type = Integer.TYPE; break;
case 'J': type = Long.TYPE; break;
case 'F': type = Float.TYPE; break;
case 'D': type = Double.TYPE; break;
case 'L':
case '[': type = Object.class; break;
default: throw new IllegalArgumentException("illegal signature");
}
}
/**
* Returns JVM type signature for given primitive.
*/
private static String getPrimitiveSignature(Class<?> cl) {
if (cl == Integer.TYPE)
return "I";
else if (cl == Byte.TYPE)
return "B";
else if (cl == Long.TYPE)
return "J";
else if (cl == Float.TYPE)
return "F";
else if (cl == Double.TYPE)
return "D";
else if (cl == Short.TYPE)
return "S";
else if (cl == Character.TYPE)
return "C";
else if (cl == Boolean.TYPE)
return "Z";
else if (cl == Void.TYPE)
return "V";
else
throw new InternalError();
}
/**
* Returns JVM type signature for given class.
*/
static String getClassSignature(Class<?> cl) {
if (cl.isPrimitive()) {
return getPrimitiveSignature(cl);
} else {
return appendClassSignature(new StringBuilder(), cl).toString();
}
}
static StringBuilder appendClassSignature(StringBuilder sbuf, Class<?> cl) {
while (cl.isArray()) {
sbuf.append('[');
cl = cl.getComponentType();
}
if (cl.isPrimitive()) {
sbuf.append(getPrimitiveSignature(cl));
} else {
sbuf.append('L').append(cl.getName().replace('.', '/')).append(';');
}
return sbuf;
}
/**
* Creates an ObjectStreamField representing the given field with the
* specified unshared setting. For compatibility with the behavior of
* earlier serialization implementations, a "showType" parameter is
* necessary to govern whether or not a getType() call on this
* ObjectStreamField (if non-primitive) will return Object.class (as
* opposed to a more specific reference type).
*/
ObjectStreamField(Field field, boolean unshared, boolean showType) {
this.field = field;
this.unshared = unshared;
name = field.getName();
Class<?> ftype = field.getType();
type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
signature = getClassSignature(ftype).intern();
}
/**
* Get the name of this field.
*
* @return a <code>String</code> representing the name of the serializable
* field
*/
public String getName() {
return name;
}
/**
* Get the type of the field. If the type is non-primitive and this
* <code>ObjectStreamField</code> was obtained from a deserialized {@link
* ObjectStreamClass} instance, then <code>Object.class</code> is returned.
* Otherwise, the <code>Class</code> object for the type of the field is
* returned.
*
* @return a <code>Class</code> object representing the type of the
* serializable field
*/
@CallerSensitive
public Class<?> getType() {
if (System.getSecurityManager() != null) {
Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) {
ReflectUtil.checkPackageAccess(type);
}
}
return type;
}
/**
* Returns character encoding of field type. The encoding is as follows:
* <blockquote><pre>
* B byte
* C char
* D double
* F float
* I int
* J long
* L class or interface
* S short
* Z boolean
* [ array
* </pre></blockquote>
*
* @return the typecode of the serializable field
*/
// REMIND: deprecate?
public char getTypeCode() {
return getSignature().charAt(0);
}
/**
* Return the JVM type signature.
*
* @return null if this field has a primitive type.
*/
// REMIND: deprecate?
public String getTypeString() {
return isPrimitive() ? null : getSignature();
}
/**
* Offset of field within instance data.
*
* @return the offset of this field
* @see #setOffset
*/
// REMIND: deprecate?
public int getOffset() {
return offset;
}
/**
* Offset within instance data.
*
* @param offset the offset of the field
* @see #getOffset
*/
// REMIND: deprecate?
protected void setOffset(int offset) {
this.offset = offset;
}
/**
* Return true if this field has a primitive type.
*
* @return true if and only if this field corresponds to a primitive type
*/
// REMIND: deprecate?
public boolean isPrimitive() {
char tcode = getTypeCode();
return ((tcode != 'L') && (tcode != '['));
}
/**
* Returns boolean value indicating whether or not the serializable field
* represented by this ObjectStreamField instance is unshared.
*
* @return {@code true} if this field is unshared
*
* @since 1.4
*/
public boolean isUnshared() {
return unshared;
}
/**
* Compare this field with another <code>ObjectStreamField</code>. Return
* -1 if this is smaller, 0 if equal, 1 if greater. Types that are
* primitives are "smaller" than object types. If equal, the field names
* are compared.
*/
// REMIND: deprecate?
public int compareTo(Object obj) {
ObjectStreamField other = (ObjectStreamField) obj;
boolean isPrim = isPrimitive();
if (isPrim != other.isPrimitive()) {
return isPrim ? -1 : 1;
}
return name.compareTo(other.name);
}
/**
* Return a string that describes this field.
*/
public String toString() {
return getSignature() + ' ' + name;
}
/**
* Returns field represented by this ObjectStreamField, or null if
* ObjectStreamField is not associated with an actual field.
*/
Field getField() {
return field;
}
/**
* Returns JVM type signature of field (similar to getTypeString, except
* that signature strings are returned for primitive fields as well).
*/
String getSignature() {
if (signature != null) {
return signature;
}
String sig = typeSignature;
// This lazy calculation is safe since signature can be null iff one
// of the public constructors are used, in which case type is always
// initialized to the exact type we want the signature to represent.
if (sig == null) {
typeSignature = sig = getClassSignature(type).intern();
}
return sig;
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Exception indicating the failure of an object read operation due to
* unread primitive data, or the end of data belonging to a serialized
* object in the stream. This exception may be thrown in two cases:
*
* <ul>
* <li>An attempt was made to read an object when the next element in the
* stream is primitive data. In this case, the OptionalDataException's
* length field is set to the number of bytes of primitive data
* immediately readable from the stream, and the eof field is set to
* false.
*
* <li>An attempt was made to read past the end of data consumable by a
* class-defined readObject or readExternal method. In this case, the
* OptionalDataException's eof field is set to true, and the length field
* is set to 0.
* </ul>
*
* @author unascribed
* @since 1.1
*/
public class OptionalDataException extends ObjectStreamException {
private static final long serialVersionUID = -8011121865681257820L;
/*
* Create an <code>OptionalDataException</code> with a length.
*/
OptionalDataException(int len) {
eof = false;
length = len;
}
/*
* Create an <code>OptionalDataException</code> signifying no
* more primitive data is available.
*/
OptionalDataException(boolean end) {
length = 0;
eof = end;
}
/**
* The number of bytes of primitive data available to be read
* in the current buffer.
*
* @serial
*/
public int length;
/**
* True if there is no more data in the buffered part of the stream.
*
* @serial
*/
public boolean eof;
}

View file

@ -0,0 +1,154 @@
/*
* Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* This abstract class is the superclass of all classes representing
* an output stream of bytes. An output stream accepts output bytes
* and sends them to some sink.
* <p>
* Applications that need to define a subclass of
* <code>OutputStream</code> must always provide at least a method
* that writes one byte of output.
*
* @author Arthur van Hoff
* @see java.io.BufferedOutputStream
* @see java.io.ByteArrayOutputStream
* @see java.io.DataOutputStream
* @see java.io.FilterOutputStream
* @see java.io.InputStream
* @see java.io.OutputStream#write(int)
* @since 1.0
*/
public abstract class OutputStream implements Closeable, Flushable {
/**
* Writes the specified byte to this output stream. The general
* contract for <code>write</code> is that one byte is written
* to the output stream. The byte to be written is the eight
* low-order bits of the argument <code>b</code>. The 24
* high-order bits of <code>b</code> are ignored.
* <p>
* Subclasses of <code>OutputStream</code> must provide an
* implementation for this method.
*
* @param b the <code>byte</code>.
* @exception IOException if an I/O error occurs. In particular,
* an <code>IOException</code> may be thrown if the
* output stream has been closed.
*/
public abstract void write(int b) throws IOException;
/**
* Writes <code>b.length</code> bytes from the specified byte array
* to this output stream. The general contract for <code>write(b)</code>
* is that it should have exactly the same effect as the call
* <code>write(b, 0, b.length)</code>.
*
* @param b the data.
* @exception IOException if an I/O error occurs.
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this output stream.
* The general contract for <code>write(b, off, len)</code> is that
* some of the bytes in the array <code>b</code> are written to the
* output stream in order; element <code>b[off]</code> is the first
* byte written and <code>b[off+len-1]</code> is the last byte written
* by this operation.
* <p>
* The <code>write</code> method of <code>OutputStream</code> calls
* the write method of one argument on each of the bytes to be
* written out. Subclasses are encouraged to override this method and
* provide a more efficient implementation.
* <p>
* If <code>b</code> is <code>null</code>, a
* <code>NullPointerException</code> is thrown.
* <p>
* If <code>off</code> is negative, or <code>len</code> is negative, or
* <code>off+len</code> is greater than the length of the array
* {@code b}, then an {@code IndexOutOfBoundsException} is thrown.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs. In particular,
* an <code>IOException</code> is thrown if the output
* stream is closed.
*/
public void write(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
/**
* Flushes this output stream and forces any buffered output bytes
* to be written out. The general contract of <code>flush</code> is
* that calling it is an indication that, if any bytes previously
* written have been buffered by the implementation of the output
* stream, such bytes should immediately be written to their
* intended destination.
* <p>
* If the intended destination of this stream is an abstraction provided by
* the underlying operating system, for example a file, then flushing the
* stream guarantees only that bytes previously written to the stream are
* passed to the operating system for writing; it does not guarantee that
* they are actually written to a physical device such as a disk drive.
* <p>
* The <code>flush</code> method of <code>OutputStream</code> does nothing.
*
* @exception IOException if an I/O error occurs.
*/
public void flush() throws IOException {
}
/**
* Closes this output stream and releases any system resources
* associated with this stream. The general contract of <code>close</code>
* is that it closes the output stream. A closed stream cannot perform
* output operations and cannot be reopened.
* <p>
* The <code>close</code> method of <code>OutputStream</code> does nothing.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
}
}

View file

@ -0,0 +1,260 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import sun.nio.cs.StreamEncoder;
/**
* An OutputStreamWriter is a bridge from character streams to byte streams:
* Characters written to it are encoded into bytes using a specified {@link
* java.nio.charset.Charset charset}. The charset that it uses
* may be specified by name or may be given explicitly, or the platform's
* default charset may be accepted.
*
* <p> Each invocation of a write() method causes the encoding converter to be
* invoked on the given character(s). The resulting bytes are accumulated in a
* buffer before being written to the underlying output stream. Note that the
* characters passed to the write() methods are not buffered.
*
* <p> For top efficiency, consider wrapping an OutputStreamWriter within a
* BufferedWriter so as to avoid frequent converter invocations. For example:
*
* <pre>
* Writer out
* = new BufferedWriter(new OutputStreamWriter(System.out));
* </pre>
*
* <p> A <i>surrogate pair</i> is a character represented by a sequence of two
* {@code char} values: A <i>high</i> surrogate in the range '&#92;uD800' to
* '&#92;uDBFF' followed by a <i>low</i> surrogate in the range '&#92;uDC00' to
* '&#92;uDFFF'.
*
* <p> A <i>malformed surrogate element</i> is a high surrogate that is not
* followed by a low surrogate or a low surrogate that is not preceded by a
* high surrogate.
*
* <p> This class always replaces malformed surrogate elements and unmappable
* character sequences with the charset's default <i>substitution sequence</i>.
* The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more
* control over the encoding process is required.
*
* @see BufferedWriter
* @see OutputStream
* @see java.nio.charset.Charset
*
* @author Mark Reinhold
* @since 1.1
*/
public class OutputStreamWriter extends Writer {
private final StreamEncoder se;
/**
* Creates an OutputStreamWriter that uses the named charset.
*
* @param out
* An OutputStream
*
* @param charsetName
* The name of a supported
* {@link java.nio.charset.Charset charset}
*
* @exception UnsupportedEncodingException
* If the named encoding is not supported
*/
public OutputStreamWriter(OutputStream out, String charsetName)
throws UnsupportedEncodingException
{
super(out);
if (charsetName == null)
throw new NullPointerException("charsetName");
se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
}
/**
* Creates an OutputStreamWriter that uses the default character encoding.
*
* @param out An OutputStream
*/
public OutputStreamWriter(OutputStream out) {
super(out);
try {
se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
/**
* Creates an OutputStreamWriter that uses the given charset.
*
* @param out
* An OutputStream
*
* @param cs
* A charset
*
* @since 1.4
* @spec JSR-51
*/
public OutputStreamWriter(OutputStream out, Charset cs) {
super(out);
if (cs == null)
throw new NullPointerException("charset");
se = StreamEncoder.forOutputStreamWriter(out, this, cs);
}
/**
* Creates an OutputStreamWriter that uses the given charset encoder.
*
* @param out
* An OutputStream
*
* @param enc
* A charset encoder
*
* @since 1.4
* @spec JSR-51
*/
public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {
super(out);
if (enc == null)
throw new NullPointerException("charset encoder");
se = StreamEncoder.forOutputStreamWriter(out, this, enc);
}
/**
* Returns the name of the character encoding being used by this stream.
*
* <p> If the encoding has an historical name then that name is returned;
* otherwise the encoding's canonical name is returned.
*
* <p> If this instance was created with the {@link
* #OutputStreamWriter(OutputStream, String)} constructor then the returned
* name, being unique for the encoding, may differ from the name passed to
* the constructor. This method may return {@code null} if the stream has
* been closed. </p>
*
* @return The historical name of this encoding, or possibly
* <code>null</code> if the stream has been closed
*
* @see java.nio.charset.Charset
*
* @revised 1.4
* @spec JSR-51
*/
public String getEncoding() {
return se.getEncoding();
}
/**
* Flushes the output buffer to the underlying byte stream, without flushing
* the byte stream itself. This method is non-private only so that it may
* be invoked by PrintStream.
*/
void flushBuffer() throws IOException {
se.flushBuffer();
}
/**
* Writes a single character.
*
* @exception IOException If an I/O error occurs
*/
public void write(int c) throws IOException {
se.write(c);
}
/**
* Writes a portion of an array of characters.
*
* @param cbuf Buffer of characters
* @param off Offset from which to start writing characters
* @param len Number of characters to write
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given array
*
* @throws IOException If an I/O error occurs
*/
public void write(char cbuf[], int off, int len) throws IOException {
se.write(cbuf, off, len);
}
/**
* Writes a portion of a string.
*
* @param str A String
* @param off Offset from which to start writing characters
* @param len Number of characters to write
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given string
*
* @throws IOException If an I/O error occurs
*/
public void write(String str, int off, int len) throws IOException {
se.write(str, off, len);
}
@Override
public Writer append(CharSequence csq, int start, int end) throws IOException {
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
@Override
public Writer append(CharSequence csq) throws IOException {
if (csq instanceof CharBuffer) {
se.write((CharBuffer) csq);
} else {
se.write(String.valueOf(csq));
}
return this;
}
/**
* Flushes the stream.
*
* @exception IOException If an I/O error occurs
*/
public void flush() throws IOException {
se.flush();
}
public void close() throws IOException {
se.close();
}
}

View file

@ -0,0 +1,449 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A piped input stream should be connected
* to a piped output stream; the piped input
* stream then provides whatever data bytes
* are written to the piped output stream.
* Typically, data is read from a <code>PipedInputStream</code>
* object by one thread and data is written
* to the corresponding <code>PipedOutputStream</code>
* by some other thread. Attempting to use
* both objects from a single thread is not
* recommended, as it may deadlock the thread.
* The piped input stream contains a buffer,
* decoupling read operations from write operations,
* within limits.
* A pipe is said to be <a id="BROKEN"> <i>broken</i> </a> if a
* thread that was providing data bytes to the connected
* piped output stream is no longer alive.
*
* @author James Gosling
* @see java.io.PipedOutputStream
* @since 1.0
*/
public class PipedInputStream extends InputStream {
boolean closedByWriter;
volatile boolean closedByReader;
boolean connected;
/* REMIND: identification of the read and write sides needs to be
more sophisticated. Either using thread groups (but what about
pipes within a thread?) or using finalization (but it may be a
long time until the next GC). */
Thread readSide;
Thread writeSide;
private static final int DEFAULT_PIPE_SIZE = 1024;
/**
* The default size of the pipe's circular input buffer.
* @since 1.1
*/
// This used to be a constant before the pipe size was allowed
// to change. This field will continue to be maintained
// for backward compatibility.
protected static final int PIPE_SIZE = DEFAULT_PIPE_SIZE;
/**
* The circular buffer into which incoming data is placed.
* @since 1.1
*/
protected byte buffer[];
/**
* The index of the position in the circular buffer at which the
* next byte of data will be stored when received from the connected
* piped output stream. <code>in&lt;0</code> implies the buffer is empty,
* <code>in==out</code> implies the buffer is full
* @since 1.1
*/
protected int in = -1;
/**
* The index of the position in the circular buffer at which the next
* byte of data will be read by this piped input stream.
* @since 1.1
*/
protected int out = 0;
/**
* Creates a <code>PipedInputStream</code> so
* that it is connected to the piped output
* stream <code>src</code>. Data bytes written
* to <code>src</code> will then be available
* as input from this stream.
*
* @param src the stream to connect to.
* @exception IOException if an I/O error occurs.
*/
public PipedInputStream(PipedOutputStream src) throws IOException {
this(src, DEFAULT_PIPE_SIZE);
}
/**
* Creates a <code>PipedInputStream</code> so that it is
* connected to the piped output stream
* <code>src</code> and uses the specified pipe size for
* the pipe's buffer.
* Data bytes written to <code>src</code> will then
* be available as input from this stream.
*
* @param src the stream to connect to.
* @param pipeSize the size of the pipe's buffer.
* @exception IOException if an I/O error occurs.
* @exception IllegalArgumentException if {@code pipeSize <= 0}.
* @since 1.6
*/
public PipedInputStream(PipedOutputStream src, int pipeSize)
throws IOException {
initPipe(pipeSize);
connect(src);
}
/**
* Creates a <code>PipedInputStream</code> so
* that it is not yet {@linkplain #connect(java.io.PipedOutputStream)
* connected}.
* It must be {@linkplain java.io.PipedOutputStream#connect(
* java.io.PipedInputStream) connected} to a
* <code>PipedOutputStream</code> before being used.
*/
public PipedInputStream() {
initPipe(DEFAULT_PIPE_SIZE);
}
/**
* Creates a <code>PipedInputStream</code> so that it is not yet
* {@linkplain #connect(java.io.PipedOutputStream) connected} and
* uses the specified pipe size for the pipe's buffer.
* It must be {@linkplain java.io.PipedOutputStream#connect(
* java.io.PipedInputStream)
* connected} to a <code>PipedOutputStream</code> before being used.
*
* @param pipeSize the size of the pipe's buffer.
* @exception IllegalArgumentException if {@code pipeSize <= 0}.
* @since 1.6
*/
public PipedInputStream(int pipeSize) {
initPipe(pipeSize);
}
private void initPipe(int pipeSize) {
if (pipeSize <= 0) {
throw new IllegalArgumentException("Pipe Size <= 0");
}
buffer = new byte[pipeSize];
}
/**
* Causes this piped input stream to be connected
* to the piped output stream <code>src</code>.
* If this object is already connected to some
* other piped output stream, an <code>IOException</code>
* is thrown.
* <p>
* If <code>src</code> is an
* unconnected piped output stream and <code>snk</code>
* is an unconnected piped input stream, they
* may be connected by either the call:
*
* <pre><code>snk.connect(src)</code> </pre>
* <p>
* or the call:
*
* <pre><code>src.connect(snk)</code> </pre>
* <p>
* The two calls have the same effect.
*
* @param src The piped output stream to connect to.
* @exception IOException if an I/O error occurs.
*/
public void connect(PipedOutputStream src) throws IOException {
src.connect(this);
}
/**
* Receives a byte of data. This method will block if no input is
* available.
* @param b the byte being received
* @exception IOException If the pipe is <a href="#BROKEN"> <code>broken</code></a>,
* {@link #connect(java.io.PipedOutputStream) unconnected},
* closed, or if an I/O error occurs.
* @since 1.1
*/
protected synchronized void receive(int b) throws IOException {
checkStateForReceive();
writeSide = Thread.currentThread();
if (in == out)
awaitSpace();
if (in < 0) {
in = 0;
out = 0;
}
buffer[in++] = (byte)(b & 0xFF);
if (in >= buffer.length) {
in = 0;
}
}
/**
* Receives data into an array of bytes. This method will
* block until some input is available.
* @param b the buffer into which the data is received
* @param off the start offset of the data
* @param len the maximum number of bytes received
* @exception IOException If the pipe is <a href="#BROKEN"> broken</a>,
* {@link #connect(java.io.PipedOutputStream) unconnected},
* closed,or if an I/O error occurs.
*/
synchronized void receive(byte b[], int off, int len) throws IOException {
checkStateForReceive();
writeSide = Thread.currentThread();
int bytesToTransfer = len;
while (bytesToTransfer > 0) {
if (in == out)
awaitSpace();
int nextTransferAmount = 0;
if (out < in) {
nextTransferAmount = buffer.length - in;
} else if (in < out) {
if (in == -1) {
in = out = 0;
nextTransferAmount = buffer.length - in;
} else {
nextTransferAmount = out - in;
}
}
if (nextTransferAmount > bytesToTransfer)
nextTransferAmount = bytesToTransfer;
assert(nextTransferAmount > 0);
System.arraycopy(b, off, buffer, in, nextTransferAmount);
bytesToTransfer -= nextTransferAmount;
off += nextTransferAmount;
in += nextTransferAmount;
if (in >= buffer.length) {
in = 0;
}
}
}
private void checkStateForReceive() throws IOException {
if (!connected) {
throw new IOException("Pipe not connected");
} else if (closedByWriter || closedByReader) {
throw new IOException("Pipe closed");
} else if (readSide != null && !readSide.isAlive()) {
throw new IOException("Read end dead");
}
}
private void awaitSpace() throws IOException {
while (in == out) {
checkStateForReceive();
/* full: kick any waiting readers */
notifyAll();
try {
wait(1000);
} catch (InterruptedException ex) {
throw new java.io.InterruptedIOException();
}
}
}
/**
* Notifies all waiting threads that the last byte of data has been
* received.
*/
synchronized void receivedLast() {
closedByWriter = true;
notifyAll();
}
/**
* Reads the next byte of data from this piped input stream. The
* value byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>.
* This method blocks until input data is available, the end of the
* stream is detected, or an exception is thrown.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if the pipe is
* {@link #connect(java.io.PipedOutputStream) unconnected},
* <a href="#BROKEN"> <code>broken</code></a>, closed,
* or if an I/O error occurs.
*/
public synchronized int read() throws IOException {
if (!connected) {
throw new IOException("Pipe not connected");
} else if (closedByReader) {
throw new IOException("Pipe closed");
} else if (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) {
throw new IOException("Write end dead");
}
readSide = Thread.currentThread();
int trials = 2;
while (in < 0) {
if (closedByWriter) {
/* closed by writer, return EOF */
return -1;
}
if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
throw new IOException("Pipe broken");
}
/* might be a writer waiting */
notifyAll();
try {
wait(1000);
} catch (InterruptedException ex) {
throw new java.io.InterruptedIOException();
}
}
int ret = buffer[out++] & 0xFF;
if (out >= buffer.length) {
out = 0;
}
if (in == out) {
/* now empty */
in = -1;
}
return ret;
}
/**
* Reads up to <code>len</code> bytes of data from this piped input
* stream into an array of bytes. Less than <code>len</code> bytes
* will be read if the end of the data stream is reached or if
* <code>len</code> exceeds the pipe's buffer size.
* If <code>len </code> is zero, then no bytes are read and 0 is returned;
* otherwise, the method blocks until at least 1 byte of input is
* available, end of the stream has been detected, or an exception is
* thrown.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if the pipe is <a href="#BROKEN"> <code>broken</code></a>,
* {@link #connect(java.io.PipedOutputStream) unconnected},
* closed, or if an I/O error occurs.
*/
public synchronized int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
/* possibly wait on the first character */
int c = read();
if (c < 0) {
return -1;
}
b[off] = (byte) c;
int rlen = 1;
while ((in >= 0) && (len > 1)) {
int available;
if (in > out) {
available = Math.min((buffer.length - out), (in - out));
} else {
available = buffer.length - out;
}
// A byte is read beforehand outside the loop
if (available > (len - 1)) {
available = len - 1;
}
System.arraycopy(buffer, out, b, off + rlen, available);
out += available;
rlen += available;
len -= available;
if (out >= buffer.length) {
out = 0;
}
if (in == out) {
/* now empty */
in = -1;
}
}
return rlen;
}
/**
* Returns the number of bytes that can be read from this input
* stream without blocking.
*
* @return the number of bytes that can be read from this input stream
* without blocking, or {@code 0} if this input stream has been
* closed by invoking its {@link #close()} method, or if the pipe
* is {@link #connect(java.io.PipedOutputStream) unconnected}, or
* <a href="#BROKEN"> <code>broken</code></a>.
*
* @exception IOException if an I/O error occurs.
* @since 1.0.2
*/
public synchronized int available() throws IOException {
if(in < 0)
return 0;
else if(in == out)
return buffer.length;
else if (in > out)
return in - out;
else
return in + buffer.length - out;
}
/**
* Closes this piped input stream and releases any system resources
* associated with the stream.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
closedByReader = true;
synchronized (this) {
in = -1;
}
}
}

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.io.*;
/**
* A piped output stream can be connected to a piped input stream
* to create a communications pipe. The piped output stream is the
* sending end of the pipe. Typically, data is written to a
* <code>PipedOutputStream</code> object by one thread and data is
* read from the connected <code>PipedInputStream</code> by some
* other thread. Attempting to use both objects from a single thread
* is not recommended as it may deadlock the thread.
* The pipe is said to be <a id=BROKEN> <i>broken</i> </a> if a
* thread that was reading data bytes from the connected piped input
* stream is no longer alive.
*
* @author James Gosling
* @see java.io.PipedInputStream
* @since 1.0
*/
public
class PipedOutputStream extends OutputStream {
/* REMIND: identification of the read and write sides needs to be
more sophisticated. Either using thread groups (but what about
pipes within a thread?) or using finalization (but it may be a
long time until the next GC). */
private PipedInputStream sink;
/**
* Creates a piped output stream connected to the specified piped
* input stream. Data bytes written to this stream will then be
* available as input from <code>snk</code>.
*
* @param snk The piped input stream to connect to.
* @exception IOException if an I/O error occurs.
*/
public PipedOutputStream(PipedInputStream snk) throws IOException {
connect(snk);
}
/**
* Creates a piped output stream that is not yet connected to a
* piped input stream. It must be connected to a piped input stream,
* either by the receiver or the sender, before being used.
*
* @see java.io.PipedInputStream#connect(java.io.PipedOutputStream)
* @see java.io.PipedOutputStream#connect(java.io.PipedInputStream)
*/
public PipedOutputStream() {
}
/**
* Connects this piped output stream to a receiver. If this object
* is already connected to some other piped input stream, an
* <code>IOException</code> is thrown.
* <p>
* If <code>snk</code> is an unconnected piped input stream and
* <code>src</code> is an unconnected piped output stream, they may
* be connected by either the call:
* <blockquote><pre>
* src.connect(snk)</pre></blockquote>
* or the call:
* <blockquote><pre>
* snk.connect(src)</pre></blockquote>
* The two calls have the same effect.
*
* @param snk the piped input stream to connect to.
* @exception IOException if an I/O error occurs.
*/
public synchronized void connect(PipedInputStream snk) throws IOException {
if (snk == null) {
throw new NullPointerException();
} else if (sink != null || snk.connected) {
throw new IOException("Already connected");
}
sink = snk;
snk.in = -1;
snk.out = 0;
snk.connected = true;
}
/**
* Writes the specified <code>byte</code> to the piped output stream.
* <p>
* Implements the <code>write</code> method of <code>OutputStream</code>.
*
* @param b the <code>byte</code> to be written.
* @exception IOException if the pipe is <a href=#BROKEN> broken</a>,
* {@link #connect(java.io.PipedInputStream) unconnected},
* closed, or if an I/O error occurs.
*/
public void write(int b) throws IOException {
if (sink == null) {
throw new IOException("Pipe not connected");
}
sink.receive(b);
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this piped output stream.
* This method blocks until all the bytes are written to the output
* stream.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if the pipe is <a href=#BROKEN> broken</a>,
* {@link #connect(java.io.PipedInputStream) unconnected},
* closed, or if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
if (sink == null) {
throw new IOException("Pipe not connected");
} else if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
sink.receive(b, off, len);
}
/**
* Flushes this output stream and forces any buffered output bytes
* to be written out.
* This will notify any readers that bytes are waiting in the pipe.
*
* @exception IOException if an I/O error occurs.
*/
public synchronized void flush() throws IOException {
if (sink != null) {
synchronized (sink) {
sink.notifyAll();
}
}
}
/**
* Closes this piped output stream and releases any system resources
* associated with this stream. This stream may no longer be used for
* writing bytes.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
if (sink != null) {
sink.receivedLast();
}
}
}

View file

@ -0,0 +1,363 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Piped character-input streams.
*
* @author Mark Reinhold
* @since 1.1
*/
public class PipedReader extends Reader {
boolean closedByWriter = false;
boolean closedByReader = false;
boolean connected = false;
/* REMIND: identification of the read and write sides needs to be
more sophisticated. Either using thread groups (but what about
pipes within a thread?) or using finalization (but it may be a
long time until the next GC). */
Thread readSide;
Thread writeSide;
/**
* The size of the pipe's circular input buffer.
*/
private static final int DEFAULT_PIPE_SIZE = 1024;
/**
* The circular buffer into which incoming data is placed.
*/
char buffer[];
/**
* The index of the position in the circular buffer at which the
* next character of data will be stored when received from the connected
* piped writer. <code>in&lt;0</code> implies the buffer is empty,
* <code>in==out</code> implies the buffer is full
*/
int in = -1;
/**
* The index of the position in the circular buffer at which the next
* character of data will be read by this piped reader.
*/
int out = 0;
/**
* Creates a <code>PipedReader</code> so
* that it is connected to the piped writer
* <code>src</code>. Data written to <code>src</code>
* will then be available as input from this stream.
*
* @param src the stream to connect to.
* @exception IOException if an I/O error occurs.
*/
public PipedReader(PipedWriter src) throws IOException {
this(src, DEFAULT_PIPE_SIZE);
}
/**
* Creates a <code>PipedReader</code> so that it is connected
* to the piped writer <code>src</code> and uses the specified
* pipe size for the pipe's buffer. Data written to <code>src</code>
* will then be available as input from this stream.
* @param src the stream to connect to.
* @param pipeSize the size of the pipe's buffer.
* @exception IOException if an I/O error occurs.
* @exception IllegalArgumentException if {@code pipeSize <= 0}.
* @since 1.6
*/
public PipedReader(PipedWriter src, int pipeSize) throws IOException {
initPipe(pipeSize);
connect(src);
}
/**
* Creates a <code>PipedReader</code> so
* that it is not yet {@linkplain #connect(java.io.PipedWriter)
* connected}. It must be {@linkplain java.io.PipedWriter#connect(
* java.io.PipedReader) connected} to a <code>PipedWriter</code>
* before being used.
*/
public PipedReader() {
initPipe(DEFAULT_PIPE_SIZE);
}
/**
* Creates a <code>PipedReader</code> so that it is not yet
* {@link #connect(java.io.PipedWriter) connected} and uses
* the specified pipe size for the pipe's buffer.
* It must be {@linkplain java.io.PipedWriter#connect(
* java.io.PipedReader) connected} to a <code>PipedWriter</code>
* before being used.
*
* @param pipeSize the size of the pipe's buffer.
* @exception IllegalArgumentException if {@code pipeSize <= 0}.
* @since 1.6
*/
public PipedReader(int pipeSize) {
initPipe(pipeSize);
}
private void initPipe(int pipeSize) {
if (pipeSize <= 0) {
throw new IllegalArgumentException("Pipe size <= 0");
}
buffer = new char[pipeSize];
}
/**
* Causes this piped reader to be connected
* to the piped writer <code>src</code>.
* If this object is already connected to some
* other piped writer, an <code>IOException</code>
* is thrown.
* <p>
* If <code>src</code> is an
* unconnected piped writer and <code>snk</code>
* is an unconnected piped reader, they
* may be connected by either the call:
*
* <pre><code>snk.connect(src)</code> </pre>
* <p>
* or the call:
*
* <pre><code>src.connect(snk)</code> </pre>
* <p>
* The two calls have the same effect.
*
* @param src The piped writer to connect to.
* @exception IOException if an I/O error occurs.
*/
public void connect(PipedWriter src) throws IOException {
src.connect(this);
}
/**
* Receives a char of data. This method will block if no input is
* available.
*/
synchronized void receive(int c) throws IOException {
if (!connected) {
throw new IOException("Pipe not connected");
} else if (closedByWriter || closedByReader) {
throw new IOException("Pipe closed");
} else if (readSide != null && !readSide.isAlive()) {
throw new IOException("Read end dead");
}
writeSide = Thread.currentThread();
while (in == out) {
if ((readSide != null) && !readSide.isAlive()) {
throw new IOException("Pipe broken");
}
/* full: kick any waiting readers */
notifyAll();
try {
wait(1000);
} catch (InterruptedException ex) {
throw new java.io.InterruptedIOException();
}
}
if (in < 0) {
in = 0;
out = 0;
}
buffer[in++] = (char) c;
if (in >= buffer.length) {
in = 0;
}
}
/**
* Receives data into an array of characters. This method will
* block until some input is available.
*/
synchronized void receive(char c[], int off, int len) throws IOException {
while (--len >= 0) {
receive(c[off++]);
}
}
/**
* Notifies all waiting threads that the last character of data has been
* received.
*/
synchronized void receivedLast() {
closedByWriter = true;
notifyAll();
}
/**
* Reads the next character of data from this piped stream.
* If no character is available because the end of the stream
* has been reached, the value <code>-1</code> is returned.
* This method blocks until input data is available, the end of
* the stream is detected, or an exception is thrown.
*
* @return the next character of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if the pipe is
* <a href=PipedInputStream.html#BROKEN> <code>broken</code></a>,
* {@link #connect(java.io.PipedWriter) unconnected}, closed,
* or an I/O error occurs.
*/
public synchronized int read() throws IOException {
if (!connected) {
throw new IOException("Pipe not connected");
} else if (closedByReader) {
throw new IOException("Pipe closed");
} else if (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) {
throw new IOException("Write end dead");
}
readSide = Thread.currentThread();
int trials = 2;
while (in < 0) {
if (closedByWriter) {
/* closed by writer, return EOF */
return -1;
}
if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
throw new IOException("Pipe broken");
}
/* might be a writer waiting */
notifyAll();
try {
wait(1000);
} catch (InterruptedException ex) {
throw new java.io.InterruptedIOException();
}
}
int ret = buffer[out++];
if (out >= buffer.length) {
out = 0;
}
if (in == out) {
/* now empty */
in = -1;
}
return ret;
}
/**
* Reads up to <code>len</code> characters of data from this piped
* stream into an array of characters. Less than <code>len</code> characters
* will be read if the end of the data stream is reached or if
* <code>len</code> exceeds the pipe's buffer size. This method
* blocks until at least one character of input is available.
*
* @param cbuf the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the maximum number of characters read.
* @return the total number of characters read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception IOException if the pipe is
* <a href=PipedInputStream.html#BROKEN> <code>broken</code></a>,
* {@link #connect(java.io.PipedWriter) unconnected}, closed,
* or an I/O error occurs.
* @exception IndexOutOfBoundsException {@inheritDoc}
*/
public synchronized int read(char cbuf[], int off, int len) throws IOException {
if (!connected) {
throw new IOException("Pipe not connected");
} else if (closedByReader) {
throw new IOException("Pipe closed");
} else if (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) {
throw new IOException("Write end dead");
}
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
/* possibly wait on the first character */
int c = read();
if (c < 0) {
return -1;
}
cbuf[off] = (char)c;
int rlen = 1;
while ((in >= 0) && (--len > 0)) {
cbuf[off + rlen] = buffer[out++];
rlen++;
if (out >= buffer.length) {
out = 0;
}
if (in == out) {
/* now empty */
in = -1;
}
}
return rlen;
}
/**
* Tell whether this stream is ready to be read. A piped character
* stream is ready if the circular buffer is not empty.
*
* @exception IOException if the pipe is
* <a href=PipedInputStream.html#BROKEN> <code>broken</code></a>,
* {@link #connect(java.io.PipedWriter) unconnected}, or closed.
*/
public synchronized boolean ready() throws IOException {
if (!connected) {
throw new IOException("Pipe not connected");
} else if (closedByReader) {
throw new IOException("Pipe closed");
} else if (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) {
throw new IOException("Write end dead");
}
if (in < 0) {
return false;
} else {
return true;
}
}
/**
* Closes this piped stream and releases any system resources
* associated with the stream.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
in = -1;
closedByReader = true;
}
}

View file

@ -0,0 +1,190 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Piped character-output streams.
*
* @author Mark Reinhold
* @since 1.1
*/
public class PipedWriter extends Writer {
/* REMIND: identification of the read and write sides needs to be
more sophisticated. Either using thread groups (but what about
pipes within a thread?) or using finalization (but it may be a
long time until the next GC). */
private PipedReader sink;
/* This flag records the open status of this particular writer. It
* is independent of the status flags defined in PipedReader. It is
* used to do a sanity check on connect.
*/
private boolean closed = false;
/**
* Creates a piped writer connected to the specified piped
* reader. Data characters written to this stream will then be
* available as input from <code>snk</code>.
*
* @param snk The piped reader to connect to.
* @exception IOException if an I/O error occurs.
*/
public PipedWriter(PipedReader snk) throws IOException {
connect(snk);
}
/**
* Creates a piped writer that is not yet connected to a
* piped reader. It must be connected to a piped reader,
* either by the receiver or the sender, before being used.
*
* @see java.io.PipedReader#connect(java.io.PipedWriter)
* @see java.io.PipedWriter#connect(java.io.PipedReader)
*/
public PipedWriter() {
}
/**
* Connects this piped writer to a receiver. If this object
* is already connected to some other piped reader, an
* <code>IOException</code> is thrown.
* <p>
* If <code>snk</code> is an unconnected piped reader and
* <code>src</code> is an unconnected piped writer, they may
* be connected by either the call:
* <blockquote><pre>
* src.connect(snk)</pre></blockquote>
* or the call:
* <blockquote><pre>
* snk.connect(src)</pre></blockquote>
* The two calls have the same effect.
*
* @param snk the piped reader to connect to.
* @exception IOException if an I/O error occurs.
*/
public synchronized void connect(PipedReader snk) throws IOException {
if (snk == null) {
throw new NullPointerException();
} else if (sink != null || snk.connected) {
throw new IOException("Already connected");
} else if (snk.closedByReader || closed) {
throw new IOException("Pipe closed");
}
sink = snk;
snk.in = -1;
snk.out = 0;
snk.connected = true;
}
/**
* Writes the specified <code>char</code> to the piped output stream.
* If a thread was reading data characters from the connected piped input
* stream, but the thread is no longer alive, then an
* <code>IOException</code> is thrown.
* <p>
* Implements the <code>write</code> method of <code>Writer</code>.
*
* @param c the <code>char</code> to be written.
* @exception IOException if the pipe is
* <a href=PipedOutputStream.html#BROKEN> <code>broken</code></a>,
* {@link #connect(java.io.PipedReader) unconnected}, closed
* or an I/O error occurs.
*/
public void write(int c) throws IOException {
if (sink == null) {
throw new IOException("Pipe not connected");
}
sink.receive(c);
}
/**
* Writes {@code len} characters from the specified character array
* starting at offset {@code off} to this piped output stream.
* This method blocks until all the characters are written to the output
* stream.
* If a thread was reading data characters from the connected piped input
* stream, but the thread is no longer alive, then an
* {@code IOException} is thrown.
*
* @param cbuf the data.
* @param off the start offset in the data.
* @param len the number of characters to write.
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given array
*
* @throws IOException if the pipe is
* <a href=PipedOutputStream.html#BROKEN><code>broken</code></a>,
* {@link #connect(java.io.PipedReader) unconnected}, closed
* or an I/O error occurs.
*/
public void write(char cbuf[], int off, int len) throws IOException {
if (sink == null) {
throw new IOException("Pipe not connected");
} else if ((off | len | (off + len) | (cbuf.length - (off + len))) < 0) {
throw new IndexOutOfBoundsException();
}
sink.receive(cbuf, off, len);
}
/**
* Flushes this output stream and forces any buffered output characters
* to be written out.
* This will notify any readers that characters are waiting in the pipe.
*
* @exception IOException if the pipe is closed, or an I/O error occurs.
*/
public synchronized void flush() throws IOException {
if (sink != null) {
if (sink.closedByReader || closed) {
throw new IOException("Pipe closed");
}
synchronized (sink) {
sink.notifyAll();
}
}
}
/**
* Closes this piped output stream and releases any system resources
* associated with this stream. This stream may no longer be used for
* writing characters.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
closed = true;
if (sink != null) {
sink.receivedLast();
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,380 @@
/*
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A <code>PushbackInputStream</code> adds
* functionality to another input stream, namely
* the ability to "push back" or "unread" bytes,
* by storing pushed-back bytes in an internal buffer.
* This is useful in situations where
* it is convenient for a fragment of code
* to read an indefinite number of data bytes
* that are delimited by a particular byte
* value; after reading the terminating byte,
* the code fragment can "unread" it, so that
* the next read operation on the input stream
* will reread the byte that was pushed back.
* For example, bytes representing the characters
* constituting an identifier might be terminated
* by a byte representing an operator character;
* a method whose job is to read just an identifier
* can read until it sees the operator and
* then push the operator back to be re-read.
*
* @author David Connelly
* @author Jonathan Payne
* @since 1.0
*/
public
class PushbackInputStream extends FilterInputStream {
/**
* The pushback buffer.
* @since 1.1
*/
protected byte[] buf;
/**
* The position within the pushback buffer from which the next byte will
* be read. When the buffer is empty, <code>pos</code> is equal to
* <code>buf.length</code>; when the buffer is full, <code>pos</code> is
* equal to zero.
*
* @since 1.1
*/
protected int pos;
/**
* Check to make sure that this stream has not been closed
*/
private void ensureOpen() throws IOException {
if (in == null)
throw new IOException("Stream closed");
}
/**
* Creates a <code>PushbackInputStream</code>
* with a pushback buffer of the specified <code>size</code>,
* and saves its argument, the input stream
* <code>in</code>, for later use. Initially,
* the pushback buffer is empty.
*
* @param in the input stream from which bytes will be read.
* @param size the size of the pushback buffer.
* @exception IllegalArgumentException if {@code size <= 0}
* @since 1.1
*/
public PushbackInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("size <= 0");
}
this.buf = new byte[size];
this.pos = size;
}
/**
* Creates a <code>PushbackInputStream</code>
* with a 1-byte pushback buffer, and saves its argument, the input stream
* <code>in</code>, for later use. Initially,
* the pushback buffer is empty.
*
* @param in the input stream from which bytes will be read.
*/
public PushbackInputStream(InputStream in) {
this(in, 1);
}
/**
* Reads the next byte of data from this input stream. The value
* byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>. If no byte is available
* because the end of the stream has been reached, the value
* <code>-1</code> is returned. This method blocks until input data
* is available, the end of the stream is detected, or an exception
* is thrown.
*
* <p> This method returns the most recently pushed-back byte, if there is
* one, and otherwise calls the <code>read</code> method of its underlying
* input stream and returns whatever value that method returns.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream has been reached.
* @exception IOException if this input stream has been closed by
* invoking its {@link #close()} method,
* or an I/O error occurs.
* @see java.io.InputStream#read()
*/
public int read() throws IOException {
ensureOpen();
if (pos < buf.length) {
return buf[pos++] & 0xff;
}
return super.read();
}
/**
* Reads up to <code>len</code> bytes of data from this input stream into
* an array of bytes. This method first reads any pushed-back bytes; after
* that, if fewer than <code>len</code> bytes have been read then it
* reads from the underlying input stream. If <code>len</code> is not zero, the method
* blocks until at least 1 byte of input is available; otherwise, no
* bytes are read and <code>0</code> is returned.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if this input stream has been closed by
* invoking its {@link #close()} method,
* or an I/O error occurs.
* @see java.io.InputStream#read(byte[], int, int)
*/
public int read(byte[] b, int off, int len) throws IOException {
ensureOpen();
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int avail = buf.length - pos;
if (avail > 0) {
if (len < avail) {
avail = len;
}
System.arraycopy(buf, pos, b, off, avail);
pos += avail;
off += avail;
len -= avail;
}
if (len > 0) {
len = super.read(b, off, len);
if (len == -1) {
return avail == 0 ? -1 : avail;
}
return avail + len;
}
return avail;
}
/**
* Pushes back a byte by copying it to the front of the pushback buffer.
* After this method returns, the next byte to be read will have the value
* <code>(byte)b</code>.
*
* @param b the <code>int</code> value whose low-order
* byte is to be pushed back.
* @exception IOException If there is not enough room in the pushback
* buffer for the byte, or this input stream has been closed by
* invoking its {@link #close()} method.
*/
public void unread(int b) throws IOException {
ensureOpen();
if (pos == 0) {
throw new IOException("Push back buffer is full");
}
buf[--pos] = (byte)b;
}
/**
* Pushes back a portion of an array of bytes by copying it to the front
* of the pushback buffer. After this method returns, the next byte to be
* read will have the value <code>b[off]</code>, the byte after that will
* have the value <code>b[off+1]</code>, and so forth.
*
* @param b the byte array to push back.
* @param off the start offset of the data.
* @param len the number of bytes to push back.
* @exception IOException If there is not enough room in the pushback
* buffer for the specified number of bytes,
* or this input stream has been closed by
* invoking its {@link #close()} method.
* @since 1.1
*/
public void unread(byte[] b, int off, int len) throws IOException {
ensureOpen();
if (len > pos) {
throw new IOException("Push back buffer is full");
}
pos -= len;
System.arraycopy(b, off, buf, pos, len);
}
/**
* Pushes back an array of bytes by copying it to the front of the
* pushback buffer. After this method returns, the next byte to be read
* will have the value <code>b[0]</code>, the byte after that will have the
* value <code>b[1]</code>, and so forth.
*
* @param b the byte array to push back
* @exception IOException If there is not enough room in the pushback
* buffer for the specified number of bytes,
* or this input stream has been closed by
* invoking its {@link #close()} method.
* @since 1.1
*/
public void unread(byte[] b) throws IOException {
unread(b, 0, b.length);
}
/**
* Returns an estimate of the number of bytes that can be read (or
* skipped over) from this input stream without blocking by the next
* invocation of a method for this input stream. The next invocation might be
* the same thread or another thread. A single read or skip of this
* many bytes will not block, but may read or skip fewer bytes.
*
* <p> The method returns the sum of the number of bytes that have been
* pushed back and the value returned by {@link
* java.io.FilterInputStream#available available}.
*
* @return the number of bytes that can be read (or skipped over) from
* the input stream without blocking.
* @exception IOException if this input stream has been closed by
* invoking its {@link #close()} method,
* or an I/O error occurs.
* @see java.io.FilterInputStream#in
* @see java.io.InputStream#available()
*/
public int available() throws IOException {
ensureOpen();
int n = buf.length - pos;
int avail = super.available();
return n > (Integer.MAX_VALUE - avail)
? Integer.MAX_VALUE
: n + avail;
}
/**
* Skips over and discards <code>n</code> bytes of data from this
* input stream. The <code>skip</code> method may, for a variety of
* reasons, end up skipping over some smaller number of bytes,
* possibly zero. If <code>n</code> is negative, no bytes are skipped.
*
* <p> The <code>skip</code> method of <code>PushbackInputStream</code>
* first skips over the bytes in the pushback buffer, if any. It then
* calls the <code>skip</code> method of the underlying input stream if
* more bytes need to be skipped. The actual number of bytes skipped
* is returned.
*
* @param n {@inheritDoc}
* @return {@inheritDoc}
* @throws IOException if the stream has been closed by
* invoking its {@link #close()} method,
* {@code in.skip(n)} throws an IOException,
* or an I/O error occurs.
* @see java.io.FilterInputStream#in
* @see java.io.InputStream#skip(long n)
* @since 1.2
*/
public long skip(long n) throws IOException {
ensureOpen();
if (n <= 0) {
return 0;
}
long pskip = buf.length - pos;
if (pskip > 0) {
if (n < pskip) {
pskip = n;
}
pos += pskip;
n -= pskip;
}
if (n > 0) {
pskip += super.skip(n);
}
return pskip;
}
/**
* Tests if this input stream supports the <code>mark</code> and
* <code>reset</code> methods, which it does not.
*
* @return <code>false</code>, since this class does not support the
* <code>mark</code> and <code>reset</code> methods.
* @see java.io.InputStream#mark(int)
* @see java.io.InputStream#reset()
*/
public boolean markSupported() {
return false;
}
/**
* Marks the current position in this input stream.
*
* <p> The <code>mark</code> method of <code>PushbackInputStream</code>
* does nothing.
*
* @param readlimit the maximum limit of bytes that can be read before
* the mark position becomes invalid.
* @see java.io.InputStream#reset()
*/
public synchronized void mark(int readlimit) {
}
/**
* Repositions this stream to the position at the time the
* <code>mark</code> method was last called on this input stream.
*
* <p> The method <code>reset</code> for class
* <code>PushbackInputStream</code> does nothing except throw an
* <code>IOException</code>.
*
* @exception IOException if this method is invoked.
* @see java.io.InputStream#mark(int)
* @see java.io.IOException
*/
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
}
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* Once the stream has been closed, further read(), unread(),
* available(), reset(), or skip() invocations will throw an IOException.
* Closing a previously closed stream has no effect.
*
* @exception IOException if an I/O error occurs.
*/
public synchronized void close() throws IOException {
if (in == null)
return;
in.close();
in = null;
buf = null;
}
}

View file

@ -0,0 +1,285 @@
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A character-stream reader that allows characters to be pushed back into the
* stream.
*
* @author Mark Reinhold
* @since 1.1
*/
public class PushbackReader extends FilterReader {
/** Pushback buffer */
private char[] buf;
/** Current position in buffer */
private int pos;
/**
* Creates a new pushback reader with a pushback buffer of the given size.
*
* @param in The reader from which characters will be read
* @param size The size of the pushback buffer
* @exception IllegalArgumentException if {@code size <= 0}
*/
public PushbackReader(Reader in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("size <= 0");
}
this.buf = new char[size];
this.pos = size;
}
/**
* Creates a new pushback reader with a one-character pushback buffer.
*
* @param in The reader from which characters will be read
*/
public PushbackReader(Reader in) {
this(in, 1);
}
/** Checks to make sure that the stream has not been closed. */
private void ensureOpen() throws IOException {
if (buf == null)
throw new IOException("Stream closed");
}
/**
* Reads a single character.
*
* @return The character read, or -1 if the end of the stream has been
* reached
*
* @exception IOException If an I/O error occurs
*/
public int read() throws IOException {
synchronized (lock) {
ensureOpen();
if (pos < buf.length)
return buf[pos++];
else
return super.read();
}
}
/**
* Reads characters into a portion of an array.
*
* @param cbuf Destination buffer
* @param off Offset at which to start writing characters
* @param len Maximum number of characters to read
*
* @return The number of characters read, or -1 if the end of the
* stream has been reached
*
* @exception IOException If an I/O error occurs
* @exception IndexOutOfBoundsException {@inheritDoc}
*/
public int read(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
try {
if (len <= 0) {
if (len < 0) {
throw new IndexOutOfBoundsException();
} else if ((off < 0) || (off > cbuf.length)) {
throw new IndexOutOfBoundsException();
}
return 0;
}
int avail = buf.length - pos;
if (avail > 0) {
if (len < avail)
avail = len;
System.arraycopy(buf, pos, cbuf, off, avail);
pos += avail;
off += avail;
len -= avail;
}
if (len > 0) {
len = super.read(cbuf, off, len);
if (len == -1) {
return (avail == 0) ? -1 : avail;
}
return avail + len;
}
return avail;
} catch (ArrayIndexOutOfBoundsException e) {
throw new IndexOutOfBoundsException();
}
}
}
/**
* Pushes back a single character by copying it to the front of the
* pushback buffer. After this method returns, the next character to be read
* will have the value <code>(char)c</code>.
*
* @param c The int value representing a character to be pushed back
*
* @exception IOException If the pushback buffer is full,
* or if some other I/O error occurs
*/
public void unread(int c) throws IOException {
synchronized (lock) {
ensureOpen();
if (pos == 0)
throw new IOException("Pushback buffer overflow");
buf[--pos] = (char) c;
}
}
/**
* Pushes back a portion of an array of characters by copying it to the
* front of the pushback buffer. After this method returns, the next
* character to be read will have the value <code>cbuf[off]</code>, the
* character after that will have the value <code>cbuf[off+1]</code>, and
* so forth.
*
* @param cbuf Character array
* @param off Offset of first character to push back
* @param len Number of characters to push back
*
* @exception IOException If there is insufficient room in the pushback
* buffer, or if some other I/O error occurs
*/
public void unread(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if (len > pos)
throw new IOException("Pushback buffer overflow");
pos -= len;
System.arraycopy(cbuf, off, buf, pos, len);
}
}
/**
* Pushes back an array of characters by copying it to the front of the
* pushback buffer. After this method returns, the next character to be
* read will have the value <code>cbuf[0]</code>, the character after that
* will have the value <code>cbuf[1]</code>, and so forth.
*
* @param cbuf Character array to push back
*
* @exception IOException If there is insufficient room in the pushback
* buffer, or if some other I/O error occurs
*/
public void unread(char cbuf[]) throws IOException {
unread(cbuf, 0, cbuf.length);
}
/**
* Tells whether this stream is ready to be read.
*
* @exception IOException If an I/O error occurs
*/
public boolean ready() throws IOException {
synchronized (lock) {
ensureOpen();
return (pos < buf.length) || super.ready();
}
}
/**
* Marks the present position in the stream. The <code>mark</code>
* for class <code>PushbackReader</code> always throws an exception.
*
* @exception IOException Always, since mark is not supported
*/
public void mark(int readAheadLimit) throws IOException {
throw new IOException("mark/reset not supported");
}
/**
* Resets the stream. The <code>reset</code> method of
* <code>PushbackReader</code> always throws an exception.
*
* @exception IOException Always, since reset is not supported
*/
public void reset() throws IOException {
throw new IOException("mark/reset not supported");
}
/**
* Tells whether this stream supports the mark() operation, which it does
* not.
*/
public boolean markSupported() {
return false;
}
/**
* Closes the stream and releases any system resources associated with
* it. Once the stream has been closed, further read(),
* unread(), ready(), or skip() invocations will throw an IOException.
* Closing a previously closed stream has no effect. This method will block
* while there is another thread blocking on the reader.
*
* @exception IOException If an I/O error occurs
*/
public void close() throws IOException {
synchronized (lock) {
super.close();
buf = null;
}
}
/**
* Skips characters. This method will block until some characters are
* available, an I/O error occurs, or the end of the stream is reached.
*
* @param n The number of characters to skip
*
* @return The number of characters actually skipped
*
* @exception IllegalArgumentException If <code>n</code> is negative.
* @exception IOException If an I/O error occurs
*/
public long skip(long n) throws IOException {
if (n < 0L)
throw new IllegalArgumentException("skip value is negative");
synchronized (lock) {
ensureOpen();
int avail = buf.length - pos;
if (avail > 0) {
if (n <= avail) {
pos += n;
return n;
} else {
pos = buf.length;
n -= avail;
}
}
return avail + super.skip(n);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,265 @@
/*
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Abstract class for reading character streams. The only methods that a
* subclass must implement are read(char[], int, int) and close(). Most
* subclasses, however, will override some of the methods defined here in order
* to provide higher efficiency, additional functionality, or both.
*
*
* @see BufferedReader
* @see LineNumberReader
* @see CharArrayReader
* @see InputStreamReader
* @see FileReader
* @see FilterReader
* @see PushbackReader
* @see PipedReader
* @see StringReader
* @see Writer
*
* @author Mark Reinhold
* @since 1.1
*/
public abstract class Reader implements Readable, Closeable {
/**
* The object used to synchronize operations on this stream. For
* efficiency, a character-stream object may use an object other than
* itself to protect critical sections. A subclass should therefore use
* the object in this field rather than {@code this} or a synchronized
* method.
*/
protected Object lock;
/**
* Creates a new character-stream reader whose critical sections will
* synchronize on the reader itself.
*/
protected Reader() {
this.lock = this;
}
/**
* Creates a new character-stream reader whose critical sections will
* synchronize on the given object.
*
* @param lock The Object to synchronize on.
*/
protected Reader(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
/**
* Attempts to read characters into the specified character buffer.
* The buffer is used as a repository of characters as-is: the only
* changes made are the results of a put operation. No flipping or
* rewinding of the buffer is performed.
*
* @param target the buffer to read characters into
* @return The number of characters added to the buffer, or
* -1 if this source of characters is at its end
* @throws IOException if an I/O error occurs
* @throws NullPointerException if target is null
* @throws java.nio.ReadOnlyBufferException if target is a read only buffer
* @since 1.5
*/
public int read(java.nio.CharBuffer target) throws IOException {
int len = target.remaining();
char[] cbuf = new char[len];
int n = read(cbuf, 0, len);
if (n > 0)
target.put(cbuf, 0, n);
return n;
}
/**
* Reads a single character. This method will block until a character is
* available, an I/O error occurs, or the end of the stream is reached.
*
* <p> Subclasses that intend to support efficient single-character input
* should override this method.
*
* @return The character read, as an integer in the range 0 to 65535
* ({@code 0x00-0xffff}), or -1 if the end of the stream has
* been reached
*
* @exception IOException If an I/O error occurs
*/
public int read() throws IOException {
char cb[] = new char[1];
if (read(cb, 0, 1) == -1)
return -1;
else
return cb[0];
}
/**
* Reads characters into an array. This method will block until some input
* is available, an I/O error occurs, or the end of the stream is reached.
*
* @param cbuf Destination buffer
*
* @return The number of characters read, or -1
* if the end of the stream
* has been reached
*
* @exception IOException If an I/O error occurs
*/
public int read(char cbuf[]) throws IOException {
return read(cbuf, 0, cbuf.length);
}
/**
* Reads characters into a portion of an array. This method will block
* until some input is available, an I/O error occurs, or the end of the
* stream is reached.
*
* @param cbuf Destination buffer
* @param off Offset at which to start storing characters
* @param len Maximum number of characters to read
*
* @return The number of characters read, or -1 if the end of the
* stream has been reached
*
* @exception IOException If an I/O error occurs
* @exception IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code len} is greater than {@code cbuf.length - off}
*/
public abstract int read(char cbuf[], int off, int len) throws IOException;
/** Maximum skip-buffer size */
private static final int maxSkipBufferSize = 8192;
/** Skip buffer, null until allocated */
private char skipBuffer[] = null;
/**
* Skips characters. This method will block until some characters are
* available, an I/O error occurs, or the end of the stream is reached.
*
* @param n The number of characters to skip
*
* @return The number of characters actually skipped
*
* @exception IllegalArgumentException If <code>n</code> is negative.
* @exception IOException If an I/O error occurs
*/
public long skip(long n) throws IOException {
if (n < 0L)
throw new IllegalArgumentException("skip value is negative");
int nn = (int) Math.min(n, maxSkipBufferSize);
synchronized (lock) {
if ((skipBuffer == null) || (skipBuffer.length < nn))
skipBuffer = new char[nn];
long r = n;
while (r > 0) {
int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
if (nc == -1)
break;
r -= nc;
}
return n - r;
}
}
/**
* Tells whether this stream is ready to be read.
*
* @return True if the next read() is guaranteed not to block for input,
* false otherwise. Note that returning false does not guarantee that the
* next read will block.
*
* @exception IOException If an I/O error occurs
*/
public boolean ready() throws IOException {
return false;
}
/**
* Tells whether this stream supports the mark() operation. The default
* implementation always returns false. Subclasses should override this
* method.
*
* @return true if and only if this stream supports the mark operation.
*/
public boolean markSupported() {
return false;
}
/**
* Marks the present position in the stream. Subsequent calls to reset()
* will attempt to reposition the stream to this point. Not all
* character-input streams support the mark() operation.
*
* @param readAheadLimit Limit on the number of characters that may be
* read while still preserving the mark. After
* reading this many characters, attempting to
* reset the stream may fail.
*
* @exception IOException If the stream does not support mark(),
* or if some other I/O error occurs
*/
public void mark(int readAheadLimit) throws IOException {
throw new IOException("mark() not supported");
}
/**
* Resets the stream. If the stream has been marked, then attempt to
* reposition it at the mark. If the stream has not been marked, then
* attempt to reset it in some way appropriate to the particular stream,
* for example by repositioning it to its starting point. Not all
* character-input streams support the reset() operation, and some support
* reset() without supporting mark().
*
* @exception IOException If the stream has not been marked,
* or if the mark has been invalidated,
* or if the stream does not support reset(),
* or if some other I/O error occurs
*/
public void reset() throws IOException {
throw new IOException("reset() not supported");
}
/**
* Closes the stream and releases any system resources associated with
* it. Once the stream has been closed, further read(), ready(),
* mark(), reset(), or skip() invocations will throw an IOException.
* Closing a previously closed stream has no effect.
*
* @exception IOException If an I/O error occurs
*/
public abstract void close() throws IOException;
}

View file

@ -0,0 +1,227 @@
/*
* Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;
/**
* A <code>SequenceInputStream</code> represents
* the logical concatenation of other input
* streams. It starts out with an ordered
* collection of input streams and reads from
* the first one until end of file is reached,
* whereupon it reads from the second one,
* and so on, until end of file is reached
* on the last of the contained input streams.
*
* @author Author van Hoff
* @since 1.0
*/
public
class SequenceInputStream extends InputStream {
Enumeration<? extends InputStream> e;
InputStream in;
/**
* Initializes a newly created <code>SequenceInputStream</code>
* by remembering the argument, which must
* be an <code>Enumeration</code> that produces
* objects whose run-time type is <code>InputStream</code>.
* The input streams that are produced by
* the enumeration will be read, in order,
* to provide the bytes to be read from this
* <code>SequenceInputStream</code>. After
* each input stream from the enumeration
* is exhausted, it is closed by calling its
* <code>close</code> method.
*
* @param e an enumeration of input streams.
* @see java.util.Enumeration
*/
public SequenceInputStream(Enumeration<? extends InputStream> e) {
this.e = e;
peekNextStream();
}
/**
* Initializes a newly
* created <code>SequenceInputStream</code>
* by remembering the two arguments, which
* will be read in order, first <code>s1</code>
* and then <code>s2</code>, to provide the
* bytes to be read from this <code>SequenceInputStream</code>.
*
* @param s1 the first input stream to read.
* @param s2 the second input stream to read.
*/
public SequenceInputStream(InputStream s1, InputStream s2) {
Vector<InputStream> v = new Vector<>(2);
v.addElement(s1);
v.addElement(s2);
e = v.elements();
peekNextStream();
}
/**
* Continues reading in the next stream if an EOF is reached.
*/
final void nextStream() throws IOException {
if (in != null) {
in.close();
}
peekNextStream();
}
private void peekNextStream() {
if (e.hasMoreElements()) {
in = (InputStream) e.nextElement();
if (in == null)
throw new NullPointerException();
} else {
in = null;
}
}
/**
* Returns an estimate of the number of bytes that can be read (or
* skipped over) from the current underlying input stream without
* blocking by the next invocation of a method for the current
* underlying input stream. The next invocation might be
* the same thread or another thread. A single read or skip of this
* many bytes will not block, but may read or skip fewer bytes.
* <p>
* This method simply calls {@code available} of the current underlying
* input stream and returns the result.
*
* @return an estimate of the number of bytes that can be read (or
* skipped over) from the current underlying input stream
* without blocking or {@code 0} if this input stream
* has been closed by invoking its {@link #close()} method
* @exception IOException if an I/O error occurs.
*
* @since 1.1
*/
public int available() throws IOException {
if (in == null) {
return 0; // no way to signal EOF from available()
}
return in.available();
}
/**
* Reads the next byte of data from this input stream. The byte is
* returned as an <code>int</code> in the range <code>0</code> to
* <code>255</code>. If no byte is available because the end of the
* stream has been reached, the value <code>-1</code> is returned.
* This method blocks until input data is available, the end of the
* stream is detected, or an exception is thrown.
* <p>
* This method
* tries to read one character from the current substream. If it
* reaches the end of the stream, it calls the <code>close</code>
* method of the current substream and begins reading from the next
* substream.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if an I/O error occurs.
*/
public int read() throws IOException {
while (in != null) {
int c = in.read();
if (c != -1) {
return c;
}
nextStream();
}
return -1;
}
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. If <code>len</code> is not zero, the method
* blocks until at least 1 byte of input is available; otherwise, no
* bytes are read and <code>0</code> is returned.
* <p>
* The <code>read</code> method of <code>SequenceInputStream</code>
* tries to read the data from the current substream. If it fails to
* read any characters because the substream has reached the end of
* the stream, it calls the <code>close</code> method of the current
* substream and begins reading from the next substream.
*
* @param b the buffer into which the data is read.
* @param off the start offset in array <code>b</code>
* at which the data is written.
* @param len the maximum number of bytes read.
* @return int the number of bytes read.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[], int off, int len) throws IOException {
if (in == null) {
return -1;
} else if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
do {
int n = in.read(b, off, len);
if (n > 0) {
return n;
}
nextStream();
} while (in != null);
return -1;
}
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* A closed <code>SequenceInputStream</code>
* cannot perform input operations and cannot
* be reopened.
* <p>
* If this stream was created
* from an enumeration, all remaining elements
* are requested from the enumeration and closed
* before the <code>close</code> method returns.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
do {
nextStream();
} while (in != null);
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Context during upcalls from object stream to class-defined
* readObject/writeObject methods.
* Holds object currently being deserialized and descriptor for current class.
*
* This context keeps track of the thread it was constructed on, and allows
* only a single call of defaultReadObject, readFields, defaultWriteObject
* or writeFields which must be invoked on the same thread before the class's
* readObject/writeObject method has returned.
* If not set to the current thread, the getObj method throws NotActiveException.
*/
final class SerialCallbackContext {
private final Object obj;
private final ObjectStreamClass desc;
/**
* Thread this context is in use by.
* As this only works in one thread, we do not need to worry about thread-safety.
*/
private Thread thread;
public SerialCallbackContext(Object obj, ObjectStreamClass desc) {
this.obj = obj;
this.desc = desc;
this.thread = Thread.currentThread();
}
public Object getObj() throws NotActiveException {
checkAndSetUsed();
return obj;
}
public ObjectStreamClass getDesc() {
return desc;
}
public void check() throws NotActiveException {
if (thread != null && thread != Thread.currentThread()) {
throw new NotActiveException(
"expected thread: " + thread + ", but got: " + Thread.currentThread());
}
}
public void checkAndSetUsed() throws NotActiveException {
if (thread != Thread.currentThread()) {
throw new NotActiveException(
"not in readObject invocation or fields already read");
}
thread = null;
}
public void setUsed() {
thread = null;
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Serializability of a class is enabled by the class implementing the
* java.io.Serializable interface. Classes that do not implement this
* interface will not have any of their state serialized or
* deserialized. All subtypes of a serializable class are themselves
* serializable. The serialization interface has no methods or fields
* and serves only to identify the semantics of being serializable. <p>
*
* To allow subtypes of non-serializable classes to be serialized, the
* subtype may assume responsibility for saving and restoring the
* state of the supertype's public, protected, and (if accessible)
* package fields. The subtype may assume this responsibility only if
* the class it extends has an accessible no-arg constructor to
* initialize the class's state. It is an error to declare a class
* Serializable if this is not the case. The error will be detected at
* runtime. <p>
*
* During deserialization, the fields of non-serializable classes will
* be initialized using the public or protected no-arg constructor of
* the class. A no-arg constructor must be accessible to the subclass
* that is serializable. The fields of serializable subclasses will
* be restored from the stream. <p>
*
* When traversing a graph, an object may be encountered that does not
* support the Serializable interface. In this case the
* NotSerializableException will be thrown and will identify the class
* of the non-serializable object. <p>
*
* Classes that require special handling during the serialization and
* deserialization process must implement special methods with these exact
* signatures:
*
* <PRE>
* private void writeObject(java.io.ObjectOutputStream out)
* throws IOException
* private void readObject(java.io.ObjectInputStream in)
* throws IOException, ClassNotFoundException;
* private void readObjectNoData()
* throws ObjectStreamException;
* </PRE>
*
* <p>The writeObject method is responsible for writing the state of the
* object for its particular class so that the corresponding
* readObject method can restore it. The default mechanism for saving
* the Object's fields can be invoked by calling
* out.defaultWriteObject. The method does not need to concern
* itself with the state belonging to its superclasses or subclasses.
* State is saved by writing the individual fields to the
* ObjectOutputStream using the writeObject method or by using the
* methods for primitive data types supported by DataOutput.
*
* <p>The readObject method is responsible for reading from the stream and
* restoring the classes fields. It may call in.defaultReadObject to invoke
* the default mechanism for restoring the object's non-static and
* non-transient fields. The defaultReadObject method uses information in
* the stream to assign the fields of the object saved in the stream with the
* correspondingly named fields in the current object. This handles the case
* when the class has evolved to add new fields. The method does not need to
* concern itself with the state belonging to its superclasses or subclasses.
* State is restored by reading data from the ObjectInputStream for
* the individual fields and making assignments to the appropriate fields
* of the object. Reading primitive data types is supported by DataInput.
*
* <p>The readObjectNoData method is responsible for initializing the state of
* the object for its particular class in the event that the serialization
* stream does not list the given class as a superclass of the object being
* deserialized. This may occur in cases where the receiving party uses a
* different version of the deserialized instance's class than the sending
* party, and the receiver's version extends classes that are not extended by
* the sender's version. This may also occur if the serialization stream has
* been tampered; hence, readObjectNoData is useful for initializing
* deserialized objects properly despite a "hostile" or incomplete source
* stream.
*
* <p>Serializable classes that need to designate an alternative object to be
* used when writing an object to the stream should implement this
* special method with the exact signature:
*
* <PRE>
* ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
* </PRE><p>
*
* This writeReplace method is invoked by serialization if the method
* exists and it would be accessible from a method defined within the
* class of the object being serialized. Thus, the method can have private,
* protected and package-private access. Subclass access to this method
* follows java accessibility rules. <p>
*
* Classes that need to designate a replacement when an instance of it
* is read from the stream should implement this special method with the
* exact signature.
*
* <PRE>
* ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
* </PRE><p>
*
* This readResolve method follows the same invocation rules and
* accessibility rules as writeReplace.<p>
*
* The serialization runtime associates with each serializable class a version
* number, called a serialVersionUID, which is used during deserialization to
* verify that the sender and receiver of a serialized object have loaded
* classes for that object that are compatible with respect to serialization.
* If the receiver has loaded a class for the object that has a different
* serialVersionUID than that of the corresponding sender's class, then
* deserialization will result in an {@link InvalidClassException}. A
* serializable class can declare its own serialVersionUID explicitly by
* declaring a field named <code>"serialVersionUID"</code> that must be static,
* final, and of type <code>long</code>:
*
* <PRE>
* ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
* </PRE>
*
* If a serializable class does not explicitly declare a serialVersionUID, then
* the serialization runtime will calculate a default serialVersionUID value
* for that class based on various aspects of the class, as described in the
* Java(TM) Object Serialization Specification. However, it is <em>strongly
* recommended</em> that all serializable classes explicitly declare
* serialVersionUID values, since the default serialVersionUID computation is
* highly sensitive to class details that may vary depending on compiler
* implementations, and can thus result in unexpected
* <code>InvalidClassException</code>s during deserialization. Therefore, to
* guarantee a consistent serialVersionUID value across different java compiler
* implementations, a serializable class must declare an explicit
* serialVersionUID value. It is also strongly advised that explicit
* serialVersionUID declarations use the <code>private</code> modifier where
* possible, since such declarations apply only to the immediately declaring
* class--serialVersionUID fields are not useful as inherited members. Array
* classes cannot declare an explicit serialVersionUID, so they always have
* the default computed value, but the requirement for matching
* serialVersionUID values is waived for array classes.
*
* @author unascribed
* @see java.io.ObjectOutputStream
* @see java.io.ObjectInputStream
* @see java.io.ObjectOutput
* @see java.io.ObjectInput
* @see java.io.Externalizable
* @since 1.1
*/
public interface Serializable {
}

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.security.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
/**
* This class is for Serializable permissions. A SerializablePermission
* contains a name (also referred to as a "target name") but
* no actions list; you either have the named permission
* or you don't.
*
* <P>
* The target name is the name of the Serializable permission (see below).
*
* <P>
* The following table lists the standard {@code SerializablePermission} target names,
* and for each provides a description of what the permission allows
* and a discussion of the risks of granting code the permission.
*
* <table class="striped">
* <caption style="display:none">Permission target name, what the permission allows, and associated risks</caption>
* <thead>
* <tr>
* <th scope="col">Permission Target Name</th>
* <th scope="col">What the Permission Allows</th>
* <th scope="col">Risks of Allowing this Permission</th>
* </tr>
* </thead>
* <tbody>
*
* <tr>
* <th scope="row">enableSubclassImplementation</th>
* <td>Subclass implementation of ObjectOutputStream or ObjectInputStream
* to override the default serialization or deserialization, respectively,
* of objects</td>
* <td>Code can use this to serialize or
* deserialize classes in a purposefully malfeasant manner. For example,
* during serialization, malicious code can use this to
* purposefully store confidential private field data in a way easily accessible
* to attackers. Or, during deserialization it could, for example, deserialize
* a class with all its private fields zeroed out.</td>
* </tr>
*
* <tr>
* <th scope="row">enableSubstitution</th>
* <td>Substitution of one object for another during
* serialization or deserialization</td>
* <td>This is dangerous because malicious code
* can replace the actual object with one which has incorrect or
* malignant data.</td>
* </tr>
*
* <tr>
* <th scope="row">serialFilter</th>
* <td>Setting a filter for ObjectInputStreams.</td>
* <td>Code could remove a configured filter and remove protections
* already established.</td>
* </tr>
* </tbody>
* </table>
*
* @see java.security.BasicPermission
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
*
* @author Joe Fialli
* @since 1.2
*/
/* code was borrowed originally from java.lang.RuntimePermission. */
public final class SerializablePermission extends BasicPermission {
private static final long serialVersionUID = 8537212141160296410L;
/**
* @serial
*/
private String actions;
/**
* Creates a new SerializablePermission with the specified name.
* The name is the symbolic name of the SerializablePermission, such as
* "enableSubstitution", etc.
*
* @param name the name of the SerializablePermission.
*
* @throws NullPointerException if <code>name</code> is <code>null</code>.
* @throws IllegalArgumentException if <code>name</code> is empty.
*/
public SerializablePermission(String name)
{
super(name);
}
/**
* Creates a new SerializablePermission object with the specified name.
* The name is the symbolic name of the SerializablePermission, and the
* actions String is currently unused and should be null.
*
* @param name the name of the SerializablePermission.
* @param actions currently unused and must be set to null
*
* @throws NullPointerException if <code>name</code> is <code>null</code>.
* @throws IllegalArgumentException if <code>name</code> is empty.
*/
public SerializablePermission(String name, String actions)
{
super(name, actions);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Thrown when control information that was read from an object stream
* violates internal consistency checks.
*
* @author unascribed
* @since 1.1
*/
public class StreamCorruptedException extends ObjectStreamException {
private static final long serialVersionUID = 8983558202217591746L;
/**
* Create a StreamCorruptedException and list a reason why thrown.
*
* @param reason String describing the reason for the exception.
*/
public StreamCorruptedException(String reason) {
super(reason);
}
/**
* Create a StreamCorruptedException and list no reason why thrown.
*/
public StreamCorruptedException() {
super();
}
}

View file

@ -0,0 +1,834 @@
/*
* Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.Arrays;
/**
* The {@code StreamTokenizer} class takes an input stream and
* parses it into "tokens", allowing the tokens to be
* read one at a time. The parsing process is controlled by a table
* and a number of flags that can be set to various states. The
* stream tokenizer can recognize identifiers, numbers, quoted
* strings, and various comment styles.
* <p>
* Each byte read from the input stream is regarded as a character
* in the range {@code '\u005Cu0000'} through {@code '\u005Cu00FF'}.
* The character value is used to look up five possible attributes of
* the character: <i>white space</i>, <i>alphabetic</i>,
* <i>numeric</i>, <i>string quote</i>, and <i>comment character</i>.
* Each character can have zero or more of these attributes.
* <p>
* In addition, an instance has four flags. These flags indicate:
* <ul>
* <li>Whether line terminators are to be returned as tokens or treated
* as white space that merely separates tokens.
* <li>Whether C-style comments are to be recognized and skipped.
* <li>Whether C++-style comments are to be recognized and skipped.
* <li>Whether the characters of identifiers are converted to lowercase.
* </ul>
* <p>
* A typical application first constructs an instance of this class,
* sets up the syntax tables, and then repeatedly loops calling the
* {@code nextToken} method in each iteration of the loop until
* it returns the value {@code TT_EOF}.
*
* @author James Gosling
* @see java.io.StreamTokenizer#nextToken()
* @see java.io.StreamTokenizer#TT_EOF
* @since 1.0
*/
public class StreamTokenizer {
/* Only one of these will be non-null */
private Reader reader = null;
private InputStream input = null;
private char buf[] = new char[20];
/**
* The next character to be considered by the nextToken method. May also
* be NEED_CHAR to indicate that a new character should be read, or SKIP_LF
* to indicate that a new character should be read and, if it is a '\n'
* character, it should be discarded and a second new character should be
* read.
*/
private int peekc = NEED_CHAR;
private static final int NEED_CHAR = Integer.MAX_VALUE;
private static final int SKIP_LF = Integer.MAX_VALUE - 1;
private boolean pushedBack;
private boolean forceLower;
/** The line number of the last token read */
private int LINENO = 1;
private boolean eolIsSignificantP = false;
private boolean slashSlashCommentsP = false;
private boolean slashStarCommentsP = false;
private byte ctype[] = new byte[256];
private static final byte CT_WHITESPACE = 1;
private static final byte CT_DIGIT = 2;
private static final byte CT_ALPHA = 4;
private static final byte CT_QUOTE = 8;
private static final byte CT_COMMENT = 16;
/**
* After a call to the {@code nextToken} method, this field
* contains the type of the token just read. For a single character
* token, its value is the single character, converted to an integer.
* For a quoted string token, its value is the quote character.
* Otherwise, its value is one of the following:
* <ul>
* <li>{@code TT_WORD} indicates that the token is a word.
* <li>{@code TT_NUMBER} indicates that the token is a number.
* <li>{@code TT_EOL} indicates that the end of line has been read.
* The field can only have this value if the
* {@code eolIsSignificant} method has been called with the
* argument {@code true}.
* <li>{@code TT_EOF} indicates that the end of the input stream
* has been reached.
* </ul>
* <p>
* The initial value of this field is -4.
*
* @see java.io.StreamTokenizer#eolIsSignificant(boolean)
* @see java.io.StreamTokenizer#nextToken()
* @see java.io.StreamTokenizer#quoteChar(int)
* @see java.io.StreamTokenizer#TT_EOF
* @see java.io.StreamTokenizer#TT_EOL
* @see java.io.StreamTokenizer#TT_NUMBER
* @see java.io.StreamTokenizer#TT_WORD
*/
public int ttype = TT_NOTHING;
/**
* A constant indicating that the end of the stream has been read.
*/
public static final int TT_EOF = -1;
/**
* A constant indicating that the end of the line has been read.
*/
public static final int TT_EOL = '\n';
/**
* A constant indicating that a number token has been read.
*/
public static final int TT_NUMBER = -2;
/**
* A constant indicating that a word token has been read.
*/
public static final int TT_WORD = -3;
/* A constant indicating that no token has been read, used for
* initializing ttype. FIXME This could be made public and
* made available as the part of the API in a future release.
*/
private static final int TT_NOTHING = -4;
/**
* If the current token is a word token, this field contains a
* string giving the characters of the word token. When the current
* token is a quoted string token, this field contains the body of
* the string.
* <p>
* The current token is a word when the value of the
* {@code ttype} field is {@code TT_WORD}. The current token is
* a quoted string token when the value of the {@code ttype} field is
* a quote character.
* <p>
* The initial value of this field is null.
*
* @see java.io.StreamTokenizer#quoteChar(int)
* @see java.io.StreamTokenizer#TT_WORD
* @see java.io.StreamTokenizer#ttype
*/
public String sval;
/**
* If the current token is a number, this field contains the value
* of that number. The current token is a number when the value of
* the {@code ttype} field is {@code TT_NUMBER}.
* <p>
* The initial value of this field is 0.0.
*
* @see java.io.StreamTokenizer#TT_NUMBER
* @see java.io.StreamTokenizer#ttype
*/
public double nval;
/** Private constructor that initializes everything except the streams. */
private StreamTokenizer() {
wordChars('a', 'z');
wordChars('A', 'Z');
wordChars(128 + 32, 255);
whitespaceChars(0, ' ');
commentChar('/');
quoteChar('"');
quoteChar('\'');
parseNumbers();
}
/**
* Creates a stream tokenizer that parses the specified input
* stream. The stream tokenizer is initialized to the following
* default state:
* <ul>
* <li>All byte values {@code 'A'} through {@code 'Z'},
* {@code 'a'} through {@code 'z'}, and
* {@code '\u005Cu00A0'} through {@code '\u005Cu00FF'} are
* considered to be alphabetic.
* <li>All byte values {@code '\u005Cu0000'} through
* {@code '\u005Cu0020'} are considered to be white space.
* <li>{@code '/'} is a comment character.
* <li>Single quote {@code '\u005C''} and double quote {@code '"'}
* are string quote characters.
* <li>Numbers are parsed.
* <li>Ends of lines are treated as white space, not as separate tokens.
* <li>C-style and C++-style comments are not recognized.
* </ul>
*
* @deprecated As of JDK version 1.1, the preferred way to tokenize an
* input stream is to convert it into a character stream, for example:
* <blockquote><pre>
* Reader r = new BufferedReader(new InputStreamReader(is));
* StreamTokenizer st = new StreamTokenizer(r);
* </pre></blockquote>
*
* @param is an input stream.
* @see java.io.BufferedReader
* @see java.io.InputStreamReader
* @see java.io.StreamTokenizer#StreamTokenizer(java.io.Reader)
*/
@Deprecated
public StreamTokenizer(InputStream is) {
this();
if (is == null) {
throw new NullPointerException();
}
input = is;
}
/**
* Create a tokenizer that parses the given character stream.
*
* @param r a Reader object providing the input stream.
* @since 1.1
*/
public StreamTokenizer(Reader r) {
this();
if (r == null) {
throw new NullPointerException();
}
reader = r;
}
/**
* Resets this tokenizer's syntax table so that all characters are
* "ordinary." See the {@code ordinaryChar} method
* for more information on a character being ordinary.
*
* @see java.io.StreamTokenizer#ordinaryChar(int)
*/
public void resetSyntax() {
for (int i = ctype.length; --i >= 0;)
ctype[i] = 0;
}
/**
* Specifies that all characters <i>c</i> in the range
* <code>low&nbsp;&lt;=&nbsp;<i>c</i>&nbsp;&lt;=&nbsp;high</code>
* are word constituents. A word token consists of a word constituent
* followed by zero or more word constituents or number constituents.
*
* @param low the low end of the range.
* @param hi the high end of the range.
*/
public void wordChars(int low, int hi) {
if (low < 0)
low = 0;
if (hi >= ctype.length)
hi = ctype.length - 1;
while (low <= hi)
ctype[low++] |= CT_ALPHA;
}
/**
* Specifies that all characters <i>c</i> in the range
* <code>low&nbsp;&lt;=&nbsp;<i>c</i>&nbsp;&lt;=&nbsp;high</code>
* are white space characters. White space characters serve only to
* separate tokens in the input stream.
*
* <p>Any other attribute settings for the characters in the specified
* range are cleared.
*
* @param low the low end of the range.
* @param hi the high end of the range.
*/
public void whitespaceChars(int low, int hi) {
if (low < 0)
low = 0;
if (hi >= ctype.length)
hi = ctype.length - 1;
while (low <= hi)
ctype[low++] = CT_WHITESPACE;
}
/**
* Specifies that all characters <i>c</i> in the range
* <code>low&nbsp;&lt;=&nbsp;<i>c</i>&nbsp;&lt;=&nbsp;high</code>
* are "ordinary" in this tokenizer. See the
* {@code ordinaryChar} method for more information on a
* character being ordinary.
*
* @param low the low end of the range.
* @param hi the high end of the range.
* @see java.io.StreamTokenizer#ordinaryChar(int)
*/
public void ordinaryChars(int low, int hi) {
if (low < 0)
low = 0;
if (hi >= ctype.length)
hi = ctype.length - 1;
while (low <= hi)
ctype[low++] = 0;
}
/**
* Specifies that the character argument is "ordinary"
* in this tokenizer. It removes any special significance the
* character has as a comment character, word component, string
* delimiter, white space, or number character. When such a character
* is encountered by the parser, the parser treats it as a
* single-character token and sets {@code ttype} field to the
* character value.
*
* <p>Making a line terminator character "ordinary" may interfere
* with the ability of a {@code StreamTokenizer} to count
* lines. The {@code lineno} method may no longer reflect
* the presence of such terminator characters in its line count.
*
* @param ch the character.
* @see java.io.StreamTokenizer#ttype
*/
public void ordinaryChar(int ch) {
if (ch >= 0 && ch < ctype.length)
ctype[ch] = 0;
}
/**
* Specified that the character argument starts a single-line
* comment. All characters from the comment character to the end of
* the line are ignored by this stream tokenizer.
*
* <p>Any other attribute settings for the specified character are cleared.
*
* @param ch the character.
*/
public void commentChar(int ch) {
if (ch >= 0 && ch < ctype.length)
ctype[ch] = CT_COMMENT;
}
/**
* Specifies that matching pairs of this character delimit string
* constants in this tokenizer.
* <p>
* When the {@code nextToken} method encounters a string
* constant, the {@code ttype} field is set to the string
* delimiter and the {@code sval} field is set to the body of
* the string.
* <p>
* If a string quote character is encountered, then a string is
* recognized, consisting of all characters after (but not including)
* the string quote character, up to (but not including) the next
* occurrence of that same string quote character, or a line
* terminator, or end of file. The usual escape sequences such as
* {@code "\u005Cn"} and {@code "\u005Ct"} are recognized and
* converted to single characters as the string is parsed.
*
* <p>Any other attribute settings for the specified character are cleared.
*
* @param ch the character.
* @see java.io.StreamTokenizer#nextToken()
* @see java.io.StreamTokenizer#sval
* @see java.io.StreamTokenizer#ttype
*/
public void quoteChar(int ch) {
if (ch >= 0 && ch < ctype.length)
ctype[ch] = CT_QUOTE;
}
/**
* Specifies that numbers should be parsed by this tokenizer. The
* syntax table of this tokenizer is modified so that each of the twelve
* characters:
* <blockquote><pre>
* 0 1 2 3 4 5 6 7 8 9 . -
* </pre></blockquote>
* <p>
* has the "numeric" attribute.
* <p>
* When the parser encounters a word token that has the format of a
* double precision floating-point number, it treats the token as a
* number rather than a word, by setting the {@code ttype}
* field to the value {@code TT_NUMBER} and putting the numeric
* value of the token into the {@code nval} field.
*
* @see java.io.StreamTokenizer#nval
* @see java.io.StreamTokenizer#TT_NUMBER
* @see java.io.StreamTokenizer#ttype
*/
public void parseNumbers() {
for (int i = '0'; i <= '9'; i++)
ctype[i] |= CT_DIGIT;
ctype['.'] |= CT_DIGIT;
ctype['-'] |= CT_DIGIT;
}
/**
* Determines whether or not ends of line are treated as tokens.
* If the flag argument is true, this tokenizer treats end of lines
* as tokens; the {@code nextToken} method returns
* {@code TT_EOL} and also sets the {@code ttype} field to
* this value when an end of line is read.
* <p>
* A line is a sequence of characters ending with either a
* carriage-return character ({@code '\u005Cr'}) or a newline
* character ({@code '\u005Cn'}). In addition, a carriage-return
* character followed immediately by a newline character is treated
* as a single end-of-line token.
* <p>
* If the {@code flag} is false, end-of-line characters are
* treated as white space and serve only to separate tokens.
*
* @param flag {@code true} indicates that end-of-line characters
* are separate tokens; {@code false} indicates that
* end-of-line characters are white space.
* @see java.io.StreamTokenizer#nextToken()
* @see java.io.StreamTokenizer#ttype
* @see java.io.StreamTokenizer#TT_EOL
*/
public void eolIsSignificant(boolean flag) {
eolIsSignificantP = flag;
}
/**
* Determines whether or not the tokenizer recognizes C-style comments.
* If the flag argument is {@code true}, this stream tokenizer
* recognizes C-style comments. All text between successive
* occurrences of {@code /*} and <code>*&#47;</code> are discarded.
* <p>
* If the flag argument is {@code false}, then C-style comments
* are not treated specially.
*
* @param flag {@code true} indicates to recognize and ignore
* C-style comments.
*/
public void slashStarComments(boolean flag) {
slashStarCommentsP = flag;
}
/**
* Determines whether or not the tokenizer recognizes C++-style comments.
* If the flag argument is {@code true}, this stream tokenizer
* recognizes C++-style comments. Any occurrence of two consecutive
* slash characters ({@code '/'}) is treated as the beginning of
* a comment that extends to the end of the line.
* <p>
* If the flag argument is {@code false}, then C++-style
* comments are not treated specially.
*
* @param flag {@code true} indicates to recognize and ignore
* C++-style comments.
*/
public void slashSlashComments(boolean flag) {
slashSlashCommentsP = flag;
}
/**
* Determines whether or not word token are automatically lowercased.
* If the flag argument is {@code true}, then the value in the
* {@code sval} field is lowercased whenever a word token is
* returned (the {@code ttype} field has the
* value {@code TT_WORD} by the {@code nextToken} method
* of this tokenizer.
* <p>
* If the flag argument is {@code false}, then the
* {@code sval} field is not modified.
*
* @param fl {@code true} indicates that all word tokens should
* be lowercased.
* @see java.io.StreamTokenizer#nextToken()
* @see java.io.StreamTokenizer#ttype
* @see java.io.StreamTokenizer#TT_WORD
*/
public void lowerCaseMode(boolean fl) {
forceLower = fl;
}
/** Read the next character */
private int read() throws IOException {
if (reader != null)
return reader.read();
else if (input != null)
return input.read();
else
throw new IllegalStateException();
}
/**
* Parses the next token from the input stream of this tokenizer.
* The type of the next token is returned in the {@code ttype}
* field. Additional information about the token may be in the
* {@code nval} field or the {@code sval} field of this
* tokenizer.
* <p>
* Typical clients of this
* class first set up the syntax tables and then sit in a loop
* calling nextToken to parse successive tokens until TT_EOF
* is returned.
*
* @return the value of the {@code ttype} field.
* @exception IOException if an I/O error occurs.
* @see java.io.StreamTokenizer#nval
* @see java.io.StreamTokenizer#sval
* @see java.io.StreamTokenizer#ttype
*/
public int nextToken() throws IOException {
if (pushedBack) {
pushedBack = false;
return ttype;
}
byte ct[] = ctype;
sval = null;
int c = peekc;
if (c < 0)
c = NEED_CHAR;
if (c == SKIP_LF) {
c = read();
if (c < 0)
return ttype = TT_EOF;
if (c == '\n')
c = NEED_CHAR;
}
if (c == NEED_CHAR) {
c = read();
if (c < 0)
return ttype = TT_EOF;
}
ttype = c; /* Just to be safe */
/* Set peekc so that the next invocation of nextToken will read
* another character unless peekc is reset in this invocation
*/
peekc = NEED_CHAR;
int ctype = c < 256 ? ct[c] : CT_ALPHA;
while ((ctype & CT_WHITESPACE) != 0) {
if (c == '\r') {
LINENO++;
if (eolIsSignificantP) {
peekc = SKIP_LF;
return ttype = TT_EOL;
}
c = read();
if (c == '\n')
c = read();
} else {
if (c == '\n') {
LINENO++;
if (eolIsSignificantP) {
return ttype = TT_EOL;
}
}
c = read();
}
if (c < 0)
return ttype = TT_EOF;
ctype = c < 256 ? ct[c] : CT_ALPHA;
}
if ((ctype & CT_DIGIT) != 0) {
boolean neg = false;
if (c == '-') {
c = read();
if (c != '.' && (c < '0' || c > '9')) {
peekc = c;
return ttype = '-';
}
neg = true;
}
double v = 0;
int decexp = 0;
int seendot = 0;
while (true) {
if (c == '.' && seendot == 0)
seendot = 1;
else if ('0' <= c && c <= '9') {
v = v * 10 + (c - '0');
decexp += seendot;
} else
break;
c = read();
}
peekc = c;
if (decexp != 0) {
double denom = 10;
decexp--;
while (decexp > 0) {
denom *= 10;
decexp--;
}
/* Do one division of a likely-to-be-more-accurate number */
v = v / denom;
}
nval = neg ? -v : v;
return ttype = TT_NUMBER;
}
if ((ctype & CT_ALPHA) != 0) {
int i = 0;
do {
if (i >= buf.length) {
buf = Arrays.copyOf(buf, buf.length * 2);
}
buf[i++] = (char) c;
c = read();
ctype = c < 0 ? CT_WHITESPACE : c < 256 ? ct[c] : CT_ALPHA;
} while ((ctype & (CT_ALPHA | CT_DIGIT)) != 0);
peekc = c;
sval = String.copyValueOf(buf, 0, i);
if (forceLower)
sval = sval.toLowerCase();
return ttype = TT_WORD;
}
if ((ctype & CT_QUOTE) != 0) {
ttype = c;
int i = 0;
/* Invariants (because \Octal needs a lookahead):
* (i) c contains char value
* (ii) d contains the lookahead
*/
int d = read();
while (d >= 0 && d != ttype && d != '\n' && d != '\r') {
if (d == '\\') {
c = read();
int first = c; /* To allow \377, but not \477 */
if (c >= '0' && c <= '7') {
c = c - '0';
int c2 = read();
if ('0' <= c2 && c2 <= '7') {
c = (c << 3) + (c2 - '0');
c2 = read();
if ('0' <= c2 && c2 <= '7' && first <= '3') {
c = (c << 3) + (c2 - '0');
d = read();
} else
d = c2;
} else
d = c2;
} else {
switch (c) {
case 'a':
c = 0x7;
break;
case 'b':
c = '\b';
break;
case 'f':
c = 0xC;
break;
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'v':
c = 0xB;
break;
}
d = read();
}
} else {
c = d;
d = read();
}
if (i >= buf.length) {
buf = Arrays.copyOf(buf, buf.length * 2);
}
buf[i++] = (char)c;
}
/* If we broke out of the loop because we found a matching quote
* character then arrange to read a new character next time
* around; otherwise, save the character.
*/
peekc = (d == ttype) ? NEED_CHAR : d;
sval = String.copyValueOf(buf, 0, i);
return ttype;
}
if (c == '/' && (slashSlashCommentsP || slashStarCommentsP)) {
c = read();
if (c == '*' && slashStarCommentsP) {
int prevc = 0;
while ((c = read()) != '/' || prevc != '*') {
if (c == '\r') {
LINENO++;
c = read();
if (c == '\n') {
c = read();
}
} else {
if (c == '\n') {
LINENO++;
c = read();
}
}
if (c < 0)
return ttype = TT_EOF;
prevc = c;
}
return nextToken();
} else if (c == '/' && slashSlashCommentsP) {
while ((c = read()) != '\n' && c != '\r' && c >= 0);
peekc = c;
return nextToken();
} else {
/* Now see if it is still a single line comment */
if ((ct['/'] & CT_COMMENT) != 0) {
while ((c = read()) != '\n' && c != '\r' && c >= 0);
peekc = c;
return nextToken();
} else {
peekc = c;
return ttype = '/';
}
}
}
if ((ctype & CT_COMMENT) != 0) {
while ((c = read()) != '\n' && c != '\r' && c >= 0);
peekc = c;
return nextToken();
}
return ttype = c;
}
/**
* Causes the next call to the {@code nextToken} method of this
* tokenizer to return the current value in the {@code ttype}
* field, and not to modify the value in the {@code nval} or
* {@code sval} field.
*
* @see java.io.StreamTokenizer#nextToken()
* @see java.io.StreamTokenizer#nval
* @see java.io.StreamTokenizer#sval
* @see java.io.StreamTokenizer#ttype
*/
public void pushBack() {
if (ttype != TT_NOTHING) /* No-op if nextToken() not called */
pushedBack = true;
}
/**
* Return the current line number.
*
* @return the current line number of this stream tokenizer.
*/
public int lineno() {
return LINENO;
}
/**
* Returns the string representation of the current stream token and
* the line number it occurs on.
*
* <p>The precise string returned is unspecified, although the following
* example can be considered typical:
*
* <blockquote><pre>Token['a'], line 10</pre></blockquote>
*
* @return a string representation of the token
* @see java.io.StreamTokenizer#nval
* @see java.io.StreamTokenizer#sval
* @see java.io.StreamTokenizer#ttype
*/
public String toString() {
String ret;
switch (ttype) {
case TT_EOF:
ret = "EOF";
break;
case TT_EOL:
ret = "EOL";
break;
case TT_WORD:
ret = sval;
break;
case TT_NUMBER:
ret = "n=" + nval;
break;
case TT_NOTHING:
ret = "NOTHING";
break;
default: {
/*
* ttype is the first character of either a quoted string or
* is an ordinary character. ttype can definitely not be less
* than 0, since those are reserved values used in the previous
* case statements
*/
if (ttype < 256 &&
((ctype[ttype] & CT_QUOTE) != 0)) {
ret = sval;
break;
}
char s[] = new char[3];
s[0] = s[2] = '\'';
s[1] = (char) ttype;
ret = new String(s);
break;
}
}
return "Token[" + ret + "], line " + LINENO;
}
}

View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* This class allows an application to create an input stream in
* which the bytes read are supplied by the contents of a string.
* Applications can also read bytes from a byte array by using a
* <code>ByteArrayInputStream</code>.
* <p>
* Only the low eight bits of each character in the string are used by
* this class.
*
* @author Arthur van Hoff
* @see java.io.ByteArrayInputStream
* @see java.io.StringReader
* @since 1.0
* @deprecated This class does not properly convert characters into bytes. As
* of JDK&nbsp;1.1, the preferred way to create a stream from a
* string is via the <code>StringReader</code> class.
*/
@Deprecated
public
class StringBufferInputStream extends InputStream {
/**
* The string from which bytes are read.
*/
protected String buffer;
/**
* The index of the next character to read from the input stream buffer.
*
* @see java.io.StringBufferInputStream#buffer
*/
protected int pos;
/**
* The number of valid characters in the input stream buffer.
*
* @see java.io.StringBufferInputStream#buffer
*/
protected int count;
/**
* Creates a string input stream to read data from the specified string.
*
* @param s the underlying input buffer.
*/
public StringBufferInputStream(String s) {
this.buffer = s;
count = s.length();
}
/**
* Reads the next byte of data from this input stream. The value
* byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>. If no byte is available
* because the end of the stream has been reached, the value
* <code>-1</code> is returned.
* <p>
* The <code>read</code> method of
* <code>StringBufferInputStream</code> cannot block. It returns the
* low eight bits of the next character in this input stream's buffer.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
*/
public synchronized int read() {
return (pos < count) ? (buffer.charAt(pos++) & 0xFF) : -1;
}
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes.
* <p>
* The <code>read</code> method of
* <code>StringBufferInputStream</code> cannot block. It copies the
* low eight bits from the characters in this input stream's buffer into
* the byte array argument.
*
* @param b the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
*/
@SuppressWarnings("deprecation")
public synchronized int read(byte b[], int off, int len) {
if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
}
if (pos >= count) {
return -1;
}
int avail = count - pos;
if (len > avail) {
len = avail;
}
if (len <= 0) {
return 0;
}
buffer.getBytes(pos, pos + len, b, off);
pos += len;
return len;
}
/**
* Skips <code>n</code> bytes of input from this input stream. Fewer
* bytes might be skipped if the end of the input stream is reached.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
*/
public synchronized long skip(long n) {
if (n < 0) {
return 0;
}
if (n > count - pos) {
n = count - pos;
}
pos += n;
return n;
}
/**
* Returns the number of bytes that can be read from the input
* stream without blocking.
*
* @return the value of <code>count&nbsp;-&nbsp;pos</code>, which is the
* number of bytes remaining to be read from the input buffer.
*/
public synchronized int available() {
return count - pos;
}
/**
* Resets the input stream to begin reading from the first character
* of this input stream's underlying buffer.
*/
public synchronized void reset() {
pos = 0;
}
}

View file

@ -0,0 +1,205 @@
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A character stream whose source is a string.
*
* @author Mark Reinhold
* @since 1.1
*/
public class StringReader extends Reader {
private String str;
private int length;
private int next = 0;
private int mark = 0;
/**
* Creates a new string reader.
*
* @param s String providing the character stream.
*/
public StringReader(String s) {
this.str = s;
this.length = s.length();
}
/** Check to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
if (str == null)
throw new IOException("Stream closed");
}
/**
* Reads a single character.
*
* @return The character read, or -1 if the end of the stream has been
* reached
*
* @exception IOException If an I/O error occurs
*/
public int read() throws IOException {
synchronized (lock) {
ensureOpen();
if (next >= length)
return -1;
return str.charAt(next++);
}
}
/**
* Reads characters into a portion of an array.
*
* @param cbuf Destination buffer
* @param off Offset at which to start writing characters
* @param len Maximum number of characters to read
*
* @return The number of characters read, or -1 if the end of the
* stream has been reached
*
* @exception IOException If an I/O error occurs
* @exception IndexOutOfBoundsException {@inheritDoc}
*/
public int read(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
if (next >= length)
return -1;
int n = Math.min(length - next, len);
str.getChars(next, next + n, cbuf, off);
next += n;
return n;
}
}
/**
* Skips the specified number of characters in the stream. Returns
* the number of characters that were skipped.
*
* <p>The <code>ns</code> parameter may be negative, even though the
* <code>skip</code> method of the {@link Reader} superclass throws
* an exception in this case. Negative values of <code>ns</code> cause the
* stream to skip backwards. Negative return values indicate a skip
* backwards. It is not possible to skip backwards past the beginning of
* the string.
*
* <p>If the entire string has been read or skipped, then this method has
* no effect and always returns 0.
*
* @exception IOException If an I/O error occurs
*/
public long skip(long ns) throws IOException {
synchronized (lock) {
ensureOpen();
if (next >= length)
return 0;
// Bound skip by beginning and end of the source
long n = Math.min(length - next, ns);
n = Math.max(-next, n);
next += n;
return n;
}
}
/**
* Tells whether this stream is ready to be read.
*
* @return True if the next read() is guaranteed not to block for input
*
* @exception IOException If the stream is closed
*/
public boolean ready() throws IOException {
synchronized (lock) {
ensureOpen();
return true;
}
}
/**
* Tells whether this stream supports the mark() operation, which it does.
*/
public boolean markSupported() {
return true;
}
/**
* Marks the present position in the stream. Subsequent calls to reset()
* will reposition the stream to this point.
*
* @param readAheadLimit Limit on the number of characters that may be
* read while still preserving the mark. Because
* the stream's input comes from a string, there
* is no actual limit, so this argument must not
* be negative, but is otherwise ignored.
*
* @exception IllegalArgumentException If {@code readAheadLimit < 0}
* @exception IOException If an I/O error occurs
*/
public void mark(int readAheadLimit) throws IOException {
if (readAheadLimit < 0){
throw new IllegalArgumentException("Read-ahead limit < 0");
}
synchronized (lock) {
ensureOpen();
mark = next;
}
}
/**
* Resets the stream to the most recent mark, or to the beginning of the
* string if it has never been marked.
*
* @exception IOException If an I/O error occurs
*/
public void reset() throws IOException {
synchronized (lock) {
ensureOpen();
next = mark;
}
}
/**
* Closes the stream and releases any system resources associated with
* it. Once the stream has been closed, further read(),
* ready(), mark(), or reset() invocations will throw an IOException.
* Closing a previously closed stream has no effect. This method will block
* while there is another thread blocking on the reader.
*/
public void close() {
synchronized (lock) {
str = null;
}
}
}

View file

@ -0,0 +1,244 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* A character stream that collects its output in a string buffer, which can
* then be used to construct a string.
* <p>
* Closing a {@code StringWriter} has no effect. The methods in this class
* can be called after the stream has been closed without generating an
* {@code IOException}.
*
* @author Mark Reinhold
* @since 1.1
*/
public class StringWriter extends Writer {
private StringBuffer buf;
/**
* Create a new string writer using the default initial string-buffer
* size.
*/
public StringWriter() {
buf = new StringBuffer();
lock = buf;
}
/**
* Create a new string writer using the specified initial string-buffer
* size.
*
* @param initialSize
* The number of {@code char} values that will fit into this buffer
* before it is automatically expanded
*
* @throws IllegalArgumentException
* If {@code initialSize} is negative
*/
public StringWriter(int initialSize) {
if (initialSize < 0) {
throw new IllegalArgumentException("Negative buffer size");
}
buf = new StringBuffer(initialSize);
lock = buf;
}
/**
* Write a single character.
*/
public void write(int c) {
buf.append((char) c);
}
/**
* Write a portion of an array of characters.
*
* @param cbuf Array of characters
* @param off Offset from which to start writing characters
* @param len Number of characters to write
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given array
*/
public void write(char cbuf[], int off, int len) {
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
buf.append(cbuf, off, len);
}
/**
* Write a string.
*/
public void write(String str) {
buf.append(str);
}
/**
* Write a portion of a string.
*
* @param str String to be written
* @param off Offset from which to start writing characters
* @param len Number of characters to write
*
* @throws IndexOutOfBoundsException
* If {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given string
*/
public void write(String str, int off, int len) {
buf.append(str, off, off + len);
}
/**
* Appends the specified character sequence to this writer.
*
* <p> An invocation of this method of the form {@code out.append(csq)}
* behaves in exactly the same way as the invocation
*
* <pre>
* out.write(csq.toString()) </pre>
*
* <p> Depending on the specification of {@code toString} for the
* character sequence {@code csq}, the entire sequence may not be
* appended. For instance, invoking the {@code toString} method of a
* character buffer will return a subsequence whose content depends upon
* the buffer's position and limit.
*
* @param csq
* The character sequence to append. If {@code csq} is
* {@code null}, then the four characters {@code "null"} are
* appended to this writer.
*
* @return This writer
*
* @since 1.5
*/
public StringWriter append(CharSequence csq) {
write(String.valueOf(csq));
return this;
}
/**
* Appends a subsequence of the specified character sequence to this writer.
*
* <p> An invocation of this method of the form
* {@code out.append(csq, start, end)} when {@code csq}
* is not {@code null}, behaves in
* exactly the same way as the invocation
*
* <pre>{@code
* out.write(csq.subSequence(start, end).toString())
* }</pre>
*
* @param csq
* The character sequence from which a subsequence will be
* appended. If {@code csq} is {@code null}, then characters
* will be appended as if {@code csq} contained the four
* characters {@code "null"}.
*
* @param start
* The index of the first character in the subsequence
*
* @param end
* The index of the character following the last character in the
* subsequence
*
* @return This writer
*
* @throws IndexOutOfBoundsException
* If {@code start} or {@code end} are negative, {@code start}
* is greater than {@code end}, or {@code end} is greater than
* {@code csq.length()}
*
* @since 1.5
*/
public StringWriter append(CharSequence csq, int start, int end) {
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
/**
* Appends the specified character to this writer.
*
* <p> An invocation of this method of the form {@code out.append(c)}
* behaves in exactly the same way as the invocation
*
* <pre>
* out.write(c) </pre>
*
* @param c
* The 16-bit character to append
*
* @return This writer
*
* @since 1.5
*/
public StringWriter append(char c) {
write(c);
return this;
}
/**
* Return the buffer's current value as a string.
*/
public String toString() {
return buf.toString();
}
/**
* Return the string buffer itself.
*
* @return StringBuffer holding the current buffer value.
*/
public StringBuffer getBuffer() {
return buf;
}
/**
* Flush the stream.
*/
public void flush() {
}
/**
* Closing a {@code StringWriter} has no effect. The methods in this
* class can be called after the stream has been closed without generating
* an {@code IOException}.
*/
public void close() throws IOException {
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Signals that a sync operation has failed.
*
* @author Ken Arnold
* @see java.io.FileDescriptor#sync
* @see java.io.IOException
* @since 1.1
*/
public class SyncFailedException extends IOException {
private static final long serialVersionUID = -2353342684412443330L;
/**
* Constructs an SyncFailedException with a detail message.
* A detail message is a String that describes this particular exception.
*
* @param desc a String describing the exception.
*/
public SyncFailedException(String desc) {
super(desc);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Signals that a malformed string in
* <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
* format has been read in a data
* input stream or by any class that implements the data input
* interface.
* See the
* <a href="DataInput.html#modified-utf-8"><code>DataInput</code></a>
* class description for the format in
* which modified UTF-8 strings are read and written.
*
* @author Frank Yellin
* @see java.io.DataInput
* @see java.io.DataInputStream#readUTF(java.io.DataInput)
* @see java.io.IOException
* @since 1.0
*/
public
class UTFDataFormatException extends IOException {
private static final long serialVersionUID = 420743449228280612L;
/**
* Constructs a <code>UTFDataFormatException</code> with
* <code>null</code> as its error detail message.
*/
public UTFDataFormatException() {
super();
}
/**
* Constructs a <code>UTFDataFormatException</code> with the
* specified detail message. The string <code>s</code> can be
* retrieved later by the
* <code>{@link java.lang.Throwable#getMessage}</code>
* method of class <code>java.lang.Throwable</code>.
*
* @param s the detail message.
*/
public UTFDataFormatException(String s) {
super(s);
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.Objects;
/**
* Wraps an {@link IOException} with an unchecked exception.
*
* @since 1.8
*/
public class UncheckedIOException extends RuntimeException {
private static final long serialVersionUID = -8134305061645241065L;
/**
* Constructs an instance of this class.
*
* @param message
* the detail message, can be null
* @param cause
* the {@code IOException}
*
* @throws NullPointerException
* if the cause is {@code null}
*/
public UncheckedIOException(String message, IOException cause) {
super(message, Objects.requireNonNull(cause));
}
/**
* Constructs an instance of this class.
*
* @param cause
* the {@code IOException}
*
* @throws NullPointerException
* if the cause is {@code null}
*/
public UncheckedIOException(IOException cause) {
super(Objects.requireNonNull(cause));
}
/**
* Returns the cause of this exception.
*
* @return the {@code IOException} which is the cause of this exception.
*/
@Override
public IOException getCause() {
return (IOException) super.getCause();
}
/**
* Called to read the object from a stream.
*
* @throws InvalidObjectException
* if the object is invalid or has a cause that is not
* an {@code IOException}
*/
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
s.defaultReadObject();
Throwable cause = super.getCause();
if (!(cause instanceof IOException))
throw new InvalidObjectException("Cause must be an IOException");
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* The Character Encoding is not supported.
*
* @author Asmus Freytag
* @since 1.1
*/
public class UnsupportedEncodingException
extends IOException
{
private static final long serialVersionUID = -4274276298326136670L;
/**
* Constructs an UnsupportedEncodingException without a detail message.
*/
public UnsupportedEncodingException() {
super();
}
/**
* Constructs an UnsupportedEncodingException with a detail message.
* @param s Describes the reason for the exception.
*/
public UnsupportedEncodingException(String s) {
super(s);
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Signals that one of the ObjectStreamExceptions was thrown during a
* write operation. Thrown during a read operation when one of the
* ObjectStreamExceptions was thrown during a write operation. The
* exception that terminated the write can be found in the detail
* field. The stream is reset to it's initial state and all references
* to objects already deserialized are discarded.
*
* <p>As of release 1.4, this exception has been retrofitted to conform to
* the general purpose exception-chaining mechanism. The "exception causing
* the abort" that is provided at construction time and
* accessed via the public {@link #detail} field is now known as the
* <i>cause</i>, and may be accessed via the {@link Throwable#getCause()}
* method, as well as the aforementioned "legacy field."
*
* @author unascribed
* @since 1.1
*/
public class WriteAbortedException extends ObjectStreamException {
private static final long serialVersionUID = -3326426625597282442L;
/**
* Exception that was caught while writing the ObjectStream.
*
* <p>This field predates the general-purpose exception chaining facility.
* The {@link Throwable#getCause()} method is now the preferred means of
* obtaining this information.
*
* @serial
*/
public Exception detail;
/**
* Constructs a WriteAbortedException with a string describing
* the exception and the exception causing the abort.
* @param s String describing the exception.
* @param ex Exception causing the abort.
*/
public WriteAbortedException(String s, Exception ex) {
super(s);
initCause(null); // Disallow subsequent initCause
detail = ex;
}
/**
* Produce the message and include the message from the nested
* exception, if there is one.
*/
public String getMessage() {
if (detail == null)
return super.getMessage();
else
return super.getMessage() + "; " + detail.toString();
}
/**
* Returns the exception that terminated the operation (the <i>cause</i>).
*
* @return the exception that terminated the operation (the <i>cause</i>),
* which may be null.
* @since 1.4
*/
public Throwable getCause() {
return detail;
}
}

View file

@ -0,0 +1,334 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
/**
* Abstract class for writing to character streams. The only methods that a
* subclass must implement are write(char[], int, int), flush(), and close().
* Most subclasses, however, will override some of the methods defined here in
* order to provide higher efficiency, additional functionality, or both.
*
* @see BufferedWriter
* @see CharArrayWriter
* @see FilterWriter
* @see OutputStreamWriter
* @see FileWriter
* @see PipedWriter
* @see PrintWriter
* @see StringWriter
* @see Reader
*
* @author Mark Reinhold
* @since 1.1
*/
public abstract class Writer implements Appendable, Closeable, Flushable {
/**
* Temporary buffer used to hold writes of strings and single characters
*/
private char[] writeBuffer;
/**
* Size of writeBuffer, must be >= 1
*/
private static final int WRITE_BUFFER_SIZE = 1024;
/**
* The object used to synchronize operations on this stream. For
* efficiency, a character-stream object may use an object other than
* itself to protect critical sections. A subclass should therefore use
* the object in this field rather than {@code this} or a synchronized
* method.
*/
protected Object lock;
/**
* Creates a new character-stream writer whose critical sections will
* synchronize on the writer itself.
*/
protected Writer() {
this.lock = this;
}
/**
* Creates a new character-stream writer whose critical sections will
* synchronize on the given object.
*
* @param lock
* Object to synchronize on
*/
protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
/**
* Writes a single character. The character to be written is contained in
* the 16 low-order bits of the given integer value; the 16 high-order bits
* are ignored.
*
* <p> Subclasses that intend to support efficient single-character output
* should override this method.
*
* @param c
* int specifying a character to be written
*
* @throws IOException
* If an I/O error occurs
*/
public void write(int c) throws IOException {
synchronized (lock) {
if (writeBuffer == null){
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
writeBuffer[0] = (char) c;
write(writeBuffer, 0, 1);
}
}
/**
* Writes an array of characters.
*
* @param cbuf
* Array of characters to be written
*
* @throws IOException
* If an I/O error occurs
*/
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
/**
* Writes a portion of an array of characters.
*
* @param cbuf
* Array of characters
*
* @param off
* Offset from which to start writing characters
*
* @param len
* Number of characters to write
*
* @throws IndexOutOfBoundsException
* Implementations should throw this exception
* if {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given array
*
* @throws IOException
* If an I/O error occurs
*/
public abstract void write(char cbuf[], int off, int len) throws IOException;
/**
* Writes a string.
*
* @param str
* String to be written
*
* @throws IOException
* If an I/O error occurs
*/
public void write(String str) throws IOException {
write(str, 0, str.length());
}
/**
* Writes a portion of a string.
*
* @implSpec
* The implementation in this class throws an
* {@code IndexOutOfBoundsException} for the indicated conditions;
* overriding methods may choose to do otherwise.
*
* @param str
* A String
*
* @param off
* Offset from which to start writing characters
*
* @param len
* Number of characters to write
*
* @throws IndexOutOfBoundsException
* Implementations should throw this exception
* if {@code off} is negative, or {@code len} is negative,
* or {@code off + len} is negative or greater than the length
* of the given string
*
* @throws IOException
* If an I/O error occurs
*/
public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
if (len <= WRITE_BUFFER_SIZE) {
if (writeBuffer == null) {
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
cbuf = writeBuffer;
} else { // Don't permanently allocate very large buffers.
cbuf = new char[len];
}
str.getChars(off, (off + len), cbuf, 0);
write(cbuf, 0, len);
}
}
/**
* Appends the specified character sequence to this writer.
*
* <p> An invocation of this method of the form {@code out.append(csq)}
* behaves in exactly the same way as the invocation
*
* <pre>
* out.write(csq.toString()) </pre>
*
* <p> Depending on the specification of {@code toString} for the
* character sequence {@code csq}, the entire sequence may not be
* appended. For instance, invoking the {@code toString} method of a
* character buffer will return a subsequence whose content depends upon
* the buffer's position and limit.
*
* @param csq
* The character sequence to append. If {@code csq} is
* {@code null}, then the four characters {@code "null"} are
* appended to this writer.
*
* @return This writer
*
* @throws IOException
* If an I/O error occurs
*
* @since 1.5
*/
public Writer append(CharSequence csq) throws IOException {
write(String.valueOf(csq));
return this;
}
/**
* Appends a subsequence of the specified character sequence to this writer.
* {@code Appendable}.
*
* <p> An invocation of this method of the form
* {@code out.append(csq, start, end)} when {@code csq}
* is not {@code null} behaves in exactly the
* same way as the invocation
*
* <pre>{@code
* out.write(csq.subSequence(start, end).toString())
* }</pre>
*
* @param csq
* The character sequence from which a subsequence will be
* appended. If {@code csq} is {@code null}, then characters
* will be appended as if {@code csq} contained the four
* characters {@code "null"}.
*
* @param start
* The index of the first character in the subsequence
*
* @param end
* The index of the character following the last character in the
* subsequence
*
* @return This writer
*
* @throws IndexOutOfBoundsException
* If {@code start} or {@code end} are negative, {@code start}
* is greater than {@code end}, or {@code end} is greater than
* {@code csq.length()}
*
* @throws IOException
* If an I/O error occurs
*
* @since 1.5
*/
public Writer append(CharSequence csq, int start, int end) throws IOException {
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
/**
* Appends the specified character to this writer.
*
* <p> An invocation of this method of the form {@code out.append(c)}
* behaves in exactly the same way as the invocation
*
* <pre>
* out.write(c) </pre>
*
* @param c
* The 16-bit character to append
*
* @return This writer
*
* @throws IOException
* If an I/O error occurs
*
* @since 1.5
*/
public Writer append(char c) throws IOException {
write(c);
return this;
}
/**
* Flushes the stream. If the stream has saved any characters from the
* various write() methods in a buffer, write them immediately to their
* intended destination. Then, if that destination is another character or
* byte stream, flush it. Thus one flush() invocation will flush all the
* buffers in a chain of Writers and OutputStreams.
*
* <p> If the intended destination of this stream is an abstraction provided
* by the underlying operating system, for example a file, then flushing the
* stream guarantees only that bytes previously written to the stream are
* passed to the operating system for writing; it does not guarantee that
* they are actually written to a physical device such as a disk drive.
*
* @throws IOException
* If an I/O error occurs
*/
public abstract void flush() throws IOException;
/**
* Closes the stream, flushing it first. Once the stream has been closed,
* further write() or flush() invocations will cause an IOException to be
* thrown. Closing a previously closed stream has no effect.
*
* @throws IOException
* If an I/O error occurs
*/
public abstract void close() throws IOException;
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Provides for system input and output through data streams,
* serialization and the file system.
*
* Unless otherwise noted, passing a null argument to a constructor or
* method in any class or interface in this package will cause a
* {@code NullPointerException} to be thrown.
*
* <h2>Package Specification</h2>
* <ul>
* <li><a href="{@docRoot}/../specs/serialization/index.html">
* Java Object Serialization Specification </a>
* </ul>
*
* <h2>Related Documentation</h2>
*
* For overviews, tutorials, examples, guides, and tool documentation,
* please see:
* <ul>
* <li>{@extLink serialver_tool_reference The serialver tool}</li>
* <li>{@extLink serialization_guide Serialization Documentation}</li>
* </ul>
*
* @since 1.0
*/
package java.io;