summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron M. Renn <arenn@urbanophile.com>1998-06-19 23:13:11 +0000
committerAaron M. Renn <arenn@urbanophile.com>1998-06-19 23:13:11 +0000
commit349e4b13bfd0f368a3b58d8487ec698c347beae2 (patch)
tree0f2bd37bd779d9fcc17f396dc87b4df1c5ea44c5
parente0a43139ffff705620e50a9d5dbe80438a3081b0 (diff)
downloadclasspath-349e4b13bfd0f368a3b58d8487ec698c347beae2.tar.gz
Initial Checkin
-rw-r--r--java/io/BufferedInputStream.java46
-rw-r--r--java/io/ByteArrayInputStream.java2
-rw-r--r--java/io/CharConversionException.java60
-rw-r--r--java/io/DataInput.java431
-rw-r--r--java/io/DataInputStream.java702
-rw-r--r--java/io/DataOutput.java206
-rw-r--r--java/io/EOFException.java64
-rw-r--r--java/io/Externalizable.java90
-rw-r--r--java/io/FileNotFoundException.java60
-rw-r--r--java/io/FilenameFilter.java50
-rw-r--r--java/io/FilterInputStream.java209
-rw-r--r--java/io/IOException.java62
-rw-r--r--java/io/InputStream.java315
-rw-r--r--java/io/InterruptedIOException.java87
-rw-r--r--java/io/InvalidClassException.java101
-rw-r--r--java/io/InvalidObjectException.java49
-rw-r--r--java/io/LineNumberInputStream.java309
-rw-r--r--java/io/Makefile.am23
-rw-r--r--java/io/NotActiveException.java60
-rw-r--r--java/io/NotSerializableException.java61
-rw-r--r--java/io/ObjectInput.java139
-rw-r--r--java/io/ObjectInputValidation.java42
-rw-r--r--java/io/ObjectOutput.java67
-rw-r--r--java/io/ObjectStreamException.java61
-rw-r--r--java/io/OptionalDataException.java71
-rw-r--r--java/io/PushbackInputStream.java17
-rw-r--r--java/io/Replaceable.java46
-rw-r--r--java/io/Resolvable.java44
-rw-r--r--java/io/SequenceInputStream.java302
-rw-r--r--java/io/Serializable.java34
-rw-r--r--java/io/StreamCorruptedException.java60
-rw-r--r--java/io/StringBufferInputStream.java217
-rw-r--r--java/io/SyncFailedException.java58
-rw-r--r--java/io/UTFDataFormatException.java60
-rw-r--r--java/io/UnsupportedEncodingException.java60
-rw-r--r--java/io/WriteAbortedException.java77
36 files changed, 4302 insertions, 40 deletions
diff --git a/java/io/BufferedInputStream.java b/java/io/BufferedInputStream.java
index fa933322f..f0ce9c01f 100644
--- a/java/io/BufferedInputStream.java
+++ b/java/io/BufferedInputStream.java
@@ -174,7 +174,7 @@ BufferedInputStream(InputStream in, int bufsize)
*
* @param readlimit The number of bytes that can be read before the mark becomes invalid
*/
-public synchronized void
+public void
mark(int readlimit)
{
// If we already have a special buffer that we are reading text from,
@@ -250,7 +250,7 @@ markSupported()
*
* @exception IOException If an error occurs;
*/
-public synchronized void
+public void
reset() throws IOException
{
if (markpos == -1)
@@ -325,12 +325,9 @@ available() throws IOException
*
* @exception IOException If an error occurs
*/
-public synchronized long
+public long
skip(long num_bytes) throws IOException
{
- if (num_bytes <= 0)
- return(0);
-
if ((count - pos) >= num_bytes)
{
pos += num_bytes;
@@ -359,20 +356,19 @@ skip(long num_bytes) throws IOException
*
* @exception IOException If an error occurs
*/
-public synchronized int
+public int
read() throws IOException
{
if ((pos == count) || !primed)
{
refillBuffer(1);
-
if (pos == count)
return(-1);
}
++pos;
- return((buf[pos - 1] & 0xFF));
+ return(buf[pos - 1]);
}
/*************************************************************************/
@@ -404,7 +400,7 @@ read() throws IOException
*
* @exception IOException If an error occurs.
*/
-public synchronized int
+public int
read(byte[] buf, int offset, int len) throws IOException
{
if (len == 0)
@@ -413,7 +409,7 @@ read(byte[] buf, int offset, int len) throws IOException
// Read the first byte here in order to allow IOException's to
// propagate up
int byte_read = read();
- if (byte_read == -1)
+ if (byte_read == -1)
return(-1);
buf[offset] = (byte)byte_read;
@@ -424,41 +420,33 @@ read(byte[] buf, int offset, int len) throws IOException
// Read the rest of the bytes
try
{
- for(;total_read != len;)
+ for(;;)
{
- if (pos == count)
- refillBuffer(len - total_read);
-
- if (pos == count)
- if (total_read == 0)
- return(-1);
- else
- return(total_read);
-
if ((len - total_read) <= (count - pos))
{
- System.arraycopy(this.buf, pos, buf, offset + total_read,
+ System.arraycopy(this.buf, pos, buf, total_read,
len - total_read);
pos += (len - total_read);
- total_read += (len - total_read);
+
+ return(len);
}
else
{
- System.arraycopy(this.buf, pos, buf, offset + total_read,
- count - pos);
+ System.arraycopy(this.buf, pos, buf, total_read, count - pos);
- total_read += (count - pos);
- pos += (count - pos);
+ total_read += count - pos;
}
+
+ refillBuffer(len - total_read);
+ if (pos == count)
+ return(total_read);
}
}
catch (IOException e)
{
return(total_read);
}
-
- return(total_read);
}
/*************************************************************************/
diff --git a/java/io/ByteArrayInputStream.java b/java/io/ByteArrayInputStream.java
index 9c84e03ba..a3bd55990 100644
--- a/java/io/ByteArrayInputStream.java
+++ b/java/io/ByteArrayInputStream.java
@@ -223,7 +223,7 @@ read()
++pos;
- return((buf[pos - 1] & 0xFF));
+ return(buf[pos - 1]);
}
/*************************************************************************/
diff --git a/java/io/CharConversionException.java b/java/io/CharConversionException.java
new file mode 100644
index 000000000..a6c3a0f00
--- /dev/null
+++ b/java/io/CharConversionException.java
@@ -0,0 +1,60 @@
+/*************************************************************************
+/* CharConversionException.java -- Character conversion exceptions
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown to indicate that a problem occured with
+ * an attempted character conversion.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class CharConversionException extends IOException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new CharConversionException without a descriptive error message
+ */
+public
+CharConversionException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new CharConversionException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+CharConversionException(String message)
+{
+ super(message);
+}
+
+} // class CharConversionException
+
diff --git a/java/io/DataInput.java b/java/io/DataInput.java
new file mode 100644
index 000000000..91548a203
--- /dev/null
+++ b/java/io/DataInput.java
@@ -0,0 +1,431 @@
+/*************************************************************************
+/* DataInput.java -- Interface for reading data from a stream
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface is implemented by classes that can data from streams
+ * into Java primitive types.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface DataInput
+{
+
+/**
+ * This method reads a Java boolean value from an input stream. It does
+ * so by reading a single byte of data. If that byte is zero, then the
+ * value returned is @code{false}. If the byte is non-zero, then
+ * the value returned is @code{true}.
+ *
+ * This method can read a @code{boolean} written by an object implementing the
+ * @code{writeBoolean()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{boolean} value read
+ *
+ * @exception EOFException If end of file is reached before reading the boolean
+ * @exception IOException If any other error occurs
+ */
+public abstract boolean
+readBoolean() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java byte value from an input stream. The value
+ * is in the range of -128 to 127.
+ *
+ * This method can read a @code{byte} written by an object implementing the
+ * @code{writeByte()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{byte} value read
+ *
+ * @exception EOFException If end of file is reached before reading the byte
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public abstract byte
+readByte() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads 8 unsigned bits into a Java @code{int} value from the
+ * stream. The value returned is in the range of 0 to 255.
+ *
+ * This method can read an unsigned byte written by an object implementing the
+ * @code{writeUnsignedByte()} method in the @code{DataOutput} interface.
+ *
+ * @return The unsigned bytes value read as a Java @code{int}.
+ *
+ * @exception EOFException If end of file is reached before reading the value
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public abstract int
+readUnsignedByte() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java @code{char} value from an input stream.
+ * It operates by reading two bytes from the stream and converting them to
+ * a single 16-bit Java @code{char}. The two bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} and code{byte2} represent the first
+ * and second byte read from the stream respectively, they will be
+ * transformed to a @code{char} in the following manner:
+ *
+ * @code{(char)((byte1 << 8) + byte2)}
+ *
+ * This method can read a @code{char} written by an object implementing the
+ * @code{writeChar()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{char} value read
+ *
+ * @exception EOFException If end of file is reached before reading the char
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public abstract char
+readChar() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads a signed 16-bit value into a Java in from the stream.
+ * It operates by reading two bytes from the stream and converting them to
+ * a single 16-bit Java @code{short}. The two bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} and code{byte2} represent the first
+ * and second byte read from the stream respectively, they will be
+ * transformed to a @code{short} in the following manner:
+ *
+ * @code{(short)((byte1 << 8) + byte2)}
+ *
+ * The value returned is in the range of -32768 to 32767.
+ *
+ * This method can read a @code{short} written by an object implementing the
+ * @code{writeShort()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{short} value read
+ *
+ * @exception EOFException If end of file is reached before reading the value
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public abstract short
+readShort() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads 16 unsigned bits into a Java int value from the stream.
+ * It operates by reading two bytes from the stream and converting them to
+ * a single Java @code{int}. The two bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} and code{byte2} represent the first
+ * and second byte read from the stream respectively, they will be
+ * transformed to an @code{int} in the following manner:
+ *
+ * @code{(int)((byte1 << 8) + byte2)}
+ *
+ * The value returned is in the range of 0 to 65535.
+ *
+ * This method can read an unsigned short written by an object implementing
+ * the @code{writeUnsignedShort()} method in the @code{DataOutput} interface.
+ *
+ * @return The unsigned short value read as a Java @code{int}.
+ *
+ * @exception EOFException If end of file is reached before reading the value
+ * @exception IOException If any other error occurs
+ */
+public abstract int
+readUnsignedShort() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java @code{int} value from an input stream
+ * It operates by reading four bytes from the stream and converting them to
+ * a single Java @code{int}. The bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} through @code{byte4} represent the first
+ * four bytes read from the stream, they will be
+ * transformed to an @code{int} in the following manner:
+ *
+ * @code{(int)((byte1 << 24) + (byte2 << 16) + (byte3 << 8) + byte4))}
+ *
+ * The value returned is in the range of 0 to 65535.
+ *
+ * This method can read an @code{int} written by an object implementing the
+ * @code{writeInt()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{int} value read
+ *
+ * @exception EOFException If end of file is reached before reading the int
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public abstract int
+readInt() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java long value from an input stream
+ * It operates by reading eight bytes from the stream and converting them to
+ * a single Java @code{long}. The bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} through @code{byte8} represent the first
+ * eight bytes read from the stream, they will be
+ * transformed to an @code{long} in the following manner:
+ *
+ * @code{(long)((byte1 << 56) + (byte2 << 48) + (byte3 << 40) +
+ * (byte4 << 32) + (byte5 << 24) + (byte6 << 16) + (byte7 << 8) + byte9))}
+ *
+ * The value returned is in the range of 0 to 65535.
+ *
+ * This method can read an @code{long} written by an object implementing the
+ * @code{writeLong()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{long} value read
+ *
+ * @exception EOFException If end of file is reached before reading the long
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public abstract long
+readLong() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java float value from an input stream. It operates
+ * by first reading an @code{int} value from the stream by calling the
+ * @code{readInt()} method in this interface, then converts that @code{int}
+ * to a @code{float} using the @code{intBitsToFloat} method in
+ * the class @{java.lang.Float}.
+ *
+ * This method can read a @code{float} written by an object implementing the
+ * @code{writeFloat()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{float} value read
+ *
+ * @exception EOFException If end of file is reached before reading the float
+ * @exception IOException If any other error occurs
+ *
+ * @see java.lang.Float
+ * @see DataOutput
+ */
+public abstract float
+readFloat() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java double value from an input stream. It operates
+ * by first reading a @code{logn} value from the stream by calling the
+ * @code{readLong()} method in this interface, then converts that @code{long}
+ * to a @code{double} using the @code{longBitsToDouble} method in
+ * the class @{java.lang.Double}.
+ *
+ * This method can read a @code{double} written by an object implementing the
+ * @code{writeDouble()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{double} value read
+ *
+ * @exception EOFException If end of file is reached before reading the double
+ * @exception IOException If any other error occurs
+ *
+ * @see java.lang.Double
+ * @see DataOutput
+ */
+public abstract double
+readDouble() throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads the next line of text data from an input stream.
+ * It operates by reading bytes and converting those bytes to @{char}
+ * values by treating the byte read as the low eight bits of the @{char}
+ * and using @code{0} as the high eight bits. Because of this, it does
+ * not support the full 16-bit Unicode character set.
+ *
+ * The reading of bytes ends when either the end of file or a line terminator
+ * is encountered. The bytes read are then returned as a @code{String}.
+ * A line terminator is a byte sequence consisting of either
+ * @samp{\r}, @samp{\n} or @samp{\r\n}. These termination charaters are
+ * discarded and are not returned as part of the string.
+ *
+ * This method can read data that was written by an object implementing the
+ * @code{writeLine()} method in @code{DataOutput}.
+ *
+ * @return The line read as a @code{String}
+ *
+ * @exception IOException If an error occurs
+ *
+ * @see DataOutput
+ */
+public abstract String
+readLine() throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads a @code{String} from an input stream that is encoded in
+ * a modified UTF-8 format. This format has a leading two byte sequence
+ * that contains the remaining number of bytes to read. This two byte
+ * sequence is read using the @code{readUnsignedShort()} method of this
+ * interface.
+ *
+ * After the number of remaining bytes have been determined, these bytes
+ * are read an transformed into @{char} values. These @code{char} values
+ * are encoded in the stream using either a one, two, or three byte format.
+ * The particular format in use can be determined by examining the first
+ * byte read.
+ *
+ * If the first byte has a high order bit of @samp{0}, then
+ * that character consists on only one byte. This character value consists
+ * of seven bits that are at positions 0 through 6 of the byte. As an
+ * example, if @code{byte1} is the byte read from the stream, it would
+ * be converted to a @code{char} like so:
+ *
+ * @code{(char)byte1}
+ *
+ * If the first byte has @code{110} as its high order bits, then the
+ * character consists of two bytes. The bits that make up the character
+ * value are in positions 0 through 4 of the first byte and bit positions
+ * 0 through 5 of the second byte. (The second byte should have
+ * @samp{10} as its high order bits). These values are in most significant
+ * byte first (i.e., "big endian") order.
+ *
+ * As an example, if @code{byte1} and @code{byte2} are the first two bytes
+ * read respectively, and the high order bits of them match the patterns
+ * which indicate a two byte character encoding, then they would be
+ * converted to a Java @code{char} like so:
+ *
+ * @code{(char)(((byte1 & 0x1F) << 6) + (byte2 & 0x3F))}
+ *
+ * If the first byte has a @code{1110} as its high order bits, then the
+ * character consists of three bytes. The bits that make up the character
+ * value are in positions 0 through 3 of the first byte and bit positions
+ * 0 through 5 of the other two bytes. (The second and third bytes should
+ * have @code{10} as their high order bits). These values are in most
+ * significant byte first (i.e., "big endian") order.
+ *
+ * As an example, if @code{byte1}, @code{byte2}, and @code{byte3} are the
+ * three bytes read, and the high order bits of them match the patterns
+ * which indicate a three byte character encoding, then they would be
+ * converted to a Java @code{char} like so:
+ *
+ * @code{(char)(((byte1 & 0x0F) << 12) + ((byte2 & 0x3F) + (byte3 & 0x3F))}
+ *
+ * Note that all characters are encoded in the method that requires the
+ * fewest number of bytes with the exception of the character with the
+ * value of @samp{\u0000} which is encoded as two bytes. This is a
+ * modification of the UTF standard used to prevent C language style
+ * @samp{NUL} values from appearing in the byte stream.
+ *
+ * This method can read data that was written by an object implementing the
+ * @code{writeUTF()} method in @code{DataOutput}.
+ *
+ * @returns The @code{String} read
+ *
+ * @exception EOFException If end of file is reached before reading the String
+ * @exception UTFDataFormatException If the data is not in UTF-8 format
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public abstract String
+readUTF() throws EOFException, UTFDataFormatException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads raw bytes into the passed array until the array is
+ * full. Note that this method blocks until the data is available and
+ * throws an exception if there is not enough data left in the stream to
+ * fill the buffer
+ *
+ * @param buf The buffer into which to read the data
+ *
+ * @exception EOFException If end of file is reached before filling the buffer
+ * @exception IOException If any other error occurs
+ */
+public abstract void
+readFully(byte[] buf) throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads raw bytes into the passed array @code{buf} starting
+ * @code{offset} bytes into the buffer. The number of bytes read will be
+ * exactly @code{len}. Note that this method blocks until the data is
+ * available and * throws an exception if there is not enough data left in
+ * the stream to read @code{len} bytes.
+ *
+ * @param buf The buffer into which to read the data
+ * @param offset The offset into the buffer to start storing data
+ * @param len The number of bytes to read into the buffer
+ *
+ * @exception EOFException If end of file is reached before filling the buffer
+ * @exception IOException If any other error occurs
+ */
+public abstract void
+readFully(byte[] buf, int offset, int len) throws EOFException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method skips and discards the specified number of bytes in an
+ * input stream
+ *
+ * @param num_bytes The number of bytes to skip
+ *
+ * @return The number of bytes actually skipped, which will always be @code{num_bytes}
+ *
+ * @exception EOFException If end of file is reached before all bytes can be skipped
+ * @exception IOException If any other error occurs
+ */
+public abstract int
+skipBytes(int n) throws EOFException, IOException;
+
+} // interface DataInput
+
diff --git a/java/io/DataInputStream.java b/java/io/DataInputStream.java
new file mode 100644
index 000000000..83c54c162
--- /dev/null
+++ b/java/io/DataInputStream.java
@@ -0,0 +1,702 @@
+/*************************************************************************
+/* DataInputStream.java -- Class for reading Java data from a stream
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This subclass of @code{FilteredInputStream} implements the
+ * @code{DataInput} interface that provides method for reading primitive
+ * Java data types from a stream.
+ *
+ * @see DataInput
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class DataInputStream extends FilterInputStream implements DataInput
+{
+
+/*************************************************************************/
+
+/*
+ * Class Methods
+ */
+
+/**
+ * This method reads a String encoded in UTF-8 format from the
+ * specified <code>DataInput</code> source.
+ *
+ * @param in The <code>DataInput</code> source to read from
+ *
+ * @return The String read from the source
+ *
+ * @exception IOException If an error occurs
+ */
+public static final String
+readUTF(DataInput in) throws IOException
+{
+ return(in.readUTF());
+}
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * This method initializes a new @code{DataInputStream} to read from
+ * the specified subordinate stream.
+ *
+ * @param in The subordinate @code{InputStream} to read from
+ */
+public
+DataInputStream(InputStream in)
+{
+ super(in);
+
+ this.in = new PushbackInputStream(in);
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method reads a Java boolean value from an input stream. It does
+ * so by reading a single byte of data. If that byte is zero, then the
+ * value returned is @code{false}. If the byte is non-zero, then
+ * the value returned is @code{true}.
+ *
+ * This method can read a @code{boolean} written by an object implementing the
+ * @code{writeBoolean()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{boolean} value read
+ *
+ * @exception EOFException If end of file is reached before reading the boolean
+ * @exception IOException If any other error occurs
+ */
+public boolean
+readBoolean() throws EOFException, IOException
+{
+ int byte_read = in.read();
+
+ if (byte_read == -1)
+ throw new EOFException("Unexpected end of stream");
+
+ if (byte_read == 0)
+ return(false);
+ else
+ return(true);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java byte value from an input stream. The value
+ * is in the range of -128 to 127.
+ *
+ * This method can read a @code{byte} written by an object implementing the
+ * @code{writeByte()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{byte} value read
+ *
+ * @exception EOFException If end of file is reached before reading the byte
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public byte
+readByte() throws EOFException, IOException
+{
+ int byte_read = in.read();
+
+ if (byte_read == -1)
+ throw new EOFException("Unexpected end of stream");
+
+ return((byte)byte_read);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads 8 unsigned bits into a Java @code{int} value from the
+ * stream. The value returned is in the range of 0 to 255.
+ *
+ * This method can read an unsigned byte written by an object implementing the
+ * @code{writeUnsignedByte()} method in the @code{DataOutput} interface.
+ *
+ * @return The unsigned bytes value read as a Java @code{int}.
+ *
+ * @exception EOFException If end of file is reached before reading the value
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public int
+readUnsignedByte() throws EOFException, IOException
+{
+ int byte_read = in.read();
+
+ if (byte_read == -1)
+ throw new EOFException("Unexpected end of stream");
+
+ return(byte_read);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java @code{char} value from an input stream.
+ * It operates by reading two bytes from the stream and converting them to
+ * a single 16-bit Java @code{char}. The two bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} and code{byte2} represent the first
+ * and second byte read from the stream respectively, they will be
+ * transformed to a @code{char} in the following manner:
+ *
+ * @code{(char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)}
+ *
+ * This method can read a @code{char} written by an object implementing the
+ * @code{writeChar()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{char} value read
+ *
+ * @exception EOFException If end of file is reached before reading the char
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public char
+readChar() throws EOFException, IOException
+{
+ byte[] buf = new byte[2];
+
+ readFully(buf);
+
+ char retval = (char)(((buf[0] & 0xFF) << 8) | (buf[1] & 0xFF));
+
+ return(retval);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads a signed 16-bit value into a Java in from the stream.
+ * It operates by reading two bytes from the stream and converting them to
+ * a single 16-bit Java @code{short}. The two bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} and code{byte2} represent the first
+ * and second byte read from the stream respectively, they will be
+ * transformed to a @code{short} in the following manner:
+ *
+ * @code{(short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)}
+ *
+ * The value returned is in the range of -32768 to 32767.
+ *
+ * This method can read a @code{short} written by an object implementing the
+ * @code{writeShort()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{short} value read
+ *
+ * @exception EOFException If end of file is reached before reading the value
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public short
+readShort() throws EOFException, IOException
+{
+ byte[] buf = new byte[2];
+
+ readFully(buf);
+
+ short retval = (short)(((buf[0] & 0xFF) << 8) | (buf[1] & 0xFF));
+
+ return(retval);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads 16 unsigned bits into a Java int value from the stream.
+ * It operates by reading two bytes from the stream and converting them to
+ * a single Java @code{int}. The two bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} and code{byte2} represent the first
+ * and second byte read from the stream respectively, they will be
+ * transformed to an @code{int} in the following manner:
+ *
+ * @code{(int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))}
+ *
+ * The value returned is in the range of 0 to 65535.
+ *
+ * This method can read an unsigned short written by an object implementing
+ * the @code{writeUnsignedShort()} method in the @code{DataOutput} interface.
+ *
+ * @return The unsigned short value read as a Java @code{int}.
+ *
+ * @exception EOFException If end of file is reached before reading the value
+ * @exception IOException If any other error occurs
+ */
+public int
+readUnsignedShort() throws EOFException, IOException
+{
+ byte[] buf = new byte[2];
+
+ readFully(buf);
+
+ int retval = ((buf[0] & 0xFF) << 8) | (buf[1] & 0xFF);
+
+ return(retval);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java @code{int} value from an input stream
+ * It operates by reading four bytes from the stream and converting them to
+ * a single Java @code{int}. The bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} through @code{byte4} represent the first
+ * four bytes read from the stream, they will be
+ * transformed to an @code{int} in the following manner:
+ *
+ * @code{(int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) +
+ * ((byte3 & 0xFF) << 8) + (byte4 & 0xFF)))}
+ *
+ * The value returned is in the range of 0 to 65535.
+ *
+ * This method can read an @code{int} written by an object implementing the
+ * @code{writeInt()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{int} value read
+ *
+ * @exception EOFException If end of file is reached before reading the int
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public int
+readInt() throws EOFException, IOException
+{
+ byte[] buf = new byte[4];
+
+ readFully(buf);
+
+ int retval = ((buf[0] & 0xFF) << 24) | ((buf[1] & 0xFF) << 16) +
+ ((buf[2] & 0xFF) << 8) | (buf[3] & 0xFF);
+
+ return(retval);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java long value from an input stream
+ * It operates by reading eight bytes from the stream and converting them to
+ * a single Java @code{long}. The bytes are stored most
+ * significant byte first (i.e., "big endian") regardless of the native
+ * host byte ordering.
+ *
+ * As an example, if @code{byte1} through @code{byte8} represent the first
+ * eight bytes read from the stream, they will be
+ * transformed to an @code{long} in the following manner:
+ *
+ * @code{(long)((((long)byte1 & 0xFF) << 56) + (((long)byte2 & 0xFF) << 48) +
+ * (((long)byte3 & 0xFF) << 40) + (((long)byte4 & 0xFF) << 32) +
+ * (((long)byte5 & 0xFF) << 24) + (((long)byte6 & 0xFF) << 16) +
+ * (((long)byte7 & 0xFF) << 8) + ((long)byte9 & 0xFF)))}
+ *
+ * The value returned is in the range of 0 to 65535.
+ *
+ * This method can read an @code{long} written by an object implementing the
+ * @code{writeLong()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{long} value read
+ *
+ * @exception EOFException If end of file is reached before reading the long
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public long
+readLong() throws EOFException, IOException
+{
+ byte[] buf = new byte[8];
+
+ readFully(buf);
+
+ long retval = (((long)buf[0] & 0xFF) << 56) | (((long)buf[1] & 0xFF) << 48) |
+ (((long)buf[2] & 0xFF) << 40) | (((long)buf[3] & 0xFF) << 32) |
+ (((long)buf[4] & 0xFF) << 24) | (((long)buf[5] & 0xFF) << 16) |
+ (((long)buf[6] & 0xFF) << 8) | ((long)buf[7] & 0xFF);
+
+ return(retval);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java float value from an input stream. It operates
+ * by first reading an @code{int} value from the stream by calling the
+ * @code{readInt()} method in this interface, then converts that @code{int}
+ * to a @code{float} using the @code{intBitsToFloat} method in
+ * the class @{java.lang.Float}.
+ *
+ * This method can read a @code{float} written by an object implementing the
+ * @code{writeFloat()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{float} value read
+ *
+ * @exception EOFException If end of file is reached before reading the float
+ * @exception IOException If any other error occurs
+ *
+ * @see java.lang.Float
+ * @see DataOutput
+ */
+public float
+readFloat() throws EOFException, IOException
+{
+ int val = readInt();
+
+ return(Float.intBitsToFloat(val));
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads a Java double value from an input stream. It operates
+ * by first reading a @code{logn} value from the stream by calling the
+ * @code{readLong()} method in this interface, then converts that @code{long}
+ * to a @code{double} using the @code{longBitsToDouble} method in
+ * the class @{java.lang.Double}.
+ *
+ * This method can read a @code{double} written by an object implementing the
+ * @code{writeDouble()} method in the @code{DataOutput} interface.
+ *
+ * @return The @code{double} value read
+ *
+ * @exception EOFException If end of file is reached before reading the double
+ * @exception IOException If any other error occurs
+ *
+ * @see java.lang.Double
+ * @see DataOutput
+ */
+public double
+readDouble() throws EOFException, IOException
+{
+ long val = readLong();
+
+ return(Double.longBitsToDouble(val));
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads the next line of text data from an input stream.
+ * It operates by reading bytes and converting those bytes to @{char}
+ * values by treating the byte read as the low eight bits of the @{char}
+ * and using @code{0} as the high eight bits. Because of this, it does
+ * not support the full 16-bit Unicode character set.
+ *
+ * The reading of bytes ends when either the end of file or a line terminator
+ * is encountered. The bytes read are then returned as a @code{String}.
+ * A line terminator is a byte sequence consisting of either
+ * @samp{\r}, @samp{\n} or @samp{\r\n}. These termination charaters are
+ * discarded and are not returned as part of the string.
+ *
+ * This method can read data that was written by an object implementing the
+ * @code{writeLine()} method in @code{DataOutput}.
+ *
+ * @return The line read as a @code{String}
+ *
+ * @exception IOException If an error occurs
+ *
+ * @see DataOutput
+ */
+public String
+readLine() throws IOException
+{
+ StringBuffer sb = new StringBuffer("");
+
+ for (;;)
+ {
+ int byte_read = in.read();
+
+ if (byte_read == -1)
+ return(sb.toString());
+
+ char c = (char)byte_read;
+
+ if (c == '\r')
+ {
+ byte_read = in.read();
+ if (((char)byte_read) != '\n')
+ ((PushbackInputStream)in).unread(byte_read);
+
+ return(sb.toString());
+ }
+
+ if (c == '\n')
+ return(sb.toString());
+
+ sb.append(c);
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads a @code{String} from an input stream that is encoded in
+ * a modified UTF-8 format. This format has a leading two byte sequence
+ * that contains the remaining number of bytes to read. This two byte
+ * sequence is read using the @code{readUnsignedShort()} method of this
+ * interface.
+ *
+ * After the number of remaining bytes have been determined, these bytes
+ * are read an transformed into @{char} values. These @code{char} values
+ * are encoded in the stream using either a one, two, or three byte format.
+ * The particular format in use can be determined by examining the first
+ * byte read.
+ *
+ * If the first byte has a high order bit of @samp{0}, then
+ * that character consists on only one byte. This character value consists
+ * of seven bits that are at positions 0 through 6 of the byte. As an
+ * example, if @code{byte1} is the byte read from the stream, it would
+ * be converted to a @code{char} like so:
+ *
+ * @code{(char)byte1}
+ *
+ * If the first byte has @code{110} as its high order bits, then the
+ * character consists of two bytes. The bits that make up the character
+ * value are in positions 0 through 4 of the first byte and bit positions
+ * 0 through 5 of the second byte. (The second byte should have
+ * @samp{10} as its high order bits). These values are in most significant
+ * byte first (i.e., "big endian") order.
+ *
+ * As an example, if @code{byte1} and @code{byte2} are the first two bytes
+ * read respectively, and the high order bits of them match the patterns
+ * which indicate a two byte character encoding, then they would be
+ * converted to a Java @code{char} like so:
+ *
+ * @code{(char)(((byte1 & 0x1F) << 6) | (byte2 & 0x3F))}
+ *
+ * If the first byte has a @code{1110} as its high order bits, then the
+ * character consists of three bytes. The bits that make up the character
+ * value are in positions 0 through 3 of the first byte and bit positions
+ * 0 through 5 of the other two bytes. (The second and third bytes should
+ * have @code{10} as their high order bits). These values are in most
+ * significant byte first (i.e., "big endian") order.
+ *
+ * As an example, if @code{byte1}, @code{byte2}, and @code{byte3} are the
+ * three bytes read, and the high order bits of them match the patterns
+ * which indicate a three byte character encoding, then they would be
+ * converted to a Java @code{char} like so:
+ *
+ * @code{(char)(((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F))}
+ *
+ * Note that all characters are encoded in the method that requires the
+ * fewest number of bytes with the exception of the character with the
+ * value of @samp{\u0000} which is encoded as two bytes. This is a
+ * modification of the UTF standard used to prevent C language style
+ * @samp{NUL} values from appearing in the byte stream.
+ *
+ * This method can read data that was written by an object implementing the
+ * @code{writeUTF()} method in @code{DataOutput}.
+ *
+ * @returns The @code{String} read
+ *
+ * @exception EOFException If end of file is reached before reading the String
+ * @exception UTFDataFormatException If the data is not in UTF-8 format
+ * @exception IOException If any other error occurs
+ *
+ * @see DataOutput
+ */
+public String
+readUTF() throws EOFException, UTFDataFormatException, IOException
+{
+ StringBuffer sb = new StringBuffer("");
+
+ int num_bytes = readUnsignedShort();
+
+ for (int i = 0; i < num_bytes; i++)
+ {
+ int byte_read = in.read();
+
+ if (byte_read == -1)
+ throw new EOFException("Unexpected end of stream");
+
+ // Three byte encoding case
+ if ((byte_read & 0xE0) == 0xE0) // 224
+ {
+ int val = (byte_read & 0x0F) << 12;
+
+ byte_read = in.read();
+ if (byte_read == -1)
+ throw new EOFException("Unexpected end of stream");
+
+ if ((byte_read & 0x80) != 0x80)
+ throw new UTFDataFormatException("Bad byte in input: " + byte_read);
+
+ val |= (byte_read & 0x3F) << 6;
+
+ byte_read = in.read();
+ if (byte_read == -1)
+ throw new EOFException("Unexpected end of stream");
+
+ if ((byte_read & 0x80) != 0x80)
+ throw new UTFDataFormatException("Bad byte in input: " + byte_read);
+
+ val |= (byte_read & 0x3F);
+
+ sb.append((char)val);
+
+ i += 2;
+ }
+ // Two byte encoding case
+ else if ((byte_read & 0xC0) == 0xC0) // 192
+ {
+ int val = (byte_read & 0x1F) << 6;
+
+ byte_read = in.read();
+ if (byte_read == -1)
+ throw new EOFException("Unexpected end of stream");
+
+ if ((byte_read & 0x80) != 0x80)
+ throw new UTFDataFormatException("Bad byte in input: " + byte_read);
+
+ val |= (byte_read & 0x3F);
+
+ sb.append((char)val);
+
+ ++i;
+ }
+ // One byte encoding case
+ else if (byte_read < 128)
+ {
+ sb.append((char)byte_read);
+ }
+ else
+ {
+ throw new UTFDataFormatException("Bad byte in input: " + byte_read);
+ }
+ }
+ return(sb.toString());
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads raw bytes into the passed array until the array is
+ * full. Note that this method blocks until the data is available and
+ * throws an exception if there is not enough data left in the stream to
+ * fill the buffer
+ *
+ * @param buf The buffer into which to read the data
+ *
+ * @exception EOFException If end of file is reached before filling the buffer
+ * @exception IOException If any other error occurs
+ */
+public void
+readFully(byte[] buf) throws EOFException, IOException
+{
+ readFully(buf, 0, buf.length);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads raw bytes into the passed array @code{buf} starting
+ * @code{offset} bytes into the buffer. The number of bytes read will be
+ * exactly @code{len}. Note that this method blocks until the data is
+ * available and * throws an exception if there is not enough data left in
+ * the stream to read @code{len} bytes.
+ *
+ * @param buf The buffer into which to read the data
+ * @param offset The offset into the buffer to start storing data
+ * @param len The number of bytes to read into the buffer
+ *
+ * @exception EOFException If end of file is reached before filling the buffer
+ * @exception IOException If any other error occurs
+ */
+public void
+readFully(byte[] buf, int offset, int len) throws EOFException, IOException
+{
+ int total_read = 0;
+
+ while (total_read < len)
+ {
+ int bytes_read = in.read(buf, offset + total_read, len - total_read);
+ if (bytes_read == -1)
+ throw new EOFException("Unexpected end of stream");
+
+ total_read += bytes_read;
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * This method skips and discards the specified number of bytes in an
+ * input stream
+ *
+ * @param num_bytes The number of bytes to skip
+ *
+ * @return The number of bytes actually skipped, which will always be @code{num_bytes}
+ *
+ * @exception EOFException If end of file is reached before all bytes can be skipped
+ * @exception IOException If any other error occurs
+ */
+public int
+skipBytes(int n) throws EOFException, IOException
+{
+ long total_skipped = 0;
+
+ while (total_skipped < n)
+ {
+ long bytes_skipped = in.skip(total_skipped - n);
+
+ // If we can't skip anymore, try once more, then bomb out
+ if (bytes_skipped == 0)
+ {
+ bytes_skipped = in.skip(total_skipped - n);
+ if (bytes_skipped == 0)
+ throw new EOFException("Unexpected end of stream");
+ }
+
+ total_skipped += bytes_skipped;
+ }
+
+ return(n);
+}
+
+} // interface DataInput
+
diff --git a/java/io/DataOutput.java b/java/io/DataOutput.java
new file mode 100644
index 000000000..1e1e732c1
--- /dev/null
+++ b/java/io/DataOutput.java
@@ -0,0 +1,206 @@
+/*************************************************************************
+/* DataOutput.java -- Interface for writing data from a stream
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface is implemented by classes that can wrte data to streams
+ * from Java primitive types.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface DataOutput
+{
+
+/**
+ * This method writes a Java boolean value to an output stream
+ *
+ * @param value The boolean value to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeBoolean(boolean value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a Java byte value to an output stream
+ *
+ * @param value The int value to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeByte(int value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a Java char value to an output stream
+ *
+ * @param value The char value to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeChar(int value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a Java int value to an output stream as a 16 bit value
+ *
+ * @param value The int value to write as a 16-bit value
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeShort(int value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a Java int value to an output stream
+ *
+ * @param value The int value to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeInt(int value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a Java long value to an output stream
+ *
+ * @param value The long value to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeLong(long value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a Java float value to an output stream
+ *
+ * @param value The float value to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeFloat(float value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a Java double value to an output stream
+ *
+ * @param value The double value to write
+ *
+ * @exception IOException If any other error occurs
+ */
+public abstract void
+writeDouble(double value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a String to an output stream as an array of bytes
+ *
+ * @param value The String to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeBytes(String value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a String to an output stream as an array of char's
+ *
+ * @param value The String to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeChars(String value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes a String to an output stream encoded in
+ * UTF-8 format.
+ *
+ * @param value The String to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeUTF(String value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes an 8-bit value (passed into the method as a Java
+ * int) to an output stream.
+ *
+ * @param value The byte to write to the output stream
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+write(int value) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes the raw byte array passed in to the output stream.
+ *
+ * @param buf The byte array to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+write(byte[] buf) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method writes raw bytes from the passed array @code{buf} starting
+ * @code{offset} bytes into the buffer. The number of bytes written will be
+ * exactly @code{len}.
+ *
+ * @param buf The buffer from which to write the data
+ * @param offset The offset into the buffer to start writing data from
+ * @param len The number of bytes to write from the buffer to the output stream
+ *
+ * @exception IOException If any other error occurs
+ */
+public abstract void
+write(byte[] buf, int offset, int len) throws IOException;
+
+} // interface DataOutput
+
diff --git a/java/io/EOFException.java b/java/io/EOFException.java
new file mode 100644
index 000000000..ef49b1072
--- /dev/null
+++ b/java/io/EOFException.java
@@ -0,0 +1,64 @@
+/*************************************************************************
+/* EOFException.java -- Unexpected end of file exception
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when the end of the file or stream was
+ * encountered unexpectedly. This is not the normal way that a normal
+ * EOF condition is reported. Normally a special value such as -1 is
+ * returned. However, certain types of streams expecting certain data
+ * in a certain format might reach EOF before reading their expected
+ * data pattern and thus throw this exception.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class EOFException extends IOException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new EOFException without a descriptive error message
+ */
+public
+EOFException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new EOFException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+EOFException(String message)
+{
+ super(message);
+}
+
+} // class EOFException
+
diff --git a/java/io/Externalizable.java b/java/io/Externalizable.java
new file mode 100644
index 000000000..ac9da076b
--- /dev/null
+++ b/java/io/Externalizable.java
@@ -0,0 +1,90 @@
+/*************************************************************************
+/* Externalizable.java -- Interface for saving and restoring object data
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface provides a way that classes can completely control how
+ * the data of their object instances are written and read to and from
+ * streams. It has two methods which are used to write the data to a stream
+ * and to read the data from a stream. The read method must read the data
+ *in exactly the way it was written by the write method.
+ *
+ * Note that classes which implement this interface must take into account
+ * that all superclass data must also be written to the stream as well.
+ * The class implementing this interface must figure out how to make that
+ * happen.
+ *
+ * This interface can be used to provide object persistence. When an
+ * object is to be stored externally, the @code{writeExternal} method is
+ * called to save state. When the object is restored, an instance is
+ * created using the default no-argument constructor and the
+ * @{readExternal} method is used to restore the state.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Externalizable
+{
+
+/**
+ * This method restores an object's state by reading in the instance data
+ * for the object from the passed in stream. Note that this stream is not
+ * a subclass of @code{InputStream}, but rather is a class that implements
+ * the @code{ObjectInput} interface. That interface provides a mechanism for
+ * reading in Java data types from a stream.
+ *
+ * Note that this method must be compatible with @code{writeExternal}.
+ * It must read back the exact same types that were written by that
+ * method in the exact order they were written.
+ *
+ * If this method needs to read back an object instance, then the class
+ * for that object must be found and loaded. If that operation fails,
+ * then this method throws a @code{ClassNotFoundException}
+ *
+ * @param in An @code{ObjectInput} instance for reading in the object state
+ *
+ * @exception ClassNotFoundException If the class of an object being restored cannot be found
+ * @exception IOException If any other error occurs
+ */
+public abstract void
+readExternal(ObjectInput in) throws ClassNotFoundException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method is responsible for writing the instance data of an object
+ * to the passed in stream. Note that this stream is not a subclass of
+ * @code{OutputStream}, but rather is a class that implements the
+ * @code{ObjectOutput} interface. That interface provides a number of methods
+ * for writing Java data values to a stream.
+ *
+ * Not that the implementation of this method must be coordinated with
+ * the implementation of @{readExternal}.
+ *
+ * @param out An @{ObjectOutput} instance for writing the object state
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeExternal(ObjectOutput out) throws IOException;
+
+} // interface Externalizable
+
diff --git a/java/io/FileNotFoundException.java b/java/io/FileNotFoundException.java
new file mode 100644
index 000000000..6a2771757
--- /dev/null
+++ b/java/io/FileNotFoundException.java
@@ -0,0 +1,60 @@
+/*************************************************************************
+/* FileNotFoundException.java -- The requested file could not be found
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when an attempt is made to access a file that
+ * does not exist.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class FileNotFoundException extends IOException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new FileNotFoundException without a descriptive error message
+ */
+public
+FileNotFoundException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new FileNotFoundException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+FileNotFoundException(String message)
+{
+ super(message);
+}
+
+} // class FileNotFoundException
+
diff --git a/java/io/FilenameFilter.java b/java/io/FilenameFilter.java
new file mode 100644
index 000000000..f7b93d296
--- /dev/null
+++ b/java/io/FilenameFilter.java
@@ -0,0 +1,50 @@
+/*************************************************************************
+/* FilenameFilter.java -- Filter a list of filenames
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface has one method which is used for filtering filenames
+ * returned in a directory listing. It is currently used by the
+ * @code{File.list()} method and by the filename dialog in AWT.
+ *
+ * The method in this interface determines if a particular file should
+ * or should not be included in the file listing.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface FilenameFilter
+{
+
+/**
+ * This method determines whether or not a given file should be included
+ * in a directory listing.
+ *
+ * @param dir The @code{File} instance for the directory being read
+ * @param name The name of the file to test
+ *
+ * @return @code{true} if the file should be included in the list, @code{false} otherwise.
+ */
+public abstract boolean
+accept(File dir, String name);
+
+} // interface FilenameFilter
+
diff --git a/java/io/FilterInputStream.java b/java/io/FilterInputStream.java
new file mode 100644
index 000000000..80f59bb0f
--- /dev/null
+++ b/java/io/FilterInputStream.java
@@ -0,0 +1,209 @@
+/*************************************************************************
+/* FilterInputStream.java -- Base class for classes that filter input
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This is the common superclass of all standard classes that filter
+ * input. It acts as a layer on top of an underlying @code{InputStream}
+ * and simply redirects calls made to it to the subordinate InputStream
+ * instead. Subclasses of this class perform additional filtering
+ * functions in addition to simply redirecting the call.
+ *
+ * This class is not abstract. However, since it only redirects calls
+ * to a subordinate @code{InputStream} without adding any functionality on top
+ * of it, this class should not be used directly. Instead, various
+ * subclasses of this class should be used. This is enforced with a
+ * protected constructor. Do not try to hack around it.
+ *
+ * When creating a subclass of @code{FilterInputStream}, override the
+ * appropriate methods to implement the desired filtering. However, note
+ * that the @code{read(byte[])} method does not need to be overridden
+ * as this class redirects calls to that method to
+ * @code{read(byte[], int, int)} instead of to the subordinate
+ * @code{InputStream} @code{read(byte[])} method.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class FilterInputStream extends InputStream
+{
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * This is the subordinate @code{InputStream} to which method calls
+ * are redirected
+ */
+protected InputStream in;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a @code{FilterInputStream} with the specified subordinate
+ * @code{InputStream}.
+ *
+ * @param in The subordinate @code{InputStream}
+ */
+protected
+FilterInputStream(InputStream in)
+{
+ this.in = in;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Calls the @code{in.mark(int)} method.
+ *
+ * @param readlimit The parameter passed to @code{in.mark(int)}
+ */
+public void
+mark(int readlimit)
+{
+ in.mark(readlimit);
+}
+
+/*************************************************************************/
+
+/**
+ * Calls the @code{in.markSupported()} method.
+ *
+ * @return @code{true} if mark/reset is supported, @code{false} otherwise
+ */
+public boolean
+markSupported()
+{
+ return(in.markSupported());
+}
+
+/*************************************************************************/
+
+/**
+ * Calls the @code{in.reset()} method.
+ *
+ * @exception IOException If an error occurs
+ */
+public void
+reset() throws IOException
+{
+ in.reset();
+}
+
+/*************************************************************************/
+
+/**
+ * Calls the @code{in.available()} method.
+ *
+ * @return The value returned from @code{in.available()}
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+available() throws IOException
+{
+ return(in.available());
+}
+
+/*************************************************************************/
+
+/**
+ * Calls the @code{in.skip(long)} method
+ *
+ * @param The requested number of bytes to skip.
+ *
+ * @return The value returned from @code{in.skip(long)}
+ *
+ * @exception IOException If an error occurs
+ */
+public long
+skip(long num_bytes) throws IOException
+{
+ return(in.skip(num_bytes));
+}
+
+/*************************************************************************/
+
+/**
+ * Calls the @code{in.read()} method
+ *
+ * @return The value returned from @code{in.read()}
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+read() throws IOException
+{
+ return(in.read());
+}
+
+/*************************************************************************/
+
+/**
+ * Calls the @code{read(byte[], int, int)} overloaded method. Note that
+ * this method does not redirect its call directly to a corresponding
+ * method in @code{in}. This allows subclasses to override only the
+ * three argument version of @code{read}.
+ *
+ * @param buf The buffer to read bytes into
+ *
+ * @return The value retured from @code{in.read(byte[], int, int)}
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+read(byte[] buf) throws IOException
+{
+ return(read(buf, 0, buf.length));
+}
+
+/*************************************************************************/
+
+/**
+ * Calls the @code{in.read(byte[], int, int)} method.
+ *
+ * @param buf The buffer to read bytes into
+ * @param offset The index into the buffer to start storing bytes
+ * @param len The maximum number of bytes to read.
+ *
+ * @return The value retured from @code{in.read(byte[], int, int)}
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+read(byte[] buf, int offset, int len) throws IOException
+{
+ return(in.read(buf, offset, len));
+}
+
+} // class FilterInputStream
+
diff --git a/java/io/IOException.java b/java/io/IOException.java
new file mode 100644
index 000000000..dfc9ae5c0
--- /dev/null
+++ b/java/io/IOException.java
@@ -0,0 +1,62 @@
+/*************************************************************************
+/* IOException.java -- Generic input/output exception
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown to indicate an I/O problem of some sort
+ * occurred. Since this is a fairly generic exception, often a subclass
+ * of IOException will actually be thrown in order to provide a more
+ * detailed indication of what happened.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class IOException extends Exception
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new IOException without a descriptive error message
+ */
+public
+IOException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new IOException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+IOException(String message)
+{
+ super(message);
+}
+
+} // class IOException
+
diff --git a/java/io/InputStream.java b/java/io/InputStream.java
new file mode 100644
index 000000000..d6d7cb97f
--- /dev/null
+++ b/java/io/InputStream.java
@@ -0,0 +1,315 @@
+/*************************************************************************
+/* InputStream.java -- Base class for input
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This abstract class forms the base of the hierarchy of classes that read
+ * input as a stream of bytes. It provides a common set of methods for
+ * reading bytes from streams. Subclasses implement and extend these
+ * methods to read bytes from a particular input source such as a file
+ * or network connection.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract class InputStream
+{
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Default, no-arg, public constructor
+ */
+public
+InputStream()
+{
+ return;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method marks a position in the input to which the stream can be
+ * "reset" by calling the @code{reset()} method. The parameter
+ * @code{readlimit} is the number of bytes that can be read from the
+ * stream after setting the mark before the mark becomes invalid. For
+ * example, if @code{mark()} is called with a read limit of 10, then when
+ * 11 bytes of data are read from the stream before the @code{reset()}
+ * method is called, then the mark is invalid and the stream object
+ * instance is not required to remember the mark.
+ *
+ * This method does nothing in this class, but subclasses may override it
+ * to provide mark/reset functionality.
+ *
+ * @param readlimit The number of bytes that can be read before the mark becomes invalid
+ */
+public void
+mark(int readlimit)
+{
+ return;
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns a boolean that indicates whether the mark/reset
+ * methods are supported in this class. Those methods can be used to
+ * remember a specific point in the stream and reset the stream to that
+ * point.
+ *
+ * This method always returns @code{false} in this class, but subclasses
+ * can override this method to return @code{true} if they support
+ * mark/reset functionality.
+ *
+ * @return @code{true} if mark/reset functionality is supported, @code{false} otherwise
+ *
+ */
+public boolean
+markSupported()
+{
+ return(false);
+}
+
+/*************************************************************************/
+
+/**
+ * This method resets a stream to the point where the @code{mark()} method
+ * was called. Any bytes that were read after the mark point was set will
+ * be re-read during subsequent reads.
+ *
+ * This method always throws an IOException in this class, but subclasses
+ * can override this method if they provide mark/reset functionality.
+ *
+ * @exception IOException Always thrown for this class
+ */
+public void
+reset() throws IOException
+{
+ throw new IOException("Mark not supported in this class");
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the number of bytes that can be read from this
+ * stream before a read can block. A return of 0 indicates that blocking
+ * might (or might not) occur on the very next read attempt.
+ *
+ * This method always returns 0 in this class
+ *
+ * @return The number of bytes that can be read before blocking could occur
+ *
+ * @return IOException If an error occurs
+ */
+public int
+available() throws IOException
+{
+ return(0);
+}
+
+/*************************************************************************/
+
+/**
+ * This method skips the specified number of bytes in the stream. It
+ * returns the actual number of bytes skipped, which may be less than the
+ * requested amount.
+ *
+ * This method reads and discards bytes into a 256 byte array until the
+ * specified number of bytes were skipped or until either the end of stream
+ * is reached or a read attempt returns a short count. Subclasses can
+ * override this metho to provide a more efficient implementation where
+ * one exists.
+ *
+ * @param num_bytes The requested number of bytes to skip
+ *
+ * @return The actual number of bytes skipped.
+ *
+ * @exception IOException If an error occurs
+ */
+public long
+skip(long num_bytes) throws IOException
+{
+ int buf_size = 256;
+ byte[] buf = new byte[buf_size];
+
+ if (num_bytes <= 0)
+ return(0);
+
+ long loop_count = num_bytes / buf_size;
+ int extra_bytes = (int)(num_bytes % buf_size);
+ long bytes_read = 0;
+ long total_read = 0;
+
+ for (long i = 0; i < loop_count; i++)
+ {
+ bytes_read = read(buf, 0, buf.length);
+
+ if (bytes_read == -1)
+ return(total_read);
+
+ if (bytes_read != buf_size)
+ return(total_read + bytes_read);
+
+ total_read += bytes_read;
+ }
+
+ bytes_read = read(buf, 0, extra_bytes);
+
+ if (bytes_read == -1)
+ return(total_read);
+
+ return(total_read + bytes_read);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads an unsigned byte from the input stream and returns it
+ * as an int in the range of 0-255. This method also will return -1 if
+ * the end of the stream has been reached.
+ *
+ * This method will block until the byte can be read.
+ *
+ * @return The byte read or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+read() throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads bytes from a stream and stores them into a caller
+ * supplied buffer. This method attempts to completely fill the buffer,
+ * but can return before doing so. The actual number of bytes read is
+ * returned as an int. A -1 is returned to indicate the end of the stream.
+ *
+ * This method will block until some data can be read.
+ *
+ * This method operates by calling an overloaded read method like so:
+ * @code{read(buf, 0, buf.length)}
+ *
+ * @param buf The buffer into which the bytes read will be stored.
+ *
+ * @return The number of bytes read or -1 if end of stream.
+ *
+ * @exception IOException If an error occurs.
+ */
+public int
+read(byte[] buf) throws IOException
+{
+ return(read(buf, 0, buf.length));
+}
+
+/*************************************************************************/
+
+/**
+ * This method read bytes from a stream and stores them into a caller
+ * supplied buffer. It starts storing the data at index @code{offset} into
+ * the buffer and attempts to read @code{len} bytes. This method can
+ * return before reading the number of bytes requested. The actual number
+ * of bytes read is returned as an int. A -1 is returned to indicate the
+ * end of the stream.
+ *
+ * This method will block until some data can be read.
+ *
+ * This method operates by calling the single byte @code{read()} method
+ * in a loop until the desired number of bytes are read. The read loop
+ * stops short if the end of the stream is encountered or if an IOException
+ * is encountered on any read operation except the first. If the first
+ * attempt to read a bytes fails, the IOException is allowed to propagate
+ * upward. And subsequent IOException is caught and treated identically
+ * to an end of stream condition. Subclasses can (and should if possible)
+ * override this method to provide a more efficient implementation.
+ *
+ * @param buf The array into which the bytes read should be stored
+ * @param offset The offset into the array to start storing bytes
+ * @param len The requested number of bytes to read
+ *
+ * @return The actual number of bytes read, or -1 if end of stream.
+ *
+ * @exception IOException If an error occurs.
+ */
+public int
+read(byte[] buf, int offset, int len) throws IOException
+{
+ if (len == 0)
+ return(0);
+
+ // Read the first byte here in order to allow IOException's to
+ // propagate up
+ int byte_read = read();
+ if (byte_read == -1)
+ return(-1);
+ buf[offset] = (byte)byte_read;
+
+ int total_read = 1;
+
+ // Read the rest of the bytes
+ try
+ {
+ for (int i = 1; i < len; i++)
+ {
+ byte_read = read();
+ if (byte_read == -1)
+ return(total_read);
+
+ buf[offset + i] = (byte)byte_read;
+
+ ++total_read;
+ }
+ }
+ catch (IOException e)
+ {
+ return(total_read);
+ }
+
+ return(total_read);
+}
+
+/*************************************************************************/
+
+/**
+ * This method closes the stream. Any futher attempts to read from the
+ * stream may generate an @code{IOException}
+ *
+ * This method does nothing in this class, but subclasses may override
+ * this method in order to provide additional functionality.
+ *
+ * @exception IOException If an error occurs, which can only happen in a subclass
+ */
+public void
+close() throws IOException
+{
+ return;
+}
+
+} // class InputStream
+
diff --git a/java/io/InterruptedIOException.java b/java/io/InterruptedIOException.java
new file mode 100644
index 000000000..e2c6e4615
--- /dev/null
+++ b/java/io/InterruptedIOException.java
@@ -0,0 +1,87 @@
+/*************************************************************************
+/* InterruptedIOException.java -- An I/O operation was interrupted.
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when a in process I/O operation is
+ * interrupted for some reason. The field bytesTransferred will contain
+ * the number of bytes that were read/written prior to the interruption.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class InterruptedIOException extends IOException
+{
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * The number of bytes read/written prior to the interruption
+ */
+public int bytesTransferred;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new InterruptedIOException without a descriptive error message
+ */
+public
+InterruptedIOException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new InterruptedIOException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+InterruptedIOException(String message)
+{
+ super(message);
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new InterruptedIOException with a descriptive error message
+ * String. Also sets the value of the bytesTransferred field.
+ *
+ * @param message The descriptive error message
+ * @param bytesTransferred The number of bytes tranferred before the interruption
+ */
+InterruptedIOException(String message, int bytesTransferred)
+{
+ super(message);
+ this.bytesTransferred = bytesTransferred;
+}
+
+} // class InterruptedIOException
+
diff --git a/java/io/InvalidClassException.java b/java/io/InvalidClassException.java
new file mode 100644
index 000000000..0a6fcc11e
--- /dev/null
+++ b/java/io/InvalidClassException.java
@@ -0,0 +1,101 @@
+/*************************************************************************
+/* InvalidClassException.java -- An I/O operation was interrupted.
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when there is some sort of problem with a
+ * class during a serialization operation. This could be that the
+ * versions don't match, that there are unknown datatypes in the class
+ * or that the class doesn't have a default no-arg constructor.
+ * <p>
+ * The field <code>classname</code> will contain the name of the
+ * class that caused the problem if known. The getMessage() method
+ * for this exception will always include the name of that class
+ * if known.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class InvalidClassException extends ObjectStreamException
+{
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * The name of the class which encountered the error.
+ */
+public String classname;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new InvalidClassException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+InvalidClassException(String message)
+{
+ super(message);
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new InvalidClassException with a descriptive error message
+ * String, and the name of the class that caused the problem.
+ *
+ * @param classname The number of bytes tranferred before the interruption
+ * @param message The descriptive error message
+ */
+InvalidClassException(String message, int bytesTransferred)
+{
+ super(message);
+ this.classname = classname;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * Returns the descriptive error message for this exception. It will
+ * include the class name that caused the problem if known. This method
+ * overrides Throwable.getMessage()
+ *
+ * @return A descriptive error message
+ */
+public String
+getMessage()
+{
+ return(super.getMessage() + ": " + classname);
+}
+
+} // class InvalidClassException
+
diff --git a/java/io/InvalidObjectException.java b/java/io/InvalidObjectException.java
new file mode 100644
index 000000000..2ecb6eea2
--- /dev/null
+++ b/java/io/InvalidObjectException.java
@@ -0,0 +1,49 @@
+/*************************************************************************
+/* InvalidObjectException.java -- An I/O operation was interrupted.
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when an object fails a validation test
+ * during serialization.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class InvalidObjectException extends ObjectStreamException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new InvalidObjectException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+InvalidObjectException(String message)
+{
+ super(message);
+}
+
+} // class InvalidObjectException
+
diff --git a/java/io/LineNumberInputStream.java b/java/io/LineNumberInputStream.java
new file mode 100644
index 000000000..da7d447da
--- /dev/null
+++ b/java/io/LineNumberInputStream.java
@@ -0,0 +1,309 @@
+/*************************************************************************
+/* LineNumberInputStream.java -- An input stream which counts line numbers
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This class functions like a standard @code{InputStream} except that it
+ * counts line numbers, and canonicalizes newline characters. As data
+ * is read, whenever the byte sequences "\r", "\n", or "\r\n" are encountered,
+ * the running line count is incremeted by one. Additionally, the whatever
+ * line termination sequence was encountered will be converted to a "\n"
+ * byte. Note that this class numbers lines from 0. When the first
+ * line terminator is encountered, the line number is incremented to 1, and
+ * so on.
+ *
+ * This class counts only line termination characters. If the last line
+ * read from the stream does not end in a line termination sequence, it
+ * will not be counted as a line.
+ *
+ * Note that since this class operates as a filter on an underlying stream,
+ * it has the same mark/reset functionality as the underlying stream. The
+ * @code{mark()} and @code{reset()} methods in this class handle line numbers
+ * correctly. Calling @code{reset()} resets the line number to the point
+ * at which @code{mark()} was called if the subordinate stream supports
+ * that functionality.
+ *
+ * This method is deprecated in favor if @code{LineNumberReader} because
+ * it operates on ASCII bytes instead of an encoded character stream. This
+ * class is for backward compatibility only and should not be used in
+ * new applications.
+ *
+ * @deprecated
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class LineNumberInputStream extends FilterInputStream
+{
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This variable is used to keep track of the current line number
+ */
+private int line_number;
+
+/**
+ * This variable is used to keep track of the line number that was
+ * current when the @code{mark()} method was called
+ */
+private int marked_line_number;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new @code{LineNumberInputStream} that reads from the
+ * specified subordinate @code{InputStream}
+ *
+ * @param in The subordinate @code{InputStream} to read from
+ */
+public
+LineNumberInputStream(InputStream in)
+{
+ super(in);
+
+ // Override this.in with another filter
+ this.in = new PushbackInputStream(in);
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method returns the current line number
+ *
+ * @returns The current line number
+ */
+public int
+getLineNumber()
+{
+ return(line_number);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the current line number to the specified value.
+ *
+ * @param line_number The new line number
+ */
+public void
+setLineNumber(int line_number)
+{
+ this.line_number = line_number;
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns the number of bytes that can be read from the
+ * stream before the stream can block. This method is tricky because
+ * the subordinate @code{InputStream} might return only "\r\n" characters,
+ * which are replaced by a single "\n" character by the @code{read()} method
+ * of this class. So this method can only guarantee that
+ * @code{in.available() / 2} bytes can actually be read before blocking.
+ * In practice, considerably more bytes might be read before blocking
+ *
+ * Note that the stream may not block if additional bytes beyond the count
+ * returned by this method are read.
+ *
+ * @return The number of bytes that can be read before blocking could occur
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+available() throws IOException
+{
+ return(in.available() / 2);
+}
+
+/*************************************************************************/
+
+/**
+ * This method marks a position in the input to which the stream can be
+ * "reset" byte calling the @code{reset()} method. The parameter
+ * @code{readlimit} is the number of bytes that can be read from the
+ * stream after setting the mark before the mark becomes invalid. For
+ * example, if @code{mark()} is called with a read limit of 10, then when
+ * 11 bytes of data are read from the stream before the @code{reset()}
+ * method is called, then the mark is invalid and the stream object
+ * instance is not required to remember the mark.
+ *
+ * In this class, this method will remember the current line number as well
+ * as the current position in the stream. When the @code{reset()} method is
+ * called, the line number will be restored to the saved line number in
+ * addition to the stream position.
+ *
+ * This method only works if the subordinate stream supports mark/reset
+ * functionality.
+ *
+ * @param readlimit The number of bytes that can be read before the mark becomes invalid
+ */
+public void
+mark(int readlimit)
+{
+ in.mark(readlimit);
+
+ marked_line_number = line_number;
+}
+
+/*************************************************************************/
+
+/**
+ * This method resets a stream to the point where the @code{mark()} method
+ * was called. Any bytes that were read after the mark point was set will
+ * be re-read during subsequent reads.
+ *
+ * In this class, this method will also restore the line number that was
+ * current when the @code{mark()} method was called.
+ *
+ * This method only works if the subordinate stream supports mark/reset
+ * functionality.
+ *
+ * @exception IOException If an error occurs
+ */
+public void
+reset() throws IOException
+{
+ in.reset();
+
+ line_number = marked_line_number;
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads an unsigned byte from the input stream and returns it
+ * as an int in the range of 0-255. This method will return -1 if the
+ * end of the stream has been reached.
+ *
+ * Note that if a line termination sequence is encountered (ie, "\r",
+ * "\n", or "\r\n") then that line termination sequence is converted to
+ * a single "\n" value which is returned from this method. This means
+ * that it is possible this method reads two bytes from the subordinate
+ * stream instead of just one.
+ *
+ * Note that this method will block until a byte of data is available
+ * to be read.
+ *
+ * @return The byte read or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+read() throws IOException
+{
+ int byte_read = in.read();
+
+ if (byte_read == '\n')
+ ++line_number;
+
+ if (byte_read == '\r')
+ {
+ int extra_byte_read = in.read();
+
+ if ((extra_byte_read != '\n') && (extra_byte_read != -1))
+ ((PushbackInputStream)in).unread(extra_byte_read);
+
+ byte_read = '\n';
+ ++line_number;
+ }
+
+ return(byte_read);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads bytes from a stream and stores them into a caller
+ * supplied buffer. It starts storing data at index @code{offset} into
+ * the buffer and attemps to read @code{len} bytes. This method can
+ * return before reading the number of bytes requested. The actual number
+ * of bytes read is returned as an int. A -1 is returned to indicated the
+ * end of the stream.
+ *
+ * This method will block until some data can be read.
+ *
+ * Note that if a line termination sequence is encountered (ie, "\r",
+ * "\n", or "\r\n") then that line termination sequence is converted to
+ * a single "\n" value which is stored in the buffer. Only a single
+ * byte is counted towards the number of bytes read in this case.
+ *
+ * @param buf The array into which the bytes read should be stored
+ * @param offset The offset into the array to start storing bytes
+ * @param len The requested number of bytes to read
+ *
+ * @return The actual number of bytes read, or -1 if end of stream
+ *
+ * @exception IOException If an error occurs.
+ */
+public int
+read(byte[] buf, int offset, int len) throws IOException
+{
+ if (len == 0)
+ return(0);
+
+ // Read the first byte here in order to allow IOException's to
+ // propagate up
+ int byte_read = read();
+ if (byte_read == -1)
+ return(-1);
+ buf[offset] = (byte)byte_read;
+
+ int total_read = 1;
+
+ // Read the rest of the bytes. We do this in a single read() loop
+ // like a raw InputStream. That's ok in my book since this class is
+ // deprecated anyway.
+ try
+ {
+ for (int i = 1; i < len; i++)
+ {
+ byte_read = read();
+ if (byte_read == -1)
+ return(total_read);
+
+ buf[offset + i] = (byte)byte_read;
+
+ ++total_read;
+ }
+ }
+ catch (IOException e)
+ {
+ return(total_read);
+ }
+
+ return(total_read);
+}
+
+} // class LineNumberInputStream
+
diff --git a/java/io/Makefile.am b/java/io/Makefile.am
new file mode 100644
index 000000000..1cc964222
--- /dev/null
+++ b/java/io/Makefile.am
@@ -0,0 +1,23 @@
+## Input file for automake to generate the Makefile.in used by configure
+
+javaiodir = $(datadir)/java/io
+
+javaio_JAVA = BufferedInputStream.java ByteArrayInputStream.java \
+ CharConversionException.java DataInput.java \
+ DataInputStream.java DataOutput.java EOFException.java \
+ Externalizable.java FileNotFoundException.java \
+ FilenameFilter.java FilterInputStream.java IOException.java \
+ InputStream.java InterruptedIOException.java \
+ InvalidClassException.java InvalidObjectException.java \
+ LineNumberInputStream.java NotActiveException.java \
+ NotSerializableException.java ObjectInput.java \
+ ObjectInputValidation.java ObjectOutput.java \
+ ObjectStreamException.java OptionalDataException.java \
+ PushbackInputStream.java Replaceable.java Resolvable.java \
+ SequenceInputStream.java Serializable.java \
+ StreamCorruptedException.java StringBufferInputStream.java \
+ SyncFailedException.java UTFDataFormatException.java \
+ UnsupportedEncodingException.java WriteAbortedException.java
+
+
+
diff --git a/java/io/NotActiveException.java b/java/io/NotActiveException.java
new file mode 100644
index 000000000..08ed07eb8
--- /dev/null
+++ b/java/io/NotActiveException.java
@@ -0,0 +1,60 @@
+/*************************************************************************
+/* NotActiveException.java -- Unexpected end of file exception
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when a problem occurs due to the fact that
+ * serialization is not active.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class NotActiveException extends ObjectStreamException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new NotActiveException without a descriptive error message
+ */
+public
+NotActiveException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new NotActiveException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+NotActiveException(String message)
+{
+ super(message);
+}
+
+} // class NotActiveException
+
diff --git a/java/io/NotSerializableException.java b/java/io/NotSerializableException.java
new file mode 100644
index 000000000..3067ecc52
--- /dev/null
+++ b/java/io/NotSerializableException.java
@@ -0,0 +1,61 @@
+/*************************************************************************
+/* NotSerializableException.java -- Unexpected end of file exception
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when a class may not be serialized. The
+ * descriptive message will consist of the name of the class in question.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class NotSerializableException extends ObjectStreamException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new NotSerializableException without a descriptive error message
+ */
+public
+NotSerializableException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new NotSerializableException with a descriptive error message String
+ * This should be the name of the class that cannot be serialized.
+ *
+ * @param message The descriptive error message
+ */
+public
+NotSerializableException(String message)
+{
+ super(message);
+}
+
+} // class NotSerializableException
+
diff --git a/java/io/ObjectInput.java b/java/io/ObjectInput.java
new file mode 100644
index 000000000..414f997d0
--- /dev/null
+++ b/java/io/ObjectInput.java
@@ -0,0 +1,139 @@
+/*************************************************************************
+/* ObjectInput.java -- Read object data from a stream
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface extends the @code{DataInput} interface to provide a
+ * facility to read objects as well as primitive types from a stream. It
+ * also has methods that allow input to be done in a manner similar to
+ * @code{InputStream}
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface ObjectInput extends DataInput
+{
+
+/**
+ * This method returns the number of bytes that can be read without
+ * blocking.
+ *
+ * @return The number of bytes available before blocking
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+available() throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reading a byte of data from a stream. It returns that byte
+ * as an int. This method blocks if no data is available to be read.
+ *
+ * @return The byte of data read
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+read() throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads raw bytes and stores them them a byte array buffer.
+ * Note that this method will block if no data is available. However,
+ * it will not necessarily block until it fills the entire buffer. That is,
+ * a "short count" is possible.
+ *
+ * @param buf The byte array to receive the data read
+ *
+ * @return The actual number fo bytes read or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+read(byte[] buf) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method reads raw bytes and stores them in a byte array buffer
+ * @code{buf} starting at position @code{offset} into the buffer. A
+ * maximum of @code{len} bytes will be read. Note that this method
+ * blocks if no data is available, but will not necessarily block until
+ * it can read @code{len} bytes of data. That is, a "short count" is
+ * possible.
+ *
+ * @param buf The byte array to receive the data read
+ * @param offset The offset into @code{buf} to start storing data
+ * @param len The maximum number of bytes to read
+ *
+ * @return The actual number fo bytes read or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract int
+read(byte[] buf, int offset, int len) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * Reads an object instance and returns it. If the class for the object
+ * being read cannot be found, then a ClassNotFoundException will
+ * be thrown.
+ *
+ * @return The object instance that was read
+ *
+ * @exception ClassNotFoundException If a class for the object cannot be found
+ * @exception IOException If an error occurs
+ */
+public abstract Object
+readObject() throws ClassNotFoundException, IOException;
+
+/*************************************************************************/
+
+/**
+ * This method causes the specified number of bytes to be read and
+ * discarded. It is possible that fewer than the requested number of bytes
+ * will actually be skipped.
+ *
+ * @param num_bytes The number of bytes to skip
+ *
+ * @return The actual number of bytes skipped
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract long
+skip(long num_bytes) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method closes the input source
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+close() throws IOException;
+
+} // interface ObjectInput
+
diff --git a/java/io/ObjectInputValidation.java b/java/io/ObjectInputValidation.java
new file mode 100644
index 000000000..aa5871e3a
--- /dev/null
+++ b/java/io/ObjectInputValidation.java
@@ -0,0 +1,42 @@
+/*************************************************************************
+/* ObjectInputValidation.java -- Validate an object
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * What does this interface really do?
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface ObjectInputValidation
+{
+
+/**
+ * This method is called to validate an object. If the object is invalid
+ * an exception is thrown.
+ *
+ * @exception InvalidObjectException If the object is invalid
+ */
+public abstract void
+validateObject() throws InvalidObjectException;
+
+} // interface ObjectInputValidation
+
diff --git a/java/io/ObjectOutput.java b/java/io/ObjectOutput.java
new file mode 100644
index 000000000..5a7109157
--- /dev/null
+++ b/java/io/ObjectOutput.java
@@ -0,0 +1,67 @@
+/*************************************************************************
+/* ObjectOutput.java -- Interface for writing objects to a stream
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface extends @code{DataOutpu} to provide the additional
+ * facility of writing object instances to a stream. It also adds some
+ * additional methods to make the interface more @code{OutputStream} like.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface ObjectOutput extends DataOutput
+{
+
+/**
+ * This method writes a object instance to a stream. The format of the
+ * data written is determined by the actual implementation of this method
+ *
+ * @param obj The object to write
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+writeObject(Object obj) throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method causes any buffered data to be flushed out to the underlying
+ * stream
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+flush() throws IOException;
+
+/*************************************************************************/
+
+/**
+ * This method closes the underlying stream.
+ *
+ * @exception IOException If an error occurs
+ */
+public abstract void
+close() throws IOException;
+
+} // interface ObjectOutput
+
diff --git a/java/io/ObjectStreamException.java b/java/io/ObjectStreamException.java
new file mode 100644
index 000000000..5758df248
--- /dev/null
+++ b/java/io/ObjectStreamException.java
@@ -0,0 +1,61 @@
+/*************************************************************************
+/* ObjectStreamException.java -- Unexpected end of file exception
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when a problem occurs during serialization.
+ * There are more specific subclasses than give more fine grained
+ * indications of the precise failure.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class ObjectStreamException extends IOException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new ObjectStreamException without a descriptive error message
+ */
+public
+ObjectStreamException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new ObjectStreamException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+ObjectStreamException(String message)
+{
+ super(message);
+}
+
+} // class ObjectStreamException
+
diff --git a/java/io/OptionalDataException.java b/java/io/OptionalDataException.java
new file mode 100644
index 000000000..ee1f64252
--- /dev/null
+++ b/java/io/OptionalDataException.java
@@ -0,0 +1,71 @@
+/*************************************************************************
+/* OptionalDataException.java -- Unexpected end of file exception
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when unexpected data appears in the input
+ * stream from which a serialized object is being read. The field
+ * <code>eof</code> will always be set to true (***Why even have it?***) and
+ * the <code>count</code> field will contain the number of valid bytes
+ * available to be read.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class OptionalDataException extends ObjectStreamException
+{
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * Whether or not the end of the stream has been reached
+ */
+public boolean eof;
+
+/**
+ * The number of valid bytes that can be read
+ */
+public int length;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new OptionalDataException with an eof parameter indicating
+ * whether or not the end of stream is reached and the number of valid
+ * bytes that may be read.
+ *
+ * @param eof 'true' if end of stream reached, 'false' otherwise
+ * @param count The number of valid bytes to be read.
+ */
+OptionalDataException()
+{
+ this.eof = eof;
+ this.length = length;
+}
+
+} // class OptionalDataException
+
diff --git a/java/io/PushbackInputStream.java b/java/io/PushbackInputStream.java
index 40e3ef084..a11967a77 100644
--- a/java/io/PushbackInputStream.java
+++ b/java/io/PushbackInputStream.java
@@ -175,12 +175,9 @@ available() throws IOException
*
* @exception IOException If an error occurs
*/
-public synchronized long
+public long
skip(long num_bytes) throws IOException
{
- if (num_bytes <= 0)
- return(0);
-
if ((buf.length - pos) >= num_bytes)
{
pos += num_bytes;
@@ -210,14 +207,14 @@ skip(long num_bytes) throws IOException
*
* @exception IOException If an error occurs
*/
-public synchronized int
+public int
read() throws IOException
{
if (pos == buf.length)
return(in.read());
++pos;
- return((buf[pos - 1] & 0xFF));
+ return(buf[pos - 1]);
}
/*************************************************************************/
@@ -245,7 +242,7 @@ read() throws IOException
*
* @exception IOException If an error occurs.
*/
-public synchronized int
+public int
read(byte[] buf, int offset, int len) throws IOException
{
if (len == 0)
@@ -317,7 +314,7 @@ read(byte[] buf, int offset, int len) throws IOException
*
* @exception IOException If the pushback buffer is full.
*/
-public synchronized void
+public void
unread(int b) throws IOException
{
if (pos == 0)
@@ -342,7 +339,7 @@ unread(int b) throws IOException
*
* @exception IOException If the pushback buffer is full
*/
-public synchronized void
+public void
unread(byte[] buf) throws IOException
{
unread(buf, 0, buf.length);
@@ -366,7 +363,7 @@ unread(byte[] buf) throws IOException
*
* @exception IOException If the pushback buffer is full
*/
-public synchronized void
+public void
unread(byte[] buf, int offset, int len) throws IOException
{
if (pos < (len - 1))
diff --git a/java/io/Replaceable.java b/java/io/Replaceable.java
new file mode 100644
index 000000000..57d55b2d3
--- /dev/null
+++ b/java/io/Replaceable.java
@@ -0,0 +1,46 @@
+/*************************************************************************
+/* Replaceable.java -- Replace an object with another object
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface is used to indicate that an object may want to have
+ * another object serialized instead of itself. It contains one method
+ * that is to be called when an object is to be serialized. That method
+ * is reponsible for returning the real object that should be serialized
+ * instead of object being queried.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Replaceable extends Serializable
+{
+
+/**
+ * This method returns the object that should be serialized instead of
+ * this object
+ *
+ * @return The real object that should be serialized
+ */
+public abstract Object
+writeReplace();
+
+} // interface Replaceable
+
diff --git a/java/io/Resolvable.java b/java/io/Resolvable.java
new file mode 100644
index 000000000..6a14ba37d
--- /dev/null
+++ b/java/io/Resolvable.java
@@ -0,0 +1,44 @@
+/*************************************************************************
+/* Resolvable.java -- Returns an object to replace the one being de-serialized
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface is implemented when an object wishes to return another
+ * object to replace it during de-serialization. It has one method that
+ * returns the object that should be used to replace the original object.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Resolvable extends Serializable
+{
+
+/**
+ * This method returns the object that should be used to replace the
+ * original object during de-serialization.
+ *
+ * @return The replacement object
+ */
+public abstract Object
+readResolve();
+
+} // interface Resolvable
+
diff --git a/java/io/SequenceInputStream.java b/java/io/SequenceInputStream.java
new file mode 100644
index 000000000..761281568
--- /dev/null
+++ b/java/io/SequenceInputStream.java
@@ -0,0 +1,302 @@
+/*************************************************************************
+/* SequenceInputStream.java -- Reads multiple input streams in sequence
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+import java.util.Enumeration;
+
+/**
+ * This class merges a sequence of multiple @code{InputStream}'s in order
+ * to form a single logical stream that can be read by applications that
+ * expect only one stream.
+ *
+ * The streams passed to the constructor method are read in order until
+ * they return -1 to indicate they are at end of stream. When a stream
+ * reports end of stream, it is closed, then the next stream is read.
+ * When the last stream is closed, the next attempt to read from this
+ * stream will return a -1 to indicate it is at end of stream.
+ *
+ * If this stream is closed prior to all subordinate streams being read
+ * to completion, all subordinate streams are closed.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class SequenceInputStream extends InputStream
+{
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This variable holds the @code{Enumeration} containing the list of
+ * streams to be read, or @code{null} if the subordinate streams are not
+ * being obtained from an @code{Enumeration}.
+ */
+private Enumeration stream_list;
+
+/**
+ * This variable holds the first @code{InputStream} to read, if the list
+ * of streams is not being obtained from an @code{Enumeration}
+ */
+private InputStream first_stream;
+
+/**
+ * This variable holds the second @code{InputStream} to read, if the list
+ * of streams is not being obtained from an @code{Enumeration}
+ */
+private InputStream second_stream;
+
+/**
+ * This is the current @code{InputStream} that is being read
+ */
+private InputStream current_stream;
+
+/**
+ * This value is @code{true} if this stream has been closed. It is
+ * @code{false} otherwise.
+ */
+private boolean closed = false;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * This method creates a new @code{SequenceInputStream} that obtains its
+ * list of subordinate @code{InputStream}'s from the specified
+ * @code{Enumeration}
+ *
+ * @param stream_list An @code{Enumeration} that will return a list of @code{InputStream}'s to read in sequence
+ */
+public
+SequenceInputStream(Enumeration stream_list)
+{
+ this.stream_list = stream_list;
+
+ current_stream = (InputStream)stream_list.nextElement();
+}
+
+/*************************************************************************/
+
+/**
+ * This method creates a new @code{SequenceInputStream} that will read the
+ * two specified subordinate @code{InputStream}'s in sequence.
+ *
+ * @param first_stream The first @code{InputStream} to read
+ * @param second_stream The second @code{InputStream to read
+ */
+public
+SequenceInputStream(InputStream first_stream, InputStream second_stream)
+{
+ this.first_stream = first_stream;
+ this.second_stream = second_stream;
+ current_stream = first_stream;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method returns the number of bytes than can be read from the
+ * currently being read subordinate stream before that stream could
+ * block. Note that it is possible more bytes than this can actually
+ * be read without the stream blocking. If a 0 is returned, then the
+ * stream could block on the very next read.
+ *
+ * @return The number of bytes that can be read before blocking could occur
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+available() throws IOException
+{
+ if (closed)
+ return(0);
+
+ return(current_stream.available());
+}
+
+/*************************************************************************/
+
+/**
+ * Closes this stream. This will cause any remaining unclosed subordinate
+ * @code{InputStream}'s to be closed as well. Subsequent attempts to
+ * read from this stream may cause an exception.
+ *
+ * @exception IOException If an error occurs
+ */
+public void
+close() throws IOException
+{
+ if (closed)
+ return;
+
+ if ((current_stream == first_stream) && (first_stream != null))
+ {
+ first_stream.close();
+ second_stream.close();
+ }
+
+ if ((current_stream == second_stream) && (second_stream != null))
+ second_stream.close();
+
+ if (stream_list != null)
+ while (stream_list.hasMoreElements())
+ {
+ InputStream stream = (InputStream)stream_list.nextElement();
+ stream.close();
+ }
+
+ closed = true;
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads an unsigned byte from the input stream and returns it
+ * as an int in the range of 0-255. This method also will return -1 if
+ * the end of the stream has been reached. This will only happen when
+ * all of the subordinate streams have been read.
+ *
+ * This method will block until the byte can be read.
+ *
+ * @return The byte read, or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+read() throws IOException
+{
+ if (closed)
+ return(-1);
+
+ int byte_read = current_stream.read();
+
+ while (byte_read == -1)
+ {
+ getNextStream();
+ if (current_stream == null)
+ {
+ close();
+ return(-1);
+ }
+
+ byte_read = current_stream.read();
+ }
+
+ return(byte_read);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads bytes from a stream and stores them into a caller
+ * supplied buffer. It starts storing the data at index @code{offset} into
+ * the buffer and attempts to read @code{len} bytes. This method can
+ * return before reading the number of bytes requested. The actual number
+ * of bytes read is returned as an int. A -1 is returend to indicate the
+ * end of the stream. This will only happen when all of the subordinate
+ * streams have been read.
+ *
+ * This method will block until at least one byte can be read.
+ *
+ * @param buf The array into which bytes read should be stored
+ * @param offset The offset into the array to start storing bytes
+ * @param len The requested number of bytes to read
+ *
+ * @return The actual number of bytes read, or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+read(byte[] buf, int offset, int len) throws IOException
+{
+ if (closed)
+ return(-1);
+
+ if (len == 0)
+ return(0);
+
+ int total_read = 0;
+ for (;;)
+ {
+ int bytes_read = current_stream.read(buf, offset + total_read,
+ len - total_read);
+
+ // Are we done?
+ if (bytes_read == (len - total_read))
+ return(len);
+
+ // Is the current stream empty?
+ if (bytes_read == -1)
+ {
+ getNextStream();
+ if (current_stream == null)
+ {
+ close();
+ if (total_read == 0)
+ return(-1);
+ else
+ return(total_read);
+ }
+ }
+ else
+ total_read += bytes_read;
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * This private method is used to get the next @code{InputStream} to read
+ * from
+ */
+private void
+getNextStream()
+{
+ if (stream_list == null)
+ {
+ if (current_stream == first_stream)
+ current_stream = second_stream;
+ else
+ current_stream = null;
+ }
+ else
+ {
+ if (stream_list.hasMoreElements())
+ current_stream = (InputStream)stream_list.nextElement();
+ else
+ current_stream = null;
+ }
+
+ return;
+}
+
+} // class SequenceInputStream
+
diff --git a/java/io/Serializable.java b/java/io/Serializable.java
new file mode 100644
index 000000000..37113e7c1
--- /dev/null
+++ b/java/io/Serializable.java
@@ -0,0 +1,34 @@
+/*************************************************************************
+/* Serializable.java -- Interface to indicate a class may be serialized
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This interface has no methods. It simply serves to indicate that
+ * the implementing class may be serialized.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public interface Serializable
+{
+
+} // interface Serializable
+
diff --git a/java/io/StreamCorruptedException.java b/java/io/StreamCorruptedException.java
new file mode 100644
index 000000000..d53876399
--- /dev/null
+++ b/java/io/StreamCorruptedException.java
@@ -0,0 +1,60 @@
+/*************************************************************************
+/* StreamCorruptedException.java -- Error in stream during serialization
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when there is an error in the data that is
+ * read from a stream during de-serialization.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class StreamCorruptedException extends ObjectStreamException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new StreamCorruptedException without a descriptive error message
+ */
+public
+StreamCorruptedException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new StreamCorruptedException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+StreamCorruptedException(String message)
+{
+ super(message);
+}
+
+} // class StreamCorruptedException
+
diff --git a/java/io/StringBufferInputStream.java b/java/io/StringBufferInputStream.java
new file mode 100644
index 000000000..16b76bd8d
--- /dev/null
+++ b/java/io/StringBufferInputStream.java
@@ -0,0 +1,217 @@
+/*************************************************************************
+/* StringBufferInputStream.java -- Read an array as a stream
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This class permits a @code{String} to be read as an input stream. The low
+ * eight bits of each character in the @code{String} are the bytes that
+ * are returned. The high eight bits of each character are discarded.
+ *
+ * The mark/reset functionality in this class behaves differently than
+ * normal. The @code{mark()} method is always ignored and the @code{reset()}
+ * method always resets in stream to start reading from position 0 in
+ * the String. Note that since this method does not override
+ * @code{markSupported()} in @code{InputStream}, calling that method will
+ * return @code{false}.
+ *
+ * Note that this class is deprecated because it does not properly handle
+ * 16-bit Java characters. It is provided for backwards compatibility only
+ * and should not be used for new development. The @code{StringReader}
+ * class should be used instead.
+ *
+ * @deprecated
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class StringBufferInputStream extends InputStream
+{
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * The @code{String} that contains the data supplied during read operations
+ */
+protected String buffer;
+
+/**
+ * The index of the next byte to be read from @code{bufer}
+ */
+protected int pos = 0;
+
+/**
+ * This indicates the maximum number of bytes that can be read from this
+ * stream. It is the length of the @code{String} that this stream is
+ * reading bytes from.
+ */
+protected int count;
+
+/*************************************************************************/
+
+/**
+ * Create a new @code{StringBufferInputStream} that will read bytes from the
+ * passed in @code{String}. This stream will read from the beginning to the
+ * end of the @code{String}.
+ *
+ * @param s The @code{String} this stream will read from.
+ */
+public
+StringBufferInputStream(String s)
+{
+ buffer = s;
+ count = s.length();
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method returns the number of bytes available to be read from this
+ * stream. The value returned will be equal to @code{count - pos}.
+ *
+ * @return The number of bytes that can be read from this stream before blocking, which is all of them
+ */
+public int
+available()
+{
+ return(count - pos);
+}
+
+/*************************************************************************/
+
+/**
+ * This method sets the read position in the stream to the beginning
+ * setting the @code{pos} variable equal to 0. Note that this differs
+ * from the common implementation of the @code{reset()} method.
+ */
+public void
+reset()
+{
+ pos = 0;
+}
+
+/*************************************************************************/
+
+/**
+ * This method attempts to skip the requested number of bytes in the
+ * input stream. It does this by advancing the @code{pos} value by the
+ * specified number of bytes. It this would exceed the length of the
+ * buffer, then only enough bytes are skipped to position the stream at
+ * the end of the buffer. The actual number of bytes skipped is returned.
+ *
+ * @param num_bytes The requested number of bytes to skip
+ *
+ * @return The actual number of bytes skipped.
+ */
+public long
+skip(long num_bytes)
+{
+ if (num_bytes > (count - pos))
+ {
+ int retval = count - pos;
+ pos = count;
+ return(retval);
+ }
+
+ pos += num_bytes;
+ return(num_bytes);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads one byte from the stream. The @code{pos} counter is
+ * advanced to the next byte to be read. The byte read is returned as
+ * an int in the range of 0-255. If the stream position is already at the
+ * end of the buffer, no byte is read and a -1 is returned in order to
+ * indicate the end of the stream.
+ *
+ * @return The byte read, or -1 if end of stream
+ */
+public int
+read()
+{
+ if (pos >= count)
+ return(-1);
+
+ ++pos;
+
+ return(buffer.charAt(pos - 1) & 0xFF);
+}
+
+/*************************************************************************/
+
+/**
+ * This method reads bytes from the stream and stores them into a caller
+ * supplied buffer. It starts storing the data at index @code{offset} into
+ * the buffer and attempts to read @code{len} bytes. This method can
+ * return before reading the number of bytes requested if the end of the
+ * stream is encountered first. The actual number of bytes read is
+ * returned. If no bytes can be read because the stream is already at
+ * the end of stream position, a -1 is returned.
+ *
+ * This method does not block.
+ *
+ * @param buf The array into which the bytes read should be stored.
+ * @param offset The offset into the array to start storing bytes
+ * @param len The requested number of bytes to read
+ *
+ * @return The actual number of bytes read, or -1 if end of stream.
+ */
+public int
+read(byte[] buf, int offset, int len)
+{
+ if (len == 0)
+ return(0);
+
+ if (pos == count)
+ return(-1);
+
+ // All requested bytes can be read
+ if (len < (count - pos))
+ {
+ for (int i = 0; i < len; i++)
+ buf[offset + i] = (byte)(buffer.charAt(pos + i) & 0xFF);
+
+ pos +=len;
+ return(len);
+ }
+ // Cannot read all requested bytes because there aren't enough left in buf
+ else
+ {
+ for (int i = 0; i < (count - pos); i++)
+ buf[offset + i] = (byte)(buffer.charAt(pos + i) & 0xFF);
+
+ int retval = count - pos;
+ pos = count;
+ return(retval);
+ }
+}
+
+} // class StringBufferInputStream
+
diff --git a/java/io/SyncFailedException.java b/java/io/SyncFailedException.java
new file mode 100644
index 000000000..a174c704c
--- /dev/null
+++ b/java/io/SyncFailedException.java
@@ -0,0 +1,58 @@
+/*************************************************************************
+/* SyncFailedException.java -- The sync failed (?)
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * I really wish I knew what caused this exception to be thrown.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class SyncFailedException extends IOException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new SyncFailedException without a descriptive error message
+ */
+SyncFailedException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new SyncFailedException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+SyncFailedException(String message)
+{
+ super(message);
+}
+
+} // class SyncFailedException
+
diff --git a/java/io/UTFDataFormatException.java b/java/io/UTFDataFormatException.java
new file mode 100644
index 000000000..13514ed98
--- /dev/null
+++ b/java/io/UTFDataFormatException.java
@@ -0,0 +1,60 @@
+/*************************************************************************
+/* UTFDataFormatException.java -- Bad format in UTF data
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * When reading a UTF string from an input stream, this exception is thrown
+ * to indicate that the data read is invalid.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class UTFDataFormatException extends IOException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new UTFDataFormatException without a descriptive error message
+ */
+public
+UTFDataFormatException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new UTFDataFormatException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+UTFDataFormatException(String message)
+{
+ super(message);
+}
+
+} // class UTFDataFormatException
+
diff --git a/java/io/UnsupportedEncodingException.java b/java/io/UnsupportedEncodingException.java
new file mode 100644
index 000000000..08add8286
--- /dev/null
+++ b/java/io/UnsupportedEncodingException.java
@@ -0,0 +1,60 @@
+/*************************************************************************
+/* UnsupportedEncodingException.java -- The requested encoding isn't supported
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when the requested character encoding is
+ * not supported.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class UnsupportedEncodingException extends IOException
+{
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new UnsupportedEncodingException without a descriptive error message
+ */
+public
+UnsupportedEncodingException()
+{
+ super();
+}
+
+/*************************************************************************/
+
+/**
+ * Create a new UnsupportedEncodingException with a descriptive error message String
+ *
+ * @param message The descriptive error message
+ */
+public
+UnsupportedEncodingException(String message)
+{
+ super(message);
+}
+
+} // class UnsupportedEncodingException
+
diff --git a/java/io/WriteAbortedException.java b/java/io/WriteAbortedException.java
new file mode 100644
index 000000000..cd1d56c56
--- /dev/null
+++ b/java/io/WriteAbortedException.java
@@ -0,0 +1,77 @@
+/*************************************************************************
+/* WriteAbortedException.java -- An exception occured while writing a serialization stream
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by the Free Software Foundation, version 2. (see COPYING.LIB)
+/*
+/* This program 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 for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; if not, write to the Free Software Foundation
+/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
+/*************************************************************************/
+
+package java.io;
+
+/**
+ * This exception is thrown when one of the other ObjectStreamException
+ * subclasses was thrown during a serialization write.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public class WriteAbortedException extends ObjectStreamException
+{
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * The detailed exception that caused this exception to be thrown
+ */
+public Exception detail;
+
+/*************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+ * Create a new WriteAbortedException with an eof parameter indicating
+ * the detailed Exception that caused this exception to be thrown.
+ *
+ * @param detail The exception that caused this exception to be thrown
+ */
+WriteAbortedException(Exception detail)
+{
+ this.detail = detail;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+ * This method returns a message indicating what went wrong, including
+ * the message text from the initial exception that caused this one to
+ * be thrown
+ */
+public String
+getMessage()
+{
+ return(super.getMessage() + ": " + detail.getMessage());
+}
+
+} // class WriteAbortedException
+