diff options
author | Aaron M. Renn <arenn@urbanophile.com> | 1998-06-19 23:13:11 +0000 |
---|---|---|
committer | Aaron M. Renn <arenn@urbanophile.com> | 1998-06-19 23:13:11 +0000 |
commit | 349e4b13bfd0f368a3b58d8487ec698c347beae2 (patch) | |
tree | 0f2bd37bd779d9fcc17f396dc87b4df1c5ea44c5 | |
parent | e0a43139ffff705620e50a9d5dbe80438a3081b0 (diff) | |
download | classpath-349e4b13bfd0f368a3b58d8487ec698c347beae2.tar.gz |
Initial Checkin
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 + |